From 8eca1e5f7e90a925dc988dfe10cf8255624f48fd Mon Sep 17 00:00:00 2001 From: Mononaut Date: Wed, 8 Feb 2023 19:07:59 -0600 Subject: [PATCH] Handle network interruptions in scrollable blockchain --- .../blockchain-blocks.component.html | 10 +++++----- .../blockchain-blocks.component.scss | 4 ++++ .../blockchain-blocks/blockchain-blocks.component.ts | 2 ++ .../components/blockchain/blockchain.component.html | 2 +- .../components/blockchain/blockchain.component.ts | 12 +++++++++++- frontend/src/app/components/start/start.component.ts | 4 +++- frontend/src/app/services/cache.service.ts | 7 ++++++- 7 files changed, 32 insertions(+), 9 deletions(-) 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 400016d02..deb915f26 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html @@ -1,6 +1,6 @@
+ *ngIf="static || (loadingBlocks$ | async) === false; else loadingBlocksTemplate">
- +
- +
- -
+ +
diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss index 64bfd2379..5db452470 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss @@ -137,6 +137,10 @@ opacity: 1; } +.loading .bitcoin-block.mined-block { + background: #2d3348; +} + @keyframes opacityPulse { 0% {opacity: 0.7;} 50% {opacity: 1.0;} 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 fb37cf72a..39f68c22e 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts @@ -22,6 +22,8 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { @Input() offset: number = 0; @Input() height: number = 0; @Input() count: number = 8; + @Input() loadingTip: boolean = false; + @Input() connected: boolean = true; specialBlocks = specialBlocks; network = ''; diff --git a/frontend/src/app/components/blockchain/blockchain.component.html b/frontend/src/app/components/blockchain/blockchain.component.html index ad2e5e86a..0c4a1cbb7 100644 --- a/frontend/src/app/components/blockchain/blockchain.component.html +++ b/frontend/src/app/components/blockchain/blockchain.component.html @@ -6,7 +6,7 @@ - +
diff --git a/frontend/src/app/components/blockchain/blockchain.component.ts b/frontend/src/app/components/blockchain/blockchain.component.ts index 0ad3625ea..ab9875a4c 100644 --- a/frontend/src/app/components/blockchain/blockchain.component.ts +++ b/frontend/src/app/components/blockchain/blockchain.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, Input, OnChanges, SimpleChanges } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { firstValueFrom, Subscription } from 'rxjs'; import { StateService } from '../../services/state.service'; @Component({ @@ -18,6 +18,9 @@ export class BlockchainComponent implements OnInit, OnDestroy { timeLtrSubscription: Subscription; timeLtr: boolean = this.stateService.timeLtr.value; ltrTransitionEnabled = false; + connectionStateSubscription: Subscription; + loadingTip: boolean = true; + connected: boolean = true; constructor( public stateService: StateService, @@ -28,10 +31,17 @@ export class BlockchainComponent implements OnInit, OnDestroy { this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => { this.timeLtr = !!ltr; }); + this.connectionStateSubscription = this.stateService.connectionState$.subscribe(state => { + this.connected = (state === 2); + }) + firstValueFrom(this.stateService.chainTip$).then(tip => { + this.loadingTip = false; + }); } ngOnDestroy() { this.timeLtrSubscription.unsubscribe(); + this.connectionStateSubscription.unsubscribe(); } trackByPageFn(index: number, item: { index: number }) { diff --git a/frontend/src/app/components/start/start.component.ts b/frontend/src/app/components/start/start.component.ts index 28f9cf6aa..c7b8a83bc 100644 --- a/frontend/src/app/components/start/start.component.ts +++ b/frontend/src/app/components/start/start.component.ts @@ -21,6 +21,7 @@ export class StartComponent implements OnInit, OnDestroy { timeLtr: boolean = this.stateService.timeLtr.value; chainTipSubscription: Subscription; chainTip: number = -1; + tipIsSet: boolean = false; markBlockSubscription: Subscription; blockCounterSubscription: Subscription; @ViewChild('blockchainContainer') blockchainContainer: ElementRef; @@ -58,6 +59,7 @@ export class StartComponent implements OnInit, OnDestroy { }); this.chainTipSubscription = this.stateService.chainTip$.subscribe((height) => { this.chainTip = height; + this.tipIsSet = true; this.updatePages(); if (this.pendingMark != null) { this.scrollToBlock(this.pendingMark); @@ -66,7 +68,7 @@ export class StartComponent implements OnInit, OnDestroy { }); this.markBlockSubscription = this.stateService.markBlock$.subscribe((mark) => { if (mark?.blockHeight != null) { - if (this.chainTip >=0) { + if (this.tipIsSet) { if (!this.blockInViewport(mark.blockHeight)) { this.scrollToBlock(mark.blockHeight); } diff --git a/frontend/src/app/services/cache.service.ts b/frontend/src/app/services/cache.service.ts index be37164dd..15ef99859 100644 --- a/frontend/src/app/services/cache.service.ts +++ b/frontend/src/app/services/cache.service.ts @@ -62,7 +62,12 @@ export class CacheService { for (let i = 0; i < chunkSize; i++) { this.blockLoading[maxHeight - i] = true; } - const result = await firstValueFrom(this.apiService.getBlocks$(maxHeight)); + let result; + try { + result = await firstValueFrom(this.apiService.getBlocks$(maxHeight)); + } catch (e) { + console.log("failed to load blocks: ", e.message); + } for (let i = 0; i < chunkSize; i++) { delete this.blockLoading[maxHeight - i]; }