load block/tx pages at correct blockchain scroll position
This commit is contained in:
parent
32bf30872d
commit
bf941b0227
@ -49,7 +49,7 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
<div [hidden]="!arrowVisible" id="arrow-up" [style.transition]="transition" [ngStyle]="{'left': arrowLeftPx + 'px' }"></div>
|
<div [hidden]="!arrowVisible" id="arrow-up" [style.transition]="arrowTransition" [ngStyle]="{'left': arrowLeftPx + 'px' }"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-template #loadingBlocksTemplate>
|
<ng-template #loadingBlocksTemplate>
|
||||||
|
@ -43,7 +43,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
arrowVisible = false;
|
arrowVisible = false;
|
||||||
arrowLeftPx = 30;
|
arrowLeftPx = 30;
|
||||||
blocksFilled = false;
|
blocksFilled = false;
|
||||||
transition = '1s';
|
arrowTransition = '1s';
|
||||||
showMiningInfo = false;
|
showMiningInfo = false;
|
||||||
timeLtrSubscription: Subscription;
|
timeLtrSubscription: Subscription;
|
||||||
timeLtr: boolean;
|
timeLtr: boolean;
|
||||||
@ -179,13 +179,13 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
const blockindex = this.blocks.findIndex((b) => b.height === this.markHeight);
|
const blockindex = this.blocks.findIndex((b) => b.height === this.markHeight);
|
||||||
if (blockindex > -1) {
|
if (blockindex > -1) {
|
||||||
if (!animate) {
|
if (!animate) {
|
||||||
this.transition = 'inherit';
|
this.arrowTransition = 'inherit';
|
||||||
}
|
}
|
||||||
this.arrowVisible = true;
|
this.arrowVisible = true;
|
||||||
if (newBlockFromLeft) {
|
if (newBlockFromLeft) {
|
||||||
this.arrowLeftPx = blockindex * 155 + 30 - 205;
|
this.arrowLeftPx = blockindex * 155 + 30 - 205;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.transition = '2s';
|
this.arrowTransition = '2s';
|
||||||
this.arrowLeftPx = blockindex * 155 + 30;
|
this.arrowLeftPx = blockindex * 155 + 30;
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
}, 50);
|
}, 50);
|
||||||
@ -193,9 +193,9 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
this.arrowLeftPx = blockindex * 155 + 30;
|
this.arrowLeftPx = blockindex * 155 + 30;
|
||||||
if (!animate) {
|
if (!animate) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.transition = '2s';
|
this.arrowTransition = '2s';
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
});
|
}, 50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<div class="position-container" [ngClass]="network ? network : ''">
|
<div class="position-container" [ngClass]="network ? network : ''">
|
||||||
<span>
|
<span>
|
||||||
<div class="blocks-wrapper">
|
<div class="blocks-wrapper">
|
||||||
|
<div class="scroll-spacer" *ngIf="minScrollWidth" [style.left]="minScrollWidth + 'px'"></div>
|
||||||
<app-mempool-blocks [hidden]="pageIndex > 0"></app-mempool-blocks>
|
<app-mempool-blocks [hidden]="pageIndex > 0"></app-mempool-blocks>
|
||||||
<app-blockchain-blocks [hidden]="pageIndex > 0"></app-blockchain-blocks>
|
<app-blockchain-blocks [hidden]="pageIndex > 0"></app-blockchain-blocks>
|
||||||
<ng-container *ngFor="let page of pages; trackBy: trackByPageFn">
|
<ng-container *ngFor="let page of pages; trackBy: trackByPageFn">
|
||||||
|
@ -72,6 +72,15 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.scroll-spacer {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.loading-block {
|
.loading-block {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -12,6 +12,7 @@ export class BlockchainComponent implements OnInit, OnDestroy {
|
|||||||
@Input() pages: any[] = [];
|
@Input() pages: any[] = [];
|
||||||
@Input() pageIndex: number;
|
@Input() pageIndex: number;
|
||||||
@Input() blocksPerPage: number = 8;
|
@Input() blocksPerPage: number = 8;
|
||||||
|
@Input() minScrollWidth: number = 0;
|
||||||
|
|
||||||
network: string;
|
network: string;
|
||||||
timeLtrSubscription: Subscription;
|
timeLtrSubscription: Subscription;
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
(dragstart)="onDragStart($event)"
|
(dragstart)="onDragStart($event)"
|
||||||
(scroll)="onScroll($event)"
|
(scroll)="onScroll($event)"
|
||||||
>
|
>
|
||||||
<app-blockchain [pageIndex]="pageIndex" [pages]="pages" [blocksPerPage]="blocksPerPage"></app-blockchain>
|
<app-blockchain [pageIndex]="pageIndex" [pages]="pages" [blocksPerPage]="blocksPerPage" [minScrollWidth]="minScrollWidth"></app-blockchain>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
@ -29,8 +29,10 @@ export class StartComponent implements OnInit, OnDestroy {
|
|||||||
blocksPerPage: number = 1;
|
blocksPerPage: number = 1;
|
||||||
pageWidth: number;
|
pageWidth: number;
|
||||||
firstPageWidth: number;
|
firstPageWidth: number;
|
||||||
|
minScrollWidth: number;
|
||||||
pageIndex: number = 0;
|
pageIndex: number = 0;
|
||||||
pages: any[] = [];
|
pages: any[] = [];
|
||||||
|
pendingMark: number | void = null;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
@ -39,17 +41,28 @@ export class StartComponent implements OnInit, OnDestroy {
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.firstPageWidth = 40 + (this.blockWidth * this.stateService.env.KEEP_BLOCKS_AMOUNT);
|
this.firstPageWidth = 40 + (this.blockWidth * this.stateService.env.KEEP_BLOCKS_AMOUNT);
|
||||||
this.onResize();
|
this.onResize();
|
||||||
|
this.updatePages();
|
||||||
this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => {
|
this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => {
|
||||||
this.timeLtr = !!ltr;
|
this.timeLtr = !!ltr;
|
||||||
});
|
});
|
||||||
this.chainTipSubscription = this.stateService.chainTip$.subscribe((height) => {
|
this.chainTipSubscription = this.stateService.chainTip$.subscribe((height) => {
|
||||||
this.chainTip = height;
|
this.chainTip = height;
|
||||||
this.updatePages();
|
this.updatePages();
|
||||||
|
if (this.pendingMark != null) {
|
||||||
|
this.scrollToBlock(this.pendingMark);
|
||||||
|
this.pendingMark = null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.markBlockSubscription = this.stateService.markBlock$.subscribe((mark) => {
|
this.markBlockSubscription = this.stateService.markBlock$.subscribe((mark) => {
|
||||||
if (mark?.blockHeight != null && !this.blockInViewport(mark.blockHeight)) {
|
if (mark?.blockHeight != null) {
|
||||||
|
if (this.chainTip >=0) {
|
||||||
|
if (!this.blockInViewport(mark.blockHeight)) {
|
||||||
this.scrollToBlock(mark.blockHeight);
|
this.scrollToBlock(mark.blockHeight);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.pendingMark = mark.blockHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.stateService.blocks$
|
this.stateService.blocks$
|
||||||
.subscribe((blocks: any) => {
|
.subscribe((blocks: any) => {
|
||||||
@ -96,6 +109,7 @@ export class StartComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
this.blocksPerPage = Math.ceil(window.innerWidth / this.blockWidth);
|
this.blocksPerPage = Math.ceil(window.innerWidth / this.blockWidth);
|
||||||
this.pageWidth = this.blocksPerPage * this.blockWidth;
|
this.pageWidth = this.blocksPerPage * this.blockWidth;
|
||||||
|
this.minScrollWidth = this.firstPageWidth + (this.pageWidth * 2);
|
||||||
|
|
||||||
if (firstVisibleBlock != null) {
|
if (firstVisibleBlock != null) {
|
||||||
this.scrollToBlock(firstVisibleBlock, offset);
|
this.scrollToBlock(firstVisibleBlock, offset);
|
||||||
@ -270,5 +284,7 @@ export class StartComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.timeLtrSubscription.unsubscribe();
|
this.timeLtrSubscription.unsubscribe();
|
||||||
|
this.chainTipSubscription.unsubscribe();
|
||||||
|
this.markBlockSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import { BlockExtended } from '../interfaces/node-api.interface';
|
|||||||
import { StateService } from './state.service';
|
import { StateService } from './state.service';
|
||||||
import { ApiService } from './api.service';
|
import { ApiService } from './api.service';
|
||||||
|
|
||||||
const BLOCK_CACHE_SIZE = 50;
|
const BLOCK_CACHE_SIZE = 500;
|
||||||
const KEEP_RECENT_BLOCKS = 50;
|
const KEEP_RECENT_BLOCKS = 50;
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
|
@ -224,12 +224,14 @@ export class WebsocketService {
|
|||||||
handleResponse(response: WebsocketResponse) {
|
handleResponse(response: WebsocketResponse) {
|
||||||
if (response.blocks && response.blocks.length) {
|
if (response.blocks && response.blocks.length) {
|
||||||
const blocks = response.blocks;
|
const blocks = response.blocks;
|
||||||
|
let maxHeight = 0;
|
||||||
blocks.forEach((block: BlockExtended) => {
|
blocks.forEach((block: BlockExtended) => {
|
||||||
if (block.height > this.stateService.latestBlockHeight) {
|
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.blocks$.next([block, false]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.stateService.updateChainTip(maxHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.tx) {
|
if (response.tx) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user