diff --git a/app/static/script.js b/app/static/script.js index 75d6094..8bbb3c9 100644 --- a/app/static/script.js +++ b/app/static/script.js @@ -20,7 +20,14 @@ function updateScoreboard(data) { const grid = document.getElementById(gridId); const hasGames = games && games.length > 0; section.classList.toggle('hidden', !hasGames); + + // Snapshot current clock state before blowing away the DOM + const clockSnapshot = snapshotClocks(grid); + grid.innerHTML = hasGames ? games.map(render).join('') : ''; + + // Restore smooth local anchors unless we're in the final 60s + if (hasGames) restoreClocks(grid, clockSnapshot); } updateGauges(); @@ -56,7 +63,7 @@ function renderLiveGame(game) { ` : ''; return ` -
+
${periodLabel} @@ -139,6 +146,8 @@ function updateGauges() { }); } +const CLOCK_SYNC_THRESHOLD = 60; // seconds — only resync from API in final 60s + // ── Clock ───────────────────────────────────────────── function timeToSeconds(str) { @@ -154,6 +163,35 @@ function secondsToTime(s) { return `${String(m).padStart(2, '0')}:${String(sec).padStart(2, '0')}`; } +function snapshotClocks(grid) { + const snapshot = new Map(); + grid.querySelectorAll('[data-game-key]').forEach(card => { + const badge = card.querySelector('[data-seconds][data-received-at]'); + if (!badge) return; + const seconds = parseInt(badge.dataset.seconds, 10); + const receivedAt = parseInt(badge.dataset.receivedAt, 10); + const elapsed = Math.floor((Date.now() - receivedAt) / 1000); + const current = Math.max(0, seconds - elapsed); + snapshot.set(card.dataset.gameKey, { current, ts: Date.now() }); + }); + return snapshot; +} + +function restoreClocks(grid, snapshot) { + grid.querySelectorAll('[data-game-key]').forEach(card => { + const prior = snapshot.get(card.dataset.gameKey); + if (!prior) return; + const badge = card.querySelector('[data-seconds][data-received-at]'); + if (!badge) return; + // Only restore if we're outside the final sync window + if (prior.current > CLOCK_SYNC_THRESHOLD) { + badge.dataset.seconds = prior.current; + badge.dataset.receivedAt = prior.ts; + badge.textContent = secondsToTime(prior.current); + } + }); +} + function tickClocks() { const now = Date.now(); document.querySelectorAll('[data-seconds][data-received-at]').forEach(el => {