Create indexing sticky notification that show indexing progress in all mining dashboard related pages
This commit is contained in:
		
							parent
							
								
									d10434af63
								
							
						
					
					
						commit
						3d29ce93d2
					
				@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -188,6 +188,24 @@ class BlocksRepository {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get blocks count for a period
 | 
			
		||||
   */
 | 
			
		||||
   public async $blockCountBetweenHeight(startHeight: number, endHeight: number): Promise<number> {
 | 
			
		||||
    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 <number>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
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
@ -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' }),
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,5 @@
 | 
			
		||||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
 | 
			
		||||
 | 
			
		||||
<div class="full-container">
 | 
			
		||||
  <div class="card-header mb-0 mb-md-4">
 | 
			
		||||
    <span i18n="mining.block-fee-rates">Block fee rates</span>
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,5 @@
 | 
			
		||||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
 | 
			
		||||
 | 
			
		||||
<div class="full-container">
 | 
			
		||||
  <div class="card-header mb-0 mb-md-4">
 | 
			
		||||
    <span i18n="mining.block-fees">Block fees</span>
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,5 @@
 | 
			
		||||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
 | 
			
		||||
 | 
			
		||||
<div class="full-container">
 | 
			
		||||
 | 
			
		||||
  <div class="card-header mb-0 mb-md-4">
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,5 @@
 | 
			
		||||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
 | 
			
		||||
 | 
			
		||||
<div class="container-xl" [class]="widget ? 'widget' : 'full-height'">
 | 
			
		||||
  <h1 *ngIf="!widget" class="float-left" i18n="latest-blocks.blocks">Blocks</h1>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,5 @@
 | 
			
		||||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
 | 
			
		||||
 | 
			
		||||
<div [class]="widget === false ? 'full-container' : ''">
 | 
			
		||||
 | 
			
		||||
  <div *ngIf="widget">
 | 
			
		||||
 | 
			
		||||
@ -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'
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,5 @@
 | 
			
		||||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
 | 
			
		||||
 | 
			
		||||
<div class="full-container">
 | 
			
		||||
 | 
			
		||||
  <div class="card-header  mb-0 mb-md-4">
 | 
			
		||||
 | 
			
		||||
@ -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',
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,3 @@
 | 
			
		||||
<div *ngIf="this.indexingProgress$ | async as progress" class="sticky-loading">
 | 
			
		||||
  <span *ngIf="progress >= 0" class="mr-auto badge badge-pill badge-warning">Indexing blocks ({{ progress }}%)</span>
 | 
			
		||||
</div>
 | 
			
		||||
@ -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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -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<number>;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    private stateService: StateService,
 | 
			
		||||
    private websocketService: WebsocketService
 | 
			
		||||
  ) {}
 | 
			
		||||
 | 
			
		||||
  ngOnInit() {
 | 
			
		||||
    this.indexingProgress$ = this.stateService.loadingIndicators$
 | 
			
		||||
      .pipe(
 | 
			
		||||
        map((indicators) => indicators[this.name] ?? -1)
 | 
			
		||||
      );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +1,5 @@
 | 
			
		||||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
 | 
			
		||||
 | 
			
		||||
<div class="container-xl dashboard-container">
 | 
			
		||||
 | 
			
		||||
  <div class="row row-cols-1 row-cols-md-2">
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,5 @@
 | 
			
		||||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
 | 
			
		||||
 | 
			
		||||
<div [class]="widget === false ? 'full-container' : ''">
 | 
			
		||||
 | 
			
		||||
  <div *ngIf="widget">
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,5 @@
 | 
			
		||||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
 | 
			
		||||
 | 
			
		||||
<div class="container-xl">
 | 
			
		||||
 | 
			
		||||
  <!-- Pool overview -->
 | 
			
		||||
 | 
			
		||||
@ -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',
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user