Footer and header design updates.
This commit is contained in:
		
							parent
							
								
									c8c1be594b
								
							
						
					
					
						commit
						d690511a08
					
				@ -60,6 +60,8 @@ class Blocks {
 | 
				
			|||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        console.log(`${found} of ${txIds.length} found in mempool. ${notFound} not found.`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        transactions.sort((a, b) => b.feePerVsize - a.feePerVsize);
 | 
					        transactions.sort((a, b) => b.feePerVsize - a.feePerVsize);
 | 
				
			||||||
        block.medianFee = this.median(transactions.map((tx) => tx.feePerVsize));
 | 
					        block.medianFee = this.median(transactions.map((tx) => tx.feePerVsize));
 | 
				
			||||||
        block.feeRange = this.getFeesInRange(transactions, 8);
 | 
					        block.feeRange = this.getFeesInRange(transactions, 8);
 | 
				
			||||||
 | 
				
			|||||||
@ -104,7 +104,7 @@ class Mempool {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Replace mempool to clear already confirmed transactions
 | 
					      // Replace mempool to clear already confirmed transactions
 | 
				
			||||||
      const newMempool: any = {};
 | 
					      const newMempool = {};
 | 
				
			||||||
      transactions.forEach((tx) => {
 | 
					      transactions.forEach((tx) => {
 | 
				
			||||||
        if (this.mempoolCache[tx]) {
 | 
					        if (this.mempoolCache[tx]) {
 | 
				
			||||||
          newMempool[tx] = this.mempoolCache[tx];
 | 
					          newMempool[tx] = this.mempoolCache[tx];
 | 
				
			||||||
@ -113,6 +113,9 @@ class Mempool {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      console.log(`New mempool size: ${Object.keys(newMempool).length} ` +
 | 
				
			||||||
 | 
					       ` Change: ${transactions.length - Object.keys(newMempool).length}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.mempoolCache = newMempool;
 | 
					      this.mempoolCache = newMempool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (hasChange && this.mempoolChangedCallback) {
 | 
					      if (hasChange && this.mempoolChangedCallback) {
 | 
				
			||||||
 | 
				
			|||||||
@ -19,16 +19,12 @@ const routes: Routes = [
 | 
				
			|||||||
        path: '',
 | 
					        path: '',
 | 
				
			||||||
        component: StartComponent,
 | 
					        component: StartComponent,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        path: 'explorer',
 | 
					 | 
				
			||||||
        component: ExplorerComponent,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        path: 'graphs',
 | 
					        path: 'graphs',
 | 
				
			||||||
        component: StatisticsComponent,
 | 
					        component: StatisticsComponent,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        path: 'about',
 | 
					        path: 'team',
 | 
				
			||||||
        component: AboutComponent,
 | 
					        component: AboutComponent,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,14 +1,15 @@
 | 
				
			|||||||
<div class="container">
 | 
					<div class="container">
 | 
				
			||||||
  <div class="text-center">
 | 
					  <div class="text-center">
 | 
				
			||||||
 | 
					    <br />
 | 
				
			||||||
    <img src="./assets/mempool-tube.png" width="63" height="63" />
 | 
					    <img src="./assets/mempool-tube.png" width="63" height="63" />
 | 
				
			||||||
    <br /><br />
 | 
					    <br /><br />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h1>About</h1>
 | 
					    <h1>Team</h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>Mempool.Space is a realtime Bitcoin blockchain explorer and mempool visualizer.</p>
 | 
					    <p>Mempool.Space is a realtime Bitcoin blockchain explorer and mempool visualizer.</p>
 | 
				
			||||||
    <p>Created by <a href="https://twitter.com/softbtc">@softbtc</a>
 | 
					    <p>Lead Developer <a href="https://twitter.com/softbtc">@softbtc</a>
 | 
				
			||||||
    <br />Hosted by <a href="https://twitter.com/wiz">@wiz</a>
 | 
					    <br />Backend Operator <a href="https://twitter.com/wiz">@wiz</a>
 | 
				
			||||||
    <br />Designed by <a href="https://instagram.com/markjborg">@markjborg</a>
 | 
					    <br />Frontend Designer <a href="https://instagram.com/markjborg">@markjborg</a>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <h2>HTTP API</h2>
 | 
					  <h2>HTTP API</h2>
 | 
				
			||||||
 | 
				
			|||||||
@ -36,6 +36,7 @@ export class AddressComponent implements OnInit, OnDestroy {
 | 
				
			|||||||
        this.isLoadingAddress = true;
 | 
					        this.isLoadingAddress = true;
 | 
				
			||||||
        this.isLoadingTransactions = true;
 | 
					        this.isLoadingTransactions = true;
 | 
				
			||||||
        this.transactions = null;
 | 
					        this.transactions = null;
 | 
				
			||||||
 | 
					        document.body.scrollTo(0, 0);
 | 
				
			||||||
        this.addressString = params.get('id') || '';
 | 
					        this.addressString = params.get('id') || '';
 | 
				
			||||||
        return this.electrsApiService.getAddress$(this.addressString);
 | 
					        return this.electrsApiService.getAddress$(this.addressString);
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
@ -44,7 +45,6 @@ export class AddressComponent implements OnInit, OnDestroy {
 | 
				
			|||||||
      this.address = address;
 | 
					      this.address = address;
 | 
				
			||||||
      this.websocketService.startTrackAddress(address.address);
 | 
					      this.websocketService.startTrackAddress(address.address);
 | 
				
			||||||
      this.isLoadingAddress = false;
 | 
					      this.isLoadingAddress = false;
 | 
				
			||||||
      document.body.scrollTo({ top: 0, behavior: 'smooth' });
 | 
					 | 
				
			||||||
      this.getAddressTransactions(address.address);
 | 
					      this.getAddressTransactions(address.address);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    (error) => {
 | 
					    (error) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -42,6 +42,7 @@ export class BlockComponent implements OnInit {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.blockHash = blockHash;
 | 
					        this.blockHash = blockHash;
 | 
				
			||||||
 | 
					        document.body.scrollTo(0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (history.state.data && history.state.data.block) {
 | 
					        if (history.state.data && history.state.data.block) {
 | 
				
			||||||
          this.blockHeight = history.state.data.block.height;
 | 
					          this.blockHeight = history.state.data.block.height;
 | 
				
			||||||
@ -57,7 +58,6 @@ export class BlockComponent implements OnInit {
 | 
				
			|||||||
      this.blockHeight = block.height;
 | 
					      this.blockHeight = block.height;
 | 
				
			||||||
      this.isLoadingBlock = false;
 | 
					      this.isLoadingBlock = false;
 | 
				
			||||||
      this.getBlockTransactions(block.id);
 | 
					      this.getBlockTransactions(block.id);
 | 
				
			||||||
      document.body.scrollTo({ top: 0, behavior: 'smooth' });
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    (error) => {
 | 
					    (error) => {
 | 
				
			||||||
      this.error = error;
 | 
					      this.error = error;
 | 
				
			||||||
 | 
				
			|||||||
@ -18,5 +18,5 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <div [hidden]="!arrowVisible" id="arrow-up" [ngStyle]="{'left': arrowLeftPx + 'px' }"></div>
 | 
					  <div [hidden]="!arrowVisible" id="arrow-up" [ngStyle]="{'right': rightPosition + 'px' }"></div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
				
			|||||||
@ -104,7 +104,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#arrow-up {
 | 
					#arrow-up {
 | 
				
			||||||
  position: relative;
 | 
					  position: relative;
 | 
				
			||||||
  left: 30px;
 | 
					  right: 30px;
 | 
				
			||||||
  top: 140px;
 | 
					  top: 140px;
 | 
				
			||||||
  transition: 1s;
 | 
					  transition: 1s;
 | 
				
			||||||
  width: 0; 
 | 
					  width: 0; 
 | 
				
			||||||
 | 
				
			|||||||
@ -10,15 +10,18 @@ import { StateService } from 'src/app/services/state.service';
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
					export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			||||||
  @Input() markHeight = 0;
 | 
					  @Input() markHeight = 0;
 | 
				
			||||||
 | 
					  @Input() txFeePerVSize: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  blocks: Block[] = [];
 | 
					  blocks: Block[] = [];
 | 
				
			||||||
  blocksSubscription: Subscription;
 | 
					  blocksSubscription: Subscription;
 | 
				
			||||||
  interval: any;
 | 
					  interval: any;
 | 
				
			||||||
  trigger = 0;
 | 
					  trigger = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  blockWidth = 125;
 | 
				
			||||||
  arrowVisible = false;
 | 
					  blockPadding = 30;
 | 
				
			||||||
  arrowLeftPx = 30;
 | 
					  arrowLeftPx = 30;
 | 
				
			||||||
 | 
					  rightPosition = 0;
 | 
				
			||||||
 | 
					  arrowVisible = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private stateService: StateService,
 | 
					    private stateService: StateService,
 | 
				
			||||||
@ -53,10 +56,38 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
      this.arrowVisible = false;
 | 
					      this.arrowVisible = false;
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const blockindex = this.blocks.findIndex((b) => b.height === this.markHeight);
 | 
					    const block = this.blocks.find((b) => b.height === this.markHeight);
 | 
				
			||||||
    if (blockindex !== -1) {
 | 
					    if (!block) {
 | 
				
			||||||
      this.arrowVisible = true;
 | 
					      return;
 | 
				
			||||||
      this.arrowLeftPx = blockindex * 155 + 30;
 | 
					    }
 | 
				
			||||||
 | 
					    const blockindex = this.blocks.indexOf(block);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.arrowVisible = true;
 | 
				
			||||||
 | 
					    this.rightPosition = blockindex * -(this.blockWidth + this.blockPadding) - 30;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!this.txFeePerVSize) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (let i = 0; i < block.feeRange.length - 1; i++) {
 | 
				
			||||||
 | 
					      if (this.txFeePerVSize < block.feeRange[i + 1] && this.txFeePerVSize >= block.feeRange[i]) {
 | 
				
			||||||
 | 
					        const feeRangeIndex = block.feeRange.findIndex((val, index) => this.txFeePerVSize < block.feeRange[index + 1]);
 | 
				
			||||||
 | 
					        const feeRangeChunkSize = 1 / (block.feeRange.length - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const txFee = this.txFeePerVSize - block.feeRange[i];
 | 
				
			||||||
 | 
					        const max = block.feeRange[i + 1] - block.feeRange[i];
 | 
				
			||||||
 | 
					        const blockLocation = txFee / max;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const chunkPositionOffset = blockLocation * feeRangeChunkSize;
 | 
				
			||||||
 | 
					        const feePosition = feeRangeChunkSize * feeRangeIndex + chunkPositionOffset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const blockedFilledPercentage = (block.weight > 4000000 ? 4000000 : block.weight) / 4000000;
 | 
				
			||||||
 | 
					        const arrowRightPosition = blockindex * (-this.blockWidth + this.blockPadding)
 | 
				
			||||||
 | 
					          + ((1 - feePosition) * blockedFilledPercentage * this.blockWidth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.rightPosition = arrowRightPosition - 93;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
<div class="text-center" class="blockchain-wrapper">
 | 
					<div class="text-center" class="blockchain-wrapper">
 | 
				
			||||||
  <div class="position-container" [ngStyle]="{'top': position === 'top' ? '75px' : 'calc(50% - 60px)'}">
 | 
					  <div class="position-container">
 | 
				
			||||||
    <app-mempool-blocks [txFeePerVSize]="txFeePerVSize"></app-mempool-blocks>
 | 
					    <app-mempool-blocks [txFeePerVSize]="markHeight ? 0 : txFeePerVSize"></app-mempool-blocks>
 | 
				
			||||||
    <app-blockchain-blocks [markHeight]="markHeight"></app-blockchain-blocks>
 | 
					    <app-blockchain-blocks [markHeight]="markHeight" [txFeePerVSize]="txFeePerVSize"></app-blockchain-blocks>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div id="divider" *ngIf="!isLoading; else loadingTmpl"></div>
 | 
					    <div id="divider" *ngIf="!isLoading; else loadingTmpl"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -23,6 +23,7 @@
 | 
				
			|||||||
.position-container {
 | 
					.position-container {
 | 
				
			||||||
  position: absolute;
 | 
					  position: absolute;
 | 
				
			||||||
  left: 50%;
 | 
					  left: 50%;
 | 
				
			||||||
 | 
					  top: 75px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@media (max-width: 767.98px) {
 | 
					@media (max-width: 767.98px) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,20 +1,14 @@
 | 
				
			|||||||
<div class="container">
 | 
					<ul class="nav nav-tabs mb-2">
 | 
				
			||||||
 | 
					  <li class="nav-item">
 | 
				
			||||||
  <br>
 | 
					    <a class="nav-link" [class.active]="view === 'blocks'" routerLink="/explorer" (click)="view = 'blocks'">Blocks</a>
 | 
				
			||||||
 | 
					  </li>
 | 
				
			||||||
  <ul class="nav nav-tabs mb-2">
 | 
					  <li class="nav-item">
 | 
				
			||||||
    <li class="nav-item">
 | 
					    <a class="nav-link" [class.active]="view === 'transactions'" routerLink="/explorer" fragment="transactions" (click)="view = 'transactions'">Transactions</a>
 | 
				
			||||||
      <a class="nav-link" [class.active]="view === 'blocks'" routerLink="/explorer" (click)="view = 'blocks'">Blocks</a>
 | 
					  </li>
 | 
				
			||||||
    </li>
 | 
					</ul>
 | 
				
			||||||
    <li class="nav-item">
 | 
					 | 
				
			||||||
      <a class="nav-link" [class.active]="view === 'transactions'" routerLink="/explorer" fragment="transactions" (click)="view = 'transactions'">Transactions</a>
 | 
					 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
  </ul>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <app-latest-blocks *ngIf="view === 'blocks'; else latestTransactions"></app-latest-blocks>
 | 
					 | 
				
			||||||
  <ng-template #latestTransactions>
 | 
					 | 
				
			||||||
    <app-latest-transactions></app-latest-transactions>
 | 
					 | 
				
			||||||
  </ng-template>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<app-latest-blocks *ngIf="view === 'blocks'; else latestTransactions"></app-latest-blocks>
 | 
				
			||||||
 | 
					<ng-template #latestTransactions>
 | 
				
			||||||
 | 
					  <app-latest-transactions></app-latest-transactions>
 | 
				
			||||||
 | 
					</ng-template>
 | 
				
			||||||
<br>
 | 
					<br>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,10 @@
 | 
				
			|||||||
import { Component, OnInit } from '@angular/core';
 | 
					import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
 | 
				
			||||||
import { ActivatedRoute } from '@angular/router';
 | 
					import { ActivatedRoute } from '@angular/router';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  selector: 'app-explorer',
 | 
					  selector: 'app-explorer',
 | 
				
			||||||
  templateUrl: './explorer.component.html',
 | 
					  templateUrl: './explorer.component.html',
 | 
				
			||||||
  styleUrls: ['./explorer.component.scss']
 | 
					  styleUrls: ['./explorer.component.scss'],
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class ExplorerComponent implements OnInit {
 | 
					export class ExplorerComponent implements OnInit {
 | 
				
			||||||
  view: 'blocks' | 'transactions' = 'blocks';
 | 
					  view: 'blocks' | 'transactions' = 'blocks';
 | 
				
			||||||
 | 
				
			|||||||
@ -1,17 +1,18 @@
 | 
				
			|||||||
<footer class="footer">
 | 
					<footer class="footer">
 | 
				
			||||||
  <div class="container">
 | 
					  <div class="container">
 | 
				
			||||||
    <div class="my-2 my-md-0 mr-md-3">
 | 
					    <div class="row" *ngIf="memPoolInfo">
 | 
				
			||||||
      <div *ngIf="memPoolInfo" class="info-block">
 | 
					      <div class="col">
 | 
				
			||||||
        <span class="unconfirmedTx">Unconfirmed transactions:</span> <b>{{ memPoolInfo?.memPoolInfo?.size | number }}</b>
 | 
					 | 
				
			||||||
        <br />
 | 
					 | 
				
			||||||
        <span class="mempoolSize">Mempool size:</span> <b>{{ mempoolSize | bytes }} ({{ mempoolBlocks }} block<span [hidden]="mempoolBlocks <= 1">s</span>)</b>
 | 
					 | 
				
			||||||
        <br />
 | 
					 | 
				
			||||||
        <span class="txPerSecond">Tx weight per second:</span> 
 | 
					        <span class="txPerSecond">Tx weight per second:</span> 
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        <div class="progress">
 | 
					        <div class="progress">
 | 
				
			||||||
          <div class="progress-bar {{ progressClass }}" role="progressbar" [ngStyle]="{'width': progressWidth}">{{ memPoolInfo?.vBytesPerSecond | ceil | number }} vBytes/s</div>
 | 
					          <div class="progress-bar {{ progressClass }}" role="progressbar" [ngStyle]="{'width': progressWidth}">{{ memPoolInfo?.vBytesPerSecond | ceil | number }} vBytes/s</div>
 | 
				
			||||||
        </div>
 | 
					        </div>      
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="col">
 | 
				
			||||||
 | 
					        <span class="unconfirmedTx">Unconfirmed transactions:</span> <b>{{ memPoolInfo?.memPoolInfo?.size | number }}</b>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="col">
 | 
				
			||||||
 | 
					        <span class="mempoolSize">Mempool size:</span> <b>{{ mempoolSize | bytes }} ({{ mempoolBlocks }} block<span [hidden]="mempoolBlocks <= 1">s</span>)</b>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -2,12 +2,12 @@
 | 
				
			|||||||
  position: fixed;
 | 
					  position: fixed;
 | 
				
			||||||
  bottom: 0;
 | 
					  bottom: 0;
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  height: 120px;
 | 
					  height: 60px;
 | 
				
			||||||
  background-color: #1d1f31;
 | 
					  background-color: #1d1f31;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.footer > .container {
 | 
					.footer > .container {
 | 
				
			||||||
  margin-top: 25px;
 | 
					  margin-top: 17px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.txPerSecond {
 | 
					.txPerSecond {
 | 
				
			||||||
 | 
				
			|||||||
@ -11,9 +11,6 @@
 | 
				
			|||||||
      <li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
 | 
					      <li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
 | 
				
			||||||
        <a class="nav-link" routerLink="/" (click)="collapse()">Blockchain</a>
 | 
					        <a class="nav-link" routerLink="/" (click)="collapse()">Blockchain</a>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
      <li class="nav-item" routerLinkActive="active">
 | 
					 | 
				
			||||||
        <a class="nav-link" routerLink="/explorer" (click)="collapse()">Explorer</a>
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li class="nav-item" routerLinkActive="active">
 | 
					      <li class="nav-item" routerLinkActive="active">
 | 
				
			||||||
        <a class="nav-link" routerLink="/graphs" (click)="collapse()">Graphs</a>
 | 
					        <a class="nav-link" routerLink="/graphs" (click)="collapse()">Graphs</a>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
@ -21,7 +18,7 @@
 | 
				
			|||||||
        <a class="nav-link" routerLink="/tv" (click)="collapse()">TV view  <img src="./assets/expand.png" width="15"/></a>
 | 
					        <a class="nav-link" routerLink="/tv" (click)="collapse()">TV view  <img src="./assets/expand.png" width="15"/></a>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
      <li class="nav-item" routerLinkActive="active">
 | 
					      <li class="nav-item" routerLinkActive="active">
 | 
				
			||||||
        <a class="nav-link" routerLink="/about" (click)="collapse()">About</a>
 | 
					        <a class="nav-link" routerLink="/team" (click)="collapse()">Team</a>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
    <app-search-form location="top"></app-search-form>
 | 
					    <app-search-form location="top"></app-search-form>
 | 
				
			||||||
@ -31,4 +28,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<br />
 | 
					<br />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<router-outlet></router-outlet>
 | 
					<router-outlet></router-outlet>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<br><br>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<app-footer></app-footer>
 | 
				
			||||||
@ -14,13 +14,10 @@ li.nav-item {
 | 
				
			|||||||
  .navbar {
 | 
					  .navbar {
 | 
				
			||||||
    padding: 0rem 1rem;
 | 
					    padding: 0rem 1rem;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  li.nav-item {
 | 
					 | 
				
			||||||
    padding: 20px;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.logo {
 | 
					.logo {
 | 
				
			||||||
  margin-left: 40px;
 | 
					  margin-left: 30px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
li.nav-item a {
 | 
					li.nav-item a {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,20 +1,22 @@
 | 
				
			|||||||
<div class="mempool-blocks-container">
 | 
					<div class="mempool-blocks-container">
 | 
				
			||||||
  <div *ngFor="let projectedBlock of mempoolBlocks; let i = index; trackBy: trackByFn">
 | 
					  <div class="flashing">
 | 
				
			||||||
    <div class="bitcoin-block text-center mempool-block" id="mempool-block-{{ i }}" [ngStyle]="getStyleForMempoolBlockAtIndex(i)">
 | 
					    <div *ngFor="let projectedBlock of mempoolBlocks; let i = index; trackBy: trackByFn">
 | 
				
			||||||
      <div class="block-body" *ngIf="mempoolBlocks?.length">
 | 
					      <div class="bitcoin-block text-center mempool-block" id="mempool-block-{{ i }}" [ngStyle]="getStyleForMempoolBlockAtIndex(i)">
 | 
				
			||||||
        <div class="fees">
 | 
					        <div class="block-body" *ngIf="mempoolBlocks?.length">
 | 
				
			||||||
          ~{{ projectedBlock.medianFee | ceil }} sat/vB
 | 
					          <div class="fees">
 | 
				
			||||||
          <br/>
 | 
					            ~{{ projectedBlock.medianFee | ceil }} sat/vB
 | 
				
			||||||
          <span class="yellow-color">{{ projectedBlock.feeRange[0] | ceil }} - {{ projectedBlock.feeRange[projectedBlock.feeRange.length - 1] | ceil }} sat/vB</span>
 | 
					            <br/>
 | 
				
			||||||
 | 
					            <span class="yellow-color">{{ projectedBlock.feeRange[0] | ceil }} - {{ projectedBlock.feeRange[projectedBlock.feeRange.length - 1] | ceil }} sat/vB</span>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div class="block-size">{{ projectedBlock.blockSize | bytes: 2 }}</div>
 | 
				
			||||||
 | 
					          <div class="transaction-count">{{ projectedBlock.nTx }} transactions</div>
 | 
				
			||||||
 | 
					          <div class="time-difference" *ngIf="i !== 3">In ~{{ 10 * i + 10 }} minutes</div>
 | 
				
			||||||
 | 
					          <ng-template [ngIf]="i === 3 && mempoolBlocks?.length >= 4 && (projectedBlock.blockVSize / 1000000 | ceil) > 1">
 | 
				
			||||||
 | 
					            <div class="time-difference">+{{ projectedBlock.blockVSize / 1000000 | ceil }} blocks</div>
 | 
				
			||||||
 | 
					          </ng-template>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="block-size">{{ projectedBlock.blockSize | bytes: 2 }}</div>
 | 
					        <span class="animated-border"></span>
 | 
				
			||||||
        <div class="transaction-count">{{ projectedBlock.nTx }} transactions</div>
 | 
					 | 
				
			||||||
        <div class="time-difference" *ngIf="i !== 3">In ~{{ 10 * i + 10 }} minutes</div>
 | 
					 | 
				
			||||||
        <ng-template [ngIf]="i === 3 && mempoolBlocks?.length >= 4 && (projectedBlock.blockVSize / 1000000 | ceil) > 1">
 | 
					 | 
				
			||||||
          <div class="time-difference">+{{ projectedBlock.blockVSize / 1000000 | ceil }} blocks</div>
 | 
					 | 
				
			||||||
        </ng-template>
 | 
					 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <span class="animated-border"></span>
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <div *ngIf="arrowVisible" id="arrow-up" [ngStyle]="{'right': rightPosition + 75 + 'px' }"></div>
 | 
					  <div *ngIf="arrowVisible" id="arrow-up" [ngStyle]="{'right': rightPosition + 75 + 'px' }"></div>
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,9 @@
 | 
				
			|||||||
  top: 0px;
 | 
					  top: 0px;
 | 
				
			||||||
  right: 0px;
 | 
					  right: 0px;
 | 
				
			||||||
  left: 0px;
 | 
					  left: 0px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.flashing {
 | 
				
			||||||
  animation: opacityPulse 2s ease-out;
 | 
					  animation: opacityPulse 2s ease-out;
 | 
				
			||||||
  animation-iteration-count: infinite; 
 | 
					  animation-iteration-count: infinite; 
 | 
				
			||||||
  opacity: 1;
 | 
					  opacity: 1;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,4 @@
 | 
				
			|||||||
<app-blockchain></app-blockchain>
 | 
					<div class="container">
 | 
				
			||||||
 | 
					  <app-blockchain></app-blockchain>
 | 
				
			||||||
<app-footer></app-footer>
 | 
					  <app-explorer></app-explorer>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
<div class="container">
 | 
					<div class="container">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <app-blockchain position="top" [txFeePerVSize]="tx?.status?.block_height ? 0 : tx?.fee / (tx?.weight / 4)" [markHeight]="tx?.status?.block_height"></app-blockchain>
 | 
					  <app-blockchain position="top" [txFeePerVSize]="tx?.fee / (tx?.weight / 4)" [markHeight]="tx?.status?.block_height"></app-blockchain>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <div class="title-block">
 | 
					  <div class="title-block">
 | 
				
			||||||
    <h1 style="float: left;">Transaction</h1>
 | 
					    <h1 style="float: left;">Transaction</h1>
 | 
				
			||||||
 | 
				
			|||||||
@ -38,6 +38,7 @@ export class TransactionComponent implements OnInit, OnDestroy {
 | 
				
			|||||||
        this.txId = params.get('id') || '';
 | 
					        this.txId = params.get('id') || '';
 | 
				
			||||||
        this.error = undefined;
 | 
					        this.error = undefined;
 | 
				
			||||||
        this.isLoadingTx = true;
 | 
					        this.isLoadingTx = true;
 | 
				
			||||||
 | 
					        document.body.scrollTo(0, 0);
 | 
				
			||||||
        if (history.state.data) {
 | 
					        if (history.state.data) {
 | 
				
			||||||
          return of(history.state.data);
 | 
					          return of(history.state.data);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@ -48,7 +49,6 @@ export class TransactionComponent implements OnInit, OnDestroy {
 | 
				
			|||||||
    .subscribe((tx: Transaction) => {
 | 
					    .subscribe((tx: Transaction) => {
 | 
				
			||||||
      this.tx = tx;
 | 
					      this.tx = tx;
 | 
				
			||||||
      this.isLoadingTx = false;
 | 
					      this.isLoadingTx = false;
 | 
				
			||||||
      document.body.scrollTo({ top: 0, behavior: 'smooth' });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (!tx.status.confirmed) {
 | 
					      if (!tx.status.confirmed) {
 | 
				
			||||||
        this.websocketService.startTrackTransaction(tx.txid);
 | 
					        this.websocketService.startTrackTransaction(tx.txid);
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@ import { HttpClient } from '@angular/common/http';
 | 
				
			|||||||
import { Observable } from 'rxjs';
 | 
					import { Observable } from 'rxjs';
 | 
				
			||||||
import { Block, Transaction, Address, Outspend, Recent } from '../interfaces/electrs.interface';
 | 
					import { Block, Transaction, Address, Outspend, Recent } from '../interfaces/electrs.interface';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const API_BASE_URL = 'https://www.blockstream.info/api';
 | 
					const API_BASE_URL = 'https://www.blockstream.info/testnet/api';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Injectable({
 | 
					@Injectable({
 | 
				
			||||||
  providedIn: 'root'
 | 
					  providedIn: 'root'
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user