diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html index b27dab69d..29df378a4 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html @@ -49,7 +49,7 @@ -
+
diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts index df583b0af..fd8819a6f 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts @@ -43,7 +43,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { arrowVisible = false; arrowLeftPx = 30; blocksFilled = false; - transition = '1s'; + arrowTransition = '1s'; showMiningInfo = false; timeLtrSubscription: Subscription; timeLtr: boolean; @@ -179,13 +179,13 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { const blockindex = this.blocks.findIndex((b) => b.height === this.markHeight); if (blockindex > -1) { if (!animate) { - this.transition = 'inherit'; + this.arrowTransition = 'inherit'; } this.arrowVisible = true; if (newBlockFromLeft) { this.arrowLeftPx = blockindex * 155 + 30 - 205; setTimeout(() => { - this.transition = '2s'; + this.arrowTransition = '2s'; this.arrowLeftPx = blockindex * 155 + 30; this.cd.markForCheck(); }, 50); @@ -193,9 +193,9 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { this.arrowLeftPx = blockindex * 155 + 30; if (!animate) { setTimeout(() => { - this.transition = '2s'; + this.arrowTransition = '2s'; this.cd.markForCheck(); - }); + }, 50); } } } else { diff --git a/frontend/src/app/components/blockchain/blockchain.component.html b/frontend/src/app/components/blockchain/blockchain.component.html index 542a837ea..ad2e5e86a 100644 --- a/frontend/src/app/components/blockchain/blockchain.component.html +++ b/frontend/src/app/components/blockchain/blockchain.component.html @@ -2,6 +2,7 @@
+
diff --git a/frontend/src/app/components/blockchain/blockchain.component.scss b/frontend/src/app/components/blockchain/blockchain.component.scss index df609ff40..63ca22626 100644 --- a/frontend/src/app/components/blockchain/blockchain.component.scss +++ b/frontend/src/app/components/blockchain/blockchain.component.scss @@ -72,6 +72,15 @@ position: relative; } +.scroll-spacer { + position: absolute; + top: 0; + left: 0; + width: 1px; + height: 1px; + pointer-events: none; +} + .loading-block { position: absolute; text-align: center; diff --git a/frontend/src/app/components/blockchain/blockchain.component.ts b/frontend/src/app/components/blockchain/blockchain.component.ts index cd09b7430..0ad3625ea 100644 --- a/frontend/src/app/components/blockchain/blockchain.component.ts +++ b/frontend/src/app/components/blockchain/blockchain.component.ts @@ -12,6 +12,7 @@ export class BlockchainComponent implements OnInit, OnDestroy { @Input() pages: any[] = []; @Input() pageIndex: number; @Input() blocksPerPage: number = 8; + @Input() minScrollWidth: number = 0; network: string; timeLtrSubscription: Subscription; diff --git a/frontend/src/app/components/start/start.component.html b/frontend/src/app/components/start/start.component.html index ae4c213cd..c3277cb9a 100644 --- a/frontend/src/app/components/start/start.component.html +++ b/frontend/src/app/components/start/start.component.html @@ -13,7 +13,7 @@ (dragstart)="onDragStart($event)" (scroll)="onScroll($event)" > - +
diff --git a/frontend/src/app/components/start/start.component.ts b/frontend/src/app/components/start/start.component.ts index d4b3a6f67..558e6f909 100644 --- a/frontend/src/app/components/start/start.component.ts +++ b/frontend/src/app/components/start/start.component.ts @@ -29,8 +29,10 @@ export class StartComponent implements OnInit, OnDestroy { blocksPerPage: number = 1; pageWidth: number; firstPageWidth: number; + minScrollWidth: number; pageIndex: number = 0; pages: any[] = []; + pendingMark: number | void = null; constructor( private stateService: StateService, @@ -39,16 +41,27 @@ export class StartComponent implements OnInit, OnDestroy { ngOnInit() { this.firstPageWidth = 40 + (this.blockWidth * this.stateService.env.KEEP_BLOCKS_AMOUNT); this.onResize(); + this.updatePages(); this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => { this.timeLtr = !!ltr; }); this.chainTipSubscription = this.stateService.chainTip$.subscribe((height) => { this.chainTip = height; this.updatePages(); + if (this.pendingMark != null) { + this.scrollToBlock(this.pendingMark); + this.pendingMark = null; + } }); this.markBlockSubscription = this.stateService.markBlock$.subscribe((mark) => { - if (mark?.blockHeight != null && !this.blockInViewport(mark.blockHeight)) { - this.scrollToBlock(mark.blockHeight); + if (mark?.blockHeight != null) { + if (this.chainTip >=0) { + if (!this.blockInViewport(mark.blockHeight)) { + this.scrollToBlock(mark.blockHeight); + } + } else { + this.pendingMark = mark.blockHeight; + } } }); this.stateService.blocks$ @@ -96,6 +109,7 @@ export class StartComponent implements OnInit, OnDestroy { this.blocksPerPage = Math.ceil(window.innerWidth / this.blockWidth); this.pageWidth = this.blocksPerPage * this.blockWidth; + this.minScrollWidth = this.firstPageWidth + (this.pageWidth * 2); if (firstVisibleBlock != null) { this.scrollToBlock(firstVisibleBlock, offset); @@ -270,5 +284,7 @@ export class StartComponent implements OnInit, OnDestroy { ngOnDestroy() { this.timeLtrSubscription.unsubscribe(); + this.chainTipSubscription.unsubscribe(); + this.markBlockSubscription.unsubscribe(); } } diff --git a/frontend/src/app/services/cache.service.ts b/frontend/src/app/services/cache.service.ts index 5e184c184..be37164dd 100644 --- a/frontend/src/app/services/cache.service.ts +++ b/frontend/src/app/services/cache.service.ts @@ -5,7 +5,7 @@ import { BlockExtended } from '../interfaces/node-api.interface'; import { StateService } from './state.service'; import { ApiService } from './api.service'; -const BLOCK_CACHE_SIZE = 50; +const BLOCK_CACHE_SIZE = 500; const KEEP_RECENT_BLOCKS = 50; @Injectable({ diff --git a/frontend/src/app/services/websocket.service.ts b/frontend/src/app/services/websocket.service.ts index ffe094456..d58ab58c9 100644 --- a/frontend/src/app/services/websocket.service.ts +++ b/frontend/src/app/services/websocket.service.ts @@ -224,12 +224,14 @@ export class WebsocketService { handleResponse(response: WebsocketResponse) { if (response.blocks && response.blocks.length) { const blocks = response.blocks; + let maxHeight = 0; blocks.forEach((block: BlockExtended) => { if (block.height > this.stateService.latestBlockHeight) { - this.stateService.updateChainTip(block.height); + maxHeight = Math.max(maxHeight, block.height); this.stateService.blocks$.next([block, false]); } }); + this.stateService.updateChainTip(maxHeight); } if (response.tx) {