mirror of
https://github.com/mempool/mempool.git
synced 2024-11-19 09:52:14 +01:00
Merge pull request #3869 from mempool/mononaut/vb-wu-preference
Weight unit preference
This commit is contained in:
commit
ad9d9c839b
@ -64,9 +64,10 @@
|
||||
{{ bisqTx.burntFee / 100 | number: '1.2-2' }} <span class="symbol">BSQ</span> <span class="fiat"><app-bsq-amount [bsq]="bisqTx.burntFee" [forceFiat]="true" [green]="true"></app-bsq-amount></span>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="transaction.fee-per-vbyte|Transaction fee">Fee per vByte</td>
|
||||
<td *only-vsize i18n="transaction.fee-per-vbyte|Transaction fee">Fee per vByte</td>
|
||||
<td *only-weight i18n="transaction.fee-per-wu|Transaction fee">Fee per weight unit</td>
|
||||
<td *ngIf="!isLoadingTx; else loadingTxFee">
|
||||
{{ tx.fee / (tx.weight / 4) | feeRounding }} <span class="symbol">sat/vB</span>
|
||||
<app-fee-rate [fee]="tx.fee" [weight]="tx.weight"></app-fee-rate>
|
||||
|
||||
<app-tx-fee-rating [tx]="tx"></app-tx-fee-rating>
|
||||
</td>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, NgZone, OnInit } from '@angular/core';
|
||||
import { EChartsOption } from 'echarts';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Observable, Subscription, combineLatest } from 'rxjs';
|
||||
import { map, share, startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
@ -76,10 +76,11 @@ export class BlockFeeRatesGraphComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
|
||||
this.statsObservable$ = this.radioGroupForm.get('dateSpan').valueChanges
|
||||
.pipe(
|
||||
startWith(this.radioGroupForm.controls.dateSpan.value),
|
||||
switchMap((timespan) => {
|
||||
this.statsObservable$ = combineLatest([
|
||||
this.radioGroupForm.get('dateSpan').valueChanges.pipe(startWith(this.radioGroupForm.controls.dateSpan.value)),
|
||||
this.stateService.rateUnits$
|
||||
]).pipe(
|
||||
switchMap(([timespan, rateUnits]) => {
|
||||
this.storageService.setValue('miningWindowPreference', timespan);
|
||||
this.timespan = timespan;
|
||||
this.isLoading = true;
|
||||
@ -135,8 +136,8 @@ export class BlockFeeRatesGraphComponent implements OnInit {
|
||||
|
||||
this.prepareChartOptions({
|
||||
legends: legends,
|
||||
series: series,
|
||||
});
|
||||
series: series
|
||||
}, rateUnits === 'wu');
|
||||
this.isLoading = false;
|
||||
}),
|
||||
map((response) => {
|
||||
@ -150,7 +151,7 @@ export class BlockFeeRatesGraphComponent implements OnInit {
|
||||
);
|
||||
}
|
||||
|
||||
prepareChartOptions(data) {
|
||||
prepareChartOptions(data, weightMode) {
|
||||
this.chartOptions = {
|
||||
color: ['#D81B60', '#8E24AA', '#1E88E5', '#7CB342', '#FDD835', '#6D4C41', '#546E7A'],
|
||||
animation: false,
|
||||
@ -181,7 +182,11 @@ export class BlockFeeRatesGraphComponent implements OnInit {
|
||||
let tooltip = `<b style="color: white; margin-left: 2px">${formatterXAxis(this.locale, this.timespan, parseInt(data[0].axisValue, 10))}</b><br>`;
|
||||
|
||||
for (const rate of data.reverse()) {
|
||||
tooltip += `${rate.marker} ${rate.seriesName}: ${rate.data[1]} sats/vByte<br>`;
|
||||
if (weightMode) {
|
||||
tooltip += `${rate.marker} ${rate.seriesName}: ${rate.data[1] / 4} sats/WU<br>`;
|
||||
} else {
|
||||
tooltip += `${rate.marker} ${rate.seriesName}: ${rate.data[1]} sats/vByte<br>`;
|
||||
}
|
||||
}
|
||||
|
||||
if (['24h', '3d'].includes(this.timespan)) {
|
||||
@ -231,9 +236,12 @@ export class BlockFeeRatesGraphComponent implements OnInit {
|
||||
axisLabel: {
|
||||
color: 'rgb(110, 112, 121)',
|
||||
formatter: (val) => {
|
||||
if (weightMode) {
|
||||
val /= 4;
|
||||
}
|
||||
const selectedPowerOfTen: any = selectPowerOfTen(val);
|
||||
const newVal = Math.round(val / selectedPowerOfTen.divider);
|
||||
return `${newVal}${selectedPowerOfTen.unit} s/vB`;
|
||||
return `${newVal}${selectedPowerOfTen.unit} s/${weightMode ? 'WU': 'vB'}`;
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
|
@ -25,19 +25,23 @@
|
||||
<tr>
|
||||
<td class="td-width" i18n="transaction.fee-rate|Transaction fee rate">Fee rate</td>
|
||||
<td>
|
||||
{{ feeRate | feeRounding }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
<app-fee-rate [fee]="feeRate"></app-fee-rate>
|
||||
</td>
|
||||
</tr>
|
||||
<tr *ngIf="effectiveRate && effectiveRate !== feeRate">
|
||||
<td class="td-width" i18n="transaction.effective-fee-rate|Effective transaction fee rate">Effective fee rate</td>
|
||||
<td>
|
||||
{{ effectiveRate | feeRounding }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
<app-fee-rate [fee]="effectiveRate"></app-fee-rate>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr *only-vsize>
|
||||
<td class="td-width" i18n="transaction.vsize|Transaction Virtual Size">Virtual size</td>
|
||||
<td [innerHTML]="'‎' + (vsize | vbytes: 2)"></td>
|
||||
</tr>
|
||||
<tr *only-weight>
|
||||
<td class="td-width" i18n="transaction.weight|Transaction Weight">Weight</td>
|
||||
<td [innerHTML]="'‎' + ((vsize * 4) | wuBytes: 2)"></td>
|
||||
</tr>
|
||||
<tr *ngIf="auditEnabled && tx && tx.status && tx.status.length">
|
||||
<td class="td-width" i18n="transaction.audit-status">Audit status</td>
|
||||
<ng-container [ngSwitch]="tx?.status">
|
||||
|
@ -34,7 +34,7 @@
|
||||
</tr>
|
||||
<tr *ngIf="block?.extras?.medianFee != undefined">
|
||||
<td class="td-width" i18n="block.median-fee">Median fee</td>
|
||||
<td>~{{ block?.extras?.medianFee | number:'1.0-0' }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></td>
|
||||
<td>~<app-fee-rate [fee]="block?.extras?.medianFee" rounding="1.0-0"></app-fee-rate></td>
|
||||
</tr>
|
||||
<ng-template [ngIf]="fees !== undefined">
|
||||
<tr>
|
||||
|
@ -121,11 +121,11 @@
|
||||
<ng-container *ngIf="!isLoadingBlock; else loadingRest">
|
||||
<tr *ngIf="network !== 'liquid' && network !== 'liquidtestnet'">
|
||||
<td i18n="mempool-block.fee-span">Fee span</td>
|
||||
<td><span>{{ block?.extras?.minFee | number:'1.0-0' }} - {{ block?.extras?.maxFee | number:'1.0-0' }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></span></td>
|
||||
<td><app-fee-rate [fee]="block?.extras?.minFee" [showUnit]="false" rounding="1.0-0"></app-fee-rate> - <app-fee-rate [fee]="block?.extras?.maxFee" rounding="1.0-0"></app-fee-rate></td>
|
||||
</tr>
|
||||
<tr *ngIf="block?.extras?.medianFee != undefined">
|
||||
<td class="td-width" i18n="block.median-fee">Median fee</td>
|
||||
<td>~{{ block?.extras?.medianFee | number:'1.0-0' }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
<td>~<app-fee-rate [fee]="block?.extras?.medianFee" rounding="1.0-0"></app-fee-rate>
|
||||
<span class="fiat">
|
||||
<app-fiat [blockConversion]="blockConversion" [value]="block?.extras?.medianFee * 140" digitsInfo="1.2-2"
|
||||
i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes"
|
||||
|
@ -22,8 +22,7 @@
|
||||
<div class="block-body">
|
||||
<ng-container *ngIf="!minimal">
|
||||
<div *ngIf="block?.extras; else emptyfees" [attr.data-cy]="'bitcoin-block-offset=' + offset + '-index-' + i + '-fees'" class="fees">
|
||||
~{{ block?.extras?.medianFee | number:feeRounding }} <ng-container
|
||||
i18n="shared.sat-vbyte|sat/vB">sat/vB</ng-container>
|
||||
~<app-fee-rate [fee]="block?.extras?.medianFee" unitClass="" rounding="1.0-0"></app-fee-rate>
|
||||
</div>
|
||||
<ng-template #emptyfees>
|
||||
<div [attr.data-cy]="'bitcoin-block-offset=' + offset + '-index-' + i + '-fees'" class="fees">
|
||||
@ -32,8 +31,9 @@
|
||||
</ng-template>
|
||||
<div [attr.data-cy]="'bitcoin-block-' + offset + '-index-' + i + '-fee-span'" class="fee-span"
|
||||
*ngIf="block?.extras?.minFee != null && block?.extras?.maxFee != null; else emptyfeespan">
|
||||
{{ block.extras.minFee | number:feeRounding }} - {{ block.extras.maxFee | number:feeRounding }} <ng-container
|
||||
i18n="shared.sat-vbyte|sat/vB">sat/vB</ng-container>
|
||||
<app-fee-rate [fee]="block?.extras?.minFee" [showUnit]="false" rounding="1.0-0" unitClass=""></app-fee-rate>
|
||||
-
|
||||
<app-fee-rate [fee]="block?.extras?.maxFee" rounding="1.0-0" unitClass=""></app-fee-rate>
|
||||
</div>
|
||||
<ng-template #emptyfeespan>
|
||||
<div [attr.data-cy]="'bitcoin-block-offset=' + offset + '-index-' + i + '-fees'" class="fee-span">
|
||||
|
@ -45,7 +45,9 @@
|
||||
</div>
|
||||
<div class="stats top right">
|
||||
<p class="label" i18n="clock.priority-rate|priority fee rate">priority rate</p>
|
||||
<p *ngIf="recommendedFees$ | async as recommendedFees;" i18n="shared.sat-vbyte|sat/vB">{{ recommendedFees.fastestFee }} sat/vB</p>
|
||||
<p *ngIf="recommendedFees$ | async as recommendedFees;">
|
||||
<app-fee-rate [fee]="recommendedFees.fastestFee" unitClass="" rounding="1.0-0"></app-fee-rate>
|
||||
</p>
|
||||
</div>
|
||||
<div *ngIf="mode !== 'mempool' && blocks?.length" class="stats bottom left">
|
||||
<p [innerHTML]="blocks[blockIndex].size | bytes: 2"></p>
|
||||
|
@ -1,16 +1,17 @@
|
||||
import { OnChanges } from '@angular/core';
|
||||
import { OnChanges, OnDestroy } from '@angular/core';
|
||||
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { TransactionStripped } from '../../interfaces/websocket.interface';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { VbytesPipe } from '../../shared/pipes/bytes-pipe/vbytes.pipe';
|
||||
import { selectPowerOfTen } from '../../bitcoin.utils';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-fee-distribution-graph',
|
||||
templateUrl: './fee-distribution-graph.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class FeeDistributionGraphComponent implements OnInit, OnChanges {
|
||||
export class FeeDistributionGraphComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() feeRange: number[];
|
||||
@Input() vsize: number;
|
||||
@Input() transactions: TransactionStripped[];
|
||||
@ -25,6 +26,8 @@ export class FeeDistributionGraphComponent implements OnInit, OnChanges {
|
||||
data: number[][];
|
||||
labelInterval: number = 50;
|
||||
|
||||
rateUnitSub: Subscription;
|
||||
weightMode: boolean = false;
|
||||
mempoolVsizeFeesOptions: any;
|
||||
mempoolVsizeFeesInitOptions = {
|
||||
renderer: 'svg'
|
||||
@ -35,8 +38,13 @@ export class FeeDistributionGraphComponent implements OnInit, OnChanges {
|
||||
private vbytesPipe: VbytesPipe,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.mountChart();
|
||||
ngOnInit() {
|
||||
this.rateUnitSub = this.stateService.rateUnits$.subscribe(rateUnits => {
|
||||
this.weightMode = rateUnits === 'wu';
|
||||
if (this.data) {
|
||||
this.mountChart();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
@ -122,8 +130,9 @@ export class FeeDistributionGraphComponent implements OnInit, OnChanges {
|
||||
},
|
||||
axisLabel: {
|
||||
formatter: (value: number): string => {
|
||||
const selectedPowerOfTen = selectPowerOfTen(value);
|
||||
const newVal = Math.round(value / selectedPowerOfTen.divider);
|
||||
const unitValue = this.weightMode ? value / 4 : value;
|
||||
const selectedPowerOfTen = selectPowerOfTen(unitValue);
|
||||
const newVal = Math.round(unitValue / selectedPowerOfTen.divider);
|
||||
return `${newVal}${selectedPowerOfTen.unit}`;
|
||||
},
|
||||
}
|
||||
@ -138,10 +147,11 @@ export class FeeDistributionGraphComponent implements OnInit, OnChanges {
|
||||
textShadowBlur: 0,
|
||||
formatter: (label: { data: number[] }): string => {
|
||||
const value = label.data[1];
|
||||
const selectedPowerOfTen = selectPowerOfTen(value);
|
||||
const newVal = Math.round(value / selectedPowerOfTen.divider);
|
||||
const unitValue = this.weightMode ? value / 4 : value;
|
||||
const selectedPowerOfTen = selectPowerOfTen(unitValue);
|
||||
const newVal = Math.round(unitValue / selectedPowerOfTen.divider);
|
||||
return `${newVal}${selectedPowerOfTen.unit}`;
|
||||
},
|
||||
}
|
||||
},
|
||||
showAllSymbol: false,
|
||||
smooth: true,
|
||||
@ -162,4 +172,8 @@ export class FeeDistributionGraphComponent implements OnInit, OnChanges {
|
||||
}]
|
||||
};
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.rateUnitSub.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
@ -13,23 +13,23 @@
|
||||
<div class="fee-estimation-container">
|
||||
<div class="item">
|
||||
<div class="card-text">
|
||||
<div class="fee-text">{{ recommendedFees.economyFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.economyFee * 140" ></app-fiat></span>
|
||||
<div class="fee-text"><app-fee-rate [fee]="recommendedFees.economyFee" rounding="1.0-0"></app-fee-rate></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.economyFee * 140" ></app-fiat></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="band-separator"></div>
|
||||
<div class="item">
|
||||
<div class="card-text">
|
||||
<div class="fee-text">{{ recommendedFees.hourFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.hourFee * 140" ></app-fiat></span>
|
||||
<div class="fee-text"><app-fee-rate [fee]="recommendedFees.hourFee" rounding="1.0-0"></app-fee-rate></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.hourFee * 140" ></app-fiat></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="card-text">
|
||||
<div class="fee-text">{{ recommendedFees.halfHourFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.halfHourFee * 140" ></app-fiat></span>
|
||||
<div class="fee-text"><app-fee-rate [fee]="recommendedFees.halfHourFee" rounding="1.0-0"></app-fee-rate></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.halfHourFee * 140" ></app-fiat></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="card-text">
|
||||
<div class="fee-text">{{ recommendedFees.fastestFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.fastestFee * 140" ></app-fiat></span>
|
||||
<div class="fee-text"><app-fee-rate [fee]="recommendedFees.fastestFee" rounding="1.0-0"></app-fee-rate></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.fastestFee * 140" ></app-fiat></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<ng-template #inSync>
|
||||
<div class="progress inc-tx-progress-bar">
|
||||
<div class="progress-bar" role="progressbar" [ngStyle]="{'width': mempoolInfoData.progressWidth, 'background-color': mempoolInfoData.progressColor}"> </div>
|
||||
<div class="progress-text">‎{{ mempoolInfoData.vBytesPerSecond | ceil | number }} <ng-container i18n="shared.vbytes-per-second|vB/s">vB/s</ng-container></div>
|
||||
<div class="progress-text" *only-vsize>‎{{ mempoolInfoData.vBytesPerSecond | ceil | number }} <ng-container i18n="shared.vbytes-per-second|vB/s">vB/s</ng-container></div>
|
||||
<div class="progress-text" *only-weight>‎{{ mempoolInfoData.vBytesPerSecond * 4 | ceil | number }} <ng-container i18n="shared.weight-units-per-second|vB/s">WU/s</ng-container></div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
|
@ -1,9 +1,11 @@
|
||||
import { Component, Input, Inject, LOCALE_ID, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { Component, Input, Inject, LOCALE_ID, ChangeDetectionStrategy, OnInit, OnDestroy } from '@angular/core';
|
||||
import { EChartsOption } from 'echarts';
|
||||
import { OnChanges } from '@angular/core';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { download, formatterXAxis, formatterXAxisLabel } from '../../shared/graphs.utils';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-incoming-transactions-graph',
|
||||
@ -18,7 +20,7 @@ import { formatNumber } from '@angular/common';
|
||||
`],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class IncomingTransactionsGraphComponent implements OnInit, OnChanges {
|
||||
export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() data: any;
|
||||
@Input() theme: string;
|
||||
@Input() height: number | string = '200';
|
||||
@ -35,14 +37,24 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges {
|
||||
};
|
||||
windowPreference: string;
|
||||
chartInstance: any = undefined;
|
||||
weightMode: boolean = false;
|
||||
rateUnitSub: Subscription;
|
||||
|
||||
constructor(
|
||||
@Inject(LOCALE_ID) private locale: string,
|
||||
private storageService: StorageService,
|
||||
private stateService: StateService,
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.isLoading = true;
|
||||
|
||||
this.rateUnitSub = this.stateService.rateUnits$.subscribe(rateUnits => {
|
||||
this.weightMode = rateUnits === 'wu';
|
||||
if (this.data) {
|
||||
this.mountChart();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
@ -118,7 +130,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges {
|
||||
itemFormatted += `<div class="item">
|
||||
<div class="indicator-container">${colorSpan(item.color)}</div>
|
||||
<div class="grow"></div>
|
||||
<div class="value">${formatNumber(item.value[1], this.locale, '1.0-0')}<span class="symbol">vB/s</span></div>
|
||||
<div class="value">${formatNumber(this.weightMode ? item.value[1] * 4 : item.value[1], this.locale, '1.0-0')} <span class="symbol">${this.weightMode ? 'WU' : 'vB'}/s</span></div>
|
||||
</div>`;
|
||||
}
|
||||
});
|
||||
@ -147,6 +159,9 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
fontSize: 11,
|
||||
formatter: (value) => {
|
||||
return this.weightMode ? value * 4 : value;
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
@ -250,4 +265,8 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges {
|
||||
this.mempoolStatsChartOption.backgroundColor = 'none';
|
||||
this.chartInstance.setOption(this.mempoolStatsChartOption);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.rateUnitSub.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
@ -14,11 +14,15 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td i18n="mempool-block.median-fee">Median fee</td>
|
||||
<td>~{{ mempoolBlock.medianFee | number:'1.0-0' }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span> <span class="fiat"><app-fiat [value]="mempoolBlock.medianFee * 140" digitsInfo="1.2-2" i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom"></app-fiat></span></td>
|
||||
<td>~<app-fee-rate [fee]="mempoolBlock.medianFee" rounding="1.0-0"></app-fee-rate> <span class="fiat"><app-fiat [value]="mempoolBlock.medianFee * 140" digitsInfo="1.2-2" i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom"></app-fiat></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="mempool-block.fee-span">Fee span</td>
|
||||
<td><span class="yellow-color">{{ mempoolBlock.feeRange[0] | number:'1.0-0' }} - {{ mempoolBlock.feeRange[mempoolBlock.feeRange.length - 1] | number:'1.0-0' }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></span></td>
|
||||
<td><span class="yellow-color">
|
||||
<app-fee-rate [fee]="mempoolBlock.feeRange[0]" [showUnit]="false" rounding="1.0-0"></app-fee-rate>
|
||||
-
|
||||
<app-fee-rate [fee]="mempoolBlock.feeRange[mempoolBlock.feeRange.length - 1]" rounding="1.0-0"></app-fee-rate>
|
||||
</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="block.total-fees|Total fees in a block">Total fees</td>
|
||||
|
@ -13,10 +13,12 @@
|
||||
<div class="block-body">
|
||||
<ng-container *ngIf="!minimal">
|
||||
<div [attr.data-cy]="'mempool-block-' + i + '-fees'" class="fees">
|
||||
~{{ projectedBlock.medianFee | number:feeRounding }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
~<app-fee-rate [fee]="projectedBlock.medianFee" unitClass="" rounding="1.0-0"></app-fee-rate>
|
||||
</div>
|
||||
<div [attr.data-cy]="'mempool-block-' + i + '-fee-span'" class="fee-span">
|
||||
{{ projectedBlock.feeRange[0] | number:feeRounding }} - {{ projectedBlock.feeRange[projectedBlock.feeRange.length - 1] | number:feeRounding }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
<app-fee-rate [fee]="projectedBlock.feeRange[0]" [showUnit]="false" rounding="1.0-0" unitClass=""></app-fee-rate>
|
||||
-
|
||||
<app-fee-rate [fee]="projectedBlock.feeRange[projectedBlock.feeRange.length - 1]" rounding="1.0-0" unitClass=""></app-fee-rate>
|
||||
</div>
|
||||
<div *ngIf="showMiningInfo" class="block-size">
|
||||
<app-amount [attr.data-cy]="'mempool-block-' + i + '-total-fees'" [satoshis]="projectedBlock.totalFees" digitsInfo="1.2-3" [noFiat]="true"></app-amount>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Component, OnInit, Input, Inject, LOCALE_ID, ChangeDetectionStrategy, OnChanges } from '@angular/core';
|
||||
import { VbytesPipe } from '../../shared/pipes/bytes-pipe/vbytes.pipe';
|
||||
import { WuBytesPipe } from '../../shared/pipes/bytes-pipe/wubytes.pipe';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { OptimizedMempoolStats } from '../../interfaces/node-api.interface';
|
||||
import { StateService } from '../../services/state.service';
|
||||
@ -48,9 +49,11 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
|
||||
chartColorsOrdered = chartColors;
|
||||
inverted: boolean;
|
||||
chartInstance: any = undefined;
|
||||
weightMode: boolean = false;
|
||||
|
||||
constructor(
|
||||
private vbytesPipe: VbytesPipe,
|
||||
private wubytesPipe: WuBytesPipe,
|
||||
private stateService: StateService,
|
||||
private storageService: StorageService,
|
||||
@Inject(LOCALE_ID) private locale: string,
|
||||
|
@ -0,0 +1,5 @@
|
||||
<div [formGroup]="rateUnitForm" class="text-small text-center">
|
||||
<select formControlName="rateUnits" class="custom-select custom-select-sm form-control-secondary form-control mx-auto" style="width: 200px;" (change)="changeUnits()">
|
||||
<option *ngFor="let unit of units" [value]="unit.name">{{ unit.label }}</option>
|
||||
</select>
|
||||
</div>
|
@ -0,0 +1,45 @@
|
||||
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-rate-unit-selector',
|
||||
templateUrl: './rate-unit-selector.component.html',
|
||||
styleUrls: ['./rate-unit-selector.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class RateUnitSelectorComponent implements OnInit, OnDestroy {
|
||||
rateUnitForm: UntypedFormGroup;
|
||||
rateUnitSub: Subscription;
|
||||
units = [
|
||||
{ name: 'vb', label: 'sat/vB' },
|
||||
{ name: 'wu', label: 'sat/WU' },
|
||||
];
|
||||
|
||||
constructor(
|
||||
private formBuilder: UntypedFormBuilder,
|
||||
private stateService: StateService,
|
||||
private storageService: StorageService,
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.rateUnitForm = this.formBuilder.group({
|
||||
rateUnits: ['vb']
|
||||
});
|
||||
this.rateUnitSub = this.stateService.rateUnits$.subscribe((units) => {
|
||||
this.rateUnitForm.get('rateUnits')?.setValue(units);
|
||||
});
|
||||
}
|
||||
|
||||
changeUnits() {
|
||||
const newUnits = this.rateUnitForm.get('rateUnits')?.value;
|
||||
this.storageService.setValue('rate-unit-preference', newUnits);
|
||||
this.stateService.rateUnits$.next(newUnits);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.rateUnitSub.unsubscribe();
|
||||
}
|
||||
}
|
@ -21,10 +21,14 @@
|
||||
<td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td>
|
||||
<td>{{ rbfInfo.tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr *only-vsize>
|
||||
<td class="td-width" i18n="transaction.vsize|Transaction Virtual Size">Virtual size</td>
|
||||
<td [innerHTML]="'‎' + (rbfInfo.tx.vsize | vbytes: 2)"></td>
|
||||
</tr>
|
||||
<tr *only-weight>
|
||||
<td class="td-width" i18n="transaction.weight|Transaction Weight">Weight</td>
|
||||
<td [innerHTML]="'‎' + (rbfInfo.tx.vsize * 4 | vbytes: 2)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td-width" i18n="transaction.status|Transaction Status">Status</td>
|
||||
<td>
|
||||
|
@ -31,7 +31,7 @@
|
||||
>
|
||||
<div class="shape"></div>
|
||||
</a>
|
||||
<span class="fee-rate">{{ cell.replacement.tx.fee / (cell.replacement.tx.vsize) | feeRounding }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></span>
|
||||
<span class="fee-rate"><app-fee-rate [fee]="cell.replacement.tx.fee" [weight]="cell.replacement.tx.vsize * 4" [unitStyle]="{ display: 'block', marginTop: '-0.5em'}"></app-fee-rate></span>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-template #nonNode>
|
||||
|
@ -126,11 +126,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.symbol::ng-deep {
|
||||
display: block;
|
||||
margin-top: -0.5em;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
.shape-border {
|
||||
background: #9339f4;
|
||||
|
@ -33,7 +33,7 @@
|
||||
<span [innerHTML]="'‎' + (tx.weight | wuBytes: 2)"></span>
|
||||
</p>
|
||||
<p class="field" *ngIf="!isCoinbase(tx)">
|
||||
{{ tx.feePerVsize | feeRounding }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
<app-fee-rate [fee]="tx.feePerVsize"></app-fee-rate>
|
||||
</p>
|
||||
</div>
|
||||
<div class="overlaid">
|
||||
|
@ -137,7 +137,8 @@
|
||||
<tr>
|
||||
<th i18n="transactions-list.vout.scriptpubkey-type">Type</th>
|
||||
<th class="txids" i18n="dashboard.latest-transactions.txid">TXID</th>
|
||||
<th class="d-none d-lg-table-cell" i18n="transaction.vsize|Transaction Virtual Size">Virtual size</th>
|
||||
<th *only-vsize class="d-none d-lg-table-cell" i18n="transaction.vsize|Transaction Virtual Size">Virtual size</th>
|
||||
<th *only-weight class="d-none d-lg-table-cell" i18n="transaction.weight|Transaction Weight">Weight</th>
|
||||
<th i18n="transaction.fee-rate|Transaction fee rate">Fee rate</th>
|
||||
<th class="d-none d-lg-table-cell"></th>
|
||||
</tr>
|
||||
@ -149,8 +150,9 @@
|
||||
<td>
|
||||
<app-truncate [text]="cpfpTx.txid" [link]="['/tx' | relativeUrl, cpfpTx.txid]"></app-truncate>
|
||||
</td>
|
||||
<td class="d-none d-lg-table-cell" [innerHTML]="cpfpTx.weight / 4 | vbytes: 2"></td>
|
||||
<td>{{ cpfpTx.fee / (cpfpTx.weight / 4) | feeRounding }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></td>
|
||||
<td *only-vsize class="d-none d-lg-table-cell" [innerHTML]="cpfpTx.weight / 4 | vbytes: 2"></td>
|
||||
<td *only-weight class="d-none d-lg-table-cell" [innerHTML]="cpfpTx.weight | wuBytes: 2"></td>
|
||||
<td><app-fee-rate [fee]="cpfpTx.fee" [weight]="cpfpTx.weight"></app-fee-rate></td>
|
||||
<td class="d-none d-lg-table-cell"><fa-icon *ngIf="roundToOneDecimal(cpfpTx) > roundToOneDecimal(tx)" class="arrow-green" [icon]="['fas', 'angle-double-up']" [fixedWidth]="true"></fa-icon></td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
@ -160,8 +162,9 @@
|
||||
<td class="txids">
|
||||
<app-truncate [text]="cpfpInfo.bestDescendant.txid" [link]="['/tx' | relativeUrl, cpfpInfo.bestDescendant.txid]"></app-truncate>
|
||||
</td>
|
||||
<td class="d-none d-lg-table-cell" [innerHTML]="cpfpInfo.bestDescendant.weight / 4 | vbytes: 2"></td>
|
||||
<td>{{ cpfpInfo.bestDescendant.fee / (cpfpInfo.bestDescendant.weight / 4) | feeRounding }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></td>
|
||||
<td *only-vsize class="d-none d-lg-table-cell" [innerHTML]="cpfpInfo.bestDescendant.weight / 4 | vbytes: 2"></td>
|
||||
<td *only-weight class="d-none d-lg-table-cell" [innerHTML]="cpfpInfo.bestDescendant.weight | wuBytes: 2"></td>
|
||||
<td><app-fee-rate [fee]="cpfpInfo.bestDescendant.fee" [weight]="cpfpInfo.bestDescendant.weight"></app-fee-rate></td>
|
||||
<td class="d-none d-lg-table-cell"><fa-icon class="arrow-green" [icon]="['fas', 'angle-double-up']" [fixedWidth]="true"></fa-icon></td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
@ -171,8 +174,9 @@
|
||||
<td class="txids">
|
||||
<app-truncate [text]="cpfpTx.txid" [link]="['/tx' | relativeUrl, cpfpTx.txid]"></app-truncate>
|
||||
</td>
|
||||
<td class="d-none d-lg-table-cell" [innerHTML]="cpfpTx.weight / 4 | vbytes: 2"></td>
|
||||
<td>{{ cpfpTx.fee / (cpfpTx.weight / 4) | feeRounding }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></td>
|
||||
<td *only-vsize class="d-none d-lg-table-cell" [innerHTML]="cpfpTx.weight / 4 | vbytes: 2"></td>
|
||||
<td *only-weight class="d-none d-lg-table-cell" [innerHTML]="cpfpTx.weight | wuBytes: 2"></td>
|
||||
<td><app-fee-rate [fee]="cpfpTx.fee" [weight]="cpfpTx.weight"></app-fee-rate></td>
|
||||
<td class="d-none d-lg-table-cell"><fa-icon *ngIf="roundToOneDecimal(cpfpTx) < roundToOneDecimal(tx)" class="arrow-red" [icon]="['fas', 'angle-double-down']" [fixedWidth]="true"></fa-icon></td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
@ -475,7 +479,7 @@
|
||||
<tr>
|
||||
<td i18n="transaction.fee-rate|Transaction fee rate">Fee rate</td>
|
||||
<td>
|
||||
{{ tx.feePerVsize | feeRounding }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
<app-fee-rate [fee]="tx.feePerVsize"></app-fee-rate>
|
||||
<ng-template [ngIf]="tx?.status?.confirmed">
|
||||
|
||||
<app-tx-fee-rating *ngIf="tx.fee && !hasEffectiveFeeRate" [tx]="tx"></app-tx-fee-rating>
|
||||
@ -486,7 +490,7 @@
|
||||
<td i18n="transaction.effective-fee-rate|Effective transaction fee rate">Effective fee rate</td>
|
||||
<td>
|
||||
<div class="effective-fee-container">
|
||||
{{ tx.effectiveFeePerVsize | feeRounding }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
<app-fee-rate [fee]="tx.effectiveFeePerVsize"></app-fee-rate>
|
||||
<ng-template [ngIf]="tx?.status?.confirmed">
|
||||
<app-tx-fee-rating class="ml-2 mr-2" *ngIf="tx.fee || tx.effectiveFeePerVsize" [tx]="tx"></app-tx-fee-rating>
|
||||
</ng-template>
|
||||
|
@ -290,8 +290,8 @@
|
||||
|
||||
<div class="summary">
|
||||
<div class="float-left mt-2-5" *ngIf="!transactionPage && !tx.vin[0].is_coinbase && tx.fee !== -1">
|
||||
{{ tx.fee / (tx.weight / 4) | feeRounding }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span> <span
|
||||
class="d-none d-sm-inline-block"> – {{ tx.fee | number }} <span class="symbol"
|
||||
<app-fee-rate [fee]="tx.fee" [weight]="tx.weight"></app-fee-rate>
|
||||
<span class="d-none d-sm-inline-block"> – {{ tx.fee | number }} <span class="symbol"
|
||||
i18n="shared.sat|sat">sat</span> <span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee"></app-fiat></span></span>
|
||||
</div>
|
||||
<div class="float-left mt-2-5 grey-info-text" *ngIf="tx.fee === -1" i18n="transactions-list.load-to-reveal-fee-info">Show more inputs to reveal fee data</div>
|
||||
|
@ -132,7 +132,7 @@
|
||||
</td>
|
||||
<td class="table-cell-satoshis"><app-amount *ngIf="(network$ | async) !== 'liquid' && (network$ | async) !== 'liquidtestnet'; else liquidAmount" [satoshis]="transaction.value" digitsInfo="1.2-4" [noFiat]="true"></app-amount><ng-template #liquidAmount i18n="shared.confidential">Confidential</ng-template></td>
|
||||
<td class="table-cell-fiat" *ngIf="(network$ | async) === ''" ><app-fiat [value]="transaction.value" digitsInfo="1.0-0"></app-fiat></td>
|
||||
<td class="table-cell-fees">{{ transaction.fee / transaction.vsize | feeRounding }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></td>
|
||||
<td class="table-cell-fees"><app-fee-rate [fee]="transaction.fee" [weight]="transaction.vsize * 4"></app-fee-rate></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -188,7 +188,7 @@
|
||||
<h5 *ngIf="!mempoolInfoData.value || mempoolInfoData.value.memPoolInfo.mempoolminfee === 0.00001 || (stateService.env.BASE_MODULE === 'liquid' && mempoolInfoData.value.memPoolInfo.mempoolminfee === 0.000001) else purgingText" class="card-title" i18n="dashboard.minimum-fee|Minimum mempool fee">Minimum fee</h5>
|
||||
<ng-template #purgingText><h5 class="card-title" i18n="dashboard.purging|Purgin below fee">Purging</h5></ng-template>
|
||||
<p class="card-text" *ngIf="(isLoadingWebSocket$ | async) === false && mempoolInfoData.value; else loading">
|
||||
<ng-template [ngIf]="mempoolInfoData.value.memPoolInfo.mempoolminfee > 0.00001">< </ng-template>{{ mempoolInfoData.value.memPoolInfo.mempoolminfee * 100000 | feeRounding }} <span><ng-container i18n="shared.sat-vbyte|sat/vB">sat/vB</ng-container></span>
|
||||
<ng-template [ngIf]="mempoolInfoData.value.memPoolInfo.mempoolminfee > 0.00001">< </ng-template><app-fee-rate [fee]="mempoolInfoData.value.memPoolInfo.mempoolminfee * 100000"></app-fee-rate>
|
||||
</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
@ -229,7 +229,8 @@
|
||||
<ng-template #inSync>
|
||||
<div class="progress inc-tx-progress-bar">
|
||||
<div class="progress-bar {{ mempoolInfoData.value.progressColor }}" role="progressbar" [ngStyle]="{'width': mempoolInfoData.value.progressWidth}"> </div>
|
||||
<div class="progress-text">‎{{ mempoolInfoData.value.vBytesPerSecond | ceil | number }} <ng-container i18n="shared.vbytes-per-second|vB/s">vB/s</ng-container></div>
|
||||
<div *only-vsize class="progress-text">‎{{ mempoolInfoData.value.vBytesPerSecond | ceil | number }} <ng-container i18n="shared.vbytes-per-second|vB/s">vB/s</ng-container></div>
|
||||
<div *only-weight class="progress-text">‎{{ mempoolInfoData.value.vBytesPerSecond * 4 | ceil | number }} <ng-container i18n="shared.weight-per-second|WU/s">WU/s</ng-container></div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
|
@ -133,6 +133,7 @@ export class StateService {
|
||||
hideFlow: BehaviorSubject<boolean>;
|
||||
hideAudit: BehaviorSubject<boolean>;
|
||||
fiatCurrency$: BehaviorSubject<string>;
|
||||
rateUnits$: BehaviorSubject<string>;
|
||||
|
||||
constructor(
|
||||
@Inject(PLATFORM_ID) private platformId: any,
|
||||
@ -225,6 +226,9 @@ export class StateService {
|
||||
|
||||
const fiatPreference = this.storageService.getValue('fiat-preference');
|
||||
this.fiatCurrency$ = new BehaviorSubject<string>(fiatPreference || 'USD');
|
||||
|
||||
const rateUnitPreference = this.storageService.getValue('rate-unit-preference');
|
||||
this.rateUnits$ = new BehaviorSubject<string>(rateUnitPreference || 'vb');
|
||||
}
|
||||
|
||||
setNetworkBasedonUrl(url: string) {
|
||||
|
@ -0,0 +1,4 @@
|
||||
<ng-container *ngIf="rateUnits$ | async as units">
|
||||
<ng-container *ngIf="units !== 'wu'">{{ fee / (weight / 4) | feeRounding:rounding }} <span *ngIf="showUnit" [class]="unitClass" [style]="unitStyle">sat/vB</span></ng-container>
|
||||
<ng-container *ngIf="units === 'wu'">{{ fee / weight | feeRounding:rounding }} <span *ngIf="showUnit" [class]="unitClass" [style]="unitStyle">sat/WU</span></ng-container>
|
||||
</ng-container>
|
@ -0,0 +1,27 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { StateService } from '../../../services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-fee-rate',
|
||||
templateUrl: './fee-rate.component.html',
|
||||
styleUrls: ['./fee-rate.component.scss']
|
||||
})
|
||||
export class FeeRateComponent implements OnInit {
|
||||
@Input() fee: number;
|
||||
@Input() weight: number = 4;
|
||||
@Input() rounding: string = null;
|
||||
@Input() showUnit: boolean = true;
|
||||
@Input() unitClass: string = 'symbol';
|
||||
@Input() unitStyle: any;
|
||||
|
||||
rateUnits$: Observable<string>;
|
||||
|
||||
constructor(
|
||||
private stateService: StateService,
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.rateUnits$ = this.stateService.rateUnits$;
|
||||
}
|
||||
}
|
@ -10,6 +10,9 @@
|
||||
<div class="selector">
|
||||
<app-fiat-selector></app-fiat-selector>
|
||||
</div>
|
||||
<div class="selector">
|
||||
<app-rate-unit-selector></app-rate-unit-selector>
|
||||
</div>
|
||||
<ng-template #temporaryHidden>
|
||||
<a *ngIf="officialMempoolSpace" class="cta btn btn-purple sponsor" [routerLink]="['/signup' | relativeUrl]">Support the Project</a>
|
||||
<p *ngIf="officialMempoolSpace && env.BASE_MODULE === 'mempool'" class="cta-secondary"><a [routerLink]="['/signin' | relativeUrl]" i18n="shared.broadcast-transaction|Broadcast Transaction">Sign In</a></p>
|
||||
|
@ -0,0 +1,45 @@
|
||||
import { Directive, OnDestroy, TemplateRef, ViewContainerRef } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { StateService } from '../../../services/state.service';
|
||||
|
||||
function createRateUnitDirective(checkFn: (rateUnit: string) => boolean): any {
|
||||
@Directive()
|
||||
class RateUnitDirective implements OnDestroy {
|
||||
private subscription: Subscription;
|
||||
private enabled: boolean;
|
||||
private hasView: boolean = false;
|
||||
|
||||
constructor(
|
||||
private templateRef: TemplateRef<any>,
|
||||
private viewContainer: ViewContainerRef,
|
||||
private stateService: StateService
|
||||
) {
|
||||
this.subscription = this.stateService.rateUnits$.subscribe(rateUnit => {
|
||||
this.enabled = checkFn(rateUnit);
|
||||
this.updateView();
|
||||
});
|
||||
}
|
||||
|
||||
updateView(): void {
|
||||
if (this.enabled && !this.hasView) {
|
||||
this.viewContainer.createEmbeddedView(this.templateRef);
|
||||
this.hasView = true;
|
||||
} else if (!this.enabled && this.hasView) {
|
||||
this.viewContainer.clear();
|
||||
this.hasView = false;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
return RateUnitDirective;
|
||||
}
|
||||
|
||||
@Directive({ selector: '[only-vsize]' })
|
||||
export class OnlyVsizeDirective extends createRateUnitDirective(rateUnit => rateUnit !== 'wu') {}
|
||||
|
||||
@Directive({ selector: '[only-weight]' })
|
||||
export class OnlyWeightDirective extends createRateUnitDirective(rateUnit => rateUnit === 'wu') {}
|
@ -17,7 +17,7 @@ export class WuBytesPipe implements PipeTransform {
|
||||
'TWU': {max: Number.MAX_SAFE_INTEGER, prev: 'GWU'}
|
||||
};
|
||||
|
||||
transform(input: any, decimal: number = 0, from: ByteUnit = 'WU', to?: ByteUnit): any {
|
||||
transform(input: any, decimal: number = 0, from: ByteUnit = 'WU', to?: ByteUnit, plainText?: boolean): any {
|
||||
|
||||
if (!(isNumberFinite(input) &&
|
||||
isNumberFinite(decimal) &&
|
||||
@ -38,7 +38,7 @@ export class WuBytesPipe implements PipeTransform {
|
||||
|
||||
const result = toDecimal(WuBytesPipe.calculateResult(format, bytes), decimal);
|
||||
|
||||
return WuBytesPipe.formatResult(result, to);
|
||||
return WuBytesPipe.formatResult(result, to, plainText);
|
||||
}
|
||||
|
||||
for (const key in WuBytesPipe.formats) {
|
||||
@ -47,12 +47,15 @@ export class WuBytesPipe implements PipeTransform {
|
||||
|
||||
const result = toDecimal(WuBytesPipe.calculateResult(format, bytes), decimal);
|
||||
|
||||
return WuBytesPipe.formatResult(result, key);
|
||||
return WuBytesPipe.formatResult(result, key, plainText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static formatResult(result: number, unit: string): string {
|
||||
static formatResult(result: number, unit: string, plainText: boolean): string {
|
||||
if (plainText){
|
||||
return `${result} ${unit}`;
|
||||
}
|
||||
return `${result} <span class="symbol">${unit}</span>`;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,11 @@ export class FeeRoundingPipe implements PipeTransform {
|
||||
@Inject(LOCALE_ID) private locale: string,
|
||||
) {}
|
||||
|
||||
transform(fee: number): string {
|
||||
transform(fee: number, rounding = null): string {
|
||||
if (rounding) {
|
||||
return formatNumber(fee, this.locale, rounding);
|
||||
}
|
||||
|
||||
if (fee >= 100) {
|
||||
return formatNumber(fee, this.locale, '1.0-0')
|
||||
} else if (fee < 10) {
|
||||
|
@ -35,6 +35,7 @@ import { TxFeeRatingComponent } from '../components/tx-fee-rating/tx-fee-rating.
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { LanguageSelectorComponent } from '../components/language-selector/language-selector.component';
|
||||
import { FiatSelectorComponent } from '../components/fiat-selector/fiat-selector.component';
|
||||
import { RateUnitSelectorComponent } from '../components/rate-unit-selector/rate-unit-selector.component';
|
||||
import { ColoredPriceDirective } from './directives/colored-price.directive';
|
||||
import { NoSanitizePipe } from './pipes/no-sanitize.pipe';
|
||||
import { MempoolBlocksComponent } from '../components/mempool-blocks/mempool-blocks.component';
|
||||
@ -82,6 +83,7 @@ import { IndexingProgressComponent } from '../components/indexing-progress/index
|
||||
import { SvgImagesComponent } from '../components/svg-images/svg-images.component';
|
||||
import { ChangeComponent } from '../components/change/change.component';
|
||||
import { SatsComponent } from './components/sats/sats.component';
|
||||
import { FeeRateComponent } from './components/fee-rate/fee-rate.component';
|
||||
import { TruncateComponent } from './components/truncate/truncate.component';
|
||||
import { SearchResultsComponent } from '../components/search-form/search-results/search-results.component';
|
||||
import { TimestampComponent } from './components/timestamp/timestamp.component';
|
||||
@ -96,6 +98,8 @@ import { ClockchainComponent } from '../components/clockchain/clockchain.compone
|
||||
import { ClockFaceComponent } from '../components/clock-face/clock-face.component';
|
||||
import { ClockComponent } from '../components/clock/clock.component';
|
||||
|
||||
import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-directives/weight-directives';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
ClipboardComponent,
|
||||
@ -106,6 +110,7 @@ import { ClockComponent } from '../components/clock/clock.component';
|
||||
TxFeeRatingComponent,
|
||||
LanguageSelectorComponent,
|
||||
FiatSelectorComponent,
|
||||
RateUnitSelectorComponent,
|
||||
ScriptpubkeyTypePipe,
|
||||
RelativeUrlPipe,
|
||||
NoSanitizePipe,
|
||||
@ -171,6 +176,7 @@ import { ClockComponent } from '../components/clock/clock.component';
|
||||
SvgImagesComponent,
|
||||
ChangeComponent,
|
||||
SatsComponent,
|
||||
FeeRateComponent,
|
||||
TruncateComponent,
|
||||
SearchResultsComponent,
|
||||
TimestampComponent,
|
||||
@ -184,6 +190,9 @@ import { ClockComponent } from '../components/clock/clock.component';
|
||||
ClockchainComponent,
|
||||
ClockComponent,
|
||||
ClockFaceComponent,
|
||||
|
||||
OnlyVsizeDirective,
|
||||
OnlyWeightDirective
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
@ -200,6 +209,7 @@ import { ClockComponent } from '../components/clock/clock.component';
|
||||
],
|
||||
providers: [
|
||||
VbytesPipe,
|
||||
WuBytesPipe,
|
||||
RelativeUrlPipe,
|
||||
NoSanitizePipe,
|
||||
ShortenStringPipe,
|
||||
@ -225,6 +235,7 @@ import { ClockComponent } from '../components/clock/clock.component';
|
||||
TxFeeRatingComponent,
|
||||
LanguageSelectorComponent,
|
||||
FiatSelectorComponent,
|
||||
RateUnitSelectorComponent,
|
||||
ScriptpubkeyTypePipe,
|
||||
RelativeUrlPipe,
|
||||
Hex2asciiPipe,
|
||||
@ -284,6 +295,7 @@ import { ClockComponent } from '../components/clock/clock.component';
|
||||
SvgImagesComponent,
|
||||
ChangeComponent,
|
||||
SatsComponent,
|
||||
FeeRateComponent,
|
||||
TruncateComponent,
|
||||
SearchResultsComponent,
|
||||
TimestampComponent,
|
||||
@ -297,6 +309,9 @@ import { ClockComponent } from '../components/clock/clock.component';
|
||||
ClockchainComponent,
|
||||
ClockComponent,
|
||||
ClockFaceComponent,
|
||||
|
||||
OnlyVsizeDirective,
|
||||
OnlyWeightDirective
|
||||
]
|
||||
})
|
||||
export class SharedModule {
|
||||
|
@ -221,7 +221,7 @@ main {
|
||||
}
|
||||
|
||||
.block-size, .blocks-container {
|
||||
span {
|
||||
.symbol {
|
||||
font-size: 16px;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user