More refactoring based on feedback
This commit is contained in:
parent
3c3ab96164
commit
aa80fa550b
@ -12,6 +12,7 @@ import { PriceService } from './services/price.service';
|
|||||||
import { EnterpriseService } from './services/enterprise.service';
|
import { EnterpriseService } from './services/enterprise.service';
|
||||||
import { WebsocketService } from './services/websocket.service';
|
import { WebsocketService } from './services/websocket.service';
|
||||||
import { AudioService } from './services/audio.service';
|
import { AudioService } from './services/audio.service';
|
||||||
|
import { PreloadService } from './services/preload.service';
|
||||||
import { SeoService } from './services/seo.service';
|
import { SeoService } from './services/seo.service';
|
||||||
import { OpenGraphService } from './services/opengraph.service';
|
import { OpenGraphService } from './services/opengraph.service';
|
||||||
import { ZoneService } from './services/zone-shim.service';
|
import { ZoneService } from './services/zone-shim.service';
|
||||||
@ -46,6 +47,7 @@ const providers = [
|
|||||||
CapAddressPipe,
|
CapAddressPipe,
|
||||||
AppPreloadingStrategy,
|
AppPreloadingStrategy,
|
||||||
ServicesApiServices,
|
ServicesApiServices,
|
||||||
|
PreloadService,
|
||||||
{ provide: HTTP_INTERCEPTORS, useClass: HttpCacheInterceptor, multi: true },
|
{ provide: HTTP_INTERCEPTORS, useClass: HttpCacheInterceptor, multi: true },
|
||||||
{ provide: ZONE_SERVICE, useClass: ZoneService },
|
{ provide: ZONE_SERVICE, useClass: ZoneService },
|
||||||
];
|
];
|
||||||
|
@ -4,6 +4,7 @@ import { Transaction, Vout } from '../../interfaces/electrs.interface';
|
|||||||
import { Observable, Subscription, catchError, combineLatest, map, of, startWith, switchMap, tap } from 'rxjs';
|
import { Observable, Subscription, catchError, combineLatest, map, of, startWith, switchMap, tap } from 'rxjs';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { ElectrsApiService } from '../../services/electrs-api.service';
|
import { ElectrsApiService } from '../../services/electrs-api.service';
|
||||||
|
import { PreloadService } from '../../services/preload.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-block-transactions',
|
selector: 'app-block-transactions',
|
||||||
@ -11,14 +12,13 @@ import { ElectrsApiService } from '../../services/electrs-api.service';
|
|||||||
styleUrl: './block-transactions.component.scss',
|
styleUrl: './block-transactions.component.scss',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class BlockTransactionsComponent implements OnInit, OnDestroy {
|
export class BlockTransactionsComponent implements OnInit {
|
||||||
@Input() txCount: number;
|
@Input() txCount: number;
|
||||||
@Input() timestamp: number;
|
@Input() timestamp: number;
|
||||||
@Input() blockHash: string;
|
@Input() blockHash: string;
|
||||||
@Input() previousBlockHash: string;
|
@Input() previousBlockHash: string;
|
||||||
@Input() block$: Observable<any>;
|
@Input() block$: Observable<any>;
|
||||||
@Input() paginationMaxSize: number;
|
@Input() paginationMaxSize: number;
|
||||||
@Output() blockReward = new EventEmitter<number>();
|
|
||||||
|
|
||||||
itemsPerPage = this.stateService.env.ITEMS_PER_PAGE;
|
itemsPerPage = this.stateService.env.ITEMS_PER_PAGE;
|
||||||
page = 1;
|
page = 1;
|
||||||
@ -50,20 +50,6 @@ export class BlockTransactionsComponent implements OnInit, OnDestroy {
|
|||||||
return of([]);
|
return of([]);
|
||||||
}))
|
}))
|
||||||
),
|
),
|
||||||
)
|
|
||||||
.pipe(
|
|
||||||
tap((transactions: Transaction[]) => {
|
|
||||||
if (transactions && transactions[0] && transactions[0].vin[0].is_coinbase) {
|
|
||||||
const blockReward = transactions[0].vout.reduce((acc: number, curr: Vout) => acc + curr.value, 0) / 100000000;
|
|
||||||
this.blockReward.emit(blockReward);
|
|
||||||
}
|
|
||||||
this.unsubscribeNextBlockSubscriptions();
|
|
||||||
if (this.previousBlockHash) {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.nextBlockTxListSubscription = this.electrsApiService.getBlockTransactions$(this.previousBlockHash).subscribe();
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.txsLoadingStatus$ = this.route.paramMap
|
this.txsLoadingStatus$ = this.route.paramMap
|
||||||
@ -77,14 +63,4 @@ export class BlockTransactionsComponent implements OnInit, OnDestroy {
|
|||||||
target.scrollIntoView(); // works for chrome
|
target.scrollIntoView(); // works for chrome
|
||||||
this.router.navigate([], { queryParams: { page: page }, queryParamsHandling: 'merge' });
|
this.router.navigate([], { queryParams: { page: page }, queryParamsHandling: 'merge' });
|
||||||
}
|
}
|
||||||
|
|
||||||
unsubscribeNextBlockSubscriptions(): void {
|
|
||||||
if (this.nextBlockTxListSubscription !== undefined) {
|
|
||||||
this.nextBlockTxListSubscription.unsubscribe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
this.unsubscribeNextBlockSubscriptions();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -326,7 +326,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@defer (on viewport) {
|
@defer (on viewport) {
|
||||||
<app-block-transactions [paginationMaxSize]="paginationMaxSize" [block$]="block$" [txCount]="block.tx_count" [timestamp]="block.timestamp" [blockHash]="blockHash" [previousBlockHash]="block.previousblockhash" (blockReward)="updateBlockReward($event)"></app-block-transactions>
|
<app-block-transactions [paginationMaxSize]="paginationMaxSize" [block$]="block$" [txCount]="block.tx_count" [timestamp]="block.timestamp" [blockHash]="blockHash" [previousBlockHash]="block.previousblockhash"></app-block-transactions>
|
||||||
} @placeholder {
|
} @placeholder {
|
||||||
<div>
|
<div>
|
||||||
<div class="block-tx-title">
|
<div class="block-tx-title">
|
||||||
|
@ -16,6 +16,7 @@ import { seoDescriptionNetwork } from '../../shared/common.utils';
|
|||||||
import { PriceService, Price } from '../../services/price.service';
|
import { PriceService, Price } from '../../services/price.service';
|
||||||
import { CacheService } from '../../services/cache.service';
|
import { CacheService } from '../../services/cache.service';
|
||||||
import { ServicesApiServices } from '../../services/services-api.service';
|
import { ServicesApiServices } from '../../services/services-api.service';
|
||||||
|
import { PreloadService } from '../../services/preload.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-block',
|
selector: 'app-block',
|
||||||
@ -67,14 +68,11 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
mode: 'projected' | 'actual' = 'projected';
|
mode: 'projected' | 'actual' = 'projected';
|
||||||
|
|
||||||
overviewSubscription: Subscription;
|
overviewSubscription: Subscription;
|
||||||
auditSubscription: Subscription;
|
|
||||||
keyNavigationSubscription: Subscription;
|
keyNavigationSubscription: Subscription;
|
||||||
blocksSubscription: Subscription;
|
blocksSubscription: Subscription;
|
||||||
cacheBlocksSubscription: Subscription;
|
cacheBlocksSubscription: Subscription;
|
||||||
networkChangedSubscription: Subscription;
|
networkChangedSubscription: Subscription;
|
||||||
queryParamsSubscription: Subscription;
|
queryParamsSubscription: Subscription;
|
||||||
nextBlockSubscription: Subscription = undefined;
|
|
||||||
nextBlockSummarySubscription: Subscription = undefined;
|
|
||||||
timeLtrSubscription: Subscription;
|
timeLtrSubscription: Subscription;
|
||||||
timeLtr: boolean;
|
timeLtr: boolean;
|
||||||
childChangeSubscription: Subscription;
|
childChangeSubscription: Subscription;
|
||||||
@ -101,6 +99,7 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
private cacheService: CacheService,
|
private cacheService: CacheService,
|
||||||
private servicesApiService: ServicesApiServices,
|
private servicesApiService: ServicesApiServices,
|
||||||
private cd: ChangeDetectorRef,
|
private cd: ChangeDetectorRef,
|
||||||
|
private preloadService: PreloadService,
|
||||||
) {
|
) {
|
||||||
this.webGlEnabled = this.stateService.isBrowser && detectWebGL();
|
this.webGlEnabled = this.stateService.isBrowser && detectWebGL();
|
||||||
}
|
}
|
||||||
@ -159,7 +158,6 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
switchMap((params: ParamMap) => {
|
switchMap((params: ParamMap) => {
|
||||||
const blockHash: string = params.get('id') || '';
|
const blockHash: string = params.get('id') || '';
|
||||||
this.block = undefined;
|
this.block = undefined;
|
||||||
// this.page = 1;
|
|
||||||
this.error = undefined;
|
this.error = undefined;
|
||||||
this.fees = undefined;
|
this.fees = undefined;
|
||||||
this.oobFees = 0;
|
this.oobFees = 0;
|
||||||
@ -237,15 +235,11 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
tap((block: BlockExtended) => {
|
tap((block: BlockExtended) => {
|
||||||
if (block.height > 0) {
|
if (block.previousblockhash) {
|
||||||
// Preload previous block summary (execute the http query so the response will be cached)
|
this.preloadService.block$.next(block.previousblockhash);
|
||||||
this.unsubscribeNextBlockSubscriptions();
|
if (this.auditSupported) {
|
||||||
setTimeout(() => {
|
this.preloadService.blockAudit$.next(block.previousblockhash);
|
||||||
this.nextBlockSubscription = this.apiService.getBlock$(block.previousblockhash).subscribe();
|
}
|
||||||
if (this.auditSupported) {
|
|
||||||
this.apiService.getBlockAudit$(block.previousblockhash);
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
}
|
}
|
||||||
this.updateAuditAvailableFromBlockHeight(block.height);
|
this.updateAuditAvailableFromBlockHeight(block.height);
|
||||||
this.block = block;
|
this.block = block;
|
||||||
@ -536,29 +530,17 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.stateService.markBlock$.next({});
|
this.stateService.markBlock$.next({});
|
||||||
this.overviewSubscription?.unsubscribe();
|
this.overviewSubscription?.unsubscribe();
|
||||||
this.auditSubscription?.unsubscribe();
|
|
||||||
this.keyNavigationSubscription?.unsubscribe();
|
this.keyNavigationSubscription?.unsubscribe();
|
||||||
this.blocksSubscription?.unsubscribe();
|
this.blocksSubscription?.unsubscribe();
|
||||||
this.cacheBlocksSubscription?.unsubscribe();
|
this.cacheBlocksSubscription?.unsubscribe();
|
||||||
this.networkChangedSubscription?.unsubscribe();
|
this.networkChangedSubscription?.unsubscribe();
|
||||||
this.queryParamsSubscription?.unsubscribe();
|
this.queryParamsSubscription?.unsubscribe();
|
||||||
this.timeLtrSubscription?.unsubscribe();
|
this.timeLtrSubscription?.unsubscribe();
|
||||||
this.auditSubscription?.unsubscribe();
|
|
||||||
this.unsubscribeNextBlockSubscriptions();
|
|
||||||
this.childChangeSubscription?.unsubscribe();
|
this.childChangeSubscription?.unsubscribe();
|
||||||
this.priceSubscription?.unsubscribe();
|
this.priceSubscription?.unsubscribe();
|
||||||
this.oobSubscription?.unsubscribe();
|
this.oobSubscription?.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsubscribeNextBlockSubscriptions(): void {
|
|
||||||
if (this.nextBlockSubscription !== undefined) {
|
|
||||||
this.nextBlockSubscription.unsubscribe();
|
|
||||||
}
|
|
||||||
if (this.nextBlockSummarySubscription !== undefined) {
|
|
||||||
this.nextBlockSummarySubscription.unsubscribe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO - Refactor this.fees/this.reward for liquid because it is not
|
// TODO - Refactor this.fees/this.reward for liquid because it is not
|
||||||
// used anymore on Bitcoin networks (we use block.extras directly)
|
// used anymore on Bitcoin networks (we use block.extras directly)
|
||||||
setBlockSubsidy(): void {
|
setBlockSubsidy(): void {
|
||||||
@ -773,10 +755,4 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
this.block.canonical = block.id;
|
this.block.canonical = block.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBlockReward(blockReward: number): void {
|
|
||||||
if (this.fees === undefined) {
|
|
||||||
this.fees = blockReward;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
33
frontend/src/app/services/preload.service.ts
Normal file
33
frontend/src/app/services/preload.service.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ElectrsApiService } from '../services/electrs-api.service';
|
||||||
|
import { Subject, debounceTime, switchMap } from 'rxjs';
|
||||||
|
import { ApiService } from './api.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class PreloadService {
|
||||||
|
block$ = new Subject<string>;
|
||||||
|
blockAudit$ = new Subject<string>;
|
||||||
|
debounceTime = 250;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private electrsApiService: ElectrsApiService,
|
||||||
|
private apiService: ApiService,
|
||||||
|
) {
|
||||||
|
this.block$
|
||||||
|
.pipe(
|
||||||
|
debounceTime(this.debounceTime),
|
||||||
|
switchMap((blockHash) => this.electrsApiService.getBlockTransactions$(blockHash))
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
|
this.blockAudit$
|
||||||
|
.pipe(
|
||||||
|
debounceTime(this.debounceTime),
|
||||||
|
switchMap((blockHash) => this.apiService.getBlockAudit$(blockHash))
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user