2024-07-26 11:21:24 +02:00
|
|
|
import { Component, Input, OnInit, OnChanges, HostListener } from '@angular/core';
|
2024-07-04 16:54:35 +09:00
|
|
|
import { ETA } from '../../services/eta.service';
|
|
|
|
import { Transaction } from '../../interfaces/electrs.interface';
|
2024-07-26 11:21:24 +02:00
|
|
|
import { Acceleration, SinglePoolStats } from '../../interfaces/node-api.interface';
|
|
|
|
import { MiningService } from '../../services/mining.service';
|
2024-07-04 16:54:35 +09:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-acceleration-timeline',
|
|
|
|
templateUrl: './acceleration-timeline.component.html',
|
|
|
|
styleUrls: ['./acceleration-timeline.component.scss'],
|
|
|
|
})
|
|
|
|
export class AccelerationTimelineComponent implements OnInit, OnChanges {
|
|
|
|
@Input() transactionTime: number;
|
|
|
|
@Input() tx: Transaction;
|
2024-07-26 11:21:24 +02:00
|
|
|
@Input() accelerationInfo: Acceleration;
|
2024-07-04 16:54:35 +09:00
|
|
|
@Input() eta: ETA;
|
2024-07-07 14:41:44 +09:00
|
|
|
// A mined transaction has standard ETA and accelerated ETA undefined
|
|
|
|
// A transaction in mempool has either standardETA defined (if accelerated) or acceleratedETA defined (if not accelerated yet)
|
|
|
|
@Input() standardETA: number;
|
|
|
|
@Input() acceleratedETA: number;
|
2024-07-04 16:54:35 +09:00
|
|
|
|
|
|
|
acceleratedAt: number;
|
2024-07-07 14:41:44 +09:00
|
|
|
now: number;
|
|
|
|
accelerateRatio: number;
|
2024-07-13 16:21:56 +09:00
|
|
|
useAbsoluteTime: boolean = false;
|
2024-07-13 18:45:18 +09:00
|
|
|
interval: number;
|
2024-09-23 14:47:57 +02:00
|
|
|
firstSeenToAccelerated: number;
|
|
|
|
acceleratedToMined: number;
|
2024-07-04 16:54:35 +09:00
|
|
|
|
2024-07-26 11:21:24 +02:00
|
|
|
tooltipPosition = null;
|
|
|
|
hoverInfo: any = null;
|
|
|
|
poolsData: { [id: number]: SinglePoolStats } = {};
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
private miningService: MiningService,
|
|
|
|
) {}
|
2024-07-04 16:54:35 +09:00
|
|
|
|
|
|
|
ngOnInit(): void {
|
|
|
|
this.acceleratedAt = this.tx.acceleratedAt ?? new Date().getTime() / 1000;
|
2024-07-13 16:21:56 +09:00
|
|
|
|
2024-07-26 11:21:24 +02:00
|
|
|
this.miningService.getPools().subscribe(pools => {
|
|
|
|
for (const pool of pools) {
|
|
|
|
this.poolsData[pool.unique_id] = pool;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2024-09-23 14:47:57 +02:00
|
|
|
this.updateTimes();
|
|
|
|
this.interval = window.setInterval(this.updateTimes.bind(this), 60000);
|
2024-07-04 16:54:35 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
ngOnChanges(changes): void {
|
2024-07-09 01:17:38 +09:00
|
|
|
// Hide standard ETA while we don't have a proper standard ETA calculation, see https://github.com/mempool/mempool/issues/65
|
|
|
|
|
|
|
|
// if (changes?.eta?.currentValue || changes?.standardETA?.currentValue || changes?.acceleratedETA?.currentValue) {
|
|
|
|
// if (changes?.eta?.currentValue) {
|
|
|
|
// if (changes?.acceleratedETA?.currentValue) {
|
|
|
|
// this.accelerateRatio = Math.floor((Math.floor(changes.eta.currentValue.time / 1000) - this.now) / (Math.floor(changes.acceleratedETA.currentValue / 1000) - this.now));
|
|
|
|
// } else if (changes?.standardETA?.currentValue) {
|
|
|
|
// this.accelerateRatio = Math.floor((Math.floor(changes.standardETA.currentValue / 1000) - this.now) / (Math.floor(changes.eta.currentValue.time / 1000) - this.now));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
2024-07-04 16:54:35 +09:00
|
|
|
}
|
2024-07-13 18:45:18 +09:00
|
|
|
|
2024-09-23 14:47:57 +02:00
|
|
|
updateTimes(): void {
|
|
|
|
this.now = Math.floor(new Date().getTime() / 1000);
|
|
|
|
this.useAbsoluteTime = this.tx.status.block_time < this.now - 7 * 24 * 3600;
|
|
|
|
this.firstSeenToAccelerated = Math.max(0, this.acceleratedAt - this.transactionTime);
|
|
|
|
this.acceleratedToMined = Math.max(0, this.tx.status.block_time - this.acceleratedAt);
|
|
|
|
}
|
|
|
|
|
2024-07-13 18:45:18 +09:00
|
|
|
ngOnDestroy(): void {
|
|
|
|
clearInterval(this.interval);
|
|
|
|
}
|
2024-07-26 11:21:24 +02:00
|
|
|
|
|
|
|
onHover(event, status: string): void {
|
|
|
|
if (status === 'seen') {
|
|
|
|
this.hoverInfo = {
|
|
|
|
status,
|
|
|
|
fee: this.tx.fee,
|
|
|
|
weight: this.tx.weight
|
|
|
|
};
|
|
|
|
} else if (status === 'accelerated') {
|
|
|
|
this.hoverInfo = {
|
|
|
|
status,
|
|
|
|
fee: this.accelerationInfo?.effectiveFee || this.tx.fee,
|
|
|
|
weight: this.tx.weight,
|
|
|
|
feeDelta: this.accelerationInfo?.feeDelta || this.tx.feeDelta,
|
|
|
|
pools: this.tx.acceleratedBy || this.accelerationInfo?.pools,
|
|
|
|
poolsData: this.poolsData
|
|
|
|
};
|
|
|
|
} else if (status === 'mined') {
|
|
|
|
this.hoverInfo = {
|
|
|
|
status,
|
|
|
|
fee: this.accelerationInfo?.effectiveFee,
|
|
|
|
weight: this.tx.weight,
|
|
|
|
bidBoost: this.accelerationInfo?.bidBoost,
|
|
|
|
minedByPoolUniqueId: this.accelerationInfo?.minedByPoolUniqueId,
|
|
|
|
pools: this.tx.acceleratedBy || this.accelerationInfo?.pools,
|
|
|
|
poolsData: this.poolsData
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onBlur(event): void {
|
|
|
|
this.hoverInfo = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@HostListener('pointermove', ['$event'])
|
|
|
|
onPointerMove(event) {
|
|
|
|
this.tooltipPosition = { x: event.clientX, y: event.clientY };
|
|
|
|
}
|
2024-07-04 16:54:35 +09:00
|
|
|
}
|