Handle network interruptions in scrollable blockchain
This commit is contained in:
		
							parent
							
								
									da3446f522
								
							
						
					
					
						commit
						8eca1e5f7e
					
				| @ -1,6 +1,6 @@ | |||||||
| <div class="blocks-container blockchain-blocks-container" [class.time-ltr]="timeLtr" | <div class="blocks-container blockchain-blocks-container" [class.time-ltr]="timeLtr" | ||||||
|   [style.left]="static ? (offset || 0) + 'px' : null" |   [style.left]="static ? (offset || 0) + 'px' : null" | ||||||
|   *ngIf="(loadingBlocks$ | async) === false; else loadingBlocksTemplate"> |   *ngIf="static || (loadingBlocks$ | async) === false; else loadingBlocksTemplate"> | ||||||
|   <div *ngFor="let block of blocks; let i = index; trackBy: trackByBlocksFn"> |   <div *ngFor="let block of blocks; let i = index; trackBy: trackByBlocksFn"> | ||||||
|     <ng-container *ngIf="block && !block.loading && !block.placeholder; else placeholderBlock"> |     <ng-container *ngIf="block && !block.loading && !block.placeholder; else placeholderBlock"> | ||||||
|       <div [attr.data-cy]="'bitcoin-block-offset-' + offset + '-index-' + i" |       <div [attr.data-cy]="'bitcoin-block-offset-' + offset + '-index-' + i" | ||||||
| @ -59,17 +59,17 @@ | |||||||
|       </div> |       </div> | ||||||
|     </ng-container> |     </ng-container> | ||||||
|     <ng-template #placeholderBlock> |     <ng-template #placeholderBlock> | ||||||
|       <ng-container *ngIf="block && block.placeholder; else loadingBlock"> |       <ng-container *ngIf="block && block.placeholder && !loadingTip; else loadingBlock"> | ||||||
|         <div [attr.data-cy]="'bitcoin-block-' + offset + '-index-' + i" |         <div [attr.data-cy]="'bitcoin-block-' + offset + '-index-' + i" | ||||||
|           class="text-center bitcoin-block mined-block placeholder-block blockchain-blocks-{{ i }}" |           class="text-center bitcoin-block mined-block placeholder-block blockchain-blocks-{{ i }}" | ||||||
|           id="bitcoin-block-{{ block.height }}" [ngStyle]="blockStyles[i]"> |           id="bitcoin-block-{{ block.height }}" [ngStyle]="blockStyles[i]"> | ||||||
| 
 |   | ||||||
|         </div> |         </div> | ||||||
|       </ng-container> |       </ng-container> | ||||||
|     </ng-template> |     </ng-template> | ||||||
|     <ng-template #loadingBlock> |     <ng-template #loadingBlock> | ||||||
|       <ng-container *ngIf="block && block.loading"> |       <ng-container *ngIf="loadingTip || (block && block.loading)"> | ||||||
|         <div class="flashing"> |         <div class="flashing loading"> | ||||||
|           <div class="text-center bitcoin-block mined-block" id="bitcoin-block-{{ block.height }}" |           <div class="text-center bitcoin-block mined-block" id="bitcoin-block-{{ block.height }}" | ||||||
|             [ngStyle]="blockStyles[i]"></div> |             [ngStyle]="blockStyles[i]"></div> | ||||||
|         </div> |         </div> | ||||||
|  | |||||||
| @ -137,6 +137,10 @@ | |||||||
|   opacity: 1; |   opacity: 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .loading .bitcoin-block.mined-block { | ||||||
|  |   background: #2d3348; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| @keyframes opacityPulse { | @keyframes opacityPulse { | ||||||
|   0% {opacity: 0.7;} |   0% {opacity: 0.7;} | ||||||
|   50% {opacity: 1.0;} |   50% {opacity: 1.0;} | ||||||
|  | |||||||
| @ -22,6 +22,8 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|   @Input() offset: number = 0; |   @Input() offset: number = 0; | ||||||
|   @Input() height: number = 0; |   @Input() height: number = 0; | ||||||
|   @Input() count: number = 8; |   @Input() count: number = 8; | ||||||
|  |   @Input() loadingTip: boolean = false; | ||||||
|  |   @Input() connected: boolean = true; | ||||||
|    |    | ||||||
|   specialBlocks = specialBlocks; |   specialBlocks = specialBlocks; | ||||||
|   network = ''; |   network = ''; | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ | |||||||
|         <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"> | ||||||
|           <app-blockchain-blocks [static]="true" [offset]="page.offset" [height]="page.height" [count]="blocksPerPage"></app-blockchain-blocks> |           <app-blockchain-blocks [static]="true" [offset]="page.offset" [height]="page.height" [count]="blocksPerPage" [loadingTip]="loadingTip" [connected]="connected"></app-blockchain-blocks> | ||||||
|         </ng-container> |         </ng-container> | ||||||
|       </div> |       </div> | ||||||
|       <div id="divider" [hidden]="pageIndex > 0"> |       <div id="divider" [hidden]="pageIndex > 0"> | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, Input, OnChanges, SimpleChanges } from '@angular/core'; | 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'; | import { StateService } from '../../services/state.service'; | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
| @ -18,6 +18,9 @@ export class BlockchainComponent implements OnInit, OnDestroy { | |||||||
|   timeLtrSubscription: Subscription; |   timeLtrSubscription: Subscription; | ||||||
|   timeLtr: boolean = this.stateService.timeLtr.value; |   timeLtr: boolean = this.stateService.timeLtr.value; | ||||||
|   ltrTransitionEnabled = false; |   ltrTransitionEnabled = false; | ||||||
|  |   connectionStateSubscription: Subscription; | ||||||
|  |   loadingTip: boolean = true; | ||||||
|  |   connected: boolean = true; | ||||||
| 
 | 
 | ||||||
|   constructor( |   constructor( | ||||||
|     public stateService: StateService, |     public stateService: StateService, | ||||||
| @ -28,10 +31,17 @@ export class BlockchainComponent implements OnInit, OnDestroy { | |||||||
|     this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => { |     this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => { | ||||||
|       this.timeLtr = !!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() { |   ngOnDestroy() { | ||||||
|     this.timeLtrSubscription.unsubscribe(); |     this.timeLtrSubscription.unsubscribe(); | ||||||
|  |     this.connectionStateSubscription.unsubscribe(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   trackByPageFn(index: number, item: { index: number }) { |   trackByPageFn(index: number, item: { index: number }) { | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ export class StartComponent implements OnInit, OnDestroy { | |||||||
|   timeLtr: boolean = this.stateService.timeLtr.value; |   timeLtr: boolean = this.stateService.timeLtr.value; | ||||||
|   chainTipSubscription: Subscription; |   chainTipSubscription: Subscription; | ||||||
|   chainTip: number = -1; |   chainTip: number = -1; | ||||||
|  |   tipIsSet: boolean = false; | ||||||
|   markBlockSubscription: Subscription; |   markBlockSubscription: Subscription; | ||||||
|   blockCounterSubscription: Subscription; |   blockCounterSubscription: Subscription; | ||||||
|   @ViewChild('blockchainContainer') blockchainContainer: ElementRef; |   @ViewChild('blockchainContainer') blockchainContainer: ElementRef; | ||||||
| @ -58,6 +59,7 @@ export class StartComponent implements OnInit, OnDestroy { | |||||||
|     }); |     }); | ||||||
|     this.chainTipSubscription = this.stateService.chainTip$.subscribe((height) => { |     this.chainTipSubscription = this.stateService.chainTip$.subscribe((height) => { | ||||||
|       this.chainTip = height; |       this.chainTip = height; | ||||||
|  |       this.tipIsSet = true; | ||||||
|       this.updatePages(); |       this.updatePages(); | ||||||
|       if (this.pendingMark != null) { |       if (this.pendingMark != null) { | ||||||
|         this.scrollToBlock(this.pendingMark); |         this.scrollToBlock(this.pendingMark); | ||||||
| @ -66,7 +68,7 @@ export class StartComponent implements OnInit, OnDestroy { | |||||||
|     }); |     }); | ||||||
|     this.markBlockSubscription = this.stateService.markBlock$.subscribe((mark) => { |     this.markBlockSubscription = this.stateService.markBlock$.subscribe((mark) => { | ||||||
|       if (mark?.blockHeight != null) { |       if (mark?.blockHeight != null) { | ||||||
|         if (this.chainTip >=0) { |         if (this.tipIsSet) { | ||||||
|           if (!this.blockInViewport(mark.blockHeight)) { |           if (!this.blockInViewport(mark.blockHeight)) { | ||||||
|             this.scrollToBlock(mark.blockHeight); |             this.scrollToBlock(mark.blockHeight); | ||||||
|           } |           } | ||||||
|  | |||||||
| @ -62,7 +62,12 @@ export class CacheService { | |||||||
|       for (let i = 0; i < chunkSize; i++) { |       for (let i = 0; i < chunkSize; i++) { | ||||||
|         this.blockLoading[maxHeight - i] = true; |         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++) { |       for (let i = 0; i < chunkSize; i++) { | ||||||
|         delete this.blockLoading[maxHeight - i]; |         delete this.blockLoading[maxHeight - i]; | ||||||
|       } |       } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user