diff --git a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts
index 8a0a06f0c..1dc280514 100644
--- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts
+++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts
@@ -1,5 +1,5 @@
-import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, Input } from '@angular/core';
-import { Subscription, Observable, fromEvent, merge, of, combineLatest, timer } from 'rxjs';
+import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
+import { Subscription, Observable, fromEvent, merge, of, combineLatest } from 'rxjs';
import { MempoolBlock } from '../../interfaces/websocket.interface';
import { StateService } from '../../services/state.service';
import { Router } from '@angular/router';
@@ -9,11 +9,18 @@ import { specialBlocks } from '../../app.constants';
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
import { Location } from '@angular/common';
import { DifficultyAdjustment } from '../../interfaces/node-api.interface';
+import { animate, style, transition, trigger } from '@angular/animations';
@Component({
selector: 'app-mempool-blocks',
templateUrl: './mempool-blocks.component.html',
styleUrls: ['./mempool-blocks.component.scss'],
+ animations: [trigger('blockEntryTrigger', [
+ transition(':enter', [
+ style({ transform: 'translateX(-155px)' }),
+ animate('2s 0s ease', style({ transform: '' })),
+ ]),
+ ])],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MempoolBlocksComponent implements OnInit, OnDestroy {
@@ -32,12 +39,14 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
isLoadingWebsocketSubscription: Subscription;
blockSubscription: Subscription;
networkSubscription: Subscription;
+ chainTipSubscription: Subscription;
network = '';
now = new Date().getTime();
timeOffset = 0;
showMiningInfo = false;
timeLtrSubscription: Subscription;
timeLtr: boolean;
+ animateEntry: boolean = false;
blockWidth = 125;
blockPadding = 30;
@@ -53,6 +62,7 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
resetTransitionTimeout: number;
+ chainTip: number = -1;
blockIndex = 1;
constructor(
@@ -69,6 +79,8 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
}
ngOnInit() {
+ this.chainTip = this.stateService.latestBlockHeight;
+
if (['', 'testnet', 'signet'].includes(this.stateService.network)) {
this.enabledMiningInfoIfNeeded(this.location.path());
this.location.onUrlChange((url) => this.enabledMiningInfoIfNeeded(url));
@@ -155,11 +167,24 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
this.blockSubscription = this.stateService.blocks$
.subscribe(([block]) => {
+ if (this.chainTip === -1) {
+ this.animateEntry = block.height === this.stateService.latestBlockHeight;
+ } else {
+ this.animateEntry = block.height > this.chainTip;
+ }
+
+ this.chainTip = this.stateService.latestBlockHeight;
if (block?.extras?.matchRate >= 66 && !this.tabHidden) {
this.blockIndex++;
}
});
+ this.chainTipSubscription = this.stateService.chainTip$.subscribe((height) => {
+ if (this.chainTip === -1) {
+ this.chainTip = height;
+ }
+ });
+
this.networkSubscription = this.stateService.networkChanged$
.subscribe((network) => this.network = network);
@@ -195,11 +220,12 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
this.blockSubscription.unsubscribe();
this.networkSubscription.unsubscribe();
this.timeLtrSubscription.unsubscribe();
+ this.chainTipSubscription.unsubscribe();
clearTimeout(this.resetTransitionTimeout);
}
trackByFn(index: number, block: MempoolBlock) {
- return block.index;
+ return (block.isStack) ? 'stack' : block.height;
}
reduceMempoolBlocksToFitScreen(blocks: MempoolBlock[]): MempoolBlock[] {
@@ -216,6 +242,9 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
lastBlock.medianFee = this.median(lastBlock.feeRange);
lastBlock.totalFees += block.totalFees;
}
+ if (blocks.length) {
+ blocks[blocks.length - 1].isStack = blocks[blocks.length - 1].blockVSize > this.stateService.blockVSize;
+ }
return blocks;
}
@@ -334,4 +363,4 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
}
return emptyBlocks;
}
-}
+}
\ No newline at end of file
diff --git a/frontend/src/app/interfaces/websocket.interface.ts b/frontend/src/app/interfaces/websocket.interface.ts
index 96f7530c9..46416857e 100644
--- a/frontend/src/app/interfaces/websocket.interface.ts
+++ b/frontend/src/app/interfaces/websocket.interface.ts
@@ -43,6 +43,7 @@ export interface MempoolBlock {
totalFees: number;
feeRange: number[];
index: number;
+ isStack?: boolean;
}
export interface MempoolBlockWithTransactions extends MempoolBlock {