diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index 40687060f..aed2d0004 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -339,7 +339,7 @@ class Blocks { return blockExtended; } - public async $getBlocksExtras(fromHeight: number): Promise { + public async $getBlocksExtras(fromHeight: number, limit: number = 15): Promise { try { loadingIndicators.setProgress('blocks', 0); @@ -360,7 +360,7 @@ class Blocks { } let nextHash = startFromHash; - for (let i = 0; i < 10 && currentHeight >= 0; i++) { + for (let i = 0; i < limit && currentHeight >= 0; i++) { let block = this.getBlocks().find((b) => b.height === currentHeight); if (!block && Common.indexingEnabled()) { block = this.prepareBlock(await this.$indexBlock(currentHeight)); diff --git a/backend/src/routes.ts b/backend/src/routes.ts index 710cd8378..c6b3656e7 100644 --- a/backend/src/routes.ts +++ b/backend/src/routes.ts @@ -658,7 +658,7 @@ class Routes { public async getBlocksExtras(req: Request, res: Response) { try { - res.json(await blocks.$getBlocksExtras(parseInt(req.params.height, 10))) + res.json(await blocks.$getBlocksExtras(parseInt(req.params.height, 10), 15)); } catch (e) { res.status(500).send(e instanceof Error ? e.message : e); } diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index 19285fc8f..1ef7e5fe0 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -31,6 +31,7 @@ import { MiningDashboardComponent } from './components/mining-dashboard/mining-d import { HashrateChartComponent } from './components/hashrate-chart/hashrate-chart.component'; import { HashrateChartPoolsComponent } from './components/hashrates-chart-pools/hashrate-chart-pools.component'; import { MiningStartComponent } from './components/mining-start/mining-start.component'; +import { BlocksList } from './components/blocks-list/blocks-list.component'; let routes: Routes = [ { @@ -75,6 +76,10 @@ let routes: Routes = [ path: 'mining', component: MiningStartComponent, children: [ + { + path: 'blocks', + component: BlocksList, + }, { path: 'hashrate', component: HashrateChartComponent, @@ -190,6 +195,10 @@ let routes: Routes = [ path: 'mining', component: MiningStartComponent, children: [ + { + path: 'blocks', + component: BlocksList, + }, { path: 'hashrate', component: HashrateChartComponent, @@ -299,6 +308,10 @@ let routes: Routes = [ path: 'mining', component: MiningStartComponent, children: [ + { + path: 'blocks', + component: BlocksList, + }, { path: 'hashrate', component: HashrateChartComponent, @@ -630,7 +643,7 @@ if (browserWindowEnv && browserWindowEnv.BASE_MODULE === 'liquid') { initialNavigation: 'enabled', scrollPositionRestoration: 'enabled', anchorScrolling: 'enabled' -})], + })], exports: [RouterModule] }) export class AppRoutingModule { } diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 0dfc853cc..3affdc7ba 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -76,6 +76,7 @@ import { MiningStartComponent } from './components/mining-start/mining-start.com import { AmountShortenerPipe } from './shared/pipes/amount-shortener.pipe'; import { ShortenStringPipe } from './shared/pipes/shorten-string-pipe/shorten-string.pipe'; import { DifficultyAdjustmentsTable } from './components/difficulty-adjustments-table/difficulty-adjustments-table.components'; +import { BlocksList } from './components/blocks-list/blocks-list.component'; @NgModule({ declarations: [ @@ -133,6 +134,7 @@ import { DifficultyAdjustmentsTable } from './components/difficulty-adjustments- MiningStartComponent, AmountShortenerPipe, DifficultyAdjustmentsTable, + BlocksList, ], imports: [ BrowserModule.withServerTransition({ appId: 'serverApp' }), diff --git a/frontend/src/app/components/blocks-list/blocks-list.component.html b/frontend/src/app/components/blocks-list/blocks-list.component.html new file mode 100644 index 000000000..480df9f3f --- /dev/null +++ b/frontend/src/app/components/blocks-list/blocks-list.component.html @@ -0,0 +1,100 @@ +
+

Blocks

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HeightTimestampMinedPoolRewardFeesTxsSize
+ {{ block.height + }} + + ‎{{ block.timestamp * 1000 | date:'yyyy-MM-dd HH:mm' }} + + + + + {{ + block.extras.pool.name }} + + + + + + {{ block.tx_count | number }} + +
+
+
+
+
+ + + + + + + + + + + + + + + +
+ + + +
\ No newline at end of file diff --git a/frontend/src/app/components/blocks-list/blocks-list.component.scss b/frontend/src/app/components/blocks-list/blocks-list.component.scss new file mode 100644 index 000000000..3d7ffe631 --- /dev/null +++ b/frontend/src/app/components/blocks-list/blocks-list.component.scss @@ -0,0 +1,74 @@ +.container-xl { + max-width: 1400px; +} + +.container { + max-width: 100%; +} + +.row { + padding-top: 15px; + padding-bottom: 15px; +} + +.pool-name { + display: inline-block; + vertical-align: text-top; + padding-left: 10px; +} + +.height { + width: 12%; + @media (max-width: 1100px) { + width: 10%; + } +} + +.timestamp { + @media (max-width: 900px) { + display: none; + } +} + +.mined { + @media (max-width: 576px) { + display: none; + } +} + +.txs { + padding-right: 40px; + @media (max-width: 1100px) { + padding-right: 10px; + } + @media (max-width: 800px) { + display: none; + } +} + +.fees { + @media (max-width: 650px) { + display: none; + } +} + +.pool { + width: 12%; +} + +.reward { + @media (max-width: 576px) { + width: 7%; + padding-right: 30px; + } +} + +.size { + width: 12%; + @media (max-width: 1000px) { + width: 15%; + } + @media (max-width: 650px) { + width: 20%; + } +} \ No newline at end of file diff --git a/frontend/src/app/components/blocks-list/blocks-list.component.ts b/frontend/src/app/components/blocks-list/blocks-list.component.ts new file mode 100644 index 000000000..56563d7e6 --- /dev/null +++ b/frontend/src/app/components/blocks-list/blocks-list.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map, repeat, tap } from 'rxjs/operators'; +import { BlockExtended } from 'src/app/interfaces/node-api.interface'; +import { ApiService } from 'src/app/services/api.service'; +import { StateService } from 'src/app/services/state.service'; + +@Component({ + selector: 'app-blocks-list', + templateUrl: './blocks-list.component.html', + styleUrls: ['./blocks-list.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class BlocksList implements OnInit { + blocks$: Observable = undefined + isLoading = true; + oldestBlockHeight = undefined; + + constructor( + private apiService: ApiService, + public stateService: StateService + ) { + + } + + ngOnInit(): void { + this.blocks$ = this.apiService.getBlocks$(this.oldestBlockHeight) + .pipe( + tap(blocks => { + this.isLoading = false; + }), + map(blocks => { + for (const block of blocks) { + // @ts-ignore + block.extras.pool.logo = `./resources/mining-pools/` + + block.extras.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg'; + this.oldestBlockHeight = block.height; + } + return blocks; + }), + repeat(2), + ); + } + + trackByBlock(index: number, block: BlockExtended) { + return block.height; + } +} \ No newline at end of file diff --git a/frontend/src/app/services/api.service.ts b/frontend/src/app/services/api.service.ts index 858da3273..142f26807 100644 --- a/frontend/src/app/services/api.service.ts +++ b/frontend/src/app/services/api.service.ts @@ -151,6 +151,13 @@ export class ApiService { ); } + getBlocks$(from: number): Observable { + return this.httpClient.get( + this.apiBasePath + this.apiBasePath + `/api/v1/blocks-extras` + + (from !== undefined ? `/${from}` : ``) + ); + } + getHistoricalDifficulty$(interval: string | undefined): Observable { return this.httpClient.get( this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/difficulty` +