mirror of
https://github.com/mempool/mempool.git
synced 2026-08-13 12:33:11 +02:00
Merge branch 'master' into natsoni/taptree-from-psbt
This commit is contained in:
commit
ef9f7aa805
8 changed files with 158 additions and 110 deletions
|
|
@ -34,7 +34,17 @@ class FeeApi {
|
|||
const mPool = mempool.getMempoolInfo();
|
||||
|
||||
// minimum non-zero minrelaytxfee / incrementalrelayfee is 1 sat/kvB = 0.001 sat/vB
|
||||
return this.calculateRecommendedFee(pBlocks, mPool, 0.001);
|
||||
const recommendations = this.calculateRecommendedFee(pBlocks, mPool, 0.001);
|
||||
// enforce floor & offset for highest priority recommendations while <100% hashrate accepts sub-sat fees
|
||||
recommendations.fastestFee = Math.max(recommendations.fastestFee + this.priorityFactor, this.minFastestFee);
|
||||
recommendations.halfHourFee = Math.max(recommendations.halfHourFee + (this.priorityFactor / 2), this.minHalfHourFee);
|
||||
return {
|
||||
'fastestFee': Math.round(recommendations.fastestFee * 1000) / 1000,
|
||||
'halfHourFee': Math.round(recommendations.halfHourFee * 1000) / 1000,
|
||||
'hourFee': Math.round(recommendations.hourFee * 1000) / 1000,
|
||||
'economyFee': Math.round(recommendations.economyFee * 1000) / 1000,
|
||||
'minimumFee': Math.round(recommendations.minimumFee * 1000) / 1000,
|
||||
};
|
||||
}
|
||||
|
||||
public calculateRecommendedFee(pBlocks: MempoolBlock[], mPool: IBitcoinApi.MempoolInfo, minIncrement: number = this.minimumIncrement): RecommendedFees {
|
||||
|
|
@ -70,8 +80,8 @@ class FeeApi {
|
|||
hourFee = Math.max(hourFee, economyFee);
|
||||
|
||||
return {
|
||||
'fastestFee': Math.max(this.roundToNearest(fastestFee + this.priorityFactor, minIncrement), this.minFastestFee),
|
||||
'halfHourFee': Math.max(this.roundToNearest(halfHourFee + (this.priorityFactor / 2), minIncrement), this.minHalfHourFee),
|
||||
'fastestFee': this.roundToNearest(fastestFee, minIncrement),
|
||||
'halfHourFee': this.roundToNearest(halfHourFee, minIncrement),
|
||||
'hourFee': this.roundToNearest(hourFee, minIncrement),
|
||||
'economyFee': this.roundToNearest(economyFee, minIncrement),
|
||||
'minimumFee': this.roundToNearest(minimumFee, minIncrement),
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class Indexer {
|
|||
private indexerRunning = false;
|
||||
private tasksRunning: { [key in TaskName]?: boolean; } = {};
|
||||
private tasksScheduled: { [key in TaskName]?: NodeJS.Timeout; } = {};
|
||||
private reindexTimeout: NodeJS.Timeout | undefined;
|
||||
private coreIndexes: CoreIndex[] = [];
|
||||
|
||||
public indexerIsRunning(): boolean {
|
||||
|
|
@ -76,10 +77,23 @@ class Indexer {
|
|||
|
||||
public reindex(): void {
|
||||
if (Common.indexingEnabled()) {
|
||||
if (this.reindexTimeout) {
|
||||
clearTimeout(this.reindexTimeout);
|
||||
this.reindexTimeout = undefined;
|
||||
}
|
||||
this.runIndexer = true;
|
||||
}
|
||||
}
|
||||
|
||||
private scheduleNextRun(timeout: number): void {
|
||||
if (!this.reindexTimeout) { // Only one future run should be planned, ignore if already scheduled
|
||||
this.reindexTimeout = setTimeout(() => {
|
||||
this.reindexTimeout = undefined;
|
||||
this.reindex();
|
||||
}, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* schedules a single task to run in `timeout` ms
|
||||
* only one task of each type may be scheduled
|
||||
|
|
@ -156,34 +170,40 @@ class Indexer {
|
|||
return;
|
||||
}
|
||||
|
||||
if (config.FIAT_PRICE.ENABLED) {
|
||||
try {
|
||||
await priceUpdater.$run();
|
||||
} catch (e) {
|
||||
logger.err(`Running priceUpdater failed. Reason: ` + (e instanceof Error ? e.message : e));
|
||||
}
|
||||
}
|
||||
|
||||
// Do not attempt to index anything unless Bitcoin Core is fully synced
|
||||
const blockchainInfo = await bitcoinClient.getBlockchainInfo();
|
||||
if (blockchainInfo.blocks !== blockchainInfo.headers) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.runIndexer = false;
|
||||
this.indexerRunning = true;
|
||||
|
||||
logger.debug(`Running mining indexer`);
|
||||
|
||||
await this.checkAvailableCoreIndexes();
|
||||
const retryDelay = 10000;
|
||||
const runEvery = 1000 * 3600; // 1 hour
|
||||
let nextRunDelay = runEvery;
|
||||
let runSuccessful = false;
|
||||
|
||||
try {
|
||||
if (config.FIAT_PRICE.ENABLED) {
|
||||
try {
|
||||
await priceUpdater.$run();
|
||||
} catch (e) {
|
||||
logger.err(`Running priceUpdater failed. Reason: ` + (e instanceof Error ? e.message : e));
|
||||
}
|
||||
}
|
||||
|
||||
// Do not attempt to index anything unless Bitcoin Core is fully synced
|
||||
const blockchainInfo = await bitcoinClient.getBlockchainInfo();
|
||||
if (blockchainInfo.blocks !== blockchainInfo.headers) {
|
||||
logger.debug(`Bitcoin Core not fully synced, retrying index run in 10 seconds.`);
|
||||
nextRunDelay = retryDelay;
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug(`Running mining indexer`);
|
||||
|
||||
await this.checkAvailableCoreIndexes();
|
||||
|
||||
const chainValid = await blocks.$generateBlockDatabase();
|
||||
if (chainValid === false) {
|
||||
// Chain of block hash was invalid, so we need to reindex. Stop here and continue at the next iteration
|
||||
logger.warn(`The chain of block hash is invalid, re-indexing invalid data in 10 seconds.`, logger.tags.mining);
|
||||
setTimeout(() => this.reindex(), 10000);
|
||||
this.indexerRunning = false;
|
||||
nextRunDelay = retryDelay;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -202,19 +222,20 @@ class Indexer {
|
|||
await BlocksRepository.$migrateBlocks();
|
||||
// do not wait for classify blocks to finish
|
||||
blocks.$classifyBlocks();
|
||||
runSuccessful = true;
|
||||
} catch (e) {
|
||||
this.indexerRunning = false;
|
||||
nextRunDelay = retryDelay;
|
||||
logger.err(`Indexer failed, trying again in 10 seconds. Reason: ` + (e instanceof Error ? e.message : e));
|
||||
setTimeout(() => this.reindex(), 10000);
|
||||
} finally {
|
||||
this.indexerRunning = false;
|
||||
return;
|
||||
const nextRunAt = new Date(Date.now() + nextRunDelay).toUTCString();
|
||||
if (runSuccessful) {
|
||||
logger.debug(`Indexing completed. Next run planned at ${nextRunAt}`);
|
||||
} else {
|
||||
logger.debug(`Indexing did not complete, next run planned at ${nextRunAt}`);
|
||||
}
|
||||
this.scheduleNextRun(nextRunDelay);
|
||||
}
|
||||
|
||||
this.indexerRunning = false;
|
||||
|
||||
const runEvery = 1000 * 3600; // 1 hour
|
||||
logger.debug(`Indexing completed. Next run planned at ${new Date(new Date().getTime() + runEvery).toUTCString()}`);
|
||||
setTimeout(() => this.reindex(), runEvery);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -216,8 +216,9 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
|||
}
|
||||
if (this._step === 'checkout' && this.canPayWithBitcoin) {
|
||||
this.btcpayInvoiceFailed = false;
|
||||
this.invoice = null;
|
||||
this.invoice = undefined;
|
||||
this.requestBTCPayInvoice();
|
||||
this.scrollToElementWithTimeout('acceleratePreviewAnchor', 'start', 100);
|
||||
} else if (this._step === 'cashapp') {
|
||||
this.loadingCashapp = true;
|
||||
this.setupSquare();
|
||||
|
|
|
|||
|
|
@ -11,12 +11,6 @@
|
|||
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="daysAvailable">
|
||||
<div class="btn-group btn-group-toggle" name="radioBasic">
|
||||
<label class="btn btn-primary btn-sm" [class.active]="radioGroupForm.get('dateSpan').value === '24h'">
|
||||
<input type="radio" [value]="'24h'" fragment="24h" [routerLink]="['/graphs/acceleration/fees' | relativeUrl]" formControlName="dateSpan"> 24H
|
||||
</label>
|
||||
<label class="btn btn-primary btn-sm" *ngIf="daysAvailable >= 1" [class.active]="radioGroupForm.get('dateSpan').value === '3d'">
|
||||
<input type="radio" [value]="'3d'" fragment="3d" [routerLink]="['/graphs/acceleration/fees' | relativeUrl]" formControlName="dateSpan"> 3D
|
||||
</label>
|
||||
<label class="btn btn-primary btn-sm" *ngIf="daysAvailable >= 3" [class.active]="radioGroupForm.get('dateSpan').value === '1w'">
|
||||
<input type="radio" [value]="'1w'" fragment="1w" [routerLink]="['/graphs/acceleration/fees' | relativeUrl]" formControlName="dateSpan"> 1W
|
||||
</label>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Input, LOCALE_ID, NgZone, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
|
||||
import { EChartsOption } from '@app/graphs/echarts';
|
||||
import { echarts, EChartsOption } from '@app/graphs/echarts';
|
||||
import { Observable, Subject, Subscription, combineLatest, fromEvent, merge, share } from 'rxjs';
|
||||
import { startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { SeoService } from '@app/services/seo.service';
|
||||
|
|
@ -12,7 +12,6 @@ import { ActivatedRoute, Router } from '@angular/router';
|
|||
import { Acceleration } from '@interfaces/node-api.interface';
|
||||
import { ServicesApiServices } from '@app/services/services-api.service';
|
||||
import { StateService } from '@app/services/state.service';
|
||||
import { RelativeUrlPipe } from '@app/shared/pipes/relative-url/relative-url.pipe';
|
||||
|
||||
@Component({
|
||||
selector: 'app-acceleration-fees-graph',
|
||||
|
|
@ -32,9 +31,9 @@ import { RelativeUrlPipe } from '@app/shared/pipes/relative-url/relative-url.pip
|
|||
export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() widget: boolean = false;
|
||||
@Input() height: number = 300;
|
||||
@Input() right: number | string = 45;
|
||||
@Input() left: number | string = 75;
|
||||
@Input() period: '24h' | '3d' | '1w' | '1m' | 'all' = '1w';
|
||||
@Input() right: number | string = 70;
|
||||
@Input() left: number | string = 55;
|
||||
@Input() period: '24h' | '1w' | '1m' | '1y' | 'all' = '1y';
|
||||
@Input() accelerations$: Observable<Acceleration[]>;
|
||||
|
||||
miningWindowPreference: string;
|
||||
|
|
@ -52,7 +51,7 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
|
|||
isLoading = true;
|
||||
formatNumber = formatNumber;
|
||||
timespan = '';
|
||||
periodSubject$: Subject<'24h' | '3d' | '1w' | '1m' | 'all'> = new Subject();
|
||||
periodSubject$: Subject<'24h' | '1w' | '1m' | '1y' | 'all'> = new Subject();
|
||||
chartInstance: any = undefined;
|
||||
daysAvailable: number = 0;
|
||||
|
||||
|
|
@ -65,9 +64,7 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
|
|||
private miningService: MiningService,
|
||||
private route: ActivatedRoute,
|
||||
public stateService: StateService,
|
||||
private cd: ChangeDetectorRef,
|
||||
private router: Router,
|
||||
private zone: NgZone,
|
||||
private cd: ChangeDetectorRef
|
||||
) {
|
||||
this.radioGroupForm = this.formBuilder.group({ dateSpan: '1w' });
|
||||
this.radioGroupForm.controls.dateSpan.setValue('1w');
|
||||
|
|
@ -84,7 +81,7 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
|
|||
this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference);
|
||||
|
||||
this.fragmentSubscription = this.route.fragment.subscribe((fragment) => {
|
||||
if (['24h', '3d', '1w', '1m', '3m', 'all'].indexOf(fragment) > -1) {
|
||||
if (['1w', '1m', '1y', 'all'].indexOf(fragment) > -1) {
|
||||
this.radioGroupForm.controls.dateSpan.setValue(fragment, { emitEvent: false });
|
||||
}
|
||||
});
|
||||
|
|
@ -99,7 +96,9 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
|
|||
if (!this.widget) {
|
||||
this.storageService.setValue('miningWindowPreference', timespan);
|
||||
}
|
||||
this.isLoading = true;
|
||||
if (timespan !== this.timespan) {
|
||||
this.isLoading = true;
|
||||
}
|
||||
this.timespan = timespan;
|
||||
return this.servicesApiService.getAggregatedAccelerationHistory$({timeframe: this.timespan});
|
||||
})
|
||||
|
|
@ -121,6 +120,9 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
|
|||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes.period) {
|
||||
if (this.period === '24h') {
|
||||
this.period = '1m';
|
||||
}
|
||||
this.periodSubject$.next(this.period);
|
||||
}
|
||||
}
|
||||
|
|
@ -142,13 +144,19 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
|
|||
this.chartOptions = {
|
||||
title: title,
|
||||
color: [
|
||||
'#8F5FF6',
|
||||
'#6b6b6b',
|
||||
new echarts.graphic.LinearGradient(0, 0, 0, 0.65, [
|
||||
{ offset: 0, color: '#F4511E' },
|
||||
{ offset: 0.25, color: '#FB8C00' },
|
||||
{ offset: 0.5, color: '#FFB300' },
|
||||
{ offset: 0.75, color: '#FDD835' },
|
||||
{ offset: 1, color: '#7CB342' }
|
||||
]),
|
||||
'#ab2dce',
|
||||
],
|
||||
animation: false,
|
||||
grid: {
|
||||
height: (this.widget && this.height) ? this.height - 30 : undefined,
|
||||
top: this.widget ? 20 : 40,
|
||||
height: (this.widget && this.height) ? this.height - 50 : undefined,
|
||||
top: this.widget ? 40 : 60,
|
||||
bottom: this.widget ? 30 : 80,
|
||||
right: this.right,
|
||||
left: this.left,
|
||||
|
|
@ -170,17 +178,18 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
|
|||
formatter: (ticks) => {
|
||||
let tooltip = `<b style="color: white; margin-left: 2px">${formatterXAxis(this.locale, this.timespan, parseInt(ticks[0].axisValue, 10))}</b><br>`;
|
||||
|
||||
if (ticks[0].data[1] > 10_000_000) {
|
||||
tooltip += `${ticks[0].marker} ${ticks[0].seriesName}: ${formatNumber(ticks[0].data[1] / 100_000_000, this.locale, '1.0-8')} BTC<br>`;
|
||||
} else {
|
||||
tooltip += `${ticks[0].marker} ${ticks[0].seriesName}: ${formatNumber(ticks[0].data[1], this.locale, '1.0-0')} sats<br>`;
|
||||
}
|
||||
|
||||
if (['24h', '3d'].includes(this.timespan)) {
|
||||
tooltip += `<small>` + $localize`At block: ${ticks[0].data[2]}` + `</small>`;
|
||||
} else {
|
||||
tooltip += `<small>` + $localize`Around block: ${ticks[0].data[2]}` + `</small>`;
|
||||
for (const tick of ticks) {
|
||||
if (tick.seriesName === 'Total bid boost') {
|
||||
if (tick.data[1] > 10_000_000) {
|
||||
tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1] / 100_000_000, this.locale, '1.0-8')} BTC<br>`;
|
||||
} else {
|
||||
tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.0-0')} sats<br>`;
|
||||
}
|
||||
} else if (tick && tick.seriesName === 'Accelerated') {
|
||||
tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.0-0')}<br>`;
|
||||
}
|
||||
}
|
||||
tooltip += `<small>` + $localize`Around block: ${ticks[0].data[2]}` + `</small>`;
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
|
@ -212,6 +221,17 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
|
|||
textStyle: {
|
||||
color: 'white',
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#FFB300',
|
||||
},
|
||||
icon: 'roundRect',
|
||||
},
|
||||
{
|
||||
name: 'Accelerated',
|
||||
inactiveColor: 'rgb(110, 112, 121)',
|
||||
textStyle: {
|
||||
color: 'white',
|
||||
},
|
||||
icon: 'roundRect',
|
||||
},
|
||||
],
|
||||
|
|
@ -223,6 +243,13 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
|
|||
yAxis: data.length === 0 ? undefined : [
|
||||
{
|
||||
type: 'value',
|
||||
name: 'Total bid boost',
|
||||
position: 'right',
|
||||
nameTextStyle: {
|
||||
align: 'right',
|
||||
padding: [0, -65, 0, 0],
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
axisLabel: {
|
||||
color: 'rgb(110, 112, 121)',
|
||||
formatter: (val) => {
|
||||
|
|
@ -233,6 +260,20 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
|
|||
}
|
||||
}
|
||||
},
|
||||
splitLine: null
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: 'Accelerated',
|
||||
position: 'left',
|
||||
axisLabel: {
|
||||
color: 'rgb(110, 112, 121)',
|
||||
},
|
||||
nameTextStyle: {
|
||||
align: 'right',
|
||||
padding: [0, -35, 0, 0],
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dotted',
|
||||
|
|
@ -241,33 +282,28 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
|
|||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
position: 'right',
|
||||
axisLabel: {
|
||||
color: 'rgb(110, 112, 121)',
|
||||
formatter: function(val) {
|
||||
return `${val}`;
|
||||
}.bind(this)
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
series: data.length === 0 ? undefined : [
|
||||
{
|
||||
legendHoverLink: false,
|
||||
zlevel: 1,
|
||||
name: 'Total bid boost',
|
||||
data: data.map(h => {
|
||||
return [h.timestamp * 1000, h.sumBidBoost, h.avgHeight]
|
||||
}),
|
||||
stack: 'Total',
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
},
|
||||
smooth: true,
|
||||
},
|
||||
{
|
||||
name: 'Accelerated',
|
||||
yAxisIndex: 1,
|
||||
data: data.map(h => {
|
||||
return [h.timestamp * 1000, h.count, h.avgHeight]
|
||||
}),
|
||||
type: 'bar',
|
||||
barWidth: '90%',
|
||||
large: true,
|
||||
barMinHeight: 3,
|
||||
},
|
||||
],
|
||||
dataZoom: (this.widget || data.length === 0 )? undefined : [{
|
||||
|
|
@ -300,19 +336,6 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
|
|||
|
||||
onChartInit(ec) {
|
||||
this.chartInstance = ec;
|
||||
|
||||
this.chartInstance.on('click', (e) => {
|
||||
this.zone.run(() => {
|
||||
if (['24h', '3d'].includes(this.timespan)) {
|
||||
const url = new RelativeUrlPipe(this.stateService).transform(`/block/${e.data[2]}`);
|
||||
if (e.event.event.shiftKey || e.event.event.ctrlKey || e.event.event.metaKey) {
|
||||
window.open(url);
|
||||
} else {
|
||||
this.router.navigate([url]);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
isMobile() {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ export type AccelerationStats = {
|
|||
standalone: false,
|
||||
})
|
||||
export class AccelerationStatsComponent implements OnInit, OnChanges {
|
||||
@Input() timespan: '24h' | '3d' | '1w' | '1m' | 'all' = '1w';
|
||||
@Input() timespan: '24h' | '1m' | '1y' | 'all' = '1y';
|
||||
accelerationStats$: Observable<AccelerationStats>;
|
||||
blocksInPeriod: number = 7 * 144;
|
||||
|
||||
|
|
@ -39,15 +39,12 @@ export class AccelerationStatsComponent implements OnInit, OnChanges {
|
|||
case '24h':
|
||||
this.blocksInPeriod = 144;
|
||||
break;
|
||||
case '3d':
|
||||
this.blocksInPeriod = 3 * 144;
|
||||
break;
|
||||
case '1w':
|
||||
this.blocksInPeriod = 7 * 144;
|
||||
break;
|
||||
case '1m':
|
||||
this.blocksInPeriod = 30 * 144;
|
||||
this.blocksInPeriod = 30.5 * 144;
|
||||
break;
|
||||
case '1y':
|
||||
this.blocksInPeriod = 30.5 * 144 * 365;
|
||||
break;
|
||||
case 'all':
|
||||
this.blocksInPeriod = Infinity;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@
|
|||
@case ('24h') {
|
||||
<span style="font-size: xx-small" i18n="mining.1-day">(1 day)</span>
|
||||
}
|
||||
@case ('1w') {
|
||||
<span style="font-size: xx-small" i18n="mining.1-week">(1 week)</span>
|
||||
}
|
||||
@case ('1m') {
|
||||
<span style="font-size: xx-small" i18n="mining.1-month">(1 month)</span>
|
||||
}
|
||||
@case ('1y') {
|
||||
<span style="font-size: xx-small" i18n="mining.1-year">(1 year)</span>
|
||||
}
|
||||
@case ('all') {
|
||||
<span style="font-size: xx-small" i18n="mining.all-time">(all time)</span>
|
||||
}
|
||||
|
|
@ -45,12 +45,12 @@
|
|||
<a href="" (click)="setTimespan('24h')" class="toggler-option"
|
||||
[ngClass]="{'inactive': timespan === '24h'}"><small>24h</small></a>
|
||||
<span style="color: #ffffff66; font-size: 8px"> | </span>
|
||||
<a href="" (click)="setTimespan('1w')" class="toggler-option"
|
||||
[ngClass]="{'inactive': timespan === '1w'}"><small>1w</small></a>
|
||||
<span style="color: #ffffff66; font-size: 8px"> | </span>
|
||||
<a href="" (click)="setTimespan('1m')" class="toggler-option"
|
||||
[ngClass]="{'inactive': timespan === '1m'}"><small>1m</small></a>
|
||||
<span style="color: #ffffff66; font-size: 8px"> | </span>
|
||||
<a href="" (click)="setTimespan('1y')" class="toggler-option"
|
||||
[ngClass]="{'inactive': timespan === '1y'}"><small>1y</small></a>
|
||||
<span style="color: #ffffff66; font-size: 8px"> | </span>
|
||||
<a href="" (click)="setTimespan('all')" class="toggler-option"
|
||||
[ngClass]="{'inactive': timespan === 'all'}"><small i18n="all">all</small></a>
|
||||
</div>
|
||||
|
|
@ -79,13 +79,15 @@
|
|||
<div class="col" style="margin-bottom: 1.47rem">
|
||||
<div class="card graph-card">
|
||||
<div class="card-body pl-2 pr-2">
|
||||
<h5 class="card-title" i18n="acceleration.total-bid-boost">Total Bid Boost</h5>
|
||||
<h5 class="card-title" i18n="acceleration.historical-trend">Historical Trend</h5>
|
||||
<div class="mempool-graph">
|
||||
<app-acceleration-fees-graph
|
||||
[height]="graphHeight"
|
||||
[attr.data-cy]="'acceleration-fees'"
|
||||
[widget]=true
|
||||
[period]="timespan"
|
||||
[right]="80"
|
||||
[left]="50"
|
||||
></app-acceleration-fees-graph>
|
||||
</div>
|
||||
<div class="mt-1"><a [attr.data-cy]="'acceleration-fees-view-more'" [routerLink]="['/graphs/acceleration/fees' | relativeUrl]" i18n="dashboard.view-more">View more »</a></div>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export class AcceleratorDashboardComponent implements OnInit, OnDestroy {
|
|||
webGlEnabled = true;
|
||||
seen: Set<string> = new Set();
|
||||
firstLoad = true;
|
||||
timespan: '24h' | '3d' | '1w' | '1m' | 'all' = '1w';
|
||||
timespan: '24h' | '1m' | '1y' | 'all' = '1y';
|
||||
|
||||
accelerationDeltaSubscription: Subscription;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue