Merge branch 'master' into shrink-og-avatar

This commit is contained in:
wiz
2023-02-16 04:56:04 +09:00
committed by GitHub
35 changed files with 427 additions and 236 deletions

View File

@@ -157,3 +157,41 @@ export const specialBlocks = {
labelEventCompleted: 'Block Subsidy has halved to 3.125 BTC per block',
}
};
export const fiatCurrencies = {
AUD: {
name: 'Australian Dollar',
code: 'AUD',
indexed: true,
},
CAD: {
name: 'Canadian Dollar',
code: 'CAD',
indexed: true,
},
CHF: {
name: 'Swiss Franc',
code: 'CHF',
indexed: true,
},
EUR: {
name: 'Euro',
code: 'EUR',
indexed: true,
},
GBP: {
name: 'Pound Sterling',
code: 'GBP',
indexed: true,
},
JPY: {
name: 'Japanese Yen',
code: 'JPY',
indexed: true,
},
USD: {
name: 'US Dollar',
code: 'USD',
indexed: true,
},
};

View File

@@ -17,6 +17,7 @@ import { StorageService } from './services/storage.service';
import { HttpCacheInterceptor } from './services/http-cache.interceptor';
import { LanguageService } from './services/language.service';
import { FiatShortenerPipe } from './shared/pipes/fiat-shortener.pipe';
import { FiatCurrencyPipe } from './shared/pipes/fiat-currency.pipe';
import { ShortenStringPipe } from './shared/pipes/shorten-string-pipe/shorten-string.pipe';
import { CapAddressPipe } from './shared/pipes/cap-address-pipe/cap-address-pipe';
import { AppPreloadingStrategy } from './app.preloading-strategy';
@@ -34,6 +35,7 @@ const providers = [
LanguageService,
ShortenStringPipe,
FiatShortenerPipe,
FiatCurrencyPipe,
CapAddressPipe,
AppPreloadingStrategy,
{ provide: HTTP_INTERCEPTORS, useClass: HttpCacheInterceptor, multi: true }

View File

@@ -1,5 +1,5 @@
<ng-container *ngIf="!noFiat && (viewFiat$ | async) && (conversions$ | async) as conversions; else viewFiatVin">
<span class="fiat">{{ addPlus && satoshis >= 0 ? '+' : '' }}{{ conversions.USD * (satoshis / 100000000) | currency:'USD':'symbol':'1.2-2' }}</span>
<span class="fiat">{{ addPlus && satoshis >= 0 ? '+' : '' }}{{ (conversions ? conversions[currency] : 0) * satoshis / 100000000 | fiatCurrency : digitsInfo : currency }}</span>
</ng-container>
<ng-template #viewFiatVin>
<ng-template [ngIf]="(network === 'liquid' || network === 'liquidtestnet') && (satoshis === undefined || satoshis === null)" [ngIfElse]="default">

View File

@@ -1,4 +1,4 @@
import { Component, OnInit, OnDestroy, Input, ChangeDetectionStrategy } from '@angular/core';
import { Component, OnInit, OnDestroy, Input, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { StateService } from '../../services/state.service';
import { Observable, Subscription } from 'rxjs';
@@ -10,10 +10,12 @@ import { Observable, Subscription } from 'rxjs';
})
export class AmountComponent implements OnInit, OnDestroy {
conversions$: Observable<any>;
currency: string;
viewFiat$: Observable<boolean>;
network = '';
stateSubscription: Subscription;
currencySubscription: Subscription;
@Input() satoshis: number;
@Input() digitsInfo = '1.8-8';
@@ -22,7 +24,13 @@ export class AmountComponent implements OnInit, OnDestroy {
constructor(
private stateService: StateService,
) { }
private cd: ChangeDetectorRef,
) {
this.currencySubscription = this.stateService.fiatCurrency$.subscribe((fiat) => {
this.currency = fiat;
this.cd.markForCheck();
});
}
ngOnInit() {
this.viewFiat$ = this.stateService.viewFiat$.asObservable();
@@ -34,6 +42,7 @@ export class AmountComponent implements OnInit, OnDestroy {
if (this.stateSubscription) {
this.stateSubscription.unsubscribe();
}
this.currencySubscription.unsubscribe();
}
}

View File

@@ -1,16 +1,19 @@
import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core';
import { EChartsOption, graphic } from 'echarts';
import { Observable } from 'rxjs';
import { Observable, Subscription } from 'rxjs';
import { map, share, startWith, switchMap, tap } from 'rxjs/operators';
import { ApiService } from '../../services/api.service';
import { SeoService } from '../../services/seo.service';
import { formatCurrency, formatNumber, getCurrencySymbol } from '@angular/common';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from '../../shared/graphs.utils';
import { StateService } from '../../services/state.service';
import { StorageService } from '../../services/storage.service';
import { MiningService } from '../../services/mining.service';
import { ActivatedRoute } from '@angular/router';
import { FiatShortenerPipe } from '../../shared/pipes/fiat-shortener.pipe';
import { FiatCurrencyPipe } from '../../shared/pipes/fiat-currency.pipe';
import { fiatCurrencies } from '../../app.constants';
@Component({
selector: 'app-block-fees-graph',
@@ -44,6 +47,9 @@ export class BlockFeesGraphComponent implements OnInit {
timespan = '';
chartInstance: any = undefined;
currencySubscription: Subscription;
currency: string;
constructor(
@Inject(LOCALE_ID) public locale: string,
private seoService: SeoService,
@@ -51,11 +57,21 @@ export class BlockFeesGraphComponent implements OnInit {
private formBuilder: UntypedFormBuilder,
private storageService: StorageService,
private miningService: MiningService,
private stateService: StateService,
private route: ActivatedRoute,
private fiatShortenerPipe: FiatShortenerPipe,
private fiatCurrencyPipe: FiatCurrencyPipe,
) {
this.radioGroupForm = this.formBuilder.group({ dateSpan: '1y' });
this.radioGroupForm.controls.dateSpan.setValue('1y');
this.currencySubscription = this.stateService.fiatCurrency$.subscribe((fiat) => {
if (fiat && fiatCurrencies[fiat]?.indexed) {
this.currency = fiat;
} else {
this.currency = 'USD';
}
});
}
ngOnInit(): void {
@@ -84,7 +100,7 @@ export class BlockFeesGraphComponent implements OnInit {
tap((response) => {
this.prepareChartOptions({
blockFees: response.body.map(val => [val.timestamp * 1000, val.avgFees / 100000000, val.avgHeight]),
blockFeesUSD: response.body.filter(val => val.USD > 0).map(val => [val.timestamp * 1000, val.avgFees / 100000000 * val.USD, val.avgHeight]),
blockFeesFiat: response.body.filter(val => val[this.currency] > 0).map(val => [val.timestamp * 1000, val.avgFees / 100000000 * val[this.currency], val.avgHeight]),
});
this.isLoading = false;
}),
@@ -157,7 +173,7 @@ export class BlockFeesGraphComponent implements OnInit {
if (tick.seriesIndex === 0) {
tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.3-3')} BTC<br>`;
} else if (tick.seriesIndex === 1) {
tooltip += `${tick.marker} ${tick.seriesName}: ${formatCurrency(tick.data[1], this.locale, getCurrencySymbol('USD', 'narrow'), 'USD', '1.0-0')}<br>`;
tooltip += `${tick.marker} ${tick.seriesName}: ${this.fiatCurrencyPipe.transform(tick.data[1], null, this.currency) }<br>`;
}
}
@@ -184,7 +200,7 @@ export class BlockFeesGraphComponent implements OnInit {
icon: 'roundRect',
},
{
name: 'Fees USD',
name: 'Fees ' + this.currency,
inactiveColor: 'rgb(110, 112, 121)',
textStyle: {
color: 'white',
@@ -216,7 +232,7 @@ export class BlockFeesGraphComponent implements OnInit {
axisLabel: {
color: 'rgb(110, 112, 121)',
formatter: function(val) {
return this.fiatShortenerPipe.transform(val);
return this.fiatShortenerPipe.transform(val, null, this.currency);
}.bind(this)
},
splitLine: {
@@ -243,8 +259,8 @@ export class BlockFeesGraphComponent implements OnInit {
legendHoverLink: false,
zlevel: 1,
yAxisIndex: 1,
name: 'Fees USD',
data: data.blockFeesUSD,
name: 'Fees ' + this.currency,
data: data.blockFeesFiat,
type: 'line',
smooth: 0.25,
symbol: 'none',

View File

@@ -1,16 +1,19 @@
import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core';
import { EChartsOption, graphic } from 'echarts';
import { Observable } from 'rxjs';
import { Observable, Subscription } from 'rxjs';
import { map, share, startWith, switchMap, tap } from 'rxjs/operators';
import { ApiService } from '../../services/api.service';
import { SeoService } from '../../services/seo.service';
import { formatCurrency, formatNumber, getCurrencySymbol } from '@angular/common';
import { formatNumber } from '@angular/common';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from '../../shared/graphs.utils';
import { MiningService } from '../../services/mining.service';
import { StateService } from '../../services/state.service';
import { StorageService } from '../../services/storage.service';
import { ActivatedRoute } from '@angular/router';
import { FiatShortenerPipe } from '../../shared/pipes/fiat-shortener.pipe';
import { FiatCurrencyPipe } from '../../shared/pipes/fiat-currency.pipe';
import { fiatCurrencies } from '../../app.constants';
@Component({
selector: 'app-block-rewards-graph',
@@ -44,16 +47,28 @@ export class BlockRewardsGraphComponent implements OnInit {
timespan = '';
chartInstance: any = undefined;
currencySubscription: Subscription;
currency: string;
constructor(
@Inject(LOCALE_ID) public locale: string,
private seoService: SeoService,
private apiService: ApiService,
private formBuilder: UntypedFormBuilder,
private miningService: MiningService,
private stateService: StateService,
private storageService: StorageService,
private route: ActivatedRoute,
private fiatShortenerPipe: FiatShortenerPipe,
private fiatCurrencyPipe: FiatCurrencyPipe,
) {
this.currencySubscription = this.stateService.fiatCurrency$.subscribe((fiat) => {
if (fiat && fiatCurrencies[fiat]?.indexed) {
this.currency = fiat;
} else {
this.currency = 'USD';
}
});
}
ngOnInit(): void {
@@ -82,7 +97,7 @@ export class BlockRewardsGraphComponent implements OnInit {
tap((response) => {
this.prepareChartOptions({
blockRewards: response.body.map(val => [val.timestamp * 1000, val.avgRewards / 100000000, val.avgHeight]),
blockRewardsUSD: response.body.filter(val => val.USD > 0).map(val => [val.timestamp * 1000, val.avgRewards / 100000000 * val.USD, val.avgHeight]),
blockRewardsFiat: response.body.filter(val => val[this.currency] > 0).map(val => [val.timestamp * 1000, val.avgRewards / 100000000 * val[this.currency], val.avgHeight]),
});
this.isLoading = false;
}),
@@ -157,7 +172,7 @@ export class BlockRewardsGraphComponent implements OnInit {
if (tick.seriesIndex === 0) {
tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.3-3')} BTC<br>`;
} else if (tick.seriesIndex === 1) {
tooltip += `${tick.marker} ${tick.seriesName}: ${formatCurrency(tick.data[1], this.locale, getCurrencySymbol('USD', 'narrow'), 'USD', '1.0-0')}<br>`;
tooltip += `${tick.marker} ${tick.seriesName}: ${this.fiatCurrencyPipe.transform(tick.data[1], null, this.currency)}<br>`;
}
}
@@ -184,7 +199,7 @@ export class BlockRewardsGraphComponent implements OnInit {
icon: 'roundRect',
},
{
name: 'Rewards USD',
name: 'Rewards ' + this.currency,
inactiveColor: 'rgb(110, 112, 121)',
textStyle: {
color: 'white',
@@ -228,7 +243,7 @@ export class BlockRewardsGraphComponent implements OnInit {
axisLabel: {
color: 'rgb(110, 112, 121)',
formatter: function(val) {
return this.fiatShortenerPipe.transform(val);
return this.fiatShortenerPipe.transform(val, null, this.currency);
}.bind(this)
},
splitLine: {
@@ -251,8 +266,8 @@ export class BlockRewardsGraphComponent implements OnInit {
legendHoverLink: false,
zlevel: 1,
yAxisIndex: 1,
name: 'Rewards USD',
data: data.blockRewardsUSD,
name: 'Rewards ' + this.currency,
data: data.blockRewardsFiat,
type: 'line',
smooth: 0.25,
symbol: 'none',

View File

@@ -0,0 +1,5 @@
<div [formGroup]="fiatForm" class="text-small text-center">
<select formControlName="fiat" class="custom-select custom-select-sm form-control-secondary form-control mx-auto" style="width: 200px;" (change)="changeFiat()">
<option *ngFor="let currency of currencies" [value]="currency[1].code">{{ currency[1].name + " (" + currency[1].code + ")" }}</option>
</select>
</div>

View File

@@ -0,0 +1,45 @@
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { StorageService } from '../../services/storage.service';
import { fiatCurrencies } from '../../app.constants';
import { StateService } from '../../services/state.service';
@Component({
selector: 'app-fiat-selector',
templateUrl: './fiat-selector.component.html',
styleUrls: ['./fiat-selector.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FiatSelectorComponent implements OnInit {
fiatForm: UntypedFormGroup;
currencies = Object.entries(fiatCurrencies).sort((a: any, b: any) => {
if (a[1].name < b[1].name) {
return -1;
}
if (a[1].name > b[1].name) {
return 1;
}
return 0;
});
constructor(
private formBuilder: UntypedFormBuilder,
private stateService: StateService,
private storageService: StorageService,
) { }
ngOnInit() {
this.fiatForm = this.formBuilder.group({
fiat: ['USD']
});
this.stateService.fiatCurrency$.subscribe((fiat) => {
this.fiatForm.get('fiat')?.setValue(fiat);
});
}
changeFiat() {
const newFiat = this.fiatForm.get('fiat')?.value;
this.storageService.setValue('fiat-preference', newFiat);
this.stateService.fiatCurrency$.next(newFiat);
}
}

View File

@@ -1,5 +1,5 @@
<div [formGroup]="languageForm" class="text-small text-center">
<select formControlName="language" class="custom-select custom-select-sm form-control-secondary form-control mx-auto" style="width: 130px;" (change)="changeLanguage()">
<select formControlName="language" class="custom-select custom-select-sm form-control-secondary form-control mx-auto" style="width: 200px;" (change)="changeLanguage()">
<option *ngFor="let lang of languages" [value]="lang.code">{{ lang.name }}</option>
</select>
</div>

View File

@@ -74,4 +74,24 @@
</div>
</div>
<div class="pref-selectors">
<div class="selector">
<app-language-selector></app-language-selector>
</div>
<div class="selector">
<app-fiat-selector></app-fiat-selector>
</div>
</div>
<div class="terms-of-service">
<a [routerLink]="['/terms-of-service']" i18n="shared.terms-of-service|Terms of Service">Terms of Service</a>
|
<a [routerLink]="['/privacy-policy']" i18n="shared.privacy-policy|Privacy Policy">Privacy Policy</a>
|
<a [routerLink]="['/tx/push' | relativeUrl]" i18n="shared.broadcast-transaction|Broadcast Transaction">Broadcast Transaction</a>
</div>
<br>
</div>

View File

@@ -103,4 +103,23 @@
margin-bottom: 10px;
text-decoration: none;
color: inherit;
}
.terms-of-service {
margin-top: 1rem;
}
.pref-selectors {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
.selector {
margin-left: .5em;
margin-bottom: .5em;
&:first {
margin-left: 0;
}
}
}

View File

@@ -235,10 +235,10 @@
</span>
</td>
<td class="reward text-right">
<app-amount [satoshis]="block.extras.reward" digitsInfo="1.2-2"></app-amount>
<app-amount [satoshis]="block.extras.reward" digitsInfo="1.2-2" [noFiat]="true"></app-amount>
</td>
<td class="fees text-right">
<app-amount [satoshis]="block.extras.totalFees" digitsInfo="1.2-2"></app-amount>
<app-amount [satoshis]="block.extras.totalFees" digitsInfo="1.2-2" [noFiat]="true"></app-amount>
</td>
<td class="txs text-right">
{{ block.tx_count | number }}

View File

@@ -122,7 +122,7 @@
<thead>
<th class="table-cell-txid" i18n="dashboard.latest-transactions.txid">TXID</th>
<th class="table-cell-satoshis" i18n="dashboard.latest-transactions.amount">Amount</th>
<th class="table-cell-fiat" *ngIf="(network$ | async) === ''" i18n="dashboard.latest-transactions.USD">USD</th>
<th class="table-cell-fiat" *ngIf="(network$ | async) === ''">{{ currency }}</th>
<th class="table-cell-fees" i18n="transaction.fee|Transaction fee">Fee</th>
</thead>
<tbody>
@@ -144,7 +144,14 @@
</div>
</div>
<app-language-selector></app-language-selector>
<div class="pref-selectors">
<div class="selector">
<app-language-selector></app-language-selector>
</div>
<div class="selector">
<app-fiat-selector></app-fiat-selector>
</div>
</div>
<div class="terms-of-service">
<a [routerLink]="['/terms-of-service']" i18n="shared.terms-of-service|Terms of Service">Terms of Service</a>

View File

@@ -323,4 +323,19 @@
margin-bottom: 10px;
text-decoration: none;
color: inherit;
}
.pref-selectors {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
.selector {
margin-left: .5em;
margin-bottom: .5em;
&:first {
margin-left: 0;
}
}
}

View File

@@ -1,5 +1,5 @@
import { ChangeDetectionStrategy, Component, Inject, LOCALE_ID, OnInit } from '@angular/core';
import { combineLatest, merge, Observable, of } from 'rxjs';
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
import { combineLatest, merge, Observable, of, Subscription } from 'rxjs';
import { filter, map, scan, share, switchMap, tap } from 'rxjs/operators';
import { BlockExtended, OptimizedMempoolStats } from '../interfaces/node-api.interface';
import { MempoolInfo, TransactionStripped } from '../interfaces/websocket.interface';
@@ -7,7 +7,6 @@ import { ApiService } from '../services/api.service';
import { StateService } from '../services/state.service';
import { WebsocketService } from '../services/websocket.service';
import { SeoService } from '../services/seo.service';
import { StorageService } from '../services/storage.service';
interface MempoolBlocksData {
blocks: number;
@@ -32,7 +31,7 @@ interface MempoolStatsData {
styleUrls: ['./dashboard.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DashboardComponent implements OnInit {
export class DashboardComponent implements OnInit, OnDestroy {
featuredAssets$: Observable<any>;
network$: Observable<string>;
mempoolBlocksData$: Observable<MempoolBlocksData>;
@@ -47,16 +46,20 @@ export class DashboardComponent implements OnInit {
transactionsWeightPerSecondOptions: any;
isLoadingWebSocket$: Observable<boolean>;
liquidPegsMonth$: Observable<any>;
currencySubscription: Subscription;
currency: string;
constructor(
@Inject(LOCALE_ID) private locale: string,
public stateService: StateService,
private apiService: ApiService,
private websocketService: WebsocketService,
private seoService: SeoService,
private storageService: StorageService,
private seoService: SeoService
) { }
ngOnDestroy(): void {
this.currencySubscription.unsubscribe();
}
ngOnInit(): void {
this.isLoadingWebSocket$ = this.stateService.isLoadingWebSocket$;
this.seoService.resetTitle();
@@ -213,6 +216,10 @@ export class DashboardComponent implements OnInit {
share(),
);
}
this.currencySubscription = this.stateService.fiatCurrency$.subscribe((fiat) => {
this.currency = fiat;
});
}
handleNewMempoolData(mempoolStats: OptimizedMempoolStats[]) {

View File

@@ -1 +1 @@
<span class="green-color">{{ (conversions$ | async)?.USD * value / 100000000 | currency:'USD':'symbol':digitsInfo }}</span>
<span class="green-color" *ngIf="(conversions$ | async) as conversions">{{ (conversions ? conversions[currency] : 0) * value / 100000000 | fiatCurrency : digitsInfo : currency }}</span>

View File

@@ -1,5 +1,5 @@
import { Component, OnInit, ChangeDetectionStrategy, Input } from '@angular/core';
import { Observable } from 'rxjs';
import { Component, OnInit, ChangeDetectionStrategy, Input, ChangeDetectorRef, OnDestroy } from '@angular/core';
import { Observable, Subscription } from 'rxjs';
import { StateService } from '../services/state.service';
@Component({
@@ -8,18 +8,30 @@ import { StateService } from '../services/state.service';
styleUrls: ['./fiat.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FiatComponent implements OnInit {
export class FiatComponent implements OnInit, OnDestroy {
conversions$: Observable<any>;
currencySubscription: Subscription;
currency: string;
@Input() value: number;
@Input() digitsInfo = '1.2-2';
constructor(
private stateService: StateService,
) { }
private cd: ChangeDetectorRef,
) {
this.currencySubscription = this.stateService.fiatCurrency$.subscribe((fiat) => {
this.currency = fiat;
this.cd.markForCheck();
});
}
ngOnInit(): void {
this.conversions$ = this.stateService.conversions$.asObservable();
}
ngOnDestroy(): void {
this.currencySubscription.unsubscribe();
}
}

View File

@@ -7,7 +7,7 @@
</div>
<div class="box-right">
<div class="second-line"><ng-container *ngTemplateOutlet="xChannels; context: {$implicit: channel.channels }"></ng-container></div>
<div class="second-line"><app-amount [satoshis]="channel.capacity" digitsInfo="1.2-2"></app-amount></div>
<div class="second-line"><app-amount [satoshis]="channel.capacity" digitsInfo="1.2-2" [noFiat]="true"></app-amount></div>
</div>
</div>

View File

@@ -17,7 +17,7 @@
<span i18n="shared.sats">sats</span>
</div>
<span class="fiat" *ngIf="statistics.previous">
<app-change [current]="statistics.latest?.avg_capacity" [previous]="statistics.previous?.avg_capacity"></app-change>
<app-fiat [value]="statistics.latest?.avg_capacity" digitsInfo="1.0-0" ></app-fiat>
</span>
</div>
</div>
@@ -63,7 +63,7 @@
<span i18n="shared.sats">sats</span>
</div>
<span class="fiat" *ngIf="statistics.previous">
<app-change [current]="statistics.latest?.med_capacity" [previous]="statistics.previous?.med_capacity"></app-change>
<app-fiat [value]="statistics.latest?.med_capacity" digitsInfo="1.0-0" ></app-fiat>
</span>
</div>
</div>

View File

@@ -84,8 +84,22 @@
</div>
<div class="text-small text-center mt-1" *ngIf="officialMempoolSpace">
<a [routerLink]="['/lightning/group/the-mempool-open-source-project' | relativeUrl]">Connect to our nodes</a>
<div class="pref-selectors">
<div class="selector">
<app-language-selector></app-language-selector>
</div>
<div class="selector">
<app-fiat-selector></app-fiat-selector>
</div>
</div>
<div class="terms-of-service">
<a [routerLink]="['/terms-of-service']" i18n="shared.terms-of-service|Terms of Service">Terms of Service</a>
|
<a [routerLink]="['/privacy-policy']" i18n="shared.privacy-policy|Privacy Policy">Privacy Policy</a>
|
<a *ngIf="officialMempoolSpace" [routerLink]="['/lightning/group/the-mempool-open-source-project' | relativeUrl]">Connect to our nodes</a>
<a *ngIf="!officialMempoolSpace" [routerLink]="['/tx/push' | relativeUrl]" i18n="shared.broadcast-transaction|Broadcast Transaction">Broadcast Transaction</a>
</div>
<br>

View File

@@ -103,4 +103,23 @@
margin-bottom: 10px;
text-decoration: none;
color: inherit;
}
.terms-of-service {
margin-top: 1rem;
}
.pref-selectors {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
.selector {
margin-left: .5em;
margin-bottom: .5em;
&:first {
margin-left: 0;
}
}
}

View File

@@ -5,11 +5,10 @@
<div class="card-text" i18n-ngbTooltip="mining.percentage-change-last-week" ngbTooltip="Percentage change past week"
[disableTooltip]="!statistics.previous" placement="bottom">
<div class="fee-text" [class]="!statistics.previous ? 'no-border' : ''">
<app-amount [satoshis]="statistics.latest?.total_capacity" digitsInfo="1.2-2"></app-amount>
<app-amount [satoshis]="statistics.latest?.total_capacity" digitsInfo="1.2-2" [noFiat]="true"></app-amount>
</div>
<span class="fiat" *ngIf="statistics.previous">
<app-change [current]="statistics.latest?.total_capacity" [previous]="statistics.previous?.total_capacity">
</app-change>
<app-fiat [value]="statistics.latest?.total_capacity" digitsInfo="1.0-0" ></app-fiat>
</span>
</div>
</div>

View File

@@ -121,6 +121,7 @@ export class StateService {
timeLtr: BehaviorSubject<boolean>;
hideFlow: BehaviorSubject<boolean>;
hideAudit: BehaviorSubject<boolean>;
fiatCurrency$: BehaviorSubject<string>;
constructor(
@Inject(PLATFORM_ID) private platformId: any,
@@ -186,6 +187,9 @@ export class StateService {
this.hideAudit.subscribe((hide) => {
this.storageService.setValue('audit-preference', hide ? 'hide' : 'show');
});
const fiatPreference = this.storageService.getValue('fiat-preference');
this.fiatCurrency$ = new BehaviorSubject<string>(fiatPreference || 'USD');
}
setNetworkBasedonUrl(url: string) {

View File

@@ -0,0 +1,28 @@
import { formatCurrency, getCurrencySymbol } from '@angular/common';
import { Inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core';
import { Subscription } from 'rxjs';
import { StateService } from '../../services/state.service';
@Pipe({
name: 'fiatCurrency'
})
export class FiatCurrencyPipe implements PipeTransform {
fiatSubscription: Subscription;
currency: string;
constructor(
@Inject(LOCALE_ID) public locale: string,
private stateService: StateService,
) {
this.fiatSubscription = this.stateService.fiatCurrency$.subscribe((fiat) => {
this.currency = fiat;
});
}
transform(num: number, ...args: any[]): unknown {
const digits = args[0] || 1;
const currency = args[1] || this.currency || 'USD';
return new Intl.NumberFormat(this.locale, { style: 'currency', currency }).format(num);
}
}

View File

@@ -1,20 +1,30 @@
import { formatCurrency, getCurrencySymbol } from '@angular/common';
import { Inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core';
import { Subscription } from 'rxjs';
import { StateService } from '../../services/state.service';
@Pipe({
name: 'fiatShortener'
})
export class FiatShortenerPipe implements PipeTransform {
fiatSubscription: Subscription;
currency: string;
constructor(
@Inject(LOCALE_ID) public locale: string
) {}
@Inject(LOCALE_ID) public locale: string,
private stateService: StateService,
) {
this.fiatSubscription = this.stateService.fiatCurrency$.subscribe((fiat) => {
this.currency = fiat;
});
}
transform(num: number, ...args: any[]): unknown {
const digits = args[0] || 1;
const unit = args[1] || undefined;
const currency = args[1] || this.currency || 'USD';
if (num < 1000) {
return num.toFixed(digits);
return new Intl.NumberFormat(this.locale, { style: 'currency', currency, maximumFractionDigits: 1 }).format(num);
}
const lookup = [
@@ -30,8 +40,8 @@ export class FiatShortenerPipe implements PipeTransform {
const item = lookup.slice().reverse().find((item) => num >= item.value);
let result = item ? (num / item.value).toFixed(digits).replace(rx, '$1') : '0';
result = formatCurrency(parseInt(result, 10), this.locale, getCurrencySymbol('USD', 'narrow'), 'USD', '1.0-0');
result = new Intl.NumberFormat(this.locale, { style: 'currency', currency, maximumFractionDigits: 0 }).format(item ? num / item.value : 0);
return result + item.symbol;
}
}

View File

@@ -23,6 +23,7 @@ import { RelativeUrlPipe } from './pipes/relative-url/relative-url.pipe';
import { ScriptpubkeyTypePipe } from './pipes/scriptpubkey-type-pipe/scriptpubkey-type.pipe';
import { BytesPipe } from './pipes/bytes-pipe/bytes.pipe';
import { WuBytesPipe } from './pipes/bytes-pipe/wubytes.pipe';
import { FiatCurrencyPipe } from './pipes/fiat-currency.pipe';
import { BlockchainComponent } from '../components/blockchain/blockchain.component';
import { TimeSinceComponent } from '../components/time-since/time-since.component';
import { TimeUntilComponent } from '../components/time-until/time-until.component';
@@ -34,6 +35,7 @@ import { TxFeaturesComponent } from '../components/tx-features/tx-features.compo
import { TxFeeRatingComponent } from '../components/tx-fee-rating/tx-fee-rating.component';
import { ReactiveFormsModule } from '@angular/forms';
import { LanguageSelectorComponent } from '../components/language-selector/language-selector.component';
import { FiatSelectorComponent } from '../components/fiat-selector/fiat-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';
@@ -93,6 +95,7 @@ import { GeolocationComponent } from '../shared/components/geolocation/geolocati
TxFeaturesComponent,
TxFeeRatingComponent,
LanguageSelectorComponent,
FiatSelectorComponent,
ScriptpubkeyTypePipe,
RelativeUrlPipe,
NoSanitizePipe,
@@ -107,6 +110,7 @@ import { GeolocationComponent } from '../shared/components/geolocation/geolocati
CapAddressPipe,
Decimal2HexPipe,
FeeRoundingPipe,
FiatCurrencyPipe,
ColoredPriceDirective,
BlockchainComponent,
MempoolBlocksComponent,
@@ -199,6 +203,7 @@ import { GeolocationComponent } from '../shared/components/geolocation/geolocati
TxFeaturesComponent,
TxFeeRatingComponent,
LanguageSelectorComponent,
FiatSelectorComponent,
ScriptpubkeyTypePipe,
RelativeUrlPipe,
Hex2asciiPipe,
@@ -207,6 +212,7 @@ import { GeolocationComponent } from '../shared/components/geolocation/geolocati
BytesPipe,
VbytesPipe,
WuBytesPipe,
FiatCurrencyPipe,
CeilPipe,
ShortenStringPipe,
CapAddressPipe,