2020-02-22 23:23:24 +01:00
|
|
|
import { Component, OnInit, OnDestroy, Input, EventEmitter, Output, OnChanges } from '@angular/core';
|
2020-02-16 16:15:07 +01:00
|
|
|
import { Subscription } from 'rxjs';
|
|
|
|
import { MempoolBlock } from 'src/app/interfaces/websocket.interface';
|
|
|
|
import { StateService } from 'src/app/services/state.service';
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-mempool-blocks',
|
|
|
|
templateUrl: './mempool-blocks.component.html',
|
|
|
|
styleUrls: ['./mempool-blocks.component.scss']
|
|
|
|
})
|
2020-02-22 23:23:24 +01:00
|
|
|
export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
|
2020-02-16 16:15:07 +01:00
|
|
|
mempoolBlocks: MempoolBlock[];
|
|
|
|
mempoolBlocksSubscription: Subscription;
|
|
|
|
|
|
|
|
blockWidth = 125;
|
2020-02-22 23:23:24 +01:00
|
|
|
blockPadding = 30;
|
|
|
|
arrowVisible = false;
|
|
|
|
|
|
|
|
rightPosition = 0;
|
2020-02-16 16:15:07 +01:00
|
|
|
|
|
|
|
@Input() txFeePerVSize: number;
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
private stateService: StateService,
|
|
|
|
) { }
|
|
|
|
|
|
|
|
ngOnInit() {
|
|
|
|
this.mempoolBlocksSubscription = this.stateService.mempoolBlocks$
|
|
|
|
.subscribe((blocks) => {
|
|
|
|
this.mempoolBlocks = blocks;
|
|
|
|
this.calculateTransactionPosition();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-02-22 23:23:24 +01:00
|
|
|
ngOnChanges() {
|
|
|
|
this.calculateTransactionPosition();
|
|
|
|
}
|
|
|
|
|
2020-02-16 16:15:07 +01:00
|
|
|
ngOnDestroy() {
|
|
|
|
this.mempoolBlocksSubscription.unsubscribe();
|
|
|
|
}
|
|
|
|
|
|
|
|
trackByFn(index: number) {
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
getStyleForMempoolBlockAtIndex(index: number) {
|
|
|
|
const greenBackgroundHeight = 100 - this.mempoolBlocks[index].blockVSize / 1000000 * 100;
|
|
|
|
return {
|
|
|
|
'right': 40 + index * 155 + 'px',
|
|
|
|
'background': `repeating-linear-gradient(to right, #554b45, #554b45 ${greenBackgroundHeight}%,
|
|
|
|
#bd7c13 ${Math.max(greenBackgroundHeight, 0)}%, #c5345a 100%)`,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
calculateTransactionPosition() {
|
2020-02-22 23:23:24 +01:00
|
|
|
if (!this.txFeePerVSize || !this.mempoolBlocks) {
|
|
|
|
this.arrowVisible = false;
|
2020-02-16 16:15:07 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-02-22 23:23:24 +01:00
|
|
|
this.arrowVisible = true;
|
|
|
|
|
2020-02-16 16:15:07 +01:00
|
|
|
for (const block of this.mempoolBlocks) {
|
|
|
|
for (let i = 0; i < block.feeRange.length - 1; i++) {
|
|
|
|
if (this.txFeePerVSize < block.feeRange[i + 1] && this.txFeePerVSize >= block.feeRange[i]) {
|
|
|
|
const txInBlockIndex = this.mempoolBlocks.indexOf(block);
|
|
|
|
const feeRangeIndex = block.feeRange.findIndex((val, index) => this.txFeePerVSize < block.feeRange[index + 1]);
|
|
|
|
const feeRangeChunkSize = 1 / (block.feeRange.length - 1);
|
|
|
|
|
|
|
|
const txFee = this.txFeePerVSize - block.feeRange[i];
|
|
|
|
const max = block.feeRange[i + 1] - block.feeRange[i];
|
|
|
|
const blockLocation = txFee / max;
|
|
|
|
|
|
|
|
const chunkPositionOffset = blockLocation * feeRangeChunkSize;
|
|
|
|
const feePosition = feeRangeChunkSize * feeRangeIndex + chunkPositionOffset;
|
|
|
|
|
|
|
|
const blockedFilledPercentage = (block.blockVSize > 1000000 ? 1000000 : block.blockVSize) / 1000000;
|
2020-02-22 23:23:24 +01:00
|
|
|
const arrowRightPosition = txInBlockIndex * (this.blockWidth + this.blockPadding)
|
2020-02-16 16:15:07 +01:00
|
|
|
+ ((1 - feePosition) * blockedFilledPercentage * this.blockWidth);
|
|
|
|
|
2020-02-22 23:23:24 +01:00
|
|
|
this.rightPosition = arrowRightPosition;
|
2020-02-16 16:15:07 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|