From ec2b11b3364c18da7e85afc40a51175deeb713de Mon Sep 17 00:00:00 2001 From: Alexander Whitestone Date: Tue, 24 Mar 2026 00:59:27 -0400 Subject: [PATCH] feat: Bitcoin block height live counter in HUD Adds a fixed bottom-right HUD widget that displays the current Bitcoin block height, polling blockstream.info every 60 s. Flashes accent white when a new block is detected. Degrades gracefully when offline. Fixes #273 --- app.js | 33 +++++++++++++++++++++++++++++++++ index.html | 5 +++++ style.css | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/app.js b/app.js index e5ea2f0..d28c358 100644 --- a/app.js +++ b/app.js @@ -2030,3 +2030,36 @@ function showTimmySpeech(text) { timmySpeechSprite = sprite; timmySpeechState = { startTime: clock.getElapsedTime(), sprite }; } + +// === BITCOIN BLOCK HEIGHT === +// Polls blockstream.info every 60 s for the current tip block height. +// Shows a flash animation when the block number increments. + +const blockHeightDisplay = document.getElementById('block-height-display'); +const blockHeightValue = document.getElementById('block-height-value'); +let lastKnownBlockHeight = null; + +async function fetchBlockHeight() { + try { + const res = await fetch('https://blockstream.info/api/blocks/tip/height'); + if (!res.ok) return; + const height = parseInt(await res.text(), 10); + if (isNaN(height)) return; + + if (lastKnownBlockHeight !== null && height !== lastKnownBlockHeight) { + // New block — trigger flash + blockHeightDisplay.classList.remove('fresh'); + // Force reflow so animation restarts + void blockHeightDisplay.offsetWidth; + blockHeightDisplay.classList.add('fresh'); + } + + lastKnownBlockHeight = height; + blockHeightValue.textContent = height.toLocaleString(); + } catch (_) { + // Network unavailable — keep last known value + } +} + +fetchBlockHeight(); +setInterval(fetchBlockHeight, 60000); diff --git a/index.html b/index.html index a5715f5..93e9dca 100644 --- a/index.html +++ b/index.html @@ -51,6 +51,11 @@
⚡ SOVEREIGNTY ⚡
+
+ ⛏ BLOCK + +
+
ZOOMED: Object [Esc] or double-click to exit diff --git a/style.css b/style.css index 7912ae2..4ac8b3d 100644 --- a/style.css +++ b/style.css @@ -234,6 +234,42 @@ body.photo-mode #overview-indicator { 100% { opacity: 0; transform: translate(-50%, -50%) scale(1); } } +/* === BITCOIN BLOCK HEIGHT === */ +#block-height-display { + position: fixed; + bottom: 12px; + right: 12px; + z-index: 20; + font-family: var(--font-body); + font-size: 11px; + letter-spacing: 0.15em; + color: var(--color-primary); + background: rgba(0, 0, 8, 0.7); + border: 1px solid var(--color-secondary); + padding: 4px 10px; + pointer-events: none; + white-space: nowrap; +} + +.block-height-label { + color: var(--color-text-muted); + margin-right: 6px; + font-size: 10px; +} + +#block-height-value { + color: var(--color-primary); +} + +#block-height-display.fresh #block-height-value { + animation: block-flash 0.6s ease-out; +} + +@keyframes block-flash { + 0% { color: #ffffff; text-shadow: 0 0 8px #4488ff; } + 100% { color: var(--color-primary); text-shadow: none; } +} + /* === CRT / CYBERPUNK OVERLAY === */ .crt-overlay { position: fixed; -- 2.43.0