Replacing footer and latest blocks with a stats dashboard.

This commit is contained in:
softsimon
2020-09-21 19:41:12 +07:00
parent 8146939f0f
commit 6c1d28a9ac
18 changed files with 235 additions and 209 deletions

View File

@@ -48,7 +48,7 @@ export class AddressComponent implements OnInit, OnDestroy {
ngOnInit() {
this.stateService.networkChanged$.subscribe((network) => this.network = network);
this.websocketService.want(['blocks', 'stats', 'mempool-blocks']);
this.websocketService.want(['blocks', 'mempool-blocks']);
this.mainSubscription = this.route.paramMap
.pipe(

View File

@@ -53,7 +53,7 @@ export class AssetComponent implements OnInit, OnDestroy {
) { }
ngOnInit() {
this.websocketService.want(['blocks', 'stats', 'mempool-blocks']);
this.websocketService.want(['blocks', 'mempool-blocks']);
this.stateService.networkChanged$.subscribe((network) => this.network = network);
this.mainSubscription = this.route.paramMap

View File

@@ -1,39 +0,0 @@
<app-fees-box *ngIf="(network$ | async) === ''" class="d-block mr-2 ml-2 mb-4"></app-fees-box>
<div class="container-xl">
<hr>
<table class="table table-borderless" [alwaysCallback]="true" [fromRoot]="true" [infiniteScrollContainer]="'body'" infiniteScroll [infiniteScrollDistance]="1.5" [infiniteScrollUpDistance]="1.5" [infiniteScrollThrottle]="50" (scrolled)="loadMore()">
<thead>
<th style="width: 15%;">Height</th>
<th class="d-none d-md-block" style="width: 20%;">Timestamp</th>
<th style="width: 20%;">Mined</th>
<th class="d-none d-lg-block" style="width: 15%;">Transactions</th>
<th style="width: 20%;">Filled</th>
</thead>
<tbody>
<tr *ngFor="let block of blocks; let i= index; trackBy: trackByBlock">
<td><a [routerLink]="['/block' | relativeUrl, block.id]" [state]="{ data: { block: block } }">{{ block.height }}</a></td>
<td class="d-none d-md-block">{{ block.timestamp * 1000 | date:'yyyy-MM-dd HH:mm' }}</td>
<td><app-time-since [time]="block.timestamp" [fastRender]="true"></app-time-since> ago</td>
<td class="d-none d-lg-block">{{ block.tx_count | number }}</td>
<td>
<div class="progress position-relative">
<div class="progress-bar progress-mempool {{ network$ | async }}" role="progressbar" [ngStyle]="{'width': (block.weight / 4000000)*100 + '%' }"></div>
<div class="progress-text">{{ block.size | bytes: 2 }}</div>
</div>
</td>
</tr>
<ng-template [ngIf]="isLoading">
<tr *ngFor="let item of [1,2,3,4,5,6,7,8,9,10]">
<td><span class="skeleton-loader"></span></td>
<td class="d-none d-md-block"><span class="skeleton-loader"></span></td>
<td><span class="skeleton-loader"></span></td>
<td class="d-none d-lg-block"><span class="skeleton-loader"></span></td>
<td><span class="skeleton-loader"></span></td>
</tr>
</ng-template>
</tbody>
</table>
</div>

View File

@@ -1,14 +0,0 @@
.progress {
background-color: #2d3348;
}
@media (min-width: 768px) {
.d-md-block {
display: table-cell !important;
}
}
@media (min-width: 992px) {
.d-lg-block {
display: table-cell !important;
}
}

View File

@@ -1,25 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LatestBlocksComponent } from './latest-blocks.component';
describe('LatestBlocksComponent', () => {
let component: LatestBlocksComponent;
let fixture: ComponentFixture<LatestBlocksComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LatestBlocksComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LatestBlocksComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,111 +0,0 @@
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { ElectrsApiService } from '../../services/electrs-api.service';
import { StateService } from '../../services/state.service';
import { Block } from '../../interfaces/electrs.interface';
import { Subscription, Observable, merge, of } from 'rxjs';
import { SeoService } from 'src/app/services/seo.service';
@Component({
selector: 'app-latest-blocks',
templateUrl: './latest-blocks.component.html',
styleUrls: ['./latest-blocks.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class LatestBlocksComponent implements OnInit, OnDestroy {
network$: Observable<string>;
blocks: any[] = [];
blockSubscription: Subscription;
isLoading = true;
interval: any;
latestBlockHeight: number;
heightOfPageUntilBlocks = 430;
heightOfBlocksTableChunk = 470;
constructor(
private electrsApiService: ElectrsApiService,
private stateService: StateService,
private seoService: SeoService,
private cd: ChangeDetectorRef,
) { }
ngOnInit() {
this.seoService.resetTitle();
this.network$ = merge(of(''), this.stateService.networkChanged$);
this.blockSubscription = this.stateService.blocks$
.subscribe(([block]) => {
if (block === null || !this.blocks.length) {
return;
}
this.latestBlockHeight = block.height;
if (block.height === this.blocks[0].height) {
return;
}
// If we are out of sync, reload the blocks instead
if (block.height > this.blocks[0].height + 1) {
this.loadInitialBlocks();
return;
}
if (block.height <= this.blocks[0].height) {
return;
}
this.blocks.pop();
this.blocks.unshift(block);
this.cd.markForCheck();
});
this.loadInitialBlocks();
}
ngOnDestroy() {
clearInterval(this.interval);
this.blockSubscription.unsubscribe();
}
loadInitialBlocks() {
this.electrsApiService.listBlocks$()
.subscribe((blocks) => {
this.blocks = blocks;
this.isLoading = false;
this.latestBlockHeight = blocks[0].height;
const spaceForBlocks = window.innerHeight - this.heightOfPageUntilBlocks;
const chunks = Math.ceil(spaceForBlocks / this.heightOfBlocksTableChunk) - 1;
if (chunks > 0) {
this.loadMore(chunks);
}
this.cd.markForCheck();
});
}
loadMore(chunks = 0) {
if (this.isLoading) {
return;
}
this.isLoading = true;
this.electrsApiService.listBlocks$(this.blocks[this.blocks.length - 1].height - 1)
.subscribe((blocks) => {
this.blocks = this.blocks.concat(blocks);
this.isLoading = false;
const chunksLeft = chunks - 1;
if (chunksLeft > 0) {
this.loadMore(chunksLeft);
}
this.cd.markForCheck();
});
}
trackByBlock(index: number, block: Block) {
return block.height;
}
}

View File

@@ -66,10 +66,4 @@
<br>
<ng-container *ngIf="network.val !== 'bisq'">
<br><br>
<app-footer></app-footer>
</ng-container>
</ng-container>

View File

@@ -108,10 +108,10 @@ export class StatisticsComponent implements OnInit {
switchMap(() => {
this.spinnerLoading = true;
if (this.radioGroupForm.controls.dateSpan.value === '2h') {
this.websocketService.want(['blocks', 'stats', 'live-2h-chart']);
this.websocketService.want(['blocks', 'live-2h-chart']);
return this.apiService.list2HStatistics$();
}
this.websocketService.want(['blocks', 'stats']);
this.websocketService.want(['blocks']);
if (this.radioGroupForm.controls.dateSpan.value === '24h') {
return this.apiService.list24HStatistics$();
}