More refactoring based on feedback

This commit is contained in:
softsimon 2024-05-22 15:28:27 +07:00
parent 3c3ab96164
commit aa80fa550b
No known key found for this signature in database
GPG Key ID: 488D7DCFB5A430D7
5 changed files with 45 additions and 58 deletions

View File

@ -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 },
]; ];

View File

@ -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();
}
} }

View File

@ -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">

View File

@ -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;
}
}
} }

View 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();
}
}