diff --git a/app/static/script.js b/app/static/script.js index 57ea4ad..75d6094 100644 --- a/app/static/script.js +++ b/app/static/script.js @@ -40,6 +40,13 @@ function renderLiveGame(game) { const dot = running ? `` : ''; + // Tick the clock locally when the clock is running or during intermission + const shouldTick = running || intermission; + const rawSeconds = timeToSeconds(time); + const clockAttrs = shouldTick + ? `data-seconds="${rawSeconds}" data-received-at="${Date.now()}"` + : ''; + const hype = !intermission ? `
Hype Meter @@ -53,7 +60,7 @@ function renderLiveGame(game) {
${periodLabel} - ${time} + ${time}
${dot}
@@ -132,6 +139,31 @@ function updateGauges() { }); } +// ── Clock ───────────────────────────────────────────── + +function timeToSeconds(str) { + if (!str || str === 'END') return 0; + const [m, s] = str.split(':').map(Number); + return m * 60 + s; +} + +function secondsToTime(s) { + if (s <= 0) return 'END'; + const m = Math.floor(s / 60); + const sec = s % 60; + return `${String(m).padStart(2, '0')}:${String(sec).padStart(2, '0')}`; +} + +function tickClocks() { + const now = Date.now(); + document.querySelectorAll('[data-seconds][data-received-at]').forEach(el => { + const seconds = parseInt(el.dataset.seconds, 10); + const receivedAt = parseInt(el.dataset.receivedAt, 10); + const elapsed = Math.floor((now - receivedAt) / 1000); + el.textContent = secondsToTime(Math.max(0, seconds - elapsed)); + }); +} + // ── Helpers ────────────────────────────────────────── function ordinalPeriod(period) { @@ -149,4 +181,7 @@ function autoRefresh() { setTimeout(autoRefresh, 5000); } -window.addEventListener('load', autoRefresh); +window.addEventListener('load', () => { + autoRefresh(); + setInterval(tickClocks, 1000); +});