2023-09-23 23:09:11 +01:00
|
|
|
import { Component, OnInit, OnDestroy, HostListener } from '@angular/core';
|
|
|
|
import { ActivatedRoute, ParamMap } from '@angular/router';
|
|
|
|
import { Subscription, filter, map, switchMap, tap } from 'rxjs';
|
|
|
|
import { StateService } from '../../services/state.service';
|
|
|
|
import { WebsocketService } from '../../services/websocket.service';
|
|
|
|
|
|
|
|
function bestFitResolution(min, max, n): number {
|
|
|
|
const target = (min + max) / 2;
|
|
|
|
let bestScore = Infinity;
|
|
|
|
let best = null;
|
|
|
|
for (let i = min; i <= max; i++) {
|
|
|
|
const remainder = (n % i);
|
|
|
|
if (remainder < bestScore || (remainder === bestScore && (Math.abs(i - target) < Math.abs(best - target)))) {
|
|
|
|
bestScore = remainder;
|
|
|
|
best = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return best;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-mempool-block-view',
|
|
|
|
templateUrl: './mempool-block-view.component.html',
|
|
|
|
styleUrls: ['./mempool-block-view.component.scss']
|
|
|
|
})
|
|
|
|
export class MempoolBlockViewComponent implements OnInit, OnDestroy {
|
|
|
|
autofit: boolean = false;
|
|
|
|
resolution: number = 80;
|
|
|
|
index: number = 0;
|
2023-12-05 06:54:31 +00:00
|
|
|
filterFlags: bigint | null = 0n;
|
2023-09-23 23:09:11 +01:00
|
|
|
|
|
|
|
routeParamsSubscription: Subscription;
|
|
|
|
queryParamsSubscription: Subscription;
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
private route: ActivatedRoute,
|
|
|
|
private websocketService: WebsocketService,
|
|
|
|
public stateService: StateService,
|
|
|
|
) { }
|
|
|
|
|
|
|
|
ngOnInit(): void {
|
2023-12-05 06:54:31 +00:00
|
|
|
window['setFlags'] = this.setFilterFlags.bind(this);
|
|
|
|
|
2023-09-23 23:09:11 +01:00
|
|
|
this.websocketService.want(['blocks', 'mempool-blocks']);
|
|
|
|
|
|
|
|
this.routeParamsSubscription = this.route.paramMap
|
|
|
|
.pipe(
|
|
|
|
switchMap((params: ParamMap) => {
|
|
|
|
this.index = parseInt(params.get('index'), 10) || 0;
|
|
|
|
return this.stateService.mempoolBlocks$
|
|
|
|
.pipe(
|
|
|
|
map((blocks) => {
|
|
|
|
if (!blocks.length) {
|
|
|
|
return [{ index: 0, blockSize: 0, blockVSize: 0, feeRange: [0, 0], medianFee: 0, nTx: 0, totalFees: 0 }];
|
|
|
|
}
|
|
|
|
return blocks;
|
|
|
|
}),
|
|
|
|
filter((mempoolBlocks) => mempoolBlocks.length > 0),
|
|
|
|
tap((mempoolBlocks) => {
|
|
|
|
while (!mempoolBlocks[this.index]) {
|
|
|
|
this.index--;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
);
|
|
|
|
})
|
|
|
|
).subscribe();
|
|
|
|
|
|
|
|
this.queryParamsSubscription = this.route.queryParams.subscribe((params) => {
|
|
|
|
this.autofit = params.autofit === 'true';
|
|
|
|
if (this.autofit) {
|
|
|
|
this.onResize();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@HostListener('window:resize', ['$event'])
|
|
|
|
onResize(): void {
|
|
|
|
if (this.autofit) {
|
|
|
|
this.resolution = bestFitResolution(64, 96, Math.min(window.innerWidth, window.innerHeight));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ngOnDestroy(): void {
|
|
|
|
this.routeParamsSubscription.unsubscribe();
|
|
|
|
this.queryParamsSubscription.unsubscribe();
|
|
|
|
}
|
2023-12-05 06:54:31 +00:00
|
|
|
|
|
|
|
setFilterFlags(flags: bigint | null) {
|
|
|
|
this.filterFlags = flags;
|
|
|
|
}
|
2023-09-23 23:09:11 +01:00
|
|
|
}
|