diff --git a/frontend/src/app/components/block-overview-graph/block-scene.ts b/frontend/src/app/components/block-overview-graph/block-scene.ts index f1c1b4d77..1c0072e31 100644 --- a/frontend/src/app/components/block-overview-graph/block-scene.ts +++ b/frontend/src/app/components/block-overview-graph/block-scene.ts @@ -36,7 +36,6 @@ export default class BlockScene { this.gridSize = this.width / this.gridWidth; this.unitPadding = Math.max(1, Math.floor(this.gridSize / 2.5)); this.unitWidth = this.gridSize - (this.unitPadding); - console.log(this.gridSize, this.unitPadding, this.unitWidth); this.dirty = true; if (this.initialised && this.scene) { diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html index 695e7c97d..0a2f0decb 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html @@ -1,21 +1,21 @@ -
  -
+
- +
~{{ block?.extras?.medianFee | number:feeRounding }} sat/vB @@ -82,11 +82,11 @@
-
+
+ [ngStyle]="emptyBlockStyles[i]" [class.offscreen]="!static && count && i >= count">
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 f0afaafd8..7e04a3af6 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss @@ -1,6 +1,6 @@ .bitcoin-block { - width: 125px; - height: 125px; + width: var(--block-size); + height: var(--block-size); } .blockLink { @@ -39,9 +39,11 @@ } .blocks-container { + --block-size: 125px; + --block-offset: calc(0.32 * var(--block-size)); position: absolute; top: 0px; - left: 40px; + left: var(--block-offset); } .block-body { @@ -81,11 +83,11 @@ .bitcoin-block::after { content: ''; - width: 125px; - height: 24px; + width: var(--block-size); + height: calc(0.192 * var(--block-size)); position:absolute; - top: -24px; - left: -20px; + top: calc(-0.192 * var(--block-size)); + left: calc(-0.16 * var(--block-size)); background-color: #232838; transform:skew(40deg); transform-origin:top; @@ -93,11 +95,11 @@ .bitcoin-block::before { content: ''; - width: 20px; - height: 125px; + width: calc(0.16 * var(--block-size)); + height: var(--block-size); position: absolute; - top: -12px; - left: -20px; + top: calc(-0.096 * var(--block-size)); + left: calc(-0.16 * var(--block-size)); background-color: #191c27; transform: skewY(50deg); diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts index e894caff7..65124e0d3 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts @@ -24,7 +24,8 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { @Input() count: number = 8; // number of blocks in this chunk (dynamic blocks only) @Input() loadingTip: boolean = false; @Input() connected: boolean = true; - @Input() tiny: boolean = false; + @Input() minimal: boolean = false; + @Input() blockWidth: number = 125; specialBlocks = specialBlocks; network = ''; @@ -52,6 +53,10 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { timeLtrSubscription: Subscription; timeLtr: boolean; + blockOffset: number = 155; + dividerBlockOffset: number = 205; + blockPadding: number = 30; + gradientColors = { '': ['#9339f4', '#105fb0'], bisq: ['#9339f4', '#105fb0'], @@ -119,7 +124,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { this.blockStyles = []; if (this.blocksFilled && block.height > this.chainTip) { - this.blocks.forEach((b, i) => this.blockStyles.push(this.getStyleForBlock(b, i, i ? -155 : -205))); + this.blocks.forEach((b, i) => this.blockStyles.push(this.getStyleForBlock(b, i, i ? -this.blockOffset : -this.dividerBlockOffset))); setTimeout(() => { this.blockStyles = []; this.blocks.forEach((b, i) => this.blockStyles.push(this.getStyleForBlock(b, i))); @@ -160,6 +165,13 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { } ngOnChanges(changes: SimpleChanges): void { + if (changes.blockWidth && this.blockWidth) { + this.blockPadding = 0.24 * this.blockWidth; + this.blockOffset = this.blockWidth + this.blockPadding; + this.dividerBlockOffset = this.blockOffset + (0.4 * this.blockWidth); + this.blockStyles = []; + this.blocks.forEach((b, i) => this.blockStyles.push(this.getStyleForBlock(b, i))); + } if (this.static) { const animateSlide = changes.height && (changes.height.currentValue === changes.height.previousValue + 1); this.updateStaticBlocks(animateSlide); @@ -192,14 +204,14 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { } this.arrowVisible = true; if (newBlockFromLeft) { - this.arrowLeftPx = blockindex * 155 + 30 - 205; + this.arrowLeftPx = blockindex * this.blockOffset + this.blockPadding - this.dividerBlockOffset; setTimeout(() => { this.arrowTransition = '2s'; - this.arrowLeftPx = blockindex * 155 + 30; + this.arrowLeftPx = blockindex * this.blockOffset + this.blockPadding; this.cd.markForCheck(); }, 50); } else { - this.arrowLeftPx = blockindex * 155 + 30; + this.arrowLeftPx = blockindex * this.blockOffset + this.blockPadding; if (!animate) { setTimeout(() => { this.arrowTransition = '2s'; @@ -246,7 +258,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { } this.blocks = this.blocks.slice(0, this.count); this.blockStyles = []; - this.blocks.forEach((b, i) => this.blockStyles.push(this.getStyleForBlock(b, i, animateSlide ? -155 : 0))); + this.blocks.forEach((b, i) => this.blockStyles.push(this.getStyleForBlock(b, i, animateSlide ? -this.blockOffset : 0))); this.cd.markForCheck(); if (animateSlide) { // animate blocks slide right @@ -288,7 +300,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { } return { - left: addLeft + 155 * index + 'px', + left: addLeft + this.blockOffset * index + 'px', background: `repeating-linear-gradient( #2d3348, #2d3348 ${greenBackgroundHeight}%, @@ -310,7 +322,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { const addLeft = animateEnterFrom || 0; return { - left: addLeft + (155 * index) + 'px', + left: addLeft + (this.blockOffset * index) + 'px', background: "#2d3348", }; } @@ -318,7 +330,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { getStyleForPlaceholderBlock(index: number, animateEnterFrom: number = 0) { const addLeft = animateEnterFrom || 0; return { - left: addLeft + (155 * index) + 'px', + left: addLeft + (this.blockOffset * index) + 'px', }; } @@ -326,7 +338,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { const addLeft = animateEnterFrom || 0; return { - left: addLeft + 155 * this.emptyBlocks.indexOf(block) + 'px', + left: addLeft + this.blockOffset * this.emptyBlocks.indexOf(block) + 'px', background: "#2d3348", }; } diff --git a/frontend/src/app/components/clock-face/clock-face.component.html b/frontend/src/app/components/clock-face/clock-face.component.html index f1893cd85..6e17dab05 100644 --- a/frontend/src/app/components/clock-face/clock-face.component.html +++ b/frontend/src/app/components/clock-face/clock-face.component.html @@ -1,94 +1,87 @@ -
-
-
- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/frontend/src/app/components/clock-face/clock-face.component.scss b/frontend/src/app/components/clock-face/clock-face.component.scss index 66d53784f..60b2c4eba 100644 --- a/frontend/src/app/components/clock-face/clock-face.component.scss +++ b/frontend/src/app/components/clock-face/clock-face.component.scss @@ -1,45 +1,20 @@ -.clock-wrapper { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - justify-content: flex-start; +.clock-face { + position: relative; + height: 84.375%; + margin: auto; + overflow: hidden; - .clockchain-bar, .clock-face { - flex-shrink: 0; - flex-grow: 0; - } + .cut-out, .demo-dial { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + width: 100%; + height: 100%; - .clockchain-bar { - position: relative; - height: 15.625%; - // background: #1d1f31; - // box-shadow: 0 0 15px #000; - } - - .clock-face { - position: relative; - height: 84.375%; - margin: auto; - overflow: hidden; - - .cut-out, .demo-dial { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - width: 100%; - height: 100%; - - .face { - fill: #11131f; - } + .face { + fill: #11131f; } } } \ No newline at end of file diff --git a/frontend/src/app/components/clock-face/clock-face.component.ts b/frontend/src/app/components/clock-face/clock-face.component.ts index 747b6221c..c63ea56ea 100644 --- a/frontend/src/app/components/clock-face/clock-face.component.ts +++ b/frontend/src/app/components/clock-face/clock-face.component.ts @@ -1,36 +1,17 @@ -import { Component, HostListener, OnInit } from '@angular/core'; +import { Component, Input, OnChanges } from '@angular/core'; @Component({ selector: 'app-clock-face', templateUrl: './clock-face.component.html', styleUrls: ['./clock-face.component.scss'], }) -export class ClockFaceComponent implements OnInit { - size: number; - wrapperStyle; - chainStyle; +export class ClockFaceComponent implements OnChanges { + @Input() size: number = 300; faceStyle; - showDial: boolean = false; constructor() {} - ngOnInit(): void { - // initialize stuff - this.resizeCanvas(); - } - - @HostListener('window:resize', ['$event']) - resizeCanvas(): void { - this.size = Math.min(window.innerWidth, 0.78125 * window.innerHeight); - this.wrapperStyle = { - '--clock-width': `${this.size}px` - }; - const scaleFactor = window.innerWidth / 1390; - this.chainStyle = { - transform: `translate(2vw, 0.5vw) scale(${scaleFactor})`, - transformOrigin: 'top left', - }; - + ngOnChanges(): void { this.faceStyle = { width: `${this.size}px`, height: `${this.size}px`, diff --git a/frontend/src/app/components/clock/clock-a.component.html b/frontend/src/app/components/clock/clock-a.component.html index 2029b9f24..a3bebd4bd 100644 --- a/frontend/src/app/components/clock/clock-a.component.html +++ b/frontend/src/app/components/clock/clock-a.component.html @@ -1,17 +1 @@ - -
- -
-
-
-
-
-
-
-
-
-

{{ block.height }}

-
-
-
-
\ No newline at end of file + \ No newline at end of file diff --git a/frontend/src/app/components/clock/clock-a.component.ts b/frontend/src/app/components/clock/clock-a.component.ts index 0242e0ab8..50f834bad 100644 --- a/frontend/src/app/components/clock/clock-a.component.ts +++ b/frontend/src/app/components/clock/clock-a.component.ts @@ -1,57 +1,7 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core'; -import { Subscription } from 'rxjs'; -import { StateService } from '../../services/state.service'; -import { BlockExtended } from '../../interfaces/node-api.interface'; -import { WebsocketService } from '../../services/websocket.service'; +import { Component } from '@angular/core'; @Component({ selector: 'app-clock-a', templateUrl: './clock-a.component.html', - styleUrls: ['./clock.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, }) -export class ClockAComponent implements OnInit { - blocksSubscription: Subscription; - block: BlockExtended; - blockStyle; - - gradientColors = { - '': ['#9339f4', '#105fb0'], - bisq: ['#9339f4', '#105fb0'], - liquid: ['#116761', '#183550'], - 'liquidtestnet': ['#494a4a', '#272e46'], - testnet: ['#1d486f', '#183550'], - signet: ['#6f1d5d', '#471850'], - }; - - constructor( - public stateService: StateService, - private websocketService: WebsocketService, - private cd: ChangeDetectorRef, - ) {} - - ngOnInit(): void { - this.websocketService.want(['blocks']); - this.blocksSubscription = this.stateService.blocks$ - .subscribe(([block]) => { - if (block) { - this.block = block; - this.blockStyle = this.getStyleForBlock(this.block); - this.cd.markForCheck(); - } - }); - } - - getStyleForBlock(block: BlockExtended) { - const greenBackgroundHeight = 100 - (block.weight / this.stateService.env.BLOCK_WEIGHT_UNITS) * 100; - - return { - background: `repeating-linear-gradient( - #2d3348, - #2d3348 ${greenBackgroundHeight}%, - ${this.gradientColors[''][0]} ${Math.max(greenBackgroundHeight, 0)}%, - ${this.gradientColors[''][1]} 100% - )`, - }; - } -} +export class ClockAComponent {} diff --git a/frontend/src/app/components/clock/clock-b.component.html b/frontend/src/app/components/clock/clock-b.component.html index 887c0a1cf..a8620a212 100644 --- a/frontend/src/app/components/clock/clock-b.component.html +++ b/frontend/src/app/components/clock/clock-b.component.html @@ -1,13 +1 @@ - -
- -
- -
-
-
-

{{ block.height }}

-
-
-
-
\ No newline at end of file + \ No newline at end of file diff --git a/frontend/src/app/components/clock/clock-b.component.ts b/frontend/src/app/components/clock/clock-b.component.ts index 626f388b6..b47c9dba3 100644 --- a/frontend/src/app/components/clock/clock-b.component.ts +++ b/frontend/src/app/components/clock/clock-b.component.ts @@ -1,57 +1,7 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostListener, OnInit } from '@angular/core'; -import { Subscription } from 'rxjs'; -import { StateService } from '../../services/state.service'; -import { BlockExtended } from '../../interfaces/node-api.interface'; -import { WebsocketService } from '../../services/websocket.service'; +import { Component } from '@angular/core'; @Component({ selector: 'app-clock-b', templateUrl: './clock-b.component.html', - styleUrls: ['./clock.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, }) -export class ClockBComponent implements OnInit { - blocksSubscription: Subscription; - block: BlockExtended; - blockSizerStyle; - - gradientColors = { - '': ['#9339f4', '#105fb0'], - bisq: ['#9339f4', '#105fb0'], - liquid: ['#116761', '#183550'], - 'liquidtestnet': ['#494a4a', '#272e46'], - testnet: ['#1d486f', '#183550'], - signet: ['#6f1d5d', '#471850'], - }; - - constructor( - public stateService: StateService, - private websocketService: WebsocketService, - private cd: ChangeDetectorRef, - ) {} - - ngOnInit(): void { - this.resizeCanvas(); - this.websocketService.want(['blocks']); - this.blocksSubscription = this.stateService.blocks$ - .subscribe(([block]) => { - if (block) { - this.block = block; - this.cd.markForCheck(); - } - }); - } - - @HostListener('window:resize', ['$event']) - resizeCanvas(): void { - const clockSize = Math.min(window.innerWidth, 0.78125 * window.innerHeight); - const size = Math.ceil(clockSize / 75) * 75; - const margin = (clockSize - size) / 2; - this.blockSizerStyle = { - transform: `translate(${margin}px, ${margin}px)`, - width: `${size}px`, - height: `${size}px`, - }; - this.cd.markForCheck(); - } -} +export class ClockBComponent {} diff --git a/frontend/src/app/components/clock/clock.component.html b/frontend/src/app/components/clock/clock.component.html new file mode 100644 index 000000000..74e06418d --- /dev/null +++ b/frontend/src/app/components/clock/clock.component.html @@ -0,0 +1,34 @@ +
+
+
+ +
+
+
+ +
+ + +
+
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+

{{ block.height }}

+
+
+
+
+
+
\ No newline at end of file diff --git a/frontend/src/app/components/clock/clock.component.scss b/frontend/src/app/components/clock/clock.component.scss index c41b33e8a..e5904b4f1 100644 --- a/frontend/src/app/components/clock/clock.component.scss +++ b/frontend/src/app/components/clock/clock.component.scss @@ -1,3 +1,44 @@ +.clock-wrapper { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: flex-start; + + --clock-width: 300px; + + .clockchain-bar, .clock-face { + flex-shrink: 0; + flex-grow: 0; + } + + .clockchain-bar { + position: relative; + width: 100%; + height: 15.625%; + z-index: 2; + overflow: hidden; + // background: #1d1f31; + // box-shadow: 0 0 15px #000; + } + + .clock-face { + position: relative; + height: 84.375%; + margin: auto; + overflow: hidden; + display: flex; + justify-content: center; + align-items: center; + z-index: 1; + } +} + .title-wrapper { position: absolute; left: 0; @@ -101,8 +142,6 @@ } } - - @keyframes block-spin { 0% {transform: translate(-50%, -50%) rotateX(-20deg) rotateY(0deg);} 100% {transform: translate(-50%, -50%) rotateX(-20deg) rotateY(-360deg);} diff --git a/frontend/src/app/components/clock/clock.component.ts b/frontend/src/app/components/clock/clock.component.ts new file mode 100644 index 000000000..7aa875695 --- /dev/null +++ b/frontend/src/app/components/clock/clock.component.ts @@ -0,0 +1,82 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostListener, Input, OnInit } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { StateService } from '../../services/state.service'; +import { BlockExtended } from '../../interfaces/node-api.interface'; +import { WebsocketService } from '../../services/websocket.service'; + +@Component({ + selector: 'app-clock', + templateUrl: './clock.component.html', + styleUrls: ['./clock.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ClockComponent implements OnInit { + @Input() mode: string = 'block'; + blocksSubscription: Subscription; + block: BlockExtended; + clockSize: number = 300; + chainWidth: number = 384; + chainHeight: number = 60; + blockStyle; + blockSizerStyle; + wrapperStyle; + + gradientColors = { + '': ['#9339f4', '#105fb0'], + bisq: ['#9339f4', '#105fb0'], + liquid: ['#116761', '#183550'], + 'liquidtestnet': ['#494a4a', '#272e46'], + testnet: ['#1d486f', '#183550'], + signet: ['#6f1d5d', '#471850'], + }; + + constructor( + public stateService: StateService, + private websocketService: WebsocketService, + private cd: ChangeDetectorRef, + ) {} + + ngOnInit(): void { + this.resizeCanvas(); + this.websocketService.want(['blocks']); + this.blocksSubscription = this.stateService.blocks$ + .subscribe(([block]) => { + if (block) { + this.block = block; + this.blockStyle = this.getStyleForBlock(this.block); + this.cd.markForCheck(); + } + }); + } + + getStyleForBlock(block: BlockExtended) { + const greenBackgroundHeight = 100 - (block.weight / this.stateService.env.BLOCK_WEIGHT_UNITS) * 100; + + return { + background: `repeating-linear-gradient( + #2d3348, + #2d3348 ${greenBackgroundHeight}%, + ${this.gradientColors[''][0]} ${Math.max(greenBackgroundHeight, 0)}%, + ${this.gradientColors[''][1]} 100% + )`, + }; + } + + @HostListener('window:resize', ['$event']) + resizeCanvas(): void { + this.chainWidth = window.innerWidth; + this.chainHeight = Math.max(60, window.innerHeight / 8); + this.clockSize = Math.min(500, window.innerWidth, window.innerHeight - (1.4 * this.chainHeight)); + const size = Math.ceil(this.clockSize / 75) * 75; + const margin = (this.clockSize - size) / 2; + this.blockSizerStyle = { + transform: `translate(${margin}px, ${margin}px)`, + width: `${size}px`, + height: `${size}px`, + }; + this.wrapperStyle = { + '--clock-width': `${this.clockSize}px` + }; + this.cd.markForCheck(); + } +} diff --git a/frontend/src/app/components/clockchain/clockchain.component.html b/frontend/src/app/components/clockchain/clockchain.component.html index 0eabc2862..3a28296ca 100644 --- a/frontend/src/app/components/clockchain/clockchain.component.html +++ b/frontend/src/app/components/clockchain/clockchain.component.html @@ -1,11 +1,25 @@
-
+
- - + + +
+
+ + +
-
diff --git a/frontend/src/app/components/clockchain/clockchain.component.scss b/frontend/src/app/components/clockchain/clockchain.component.scss index d6fc00090..0b01adc26 100644 --- a/frontend/src/app/components/clockchain/clockchain.component.scss +++ b/frontend/src/app/components/clockchain/clockchain.component.scss @@ -1,15 +1,17 @@ .divider { - width: 4px; - height: 180px; - left: 0; - top: -40px; position: absolute; - margin-bottom: 120px; - background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3cline x1='0' y1='0' x2='0' y2='100%' stroke='white' stroke-width='8' stroke-dasharray='18%2c32' stroke-dashoffset='-5' stroke-linecap='square'/%3e%3c/svg%3e"); + left: -1px; + top: 0; + .divider-line { + stroke: white; + stroke-width: 4px; + stroke-linecap: butt; + stroke-dasharray: 25px 25px; + } } .blockchain-wrapper { - height: 250px; + height: 100%; -webkit-user-select: none; /* Safari */ -moz-user-select: none; /* Firefox */ @@ -20,37 +22,10 @@ .position-container { position: absolute; left: 0; - top: 75px; + top: 0; transform: translateX(50vw); } -.position-container.liquid, .position-container.liquidtestnet { - transform: translateX(420px); -} - -.blockchain-wrapper { - .position-container { - transform: translateX(95vw); - } - .position-container.liquid, .position-container.liquidtestnet { - transform: translateX(50vw); - } - .position-container.loading { - transform: translateX(50vw); - } -} -.blockchain-wrapper.time-ltr { - .position-container { - transform: translateX(5vw); - } - .position-container.liquid, .position-container.liquidtestnet { - transform: translateX(50vw); - } - .position-container.loading { - transform: translateX(50vw); - } -} - .black-background { background-color: #11131f; z-index: 100; diff --git a/frontend/src/app/components/clockchain/clockchain.component.ts b/frontend/src/app/components/clockchain/clockchain.component.ts index e5c63dbe4..addc22948 100644 --- a/frontend/src/app/components/clockchain/clockchain.component.ts +++ b/frontend/src/app/components/clockchain/clockchain.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, Input } from '@angular/core'; +import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, Input, OnChanges, ChangeDetectorRef } from '@angular/core'; import { firstValueFrom, Subscription } from 'rxjs'; import { StateService } from '../../services/state.service'; @@ -8,7 +8,15 @@ import { StateService } from '../../services/state.service'; styleUrls: ['./clockchain.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class ClockchainComponent implements OnInit, OnDestroy { +export class ClockchainComponent implements OnInit, OnChanges, OnDestroy { + @Input() width: number = 300; + @Input() height: number = 60; + + mempoolBlocks: number = 3; + blockchainBlocks: number = 6; + blockWidth: number = 50; + dividerStyle; + network: string; timeLtrSubscription: Subscription; timeLtr: boolean = this.stateService.timeLtr.value; @@ -19,9 +27,12 @@ export class ClockchainComponent implements OnInit, OnDestroy { constructor( public stateService: StateService, + private cd: ChangeDetectorRef, ) {} ngOnInit() { + this.ngOnChanges(); + this.network = this.stateService.network; this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => { this.timeLtr = !!ltr; @@ -34,6 +45,17 @@ export class ClockchainComponent implements OnInit, OnDestroy { }); } + ngOnChanges() { + this.blockWidth = Math.floor(7 * this.height / 12); + this.mempoolBlocks = Math.floor(((this.width / 2) - (this.blockWidth * 0.32)) / (1.24 * this.blockWidth)); + this.blockchainBlocks = this.mempoolBlocks; + this.dividerStyle = { + width: '2px', + height: `${this.height}px`, + }; + this.cd.markForCheck(); + } + ngOnDestroy() { this.timeLtrSubscription.unsubscribe(); this.connectionStateSubscription.unsubscribe(); 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 b11fbb888..cfb091e9b 100644 --- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.html +++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.html @@ -1,12 +1,12 @@ - -
+ +
-
+
 
- +
~{{ projectedBlock.medianFee | number:feeRounding }} sat/vB
@@ -73,10 +73,10 @@
-
+
-
+
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 a0140f55c..6d1ec326e 100644 --- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss +++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss @@ -1,6 +1,6 @@ .bitcoin-block { - width: 125px; - height: 125px; + width: var(--block-size); + height: var(--block-size); transition: background 2s, right 2s, transform 1s, opacity 1s; } @@ -14,6 +14,7 @@ top: 0px; right: 0px; left: 0px; + --block-size: 125px; } .flashing { @@ -66,11 +67,11 @@ .bitcoin-block::after { content: ''; - width: 125px; - height: 24px; + width: var(--block-size); + height: calc(0.192 * var(--block-size)); position:absolute; - top: -24px; - left: -20px; + top: calc(-0.192 * var(--block-size)); + left: calc(-0.16 * var(--block-size)); background-color: #232838; transform:skew(40deg); transform-origin:top; @@ -79,11 +80,11 @@ .bitcoin-block::before { content: ''; - width: 20px; - height: 125px; + width: calc(0.16 * var(--block-size)); + height: var(--block-size); position: absolute; - top: -12px; - left: -20px; + top: calc(-0.096 * var(--block-size)); + left: calc(-0.16 * var(--block-size)); background-color: #191c27; z-index: -1; @@ -100,7 +101,7 @@ background-color: #2d2825; } -.mempool-block.last-block { +.mempool-block.hide-block { opacity: 0; } @@ -145,7 +146,7 @@ .bitcoin-block::before { transform: skewY(-50deg); - left: 125px; + left: var(--block-size); } .block-body { transform: scaleX(-1); 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 b711ce805..6877823f5 100644 --- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts +++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, HostListener, Input } from '@angular/core'; +import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, HostListener, Input, OnChanges, SimpleChanges } from '@angular/core'; import { Subscription, Observable, fromEvent, merge, of, combineLatest } from 'rxjs'; import { MempoolBlock } from '../../interfaces/websocket.interface'; import { StateService } from '../../services/state.service'; @@ -23,8 +23,9 @@ import { animate, style, transition, trigger } from '@angular/animations'; ])], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MempoolBlocksComponent implements OnInit, OnDestroy { - @Input() tiny: boolean = false; +export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy { + @Input() minimal: boolean = false; + @Input() blockWidth: number = 125; @Input() count: number = null; specialBlocks = specialBlocks; @@ -51,8 +52,9 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy { timeLtr: boolean; animateEntry: boolean = false; - blockWidth = 125; - blockPadding = 30; + blockOffset: number = 155; + blockPadding: number = 30; + containerOffset: number = 40; arrowVisible = false; tabHidden = false; feeRounding = '1.0-0'; @@ -221,6 +223,14 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy { }); } + ngOnChanges(changes: SimpleChanges): void { + if (changes.blockWidth && this.blockWidth) { + this.blockPadding = 0.24 * this.blockWidth; + this.containerOffset = 0.32 * this.blockWidth; + this.blockOffset = this.blockWidth + this.blockPadding; + } + } + ngOnDestroy() { this.markBlocksSubscription.unsubscribe(); this.blockSubscription.unsubscribe(); @@ -243,20 +253,22 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy { const innerWidth = this.stateService.env.BASE_MODULE !== 'liquid' && window.innerWidth <= 767.98 ? window.innerWidth : window.innerWidth / 2; let blocksAmount; if (this.count) { - blocksAmount = this.count; + blocksAmount = 8; } else { blocksAmount = Math.min(this.stateService.env.MEMPOOL_BLOCKS_AMOUNT, Math.floor(innerWidth / (this.blockWidth + this.blockPadding))); } while (blocks.length > blocksAmount) { const block = blocks.pop(); - const lastBlock = blocks[blocks.length - 1]; - lastBlock.blockSize += block.blockSize; - lastBlock.blockVSize += block.blockVSize; - lastBlock.nTx += block.nTx; - lastBlock.feeRange = lastBlock.feeRange.concat(block.feeRange); - lastBlock.feeRange.sort((a, b) => a - b); - lastBlock.medianFee = this.median(lastBlock.feeRange); - lastBlock.totalFees += block.totalFees; + if (!this.count) { + const lastBlock = blocks[blocks.length - 1]; + lastBlock.blockSize += block.blockSize; + lastBlock.blockVSize += block.blockVSize; + lastBlock.nTx += block.nTx; + lastBlock.feeRange = lastBlock.feeRange.concat(block.feeRange); + lastBlock.feeRange.sort((a, b) => a - b); + lastBlock.medianFee = this.median(lastBlock.feeRange); + lastBlock.totalFees += block.totalFees; + } } if (blocks.length) { blocks[blocks.length - 1].isStack = blocks[blocks.length - 1].blockVSize > this.stateService.blockVSize; @@ -302,14 +314,14 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy { }); return { - 'right': 40 + index * 155 + 'px', + 'right': this.containerOffset + index * this.blockOffset + 'px', 'background': backgroundGradients.join(',') + ')' }; } getStyleForMempoolEmptyBlock(index: number) { return { - 'right': 40 + index * 155 + 'px', + 'right': this.containerOffset + index * this.blockOffset + 'px', 'background': '#554b45', }; } diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts index 0765298bd..21cbb17a8 100644 --- a/frontend/src/app/shared/shared.module.ts +++ b/frontend/src/app/shared/shared.module.ts @@ -93,6 +93,7 @@ import { GlobalFooterComponent } from './components/global-footer/global-footer. import { MempoolBlockOverviewComponent } from '../components/mempool-block-overview/mempool-block-overview.component'; import { ClockchainComponent } from '../components/clockchain/clockchain.component'; import { ClockFaceComponent } from '../components/clock-face/clock-face.component'; +import { ClockComponent } from '../components/clock/clock.component'; import { ClockAComponent } from '../components/clock/clock-a.component'; import { ClockBComponent } from '../components/clock/clock-b.component'; @@ -181,6 +182,7 @@ import { ClockBComponent } from '../components/clock/clock-b.component'; MempoolBlockOverviewComponent, ClockchainComponent, + ClockComponent, ClockAComponent, ClockBComponent, ClockFaceComponent, @@ -294,6 +296,7 @@ import { ClockBComponent } from '../components/clock/clock-b.component'; MempoolBlockOverviewComponent, ClockchainComponent, + ClockComponent, ClockAComponent, ClockBComponent, ClockFaceComponent,