Merge branch 'master' into nymkappa/feature/preload-prev-block-summary
This commit is contained in:
		
						commit
						5373078a30
					
				@ -26,6 +26,7 @@
 | 
			
		||||
 | 
			
		||||
.loader-wrapper {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  background: #181b2d7f;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  right: 0;
 | 
			
		||||
  top: 0;
 | 
			
		||||
 | 
			
		||||
@ -68,6 +68,21 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy {
 | 
			
		||||
    this.start();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  destroy(): void {
 | 
			
		||||
    if (this.scene) {
 | 
			
		||||
      this.scene.destroy();
 | 
			
		||||
      this.start();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // initialize the scene without any entry transition
 | 
			
		||||
  setup(transactions: TransactionStripped[]): void {
 | 
			
		||||
    if (this.scene) {
 | 
			
		||||
      this.scene.setup(transactions);
 | 
			
		||||
      this.start();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  enter(transactions: TransactionStripped[], direction: string): void {
 | 
			
		||||
    if (this.scene) {
 | 
			
		||||
      this.scene.enter(transactions, direction);
 | 
			
		||||
 | 
			
		||||
@ -29,10 +29,6 @@ export default class BlockScene {
 | 
			
		||||
    this.init({ width, height, resolution, blockLimit, orientation, flip, vertexArray });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  destroy(): void {
 | 
			
		||||
    Object.values(this.txs).forEach(tx => tx.destroy());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  resize({ width = this.width, height = this.height }: { width?: number, height?: number}): void {
 | 
			
		||||
    this.width = width;
 | 
			
		||||
    this.height = height;
 | 
			
		||||
@ -46,6 +42,36 @@ export default class BlockScene {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Destroy the current layout and clean up graphics sprites without any exit animation
 | 
			
		||||
  destroy(): void {
 | 
			
		||||
    Object.values(this.txs).forEach(tx => tx.destroy());
 | 
			
		||||
    this.txs = {};
 | 
			
		||||
    this.layout = null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // set up the scene with an initial set of transactions, without any transition animation
 | 
			
		||||
  setup(txs: TransactionStripped[]) {
 | 
			
		||||
    // clean up any old transactions
 | 
			
		||||
    Object.values(this.txs).forEach(tx => {
 | 
			
		||||
      tx.destroy();
 | 
			
		||||
      delete this.txs[tx.txid];
 | 
			
		||||
    });
 | 
			
		||||
    this.layout = new BlockLayout({ width: this.gridWidth, height: this.gridHeight });
 | 
			
		||||
    txs.forEach(tx => {
 | 
			
		||||
      const txView = new TxView(tx, this.vertexArray);
 | 
			
		||||
      this.txs[tx.txid] = txView;
 | 
			
		||||
      this.place(txView);
 | 
			
		||||
      this.saveGridToScreenPosition(txView);
 | 
			
		||||
      this.applyTxUpdate(txView, {
 | 
			
		||||
        display: {
 | 
			
		||||
          position: txView.screenPosition,
 | 
			
		||||
          color: txView.getColor()
 | 
			
		||||
        },
 | 
			
		||||
        duration: 0
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Animate new block entering scene
 | 
			
		||||
  enter(txs: TransactionStripped[], direction) {
 | 
			
		||||
    this.replace(txs, direction);
 | 
			
		||||
 | 
			
		||||
@ -2,9 +2,9 @@ import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/co
 | 
			
		||||
import { Location } from '@angular/common';
 | 
			
		||||
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
 | 
			
		||||
import { ElectrsApiService } from '../../services/electrs-api.service';
 | 
			
		||||
import { switchMap, tap, debounceTime, catchError, map, shareReplay, startWith, pairwise } from 'rxjs/operators';
 | 
			
		||||
import { switchMap, tap, throttleTime, catchError, map, shareReplay, startWith, pairwise } from 'rxjs/operators';
 | 
			
		||||
import { Transaction, Vout } from '../../interfaces/electrs.interface';
 | 
			
		||||
import { Observable, of, Subscription } from 'rxjs';
 | 
			
		||||
import { Observable, of, Subscription, asyncScheduler } from 'rxjs';
 | 
			
		||||
import { StateService } from '../../services/state.service';
 | 
			
		||||
import { SeoService } from 'src/app/services/seo.service';
 | 
			
		||||
import { WebsocketService } from 'src/app/services/websocket.service';
 | 
			
		||||
@ -33,7 +33,6 @@ export class BlockComponent implements OnInit, OnDestroy {
 | 
			
		||||
  strippedTransactions: TransactionStripped[];
 | 
			
		||||
  overviewTransitionDirection: string;
 | 
			
		||||
  isLoadingOverview = true;
 | 
			
		||||
  isAwaitingOverview = true;
 | 
			
		||||
  error: any;
 | 
			
		||||
  blockSubsidy: number;
 | 
			
		||||
  fees: number;
 | 
			
		||||
@ -127,6 +126,7 @@ export class BlockComponent implements OnInit, OnDestroy {
 | 
			
		||||
          return of(history.state.data.block);
 | 
			
		||||
        } else {
 | 
			
		||||
          this.isLoadingBlock = true;
 | 
			
		||||
          this.isLoadingOverview = true;
 | 
			
		||||
 | 
			
		||||
          let blockInCache: BlockExtended;
 | 
			
		||||
          if (isBlockHeight) {
 | 
			
		||||
@ -181,12 +181,9 @@ export class BlockComponent implements OnInit, OnDestroy {
 | 
			
		||||
        this.transactions = null;
 | 
			
		||||
        this.transactionsError = null;
 | 
			
		||||
        this.isLoadingOverview = true;
 | 
			
		||||
        this.isAwaitingOverview = true;
 | 
			
		||||
        this.overviewError = true;
 | 
			
		||||
        if (this.blockGraph) {
 | 
			
		||||
          this.blockGraph.exit(direction);
 | 
			
		||||
        }
 | 
			
		||||
        this.overviewError = null;
 | 
			
		||||
      }),
 | 
			
		||||
      throttleTime(300, asyncScheduler, { leading: true, trailing: true }),
 | 
			
		||||
      shareReplay(1)
 | 
			
		||||
    );
 | 
			
		||||
    this.transactionSubscription = block$.pipe(
 | 
			
		||||
@ -204,11 +201,6 @@ export class BlockComponent implements OnInit, OnDestroy {
 | 
			
		||||
      }
 | 
			
		||||
      this.transactions = transactions;
 | 
			
		||||
      this.isLoadingTransactions = false;
 | 
			
		||||
 | 
			
		||||
      if (!this.isAwaitingOverview && this.blockGraph && this.strippedTransactions && this.overviewTransitionDirection) {
 | 
			
		||||
        this.isLoadingOverview = false;
 | 
			
		||||
        this.blockGraph.replace(this.strippedTransactions, this.overviewTransitionDirection, false);
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    (error) => {
 | 
			
		||||
      this.error = error;
 | 
			
		||||
@ -236,18 +228,19 @@ export class BlockComponent implements OnInit, OnDestroy {
 | 
			
		||||
      ),
 | 
			
		||||
    )
 | 
			
		||||
    .subscribe(({transactions, direction}: {transactions: TransactionStripped[], direction: string}) => {
 | 
			
		||||
      this.isAwaitingOverview = false;
 | 
			
		||||
      this.strippedTransactions = transactions;
 | 
			
		||||
      this.overviewTransitionDirection = direction;
 | 
			
		||||
      if (!this.isLoadingTransactions && this.blockGraph) {
 | 
			
		||||
      this.isLoadingOverview = false;
 | 
			
		||||
        this.blockGraph.replace(this.strippedTransactions, this.overviewTransitionDirection, false);
 | 
			
		||||
      if (this.blockGraph) {
 | 
			
		||||
        this.blockGraph.destroy();
 | 
			
		||||
        this.blockGraph.setup(this.strippedTransactions);
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    (error) => {
 | 
			
		||||
      this.error = error;
 | 
			
		||||
      this.isLoadingOverview = false;
 | 
			
		||||
      this.isAwaitingOverview = false;
 | 
			
		||||
      if (this.blockGraph) {
 | 
			
		||||
        this.blockGraph.destroy();
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    this.networkChangedSubscription = this.stateService.networkChanged$
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
<div [formGroup]="languageForm" class="text-small text-center mt-4">
 | 
			
		||||
<div [formGroup]="languageForm" class="text-small text-center">
 | 
			
		||||
    <select formControlName="language" class="custom-select custom-select-sm form-control-secondary form-control mx-auto" style="width: 130px;" (change)="changeLanguage()">
 | 
			
		||||
        <option *ngFor="let lang of languages" [value]="lang.code">{{ lang.name }}</option>
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
@ -1,34 +1,6 @@
 | 
			
		||||
 | 
			
		||||
<div class="container-xl dashboard-container">
 | 
			
		||||
  <div class="row row-cols-1 row-cols-md-2" *ngIf="{ value: (mempoolInfoData$ | async) } as mempoolInfoData">
 | 
			
		||||
    <ng-template [ngIf]="collapseLevel === 'three'" [ngIfElse]="expanded">
 | 
			
		||||
      <div class="col card-wrapper" *ngIf="(network$ | async) !== 'liquid' && (network$ | async) !== 'liquidtestnet'">
 | 
			
		||||
        <div class="main-title" i18n="fees-box.transaction-fees">Transaction Fees</div>
 | 
			
		||||
        <div class="card">
 | 
			
		||||
          <div class="card-body less-padding">
 | 
			
		||||
            <app-fees-box class="d-block"></app-fees-box>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="col" *ngIf="(network$ | async) !== 'liquid' && (network$ | async) !== 'liquidtestnet'">
 | 
			
		||||
        <app-difficulty></app-difficulty>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="col">
 | 
			
		||||
        <div class="card">
 | 
			
		||||
          <div class="card-body">
 | 
			
		||||
            <ng-container *ngTemplateOutlet="stateService.network === 'liquid' ? lbtcPegs : mempoolTable; context: { $implicit: mempoolInfoData }"></ng-container>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="col">
 | 
			
		||||
        <div class="card">
 | 
			
		||||
          <div class="card-body">
 | 
			
		||||
            <ng-container *ngTemplateOutlet="stateService.network === 'liquid' ? mempoolTable : txPerSecond; context: { $implicit: mempoolInfoData }"></ng-container>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </ng-template>
 | 
			
		||||
    <ng-template #expanded>
 | 
			
		||||
    <ng-container *ngIf="(network$ | async) !== 'liquid' && (network$ | async) !== 'liquidtestnet'">
 | 
			
		||||
      <div class="col card-wrapper">
 | 
			
		||||
        <div class="main-title" i18n="fees-box.transaction-fees">Transaction Fees</div>
 | 
			
		||||
@ -102,7 +74,6 @@
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
      <ng-template [ngIf]="collapseLevel === 'one'">
 | 
			
		||||
    <div class="col" style="max-height: 410px">
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <div class="card-body">
 | 
			
		||||
@ -163,20 +134,12 @@
 | 
			
		||||
              </tr>
 | 
			
		||||
            </tbody>
 | 
			
		||||
          </table>
 | 
			
		||||
          <div class=""> </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    </ng-template>
 | 
			
		||||
    </ng-template>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <button type="button" class="btn btn-secondary btn-sm d-block mx-auto" (click)="toggleCollapsed()">
 | 
			
		||||
    <div [ngSwitch]="collapseLevel">
 | 
			
		||||
      <fa-icon *ngSwitchCase="'three'" [icon]="['fas', 'angle-down']" [fixedWidth]="true" i18n-title="dashboard.expand" title="Expand"></fa-icon>
 | 
			
		||||
      <fa-icon *ngSwitchDefault [icon]="['fas', 'angle-up']" [fixedWidth]="true" i18n-title="dashboard.collapse" title="Collapse"></fa-icon>
 | 
			
		||||
    </div>
 | 
			
		||||
  </button>
 | 
			
		||||
 | 
			
		||||
  <app-language-selector></app-language-selector>
 | 
			
		||||
 | 
			
		||||
  <div class="terms-of-service">
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,6 @@ interface MempoolStatsData {
 | 
			
		||||
  changeDetection: ChangeDetectionStrategy.OnPush
 | 
			
		||||
})
 | 
			
		||||
export class DashboardComponent implements OnInit {
 | 
			
		||||
  collapseLevel: string;
 | 
			
		||||
  featuredAssets$: Observable<any>;
 | 
			
		||||
  network$: Observable<string>;
 | 
			
		||||
  mempoolBlocksData$: Observable<MempoolBlocksData>;
 | 
			
		||||
@ -63,7 +62,6 @@ export class DashboardComponent implements OnInit {
 | 
			
		||||
    this.seoService.resetTitle();
 | 
			
		||||
    this.websocketService.want(['blocks', 'stats', 'mempool-blocks', 'live-2h-chart']);
 | 
			
		||||
    this.network$ = merge(of(''), this.stateService.networkChanged$);
 | 
			
		||||
    this.collapseLevel = this.storageService.getValue('dashboard-collapsed') || 'one';
 | 
			
		||||
    this.mempoolLoadingStatus$ = this.stateService.loadingIndicators$
 | 
			
		||||
      .pipe(
 | 
			
		||||
        map((indicators) => indicators.mempool !== undefined ? indicators.mempool : 100)
 | 
			
		||||
@ -230,15 +228,4 @@ export class DashboardComponent implements OnInit {
 | 
			
		||||
  trackByBlock(index: number, block: BlockExtended) {
 | 
			
		||||
    return block.height;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  toggleCollapsed() {
 | 
			
		||||
    if (this.collapseLevel === 'one') {
 | 
			
		||||
      this.collapseLevel = 'two';
 | 
			
		||||
    } else if (this.collapseLevel === 'two') {
 | 
			
		||||
      this.collapseLevel = 'three';
 | 
			
		||||
    } else {
 | 
			
		||||
      this.collapseLevel = 'one';
 | 
			
		||||
    }
 | 
			
		||||
    this.storageService.setValue('dashboard-collapsed', this.collapseLevel);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user