Merge pull request #923 from mempool/simon/taproot-activation-countdown

Adding taproot countdown
This commit is contained in:
wiz 2021-11-13 15:19:42 +09:00 committed by GitHub
commit 475f9344a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 42 additions and 46 deletions

View File

@ -132,9 +132,11 @@ export const languages: Language[] = [
export const specialBlocks = { export const specialBlocks = {
'709632': { '709632': {
labelEvent: '🌱 Taproot activated!', labelEvent: 'Taproot 🌱 activation',
labelEventCompleted: 'Taproot 🌱 has been activated!',
}, },
'840000': { '840000': {
labelEvent: '🥳 Halving', labelEvent: 'Halving 🥳',
labelEventCompleted: 'Block Subsidy has halved to 3.125 BTC per block',
} }
}; };

View File

@ -25,7 +25,7 @@
<div [hidden]="!arrowVisible" id="arrow-up" [style.transition]="transition" [ngStyle]="{'left': arrowLeftPx + 'px' }"></div> <div [hidden]="!arrowVisible" id="arrow-up" [style.transition]="transition" [ngStyle]="{'left': arrowLeftPx + 'px' }"></div>
</div> </div>
<ng-template #loadingBlocksTemplate > <ng-template #loadingBlocksTemplate>
<div class="blocks-container"> <div class="blocks-container">
<div class="flashing"> <div class="flashing">
<div *ngFor="let block of emptyBlocks; let i = index; trackBy: trackByBlocksFn" > <div *ngFor="let block of emptyBlocks; let i = index; trackBy: trackByBlocksFn" >

View File

@ -2,7 +2,7 @@
<div class="mempool-blocks-container" *ngIf="(timeAvg$ | async) as timeAvg;"> <div class="mempool-blocks-container" *ngIf="(timeAvg$ | async) as timeAvg;">
<div class="flashing"> <div class="flashing">
<ng-template ngFor let-projectedBlock [ngForOf]="mempoolBlocks$ | async" let-i="index" [ngForTrackBy]="trackByFn"> <ng-template ngFor let-projectedBlock [ngForOf]="mempoolBlocks$ | async" let-i="index" [ngForTrackBy]="trackByFn">
<div class="bitcoin-block text-center mempool-block" id="mempool-block-{{ i }}" [ngStyle]="mempoolBlockStyles[i]" [class.blink-bg]="projectedBlock.blink"> <div class="bitcoin-block text-center mempool-block" id="mempool-block-{{ i }}" [ngStyle]="mempoolBlockStyles[i]" [class.blink-bg]="projectedBlock.blink">
<a [routerLink]="['/mempool-block/' | relativeUrl, i]" class="blockLink">&nbsp;</a> <a [routerLink]="['/mempool-block/' | relativeUrl, i]" class="blockLink">&nbsp;</a>
<div class="block-body"> <div class="block-body">
<div class="fees"> <div class="fees">

View File

@ -3,10 +3,9 @@ import { Subscription, Observable, fromEvent, merge, of, combineLatest, timer }
import { MempoolBlock } from 'src/app/interfaces/websocket.interface'; import { MempoolBlock } from 'src/app/interfaces/websocket.interface';
import { StateService } from 'src/app/services/state.service'; import { StateService } from 'src/app/services/state.service';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { take, map, switchMap, share } from 'rxjs/operators'; import { take, map, switchMap } from 'rxjs/operators';
import { feeLevels, mempoolFeeColors } from 'src/app/app.constants'; import { feeLevels, mempoolFeeColors } from 'src/app/app.constants';
import { specialBlocks } from 'src/app/app.constants'; import { specialBlocks } from 'src/app/app.constants';
import { Block } from 'src/app/interfaces/electrs.interface';
@Component({ @Component({
selector: 'app-mempool-blocks', selector: 'app-mempool-blocks',
@ -85,7 +84,9 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
mempoolBlocks.forEach((block, i) => { mempoolBlocks.forEach((block, i) => {
block.index = this.blockIndex + i; block.index = this.blockIndex + i;
block.height = lastBlock.height + i + 1; block.height = lastBlock.height + i + 1;
block.blink = specialBlocks[block.height] ? true : false; if (this.stateService.network === '') {
block.blink = specialBlocks[block.height] ? true : false;
}
}); });
const stringifiedBlocks = JSON.stringify(mempoolBlocks); const stringifiedBlocks = JSON.stringify(mempoolBlocks);
this.mempoolBlocksFull = JSON.parse(stringifiedBlocks); this.mempoolBlocksFull = JSON.parse(stringifiedBlocks);

View File

@ -5,6 +5,9 @@
</div> </div>
<div class="warning-label">{{ eventName }}</div> <div class="warning-label">{{ eventName }}</div>
</ng-container> </ng-container>
<div *ngIf="countdown > 0" class="warning-label">{{ eventName }} in {{ countdown | number }} block{{ countdown === 1 ? '' : 's' }}!</div>
<div id="blockchain-container" dir="ltr"> <div id="blockchain-container" dir="ltr">
<app-blockchain></app-blockchain> <app-blockchain></app-blockchain>
</div> </div>

View File

@ -1,3 +1,5 @@
@use 'sass:math';
#blockchain-container { #blockchain-container {
position: relative; position: relative;
overflow-x: scroll; overflow-x: scroll;
@ -11,15 +13,12 @@
} }
.warning-label { .warning-label {
position: absolute; position: relative;
width: 150px;
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
font-size: 12px; font-size: 12px;
padding: 6px 4px; padding: 6px 4px;
border-radius: 4px;
margin-top: -10px; margin-top: -10px;
margin-left: 10px;
} }
// Fireworks // Fireworks
@ -32,9 +31,9 @@ $box-shadow: ();
$box-shadow2: (); $box-shadow2: ();
@for $i from 0 through $particles { @for $i from 0 through $particles {
$box-shadow: $box-shadow, $box-shadow: $box-shadow,
random($width)-$width / 2 + px random($width) - math.div($width, 1.2) + px
random($height)-$height / 1.2 + px random($height) - math.div($height, 1.2) + px
hsl(random(360), 100, 50); hsl(random(360), 100%, 50%);
$box-shadow2: $box-shadow2, 0 0 #fff $box-shadow2: $box-shadow2, 0 0 #fff
} }
@mixin keyframes ($animationName) { @mixin keyframes ($animationName) {

View File

@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { WebsocketService } from 'src/app/services/websocket.service'; import { WebsocketService } from 'src/app/services/websocket.service';
import { StateService } from 'src/app/services/state.service'; import { StateService } from 'src/app/services/state.service';
import { specialBlocks } from 'src/app/app.constants'; import { specialBlocks } from 'src/app/app.constants';
import { takeLast } from 'rxjs/operators';
@Component({ @Component({
selector: 'app-start', selector: 'app-start',
@ -9,26 +10,12 @@ import { specialBlocks } from 'src/app/app.constants';
styleUrls: ['./start.component.scss'], styleUrls: ['./start.component.scss'],
}) })
export class StartComponent implements OnInit { export class StartComponent implements OnInit {
interval = 60; interval = 60;
colors = ['#5E35B1', '#ffffff']; colors = ['#5E35B1', '#ffffff'];
countdown = 0;
specialEvent = false; specialEvent = false;
eventName = ''; eventName = '';
optionsLeft = {
particleCount: 2,
angle: 70,
spread: 50,
origin: { x: 0 },
colors: this.colors,
};
optionsRight = {
particleCount: 2,
angle: 110,
spread: 50,
origin: { x: 1 },
colors: this.colors,
};
constructor( constructor(
private websocketService: WebsocketService, private websocketService: WebsocketService,
@ -39,10 +26,23 @@ export class StartComponent implements OnInit {
this.websocketService.want(['blocks', 'stats', 'mempool-blocks']); this.websocketService.want(['blocks', 'stats', 'mempool-blocks']);
this.stateService.blocks$ this.stateService.blocks$
.subscribe((blocks: any) => { .subscribe((blocks: any) => {
if (this.stateService.network !== '') {
return;
}
this.countdown = 0;
const block = blocks[0]; const block = blocks[0];
if(specialBlocks[block.height]) {
for (const sb in specialBlocks) {
const height = parseInt(sb, 10);
const diff = height - block.height;
if (diff > 0 && diff <= 1008) {
this.countdown = diff;
this.eventName = specialBlocks[sb].labelEvent;
}
}
if (specialBlocks[block.height]) {
this.specialEvent = true; this.specialEvent = true;
this.eventName = specialBlocks[block.height].labelEvent; this.eventName = specialBlocks[block.height].labelEventCompleted;
setTimeout(() => { setTimeout(() => {
this.specialEvent = false; this.specialEvent = false;
}, 60 * 60 * 1000); }, 60 * 60 * 1000);

View File

@ -166,7 +166,7 @@ export class TransactionComponent implements OnInit, OnDestroy {
this.errorUnblinded = error; this.errorUnblinded = error;
return of(tx); return of(tx);
}) })
) );
} }
return of(tx); return of(tx);
}) })

View File

@ -947,29 +947,20 @@ th {
// Blinking block // Blinking block
@keyframes shadowyBackground { @keyframes shadowyBackground {
0% { 0% {
box-shadow: -10px -15px 75px rgba(#5E35B1, 1); box-shadow: -10px -15px 75px rgba(#eba814, 1);
transform: rotate(0deg) translateY(0px);
}
25% {
transform: rotate(3deg) translateY(5px);
} }
50% { 50% {
box-shadow: -10px -15px 75px rgba(#5E35B1, .3); box-shadow: -10px -15px 75px rgba(#eba814, .3);
transform: rotate(0deg) translateY(0px);
}
75% {
transform: rotate(-3deg) translateY(5px);
} }
100% { 100% {
box-shadow: -10px -15px 75px rgba(#5E35B1, 1); box-shadow: -10px -15px 75px rgba(#eba814, 1);
transform: rotate(0deg);
} }
} }
.blink-bg { .blink-bg {
color: #fff; color: #fff;
background: repeating-linear-gradient(rgb(45, 51, 72), rgb(45, 51, 72) 0.163525%, rgb(16, 95, 176) 100%, rgb(147, 57, 244) 0.163525%) !important; background: repeating-linear-gradient(#9d7c05, #9d7c05 0.163525%, #d5a90a 100%) !important;
animation: shadowyBackground 1s infinite; animation: shadowyBackground 1s infinite;
box-shadow: -10px -15px 75px rgba(#5E35B1, 1); box-shadow: -10px -15px 75px rgba(#eba814, 1);
transition: 100ms all ease-in; transition: 100ms all ease-in;
} }