mirror of
https://github.com/mempool/mempool.git
synced 2025-04-22 14:34:47 +02:00
Add latest block accelerations list
This commit is contained in:
parent
f23bcec10d
commit
f86645b50c
@ -22,7 +22,7 @@
|
||||
tr, td, th {
|
||||
border: 0px;
|
||||
padding-top: 0.65rem !important;
|
||||
padding-bottom: 0.7rem !important;
|
||||
padding-bottom: 0.8rem !important;
|
||||
|
||||
.difference {
|
||||
margin-left: 0.5em;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component, OnInit, ChangeDetectionStrategy, Input, ChangeDetectorRef } from '@angular/core';
|
||||
import { Observable, catchError, of } from 'rxjs';
|
||||
import { Observable, catchError, of, switchMap } from 'rxjs';
|
||||
import { Acceleration, BlockExtended } from '../../interfaces/node-api.interface';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
@ -39,7 +39,14 @@ export class AccelerationsListComponent implements OnInit {
|
||||
this.skeletonLines = this.widget === true ? [...Array(6).keys()] : [...Array(15).keys()];
|
||||
this.paginationMaxSize = window.matchMedia('(max-width: 670px)').matches ? 3 : 5;
|
||||
|
||||
this.accelerations$ = this.apiService.getAccelerations$().pipe(
|
||||
this.accelerations$ = this.apiService.getAccelerations$('24h').pipe(
|
||||
switchMap(accelerations => {
|
||||
if (this.widget) {
|
||||
return of(accelerations.slice(0, 6));
|
||||
} else {
|
||||
return of(accelerations);
|
||||
}
|
||||
}),
|
||||
catchError((err) => {
|
||||
this.isLoading = false;
|
||||
return of([]);
|
||||
|
@ -58,16 +58,37 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Difficult adjustments -->
|
||||
<!-- Latest blocks -->
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<a class="title-link" href="" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]">
|
||||
<h5 class="card-title d-inline" i18n="dashboard.adjustments">Adjustments</h5>
|
||||
<a class="title-link" href="" [routerLink]="['/blocks' | relativeUrl]">
|
||||
<h5 class="card-title d-inline" i18n="dashboard.latest-blocks">Latest blocks</h5>
|
||||
<span> </span>
|
||||
<fa-icon [icon]="['fas', 'external-link-alt']" [fixedWidth]="true" style="vertical-align: 'text-top'; font-size: 13px; color: '#4a68b9'"></fa-icon>
|
||||
</a>
|
||||
<app-difficulty-adjustments-table [attr.data-cy]="'difficulty-adjustments-table'"></app-difficulty-adjustments-table>
|
||||
<table class="table lastest-blocks-table">
|
||||
<thead>
|
||||
<th class="table-cell-height" i18n="dashboard.latest-blocks.height">Height</th>
|
||||
<th class="table-cell-pool" i18n="mining.pool-name">Pool</th>
|
||||
<th class="table-cell-fee" i18n="block.median-fee">Median fee</th>
|
||||
<th class="table-cell-acceleration-count" i18n="accelerator.transaction-count">Accelerations</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let block of blocks$ | async; let i = index">
|
||||
<td class="table-cell-height" ><a [routerLink]="['/block' | relativeUrl, block.id]" [state]="{ data: { block: block } }">{{ block.height }}</a></td>
|
||||
<td class="table-cell-pool">
|
||||
<a class="clear-link" [routerLink]="[('/mining/pool/' + block.extras.pool.slug) | relativeUrl]">
|
||||
<img width="22" height="22" src="{{ block.extras.pool['logo'] }}"
|
||||
onError="this.src = '/resources/mining-pools/default.svg'">
|
||||
<span class="pool-name">{{ block.extras.pool.name }}</span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="table-cell-fee" ><app-fee-rate [fee]="block?.extras?.medianFee" rounding="1.0-0"></app-fee-rate></td>
|
||||
<td class="table-cell-acceleration-count">{{ block.accelerationCount | number }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -100,3 +100,32 @@
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.lastest-blocks-table {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
tr, td, th {
|
||||
border: 0px;
|
||||
padding-top: 0.65rem !important;
|
||||
padding-bottom: 0.8rem !important;
|
||||
}
|
||||
.table-cell-height {
|
||||
width: 25%;
|
||||
}
|
||||
.table-cell-fee {
|
||||
width: 25%;
|
||||
text-align: right;
|
||||
}
|
||||
.table-cell-pool {
|
||||
text-align: left;
|
||||
width: 30%;
|
||||
|
||||
.pool-name {
|
||||
margin-left: 1em;
|
||||
}
|
||||
}
|
||||
.table-cell-acceleration-count {
|
||||
text-align: right;
|
||||
width: 20%;
|
||||
}
|
||||
}
|
@ -1,6 +1,14 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
import { Acceleration, BlockExtended } from '../../interfaces/node-api.interface';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Observable, catchError, combineLatest, of, switchMap } from 'rxjs';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
|
||||
interface AccelerationBlock extends BlockExtended {
|
||||
accelerationCount: number,
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-accelerator-dashboard',
|
||||
@ -9,14 +17,57 @@ import { WebsocketService } from '../../services/websocket.service';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AcceleratorDashboardComponent implements OnInit {
|
||||
blocks$: Observable<AccelerationBlock[]>;
|
||||
|
||||
loadingBlocks: boolean = true;
|
||||
|
||||
constructor(
|
||||
private seoService: SeoService,
|
||||
private websocketService: WebsocketService,
|
||||
private apiService: ApiService,
|
||||
private stateService: StateService,
|
||||
) {
|
||||
this.seoService.setTitle($localize`:@@a681a4e2011bb28157689dbaa387de0dd0aa0c11:Accelerator Dashboard`);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.websocketService.want(['blocks', 'mempool-blocks', 'stats']);
|
||||
|
||||
this.blocks$ = combineLatest([
|
||||
this.stateService.blocks$.pipe(
|
||||
switchMap((blocks) => {
|
||||
if (this.stateService.env.MINING_DASHBOARD === true) {
|
||||
for (const block of blocks) {
|
||||
// @ts-ignore: Need to add an extra field for the template
|
||||
block.extras.pool.logo = `/resources/mining-pools/` +
|
||||
block.extras.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg';
|
||||
}
|
||||
}
|
||||
return of(blocks as AccelerationBlock[]);
|
||||
})
|
||||
),
|
||||
this.apiService.getAccelerations$('24h').pipe(
|
||||
catchError((err) => {
|
||||
this.loadingBlocks = false;
|
||||
return of([]);
|
||||
})
|
||||
)
|
||||
]).pipe(
|
||||
switchMap(([blocks, accelerations]) => {
|
||||
const accelerationsByBlock: { [ hash: string ]: Acceleration[] } = {};
|
||||
for (const acceleration of accelerations) {
|
||||
if (acceleration.mined && !accelerationsByBlock[acceleration.block_hash]) {
|
||||
accelerationsByBlock[acceleration.block_hash] = [];
|
||||
}
|
||||
if (acceleration.mined) {
|
||||
accelerationsByBlock[acceleration.block_hash].push(acceleration);
|
||||
}
|
||||
}
|
||||
return of(blocks.slice(0, 6).map(block => {
|
||||
block.accelerationCount = (accelerationsByBlock[block.id] || []).length;
|
||||
return block;
|
||||
}));
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user