From 3b459b6857e7a3610bd13a6acc7d644df7e6a301 Mon Sep 17 00:00:00 2001 From: Mononaut Date: Sat, 15 Apr 2023 05:26:18 +0900 Subject: [PATCH] hourly blocks clock faces --- frontend/src/app/app-routing.module.ts | 10 ++ .../block-overview-graph/block-scene.ts | 2 +- .../clock-face/clock-face.component.html | 93 ++++++++++++++ .../clock-face/clock-face.component.scss | 23 ++++ .../clock-face/clock-face.component.ts | 15 +++ .../components/clock/clock-a.component.html | 19 +++ .../app/components/clock/clock-a.component.ts | 57 +++++++++ .../components/clock/clock-b.component.html | 15 +++ .../app/components/clock/clock-b.component.ts | 58 +++++++++ .../app/components/clock/clock.component.scss | 119 ++++++++++++++++++ frontend/src/app/graphs/graphs.module.ts | 4 +- frontend/src/app/shared/shared.module.ts | 15 +++ frontend/src/index.mempool.html | 2 +- 13 files changed, 428 insertions(+), 4 deletions(-) create mode 100644 frontend/src/app/components/clock-face/clock-face.component.html create mode 100644 frontend/src/app/components/clock-face/clock-face.component.scss create mode 100644 frontend/src/app/components/clock-face/clock-face.component.ts create mode 100644 frontend/src/app/components/clock/clock-a.component.html create mode 100644 frontend/src/app/components/clock/clock-a.component.ts create mode 100644 frontend/src/app/components/clock/clock-b.component.html create mode 100644 frontend/src/app/components/clock/clock-b.component.ts create mode 100644 frontend/src/app/components/clock/clock.component.scss diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index 06334c5b5..0146fb535 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -4,6 +4,8 @@ import { AppPreloadingStrategy } from './app.preloading-strategy' import { StartComponent } from './components/start/start.component'; import { TransactionComponent } from './components/transaction/transaction.component'; import { BlockComponent } from './components/block/block.component'; +import { ClockAComponent } from './components/clock/clock-a.component'; +import { ClockBComponent } from './components/clock/clock-b.component'; import { AddressComponent } from './components/address/address.component'; import { MasterPageComponent } from './components/master-page/master-page.component'; import { AboutComponent } from './components/about/about.component'; @@ -355,6 +357,14 @@ let routes: Routes = [ }, ], }, + { + path: 'clock-face-a', + component: ClockAComponent, + }, + { + path: 'clock-face-b', + component: ClockBComponent, + }, { path: 'status', data: { networks: ['bitcoin', 'liquid'] }, 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 7fb0a1e99..5ab0eefea 100644 --- a/frontend/src/app/components/block-overview-graph/block-scene.ts +++ b/frontend/src/app/components/block-overview-graph/block-scene.ts @@ -34,7 +34,7 @@ export default class BlockScene { this.width = width; this.height = height; this.gridSize = this.width / this.gridWidth; - this.unitPadding = width / 500; + this.unitPadding = this.gridSize / 5; this.unitWidth = this.gridSize - (this.unitPadding * 2); this.dirty = true; diff --git a/frontend/src/app/components/clock-face/clock-face.component.html b/frontend/src/app/components/clock-face/clock-face.component.html new file mode 100644 index 000000000..a5db1538c --- /dev/null +++ b/frontend/src/app/components/clock-face/clock-face.component.html @@ -0,0 +1,93 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ 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 new file mode 100644 index 000000000..fa73ad90a --- /dev/null +++ b/frontend/src/app/components/clock-face/clock-face.component.scss @@ -0,0 +1,23 @@ +.clock-face { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + width: 100%; + height: 100%; + + .cut-out, .demo-dial { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + width: 100%; + height: 100%; + + .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 new file mode 100644 index 000000000..fcd4b75cc --- /dev/null +++ b/frontend/src/app/components/clock-face/clock-face.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-clock-face', + templateUrl: './clock-face.component.html', + styleUrls: ['./clock-face.component.scss'], +}) +export class ClockFaceComponent implements OnInit { + + constructor() {} + + ngOnInit(): void { + // initialize stuff + } +} diff --git a/frontend/src/app/components/clock/clock-a.component.html b/frontend/src/app/components/clock/clock-a.component.html new file mode 100644 index 000000000..c7eea67c9 --- /dev/null +++ b/frontend/src/app/components/clock/clock-a.component.html @@ -0,0 +1,19 @@ +
+ +
+ +
+
+
+
+
+
+
+
+
+

{{ block.height }}

+
+
+
+
+
\ 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 new file mode 100644 index 000000000..0242e0ab8 --- /dev/null +++ b/frontend/src/app/components/clock/clock-a.component.ts @@ -0,0 +1,57 @@ +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'; + +@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% + )`, + }; + } +} diff --git a/frontend/src/app/components/clock/clock-b.component.html b/frontend/src/app/components/clock/clock-b.component.html new file mode 100644 index 000000000..f3d65562d --- /dev/null +++ b/frontend/src/app/components/clock/clock-b.component.html @@ -0,0 +1,15 @@ +
+ +
+ +
+ +
+
+
+

{{ block.height }}

+
+
+
+
+
\ 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 new file mode 100644 index 000000000..95ae803b8 --- /dev/null +++ b/frontend/src/app/components/clock/clock-b.component.ts @@ -0,0 +1,58 @@ +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'; + +@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 screenSize = Math.min(window.innerWidth, window.innerHeight); + const baseSize = 0.92 * screenSize; + const size = Math.ceil(baseSize / 75) * 75; + const margin = screenSize - size; + this.blockSizerStyle = { + transform: `translate(${margin}px, ${margin}px)`, + width: `${size}px`, + height: `${size}px`, + }; + this.cd.markForCheck(); + } +} diff --git a/frontend/src/app/components/clock/clock.component.scss b/frontend/src/app/components/clock/clock.component.scss new file mode 100644 index 000000000..385df2ea0 --- /dev/null +++ b/frontend/src/app/components/clock/clock.component.scss @@ -0,0 +1,119 @@ +.clock-wrapper { + --clock-width: min(100vw, 100vh); + position: relative; + width: 100vw; + max-width: var(--clock-width); + height: 100vh; + max-height: var(--clock-width); + margin: auto; +} + +.title-wrapper { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + width: 100%; + height: 100%; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + + .block-height { + font-size: calc(0.2 * var(--clock-width)); + padding: 0; + margin: 0; + background: radial-gradient(rgba(0,0,0,0.5), transparent 67%); + padding: calc(0.05 * var(--clock-width)) calc(0.15 * var(--clock-width)); + } +} + +.block-wrapper { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + width: 100%; + height: 100%; + + .block-sizer { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + } + + .fader { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + background: radial-gradient(transparent 0%, transparent 55%, #11131f 65%, #11131f 100%); + } + + .block-cube { + --side-width: calc(0.4 * var(--clock-width)); + --half-side: calc(0.2 * var(--clock-width)); + --neg-half-side: calc(-0.2 * var(--clock-width)); + transform-style: preserve-3d; + animation: block-spin 60s infinite linear; + position: absolute; + z-index: -1; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: var(--side-width); + height: var(--side-width); + + .side { + width: var(--side-width); + height: var(--side-width); + line-height: 100px; + text-align: center; + background: #232838; + display: block; + position: absolute; + } + + .side.top { + transform: rotateX(90deg); + margin-top: var(--neg-half-side); + } + + .side.bottom { + background: #105fb0; + transform: rotateX(-90deg); + margin-top: var(--half-side); + } + + .side.right { + transform: rotateY(90deg); + margin-left: var(--half-side); + } + + .side.left { + transform: rotateY(-90deg); + margin-left: var(--neg-half-side); + } + + .side.front { + transform: translateZ(var(--half-side)); + } + + .side.back { + transform: translateZ(var(--neg-half-side)); + } + } +} + + + +@keyframes block-spin { + 0% {transform: translate(-50%, -50%) rotateX(-20deg) rotateY(0deg);} + 100% {transform: translate(-50%, -50%) rotateX(-20deg) rotateY(-360deg);} +} \ No newline at end of file diff --git a/frontend/src/app/graphs/graphs.module.ts b/frontend/src/app/graphs/graphs.module.ts index 4cb803888..a7e627736 100644 --- a/frontend/src/app/graphs/graphs.module.ts +++ b/frontend/src/app/graphs/graphs.module.ts @@ -14,7 +14,7 @@ import { LbtcPegsGraphComponent } from '../components/lbtc-pegs-graph/lbtc-pegs- import { GraphsComponent } from '../components/graphs/graphs.component'; import { StatisticsComponent } from '../components/statistics/statistics.component'; import { MempoolBlockComponent } from '../components/mempool-block/mempool-block.component'; -import { MempoolBlockOverviewComponent } from '../components/mempool-block-overview/mempool-block-overview.component'; +// import { MempoolBlockOverviewComponent } from '../components/mempool-block-overview/mempool-block-overview.component'; import { PoolRankingComponent } from '../components/pool-ranking/pool-ranking.component'; import { PoolComponent } from '../components/pool/pool.component'; import { TelevisionComponent } from '../components/television/television.component'; @@ -42,7 +42,7 @@ import { CommonModule } from '@angular/common'; BlockFeeRatesGraphComponent, BlockSizesWeightsGraphComponent, FeeDistributionGraphComponent, - MempoolBlockOverviewComponent, + // MempoolBlockOverviewComponent, IncomingTransactionsGraphComponent, MempoolGraphComponent, LbtcPegsGraphComponent, diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts index 7d3e51d20..4dd915889 100644 --- a/frontend/src/app/shared/shared.module.ts +++ b/frontend/src/app/shared/shared.module.ts @@ -90,6 +90,11 @@ import { GeolocationComponent } from '../shared/components/geolocation/geolocati import { TestnetAlertComponent } from './components/testnet-alert/testnet-alert.component'; import { GlobalFooterComponent } from './components/global-footer/global-footer.component'; +import { MempoolBlockOverviewComponent } from '../components/mempool-block-overview/mempool-block-overview.component'; +import { ClockFaceComponent } from '../components/clock-face/clock-face.component'; +import { ClockAComponent } from '../components/clock/clock-a.component'; +import { ClockBComponent } from '../components/clock/clock-b.component'; + @NgModule({ declarations: [ ClipboardComponent, @@ -172,6 +177,11 @@ import { GlobalFooterComponent } from './components/global-footer/global-footer. GeolocationComponent, TestnetAlertComponent, GlobalFooterComponent, + + MempoolBlockOverviewComponent, + ClockAComponent, + ClockBComponent, + ClockFaceComponent, ], imports: [ CommonModule, @@ -279,6 +289,11 @@ import { GlobalFooterComponent } from './components/global-footer/global-footer. GeolocationComponent, PreviewTitleComponent, GlobalFooterComponent, + + MempoolBlockOverviewComponent, + ClockAComponent, + ClockBComponent, + ClockFaceComponent, ] }) export class SharedModule { diff --git a/frontend/src/index.mempool.html b/frontend/src/index.mempool.html index 60f1b4421..02765c0ba 100644 --- a/frontend/src/index.mempool.html +++ b/frontend/src/index.mempool.html @@ -32,7 +32,7 @@ - +