Replacing footer and latest blocks with a stats dashboard.
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -66,10 +66,4 @@
|
||||
|
||||
<br>
|
||||
|
||||
<ng-container *ngIf="network.val !== 'bisq'">
|
||||
<br><br>
|
||||
|
||||
<app-footer></app-footer>
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
@@ -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$();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user