diff --git a/frontend/src/app/app.constants.ts b/frontend/src/app/app.constants.ts index a680d45f6..e18f223c2 100644 --- a/frontend/src/app/app.constants.ts +++ b/frontend/src/app/app.constants.ts @@ -130,12 +130,11 @@ export const languages: Language[] = [ { code: 'zh', name: 'δΈ­ζ–‡' }, // Chinese ]; - export const specialBlocks = { - '708998': { - labelEvent: '🌱 Taproot Activated!', + '709632': { + labelEvent: '🌱 Taproot activated!', }, '840000': { - labelEvent: 'πŸ₯³ Halving Event!', + labelEvent: 'πŸ₯³ Halving', } }; diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss index c0e172059..569f464a5 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss @@ -120,33 +120,3 @@ 50% {opacity: 1.0;} 100% {opacity: 0.7;} } - -// Blinking block -@keyframes shadowyBackground { - 0% { - box-shadow: -10px -15px 75px rgba(#5E35B1, 1); - transform: rotate(0deg) translateY(0px); - } - 25% { - transform: rotate(3deg) translateY(5px); - } - 50% { - box-shadow: -10px -15px 75px rgba(#5E35B1, .3); - transform: rotate(0deg) translateY(0px); - } - 75% { - transform: rotate(-3deg) translateY(5px); - } - 100% { - box-shadow: -10px -15px 75px rgba(#5E35B1, 1); - transform: rotate(0deg); - } -} - -.blink-bg { - 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; - animation: shadowyBackground 1s infinite; - box-shadow: -10px -15px 75px rgba(#5E35B1, 1); - transition: 100ms all ease-in; -} diff --git a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.html b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.html index 3c2f599df..de28df624 100644 --- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.html +++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.html @@ -1,8 +1,8 @@
-
+
-
+
 
diff --git a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss index 5db365452..92c40c73b 100644 --- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss +++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss @@ -18,7 +18,7 @@ .flashing { animation: opacityPulse 2s ease-out; - animation-iteration-count: infinite; + animation-iteration-count: infinite; opacity: 1; } @@ -60,7 +60,7 @@ } .bitcoin-block::after { - content: ''; + content: ''; width: 125px; height: 24px; position:absolute; @@ -68,7 +68,7 @@ left: -20px; background-color: #232838; transform:skew(40deg); - transform-origin:top; + transform-origin:top; } .bitcoin-block::before { @@ -78,18 +78,18 @@ position: absolute; top: -12px; left: -20px; - background-color: #191c27; - + background-color: #191c27; + transform: skewY(50deg); - transform-origin: top; + transform-origin: top; } .mempool-block.bitcoin-block::after { - background-color: #403834; + background-color: #403834; } .mempool-block.bitcoin-block::before { - background-color: #2d2825; + background-color: #2d2825; } .black-background { @@ -102,8 +102,8 @@ position: relative; right: 75px; top: 140px; - width: 0; - height: 0; + width: 0; + height: 0; border-left: 35px solid transparent; border-right: 35px solid transparent; border-bottom: 35px solid #FFF; diff --git a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts index d75ae4409..1cc83ad52 100644 --- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts +++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts @@ -5,6 +5,8 @@ import { StateService } from 'src/app/services/state.service'; import { Router } from '@angular/router'; import { take, map, switchMap, share } from 'rxjs/operators'; import { feeLevels, mempoolFeeColors } from 'src/app/app.constants'; +import { specialBlocks } from 'src/app/app.constants'; +import { Block } from 'src/app/interfaces/electrs.interface'; @Component({ selector: 'app-mempool-blocks', @@ -13,12 +15,13 @@ import { feeLevels, mempoolFeeColors } from 'src/app/app.constants'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class MempoolBlocksComponent implements OnInit, OnDestroy { - + specialBlocks = specialBlocks; mempoolBlocks: MempoolBlock[] = []; mempoolEmptyBlocks: MempoolBlock[] = this.mountEmptyBlocks(); mempoolBlocks$: Observable; timeAvg$: Observable; loadingBlocks$: Observable; + blocksSubscription: Subscription; mempoolBlocksFull: MempoolBlock[] = []; mempoolBlockStyles = []; @@ -74,26 +77,25 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy { fromEvent(window, 'resize') ) .pipe( - switchMap(() => this.stateService.mempoolBlocks$), - map((blocks) => { - if (!blocks.length) { - return [{ index: 0, blockSize: 0, blockVSize: 0, feeRange: [0, 0], medianFee: 0, nTx: 0, totalFees: 0 }]; - } - return blocks; - }), - map((blocks) => { - blocks.forEach((block, i) => { - block.index = this.blockIndex + i; - }); - const stringifiedBlocks = JSON.stringify(blocks); - this.mempoolBlocksFull = JSON.parse(stringifiedBlocks); - this.mempoolBlocks = this.reduceMempoolBlocksToFitScreen(JSON.parse(stringifiedBlocks)); - this.updateMempoolBlockStyles(); - this.calculateTransactionPosition(); - return this.mempoolBlocks; - }) - ); + switchMap(() => combineLatest([ + this.stateService.blocks$.pipe(map(([block]) => block)), + this.stateService.mempoolBlocks$ + ])), + map(([lastBlock, mempoolBlocks]) => { + mempoolBlocks.forEach((block, i) => { + block.index = this.blockIndex + i; + block.height = lastBlock.height + i + 1; + block.blink = specialBlocks[block.height] ? true : false; + }); + const stringifiedBlocks = JSON.stringify(mempoolBlocks); + this.mempoolBlocksFull = JSON.parse(stringifiedBlocks); + this.mempoolBlocks = this.reduceMempoolBlocksToFitScreen(JSON.parse(stringifiedBlocks)); + this.updateMempoolBlockStyles(); + this.calculateTransactionPosition(); + return this.mempoolBlocks; + }) + ); this.timeAvg$ = timer(0, 1000) .pipe( @@ -118,7 +120,7 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy { } else { timeAvgMins += Math.abs(timeAvgDiff); } - + return timeAvgMins * 60 * 1000; }) ); diff --git a/frontend/src/app/interfaces/websocket.interface.ts b/frontend/src/app/interfaces/websocket.interface.ts index e4e31b942..989c4176b 100644 --- a/frontend/src/app/interfaces/websocket.interface.ts +++ b/frontend/src/app/interfaces/websocket.interface.ts @@ -26,6 +26,8 @@ export interface WebsocketResponse { } export interface MempoolBlock { + blink?: boolean; + height?: number; blockSize: number; blockVSize: number; nTx: number; diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss index 4549b4d5d..91f981ba9 100644 --- a/frontend/src/styles.scss +++ b/frontend/src/styles.scss @@ -941,3 +941,35 @@ th { width: 220px; } } + + + +// Blinking block +@keyframes shadowyBackground { + 0% { + box-shadow: -10px -15px 75px rgba(#5E35B1, 1); + transform: rotate(0deg) translateY(0px); + } + 25% { + transform: rotate(3deg) translateY(5px); + } + 50% { + box-shadow: -10px -15px 75px rgba(#5E35B1, .3); + transform: rotate(0deg) translateY(0px); + } + 75% { + transform: rotate(-3deg) translateY(5px); + } + 100% { + box-shadow: -10px -15px 75px rgba(#5E35B1, 1); + transform: rotate(0deg); + } +} + +.blink-bg { + 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; + animation: shadowyBackground 1s infinite; + box-shadow: -10px -15px 75px rgba(#5E35B1, 1); + transition: 100ms all ease-in; +}