Refactored frontend data handling.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
<div *ngIf="blocks.length === 0" class="text-center">
|
||||
<div *ngIf="isLoading" class="text-center">
|
||||
<h3>Loading blocks...</h3>
|
||||
<br>
|
||||
<div class="spinner-border text-light"></div>
|
||||
</div>
|
||||
<div *ngIf="blocks.length !== 0 && txTrackingLoading" class="text-center black-background">
|
||||
<div *ngIf="!isLoading && txTrackingLoading" class="text-center black-background">
|
||||
<h3>Locating transaction...</h3>
|
||||
</div>
|
||||
<div *ngIf="txShowTxNotFound" class="text-center black-background">
|
||||
@@ -11,15 +11,14 @@
|
||||
</div>
|
||||
<div class="text-center" class="blockchain-wrapper">
|
||||
<div class="position-container">
|
||||
<app-blockchain-projected-blocks></app-blockchain-projected-blocks>
|
||||
<app-blockchain-blocks></app-blockchain-blocks>
|
||||
|
||||
<app-blockchain-projected-blocks [projectedBlocks]="projectedBlocks"></app-blockchain-projected-blocks>
|
||||
<app-blockchain-blocks [blocks]="blocks"></app-blockchain-blocks>
|
||||
|
||||
<div id="divider" *ngIf="blocks.length"></div>
|
||||
<div id="divider" *ngIf="!isLoading"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<app-tx-bubble *ngIf="blocks?.length && txTrackingTx" [tx]="txTrackingTx" [arrowPosition]="txBubbleArrowPosition" [ngStyle]="txBubbleStyle" [latestBlockHeight]="blocks[0].height" [txTrackingBlockHeight]="txTrackingBlockHeight"></app-tx-bubble>
|
||||
<app-tx-bubble></app-tx-bubble>
|
||||
|
||||
<app-footer></app-footer>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Component, OnInit, OnDestroy, Renderer2, HostListener } from '@angular/core';
|
||||
import { IMempoolDefaultResponse, IBlock, IProjectedBlock, ITransaction } from './interfaces';
|
||||
import { retryWhen, tap } from 'rxjs/operators';
|
||||
import { MemPoolService } from '../services/mem-pool.service';
|
||||
import { Component, OnInit, OnDestroy, Renderer2 } from '@angular/core';
|
||||
import { MemPoolService, ITxTracking } from '../services/mem-pool.service';
|
||||
import { ApiService } from '../services/api.service';
|
||||
import { ActivatedRoute, ParamMap } from '@angular/router';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'app-blockchain',
|
||||
@@ -11,23 +11,12 @@ import { ActivatedRoute, ParamMap } from '@angular/router';
|
||||
styleUrls: ['./blockchain.component.scss']
|
||||
})
|
||||
export class BlockchainComponent implements OnInit, OnDestroy {
|
||||
blocks: IBlock[] = [];
|
||||
projectedBlocks: IProjectedBlock[] = [];
|
||||
subscription: any;
|
||||
socket: any;
|
||||
txBubbleStyle: any = {};
|
||||
txTrackingSubscription: Subscription;
|
||||
blocksSubscription: Subscription;
|
||||
|
||||
txTrackingLoading = false;
|
||||
txTrackingEnabled = false;
|
||||
txTrackingTx: ITransaction | null = null;
|
||||
txTrackingBlockHeight = 0;
|
||||
txShowTxNotFound = false;
|
||||
txBubbleArrowPosition = 'top';
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(event: Event) {
|
||||
this.moveTxBubbleToPosition();
|
||||
}
|
||||
isLoading = true;
|
||||
|
||||
constructor(
|
||||
private memPoolService: MemPoolService,
|
||||
@@ -37,72 +26,15 @@ export class BlockchainComponent implements OnInit, OnDestroy {
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.txTrackingSubscription = this.memPoolService.txTracking$
|
||||
.subscribe((response: ITxTracking) => {
|
||||
this.txTrackingLoading = false;
|
||||
this.txShowTxNotFound = response.notFound;
|
||||
if (this.txShowTxNotFound) {
|
||||
setTimeout(() => { this.txShowTxNotFound = false; }, 2000);
|
||||
}
|
||||
});
|
||||
|
||||
this.txBubbleStyle = {
|
||||
'position': 'absolute',
|
||||
'top': '425px',
|
||||
'visibility': 'hidden',
|
||||
};
|
||||
this.socket = this.apiService.websocketSubject;
|
||||
this.subscription = this.socket
|
||||
.pipe(
|
||||
retryWhen((errors: any) => errors.pipe(
|
||||
tap(() => this.memPoolService.isOffline.next(true))))
|
||||
)
|
||||
.subscribe((response: IMempoolDefaultResponse) => {
|
||||
this.memPoolService.isOffline.next(false);
|
||||
if (response.mempoolInfo && response.txPerSecond !== undefined) {
|
||||
this.memPoolService.loaderSubject.next({
|
||||
memPoolInfo: response.mempoolInfo,
|
||||
txPerSecond: response.txPerSecond,
|
||||
vBytesPerSecond: response.vBytesPerSecond,
|
||||
});
|
||||
}
|
||||
if (response.blocks && response.blocks.length) {
|
||||
this.blocks = response.blocks;
|
||||
this.blocks.reverse();
|
||||
}
|
||||
if (response.block) {
|
||||
if (!this.blocks.some((block) => response.block !== undefined && response.block.height === block.height )) {
|
||||
this.blocks.unshift(response.block);
|
||||
if (this.blocks.length >= 8) {
|
||||
this.blocks.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (response.conversions) {
|
||||
this.memPoolService.conversions.next(response.conversions);
|
||||
}
|
||||
if (response.projectedBlocks) {
|
||||
this.projectedBlocks = response.projectedBlocks;
|
||||
const mempoolWeight = this.projectedBlocks.map((block) => block.blockWeight).reduce((a, b) => a + b);
|
||||
this.memPoolService.mempoolWeight.next(mempoolWeight);
|
||||
}
|
||||
if (response['track-tx']) {
|
||||
if (response['track-tx'].tracking) {
|
||||
this.txTrackingEnabled = true;
|
||||
this.txTrackingBlockHeight = response['track-tx'].blockHeight;
|
||||
if (response['track-tx'].tx) {
|
||||
this.txTrackingTx = response['track-tx'].tx;
|
||||
this.txTrackingLoading = false;
|
||||
}
|
||||
} else {
|
||||
this.txTrackingEnabled = false;
|
||||
this.txTrackingTx = null;
|
||||
this.txTrackingBlockHeight = 0;
|
||||
}
|
||||
if (response['track-tx'].message && response['track-tx'].message === 'not-found') {
|
||||
this.txTrackingLoading = false;
|
||||
this.txShowTxNotFound = true;
|
||||
setTimeout(() => { this.txShowTxNotFound = false; }, 2000);
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.moveTxBubbleToPosition();
|
||||
});
|
||||
}
|
||||
},
|
||||
(err: Error) => console.log(err)
|
||||
);
|
||||
this.renderer.addClass(document.body, 'disable-scroll');
|
||||
|
||||
this.route.paramMap
|
||||
@@ -112,73 +44,27 @@ export class BlockchainComponent implements OnInit, OnDestroy {
|
||||
return;
|
||||
}
|
||||
this.txTrackingLoading = true;
|
||||
this.socket.next({'action': 'track-tx', 'txId': txId});
|
||||
this.apiService.sendWebSocket({'action': 'track-tx', 'txId': txId});
|
||||
});
|
||||
|
||||
this.memPoolService.txIdSearch
|
||||
this.memPoolService.txIdSearch$
|
||||
.subscribe((txId) => {
|
||||
if (txId) {
|
||||
this.txTrackingLoading = true;
|
||||
this.socket.next({'action': 'track-tx', 'txId': txId});
|
||||
this.apiService.sendWebSocket({'action': 'track-tx', 'txId': txId});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
moveTxBubbleToPosition() {
|
||||
let element: HTMLElement | null = null;
|
||||
if (this.txTrackingBlockHeight === 0) {
|
||||
const index = this.projectedBlocks.findIndex((pB) => pB.hasMytx);
|
||||
if (index > -1) {
|
||||
element = document.getElementById('projected-block-' + index);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
element = document.getElementById('bitcoin-block-' + this.txTrackingBlockHeight);
|
||||
}
|
||||
|
||||
this.txBubbleStyle['visibility'] = 'visible';
|
||||
this.txBubbleStyle['position'] = 'absolute';
|
||||
|
||||
if (!element) {
|
||||
if (window.innerWidth <= 768) {
|
||||
this.txBubbleArrowPosition = 'bottom';
|
||||
this.txBubbleStyle['left'] = window.innerWidth / 2 - 50 + 'px';
|
||||
this.txBubbleStyle['bottom'] = '270px';
|
||||
this.txBubbleStyle['top'] = 'inherit';
|
||||
this.txBubbleStyle['position'] = 'fixed';
|
||||
} else {
|
||||
this.txBubbleStyle['left'] = window.innerWidth - 220 + 'px';
|
||||
this.txBubbleArrowPosition = 'right';
|
||||
this.txBubbleStyle['top'] = '425px';
|
||||
}
|
||||
} else {
|
||||
this.txBubbleArrowPosition = 'top';
|
||||
const domRect: DOMRect | ClientRect = element.getBoundingClientRect();
|
||||
this.txBubbleStyle['left'] = domRect.left - 50 + 'px';
|
||||
this.txBubbleStyle['top'] = domRect.top + 125 + window.scrollY + 'px';
|
||||
|
||||
if (domRect.left + 100 > window.innerWidth) {
|
||||
this.txBubbleStyle['left'] = window.innerWidth - 220 + 'px';
|
||||
this.txBubbleArrowPosition = 'right';
|
||||
} else if (domRect.left + 220 > window.innerWidth) {
|
||||
this.txBubbleStyle['left'] = window.innerWidth - 240 + 'px';
|
||||
this.txBubbleArrowPosition = 'top-right';
|
||||
} else {
|
||||
this.txBubbleStyle['left'] = domRect.left + 15 + 'px';
|
||||
}
|
||||
|
||||
if (domRect.left < 86) {
|
||||
this.txBubbleArrowPosition = 'top-left';
|
||||
this.txBubbleStyle['left'] = 125 + 'px';
|
||||
}
|
||||
}
|
||||
this.blocksSubscription = this.memPoolService.blocks$
|
||||
.pipe(
|
||||
take(1)
|
||||
)
|
||||
.subscribe((block) => this.isLoading = false);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.subscription) {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
this.blocksSubscription.unsubscribe();
|
||||
this.txTrackingSubscription.unsubscribe();
|
||||
this.renderer.removeClass(document.body, 'disable-scroll');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user