import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { SeoService } from '../../../services/seo.service'; import { WebsocketService } from '../../../services/websocket.service'; import { Acceleration, BlockExtended } from '../../../interfaces/node-api.interface'; import { StateService } from '../../../services/state.service'; import { Observable, Subject, catchError, combineLatest, distinctUntilChanged, of, share, switchMap, tap } from 'rxjs'; import { ApiService } from '../../../services/api.service'; interface AccelerationBlock extends BlockExtended { accelerationCount: number, } @Component({ selector: 'app-accelerator-dashboard', templateUrl: './accelerator-dashboard.component.html', styleUrls: ['./accelerator-dashboard.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) export class AcceleratorDashboardComponent implements OnInit { blocks$: Observable; accelerations$: Observable; loadingBlocks: boolean = true; constructor( private seoService: SeoService, private websocketService: WebsocketService, private apiService: ApiService, private stateService: StateService, ) { this.seoService.setTitle($localize`:@@a681a4e2011bb28157689dbaa387de0dd0aa0c11:Accelerator Dashboard`); } ngOnInit(): void { this.websocketService.want(['blocks', 'mempool-blocks', 'stats']); this.accelerations$ = this.stateService.chainTip$.pipe( distinctUntilChanged(), switchMap((chainTip) => { return this.apiService.getAccelerationHistory$({ timeframe: '1w' }); }), catchError((e) => { return of([]); }), share(), ); this.blocks$ = combineLatest([ this.accelerations$, this.stateService.blocks$.pipe( switchMap((blocks) => { if (this.stateService.env.MINING_DASHBOARD === true) { for (const block of blocks) { // @ts-ignore: Need to add an extra field for the template block.extras.pool.logo = `/resources/mining-pools/` + block.extras.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg'; } } return of(blocks as AccelerationBlock[]); }), tap(() => { this.loadingBlocks = false; }) ) ]).pipe( switchMap(([accelerations, blocks]) => { const blockMap = {}; for (const block of blocks) { blockMap[block.id] = block; } const accelerationsByBlock: { [ hash: string ]: Acceleration[] } = {}; for (const acceleration of accelerations) { if (['mined', 'completed'].includes(acceleration.status) && acceleration.pools.includes(blockMap[acceleration.blockHash]?.extras.pool.id)) { if (!accelerationsByBlock[acceleration.blockHash]) { accelerationsByBlock[acceleration.blockHash] = []; } accelerationsByBlock[acceleration.blockHash].push(acceleration); } } return of(blocks.slice(0, 6).map(block => { block.accelerationCount = (accelerationsByBlock[block.id] || []).length; return block; })); }) ); } }