diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index 633e797d1..7e79f6421 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -221,9 +221,10 @@ class Blocks { const lastBlockToIndex = Math.max(0, currentBlockHeight - indexingBlockAmount + 1); logger.debug(`Indexing blocks from #${currentBlockHeight} to #${lastBlockToIndex}`); + loadingIndicators.setProgress('block-indexing', 0); const chunkSize = 10000; - let totaIndexed = await blocksRepository.$blockCount(null, null); + let totaIndexed = await blocksRepository.$blockCountBetweenHeight(currentBlockHeight, lastBlockToIndex); let indexedThisRun = 0; let newlyIndexed = 0; const startedAt = new Date().getTime() / 1000; @@ -256,6 +257,7 @@ class Blocks { logger.debug(`Indexing block #${blockHeight} | ~${blockPerSeconds} blocks/sec | total: ${totaIndexed}/${indexingBlockAmount} (${progress}%) | elapsed: ${runningFor} seconds | left: ~${timeLeft} seconds`); timer = new Date().getTime() / 1000; indexedThisRun = 0; + loadingIndicators.setProgress('block-indexing', progress); } const blockHash = await bitcoinApi.$getBlockHash(blockHeight); const block = BitcoinApi.convertBlock(await bitcoinClient.getBlock(blockHash)); @@ -269,9 +271,11 @@ class Blocks { currentBlockHeight -= chunkSize; } logger.info(`Indexed ${newlyIndexed} blocks`); + loadingIndicators.setProgress('block-indexing', 100); } catch (e) { logger.err('Block indexing failed. Trying again later. Reason: ' + (e instanceof Error ? e.message : e)); this.blockIndexingStarted = false; + loadingIndicators.setProgress('block-indexing', 100); return; } diff --git a/backend/src/repositories/BlocksRepository.ts b/backend/src/repositories/BlocksRepository.ts index c5267c461..e04080a9c 100644 --- a/backend/src/repositories/BlocksRepository.ts +++ b/backend/src/repositories/BlocksRepository.ts @@ -188,6 +188,24 @@ class BlocksRepository { } } + /** + * Get blocks count for a period + */ + public async $blockCountBetweenHeight(startHeight: number, endHeight: number): Promise { + const params: any[] = []; + let query = `SELECT count(height) as blockCount + FROM blocks + WHERE height <= ${startHeight} AND height >= ${endHeight}`; + + try { + const [rows] = await DB.query(query, params); + return rows[0].blockCount; + } catch (e) { + logger.err(`Cannot count blocks for this pool (using offset). Reason: ` + (e instanceof Error ? e.message : e)); + throw e; + } + } + /** * Get the oldest indexed block */ diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index ef40be5a3..c72460bb6 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -76,6 +76,7 @@ import { DataCyDirective } from './data-cy.directive'; import { BlockFeesGraphComponent } from './components/block-fees-graph/block-fees-graph.component'; import { BlockRewardsGraphComponent } from './components/block-rewards-graph/block-rewards-graph.component'; import { BlockFeeRatesGraphComponent } from './components/block-fee-rates-graph/block-fee-rates-graph.component'; +import { LoadingIndicatorComponent } from './components/loading-indicator/loading-indicator.component'; @NgModule({ declarations: [ @@ -132,6 +133,7 @@ import { BlockFeeRatesGraphComponent } from './components/block-fee-rates-graph/ BlockFeesGraphComponent, BlockRewardsGraphComponent, BlockFeeRatesGraphComponent, + LoadingIndicatorComponent, ], imports: [ BrowserModule.withServerTransition({ appId: 'serverApp' }), diff --git a/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.html b/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.html index a4325927f..f4ee2bd07 100644 --- a/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.html +++ b/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.html @@ -1,3 +1,5 @@ + +
Block fee rates diff --git a/frontend/src/app/components/block-fees-graph/block-fees-graph.component.html b/frontend/src/app/components/block-fees-graph/block-fees-graph.component.html index 88ce7db8a..b31ba5678 100644 --- a/frontend/src/app/components/block-fees-graph/block-fees-graph.component.html +++ b/frontend/src/app/components/block-fees-graph/block-fees-graph.component.html @@ -1,3 +1,5 @@ + +
Block fees diff --git a/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.html b/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.html index 32b4a66a0..d961e70bf 100644 --- a/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.html +++ b/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.html @@ -1,3 +1,5 @@ + +
diff --git a/frontend/src/app/components/blocks-list/blocks-list.component.html b/frontend/src/app/components/blocks-list/blocks-list.component.html index 703ccb6fc..c6746b142 100644 --- a/frontend/src/app/components/blocks-list/blocks-list.component.html +++ b/frontend/src/app/components/blocks-list/blocks-list.component.html @@ -1,3 +1,5 @@ + +

Blocks

diff --git a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.html b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.html index 532d433bc..d9977a0e8 100644 --- a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.html +++ b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.html @@ -1,3 +1,5 @@ + +
diff --git a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts index faeb2c8ce..f20f9db3a 100644 --- a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts +++ b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts @@ -136,16 +136,12 @@ export class HashrateChartComponent implements OnInit { prepareChartOptions(data) { let title: object; if (data.hashrates.length === 0) { - const lastBlock = new Date(data.timestamp * 1000); - const dd = String(lastBlock.getDate()).padStart(2, '0'); - const mm = String(lastBlock.getMonth() + 1).padStart(2, '0'); // January is 0! - const yyyy = lastBlock.getFullYear(); title = { textStyle: { color: 'grey', fontSize: 15 }, - text: `Indexing in progess - ${yyyy}-${mm}-${dd}`, + text: `Indexing in progess`, left: 'center', top: 'center' }; diff --git a/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.html b/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.html index 67cd3ff83..b8bff0020 100644 --- a/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.html +++ b/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.html @@ -1,3 +1,5 @@ + +
diff --git a/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts b/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts index d6bfd66d6..528a783d5 100644 --- a/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts +++ b/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts @@ -150,16 +150,12 @@ export class HashrateChartPoolsComponent implements OnInit { prepareChartOptions(data) { let title: object; if (data.series.length === 0) { - const lastBlock = new Date(data.timestamp * 1000); - const dd = String(lastBlock.getDate()).padStart(2, '0'); - const mm = String(lastBlock.getMonth() + 1).padStart(2, '0'); // January is 0! - const yyyy = lastBlock.getFullYear(); title = { textStyle: { color: 'grey', fontSize: 15 }, - text: `Indexing in progess - ${yyyy}-${mm}-${dd}`, + text: `Indexing in progess`, left: 'center', top: 'center', }; diff --git a/frontend/src/app/components/loading-indicator/loading-indicator.component.html b/frontend/src/app/components/loading-indicator/loading-indicator.component.html new file mode 100644 index 000000000..a3929c621 --- /dev/null +++ b/frontend/src/app/components/loading-indicator/loading-indicator.component.html @@ -0,0 +1,3 @@ +
+ Indexing blocks ({{ progress }}%) +
\ No newline at end of file diff --git a/frontend/src/app/components/loading-indicator/loading-indicator.component.scss b/frontend/src/app/components/loading-indicator/loading-indicator.component.scss new file mode 100644 index 000000000..cb49e08ab --- /dev/null +++ b/frontend/src/app/components/loading-indicator/loading-indicator.component.scss @@ -0,0 +1,14 @@ +.sticky-loading { + position: fixed; + right: 10px; + z-index: 100; + @media (width > 991px) { + bottom: 15px; + } + @media (576px <= width <= 991px) { + bottom: 60px; + } + @media (width <= 575px) { + top: 17px; + } +} \ No newline at end of file diff --git a/frontend/src/app/components/loading-indicator/loading-indicator.component.ts b/frontend/src/app/components/loading-indicator/loading-indicator.component.ts new file mode 100644 index 000000000..2dfbc81c6 --- /dev/null +++ b/frontend/src/app/components/loading-indicator/loading-indicator.component.ts @@ -0,0 +1,29 @@ +import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { StateService } from 'src/app/services/state.service'; +import { WebsocketService } from 'src/app/services/websocket.service'; + +@Component({ + selector: 'app-loading-indicator', + templateUrl: './loading-indicator.component.html', + styleUrls: ['./loading-indicator.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class LoadingIndicatorComponent implements OnInit { + @Input() name: string; + + public indexingProgress$: Observable; + + constructor( + private stateService: StateService, + private websocketService: WebsocketService + ) {} + + ngOnInit() { + this.indexingProgress$ = this.stateService.loadingIndicators$ + .pipe( + map((indicators) => indicators[this.name] ?? -1) + ); + } +} diff --git a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html index 3b32408c8..db395bf39 100644 --- a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html +++ b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html @@ -1,3 +1,5 @@ + +
diff --git a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.ts b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.ts index cfd1eafbd..352586f14 100644 --- a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.ts +++ b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.ts @@ -1,8 +1,5 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; -import { map } from 'rxjs/operators'; import { SeoService } from 'src/app/services/seo.service'; -import { StateService } from 'src/app/services/state.service'; -import { Observable } from 'rxjs'; import { WebsocketService } from 'src/app/services/websocket.service'; @Component({ @@ -12,8 +9,6 @@ import { WebsocketService } from 'src/app/services/websocket.service'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class MiningDashboardComponent implements OnInit { - private blocks = []; - constructor( private seoService: SeoService, private websocketService: WebsocketService, diff --git a/frontend/src/app/components/pool-ranking/pool-ranking.component.html b/frontend/src/app/components/pool-ranking/pool-ranking.component.html index 5d3d5dd3d..56c73a8c0 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.html +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.html @@ -1,3 +1,5 @@ + +
diff --git a/frontend/src/app/components/pool/pool.component.html b/frontend/src/app/components/pool/pool.component.html index c51360a2d..c9d12ee22 100644 --- a/frontend/src/app/components/pool/pool.component.html +++ b/frontend/src/app/components/pool/pool.component.html @@ -1,3 +1,5 @@ + +
diff --git a/frontend/src/app/components/pool/pool.component.ts b/frontend/src/app/components/pool/pool.component.ts index 9d644121a..3111d78b8 100644 --- a/frontend/src/app/components/pool/pool.component.ts +++ b/frontend/src/app/components/pool/pool.component.ts @@ -111,7 +111,7 @@ export class PoolComponent implements OnInit { color: 'grey', fontSize: 15 }, - text: `No data`, + text: `Indexing in progress`, left: 'center', top: 'center' }; @@ -164,14 +164,14 @@ export class PoolComponent implements OnInit { `; }.bind(this) }, - xAxis: { + xAxis: data.length === 0 ? undefined : { type: 'time', splitNumber: (this.isMobile()) ? 5 : 10, axisLabel: { hideOverlap: true, } }, - yAxis: [ + yAxis: data.length === 0 ? undefined : [ { min: (value) => { return value.min * 0.9; @@ -190,7 +190,7 @@ export class PoolComponent implements OnInit { } }, ], - series: [ + series: data.length === 0 ? undefined : [ { zlevel: 0, name: 'Hashrate',