-
+
+
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 @@
0">
0">
-
+
0">
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];
}