From d4e0974881b834288b28e7b2fd8b951e5c68fad8 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Sun, 26 Jul 2026 21:55:37 +0200 Subject: [PATCH] Let JS own the live status labels instead of sharing them with data-i18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #chain-status-label and #draw-label carried a data-i18n attribute *and* were written from live state by app.js, so a language switch had both mechanisms fighting over them: applyStaticTranslations reset each to its static default and the next poll put the real value back. On the draw label that was a flicker. On the status bar it was a false statement — with the connection down, the bar went back to claiming "connecting" until a further fetch failed, up to a full poll interval later. The attribute is gone from both. The status bar is now rendered from remembered state (last payload, plus whether we're in the offline state) rather than straight from the response that triggered it, so a language switch repaints it correctly and immediately, with no fetch involved. logout() also stops wiping the chosen language: localStorage.clear() took plm_lang with it, dropping the user back to the browser-detected default on the one screen where they'd have to go find the switcher again. Co-Authored-By: Claude Opus 5 --- app/static/app.js | 36 ++++++++++++++++++++++++++++++++++-- app/static/index.html | 7 +++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/app/static/app.js b/app/static/app.js index ef788f5..9ba8b2c 100644 --- a/app/static/app.js +++ b/app/static/app.js @@ -159,11 +159,36 @@ const CHAIN_STATUS_KEYS = { paying_out: 'chain.status.paying_out', }; +// The bar is rendered from remembered state rather than straight from the +// response that triggered it, so a language switch can repaint it immediately +// instead of waiting for the next poll. That wait used to make it lie: with the +// connection down, switching language reset the label to "connecting" until a +// further fetch failed. +let lastChainData = null; +let chainOffline = false; + function updateChainStatusBar(data) { + lastChainData = data; + chainOffline = false; + renderChainStatusBar(); +} + +function renderChainStatusBar() { const dot = document.getElementById('chain-status-dot'); const label = document.getElementById('chain-status-label'); const block = document.getElementById('chain-block'); + if (chainOffline) { + dot.className = 'status-dot status-offline'; + label.textContent = t('chain.connectionLost'); + return; // block height deliberately left showing its last known value + } + if (lastChainData === null) { + label.textContent = t('chain.connecting'); + return; + } + const data = lastChainData; + // The dot's color/pulse only distinguishes waiting/open/drawing (that's all // the CSS defines) — closing and paying_out both pulse like drawing, they // just get their own text label below. @@ -189,8 +214,8 @@ const STALE_AFTER_FAILURES = 2; let consecutiveFetchFailures = 0; function showConnectionLost() { - document.getElementById('chain-status-dot').className = 'status-dot status-offline'; - document.getElementById('chain-status-label').textContent = t('chain.connectionLost'); + chainOffline = true; + renderChainStatusBar(); } function noteFetchOutcome(ok) { @@ -575,7 +600,12 @@ function resetToLoggedOutUI() { } function logout() { + // The chosen language is a device preference, not session state — clearing it + // on logout would drop the user back to the browser-detected default on the + // very screen where they'd have to find the switcher again. + const lang = localStorage.getItem(LANG_STORAGE_KEY); localStorage.clear(); + if (lang) localStorage.setItem(LANG_STORAGE_KEY, lang); resetToLoggedOutUI(); } @@ -774,6 +804,7 @@ function connectRoundEvents() { // those are built from server data + t() rather than fixed markup. function onLanguageChange() { renderBetButton(); + renderChainStatusBar(); // repaints from remembered state, without waiting for the next poll if (token) { refreshRound(); refreshMe(); @@ -787,5 +818,6 @@ function onLanguageChange() { } renderBetButton(); +renderChainStatusBar(); connectRoundEvents(); initAuthState(); diff --git a/app/static/index.html b/app/static/index.html index 2048b22..28a55e1 100644 --- a/app/static/index.html +++ b/app/static/index.html @@ -59,7 +59,10 @@
- Connecting… + + Connecting… @@ -157,7 +160,7 @@
-
Estrazione del vincitore in corso…
+
Drawing the winner…