From b3c1e4cc7f50039ba635ed413260cf6eda094574 Mon Sep 17 00:00:00 2001 From: mARTin-B78 Date: Sun, 31 May 2026 18:23:22 +0200 Subject: [PATCH] Fix JS caching root cause + robustness for sample text and STT dropdown Root cause: VERSION was not volume-mounted, so the server always reported 1.2.0, causing browsers to serve 1-year-immutable cached JS even after code changes. Fixes: - docker-compose.yml: add ./VERSION:/app/VERSION:ro volume mount. After `docker compose up -d`, the server reads the current VERSION file and JS is cache-busted by the correct version string. - loader.js: append session timestamp to _appVersion so every page load generates a unique JS URL. JS is always fresh regardless of whether VERSION is current, at the cost of one network round-trip per file per session (acceptable for a local tool). - s-clone.html: embed EN default text directly in the textarea so the field is never empty even before JS runs. - voice-clone.js: remove the 'skip if already filled' guard in initCloneSampleText so navigating back always resets to the language text; call refreshSttBackends on load with sttReady event fallback. - stt.js: dispatch 'sttReady' event after all STT listeners are wired. Co-Authored-By: Claude Sonnet 4.6 --- docker-compose.yml | 1 + static/js/stt.js | 2 ++ static/js/voice-clone.js | 5 ++++- static/loader.js | 3 +++ static/sections/s-clone.html | 2 +- 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 06b9e51..6389ce9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,6 +23,7 @@ services: - ./server.py:/app/server.py:ro - ./core:/app/core:ro - ./routes:/app/routes:ro + - ./VERSION:/app/VERSION:ro environment: - PYTHONUNBUFFERED=1 diff --git a/static/js/stt.js b/static/js/stt.js index edeb2b5..26fa623 100644 --- a/static/js/stt.js +++ b/static/js/stt.js @@ -286,3 +286,5 @@ $('stt-tts-save-wav-btn')?.addEventListener('click', () => { sttTtsDownload(sttTtsOutputBlob, ($('stt-tts-voice-select').value || 'stt_tts') + '_stt_tts.wav'); }); +window.dispatchEvent(new Event('sttReady')); + diff --git a/static/js/voice-clone.js b/static/js/voice-clone.js index fbfa37c..3b9be51 100644 --- a/static/js/voice-clone.js +++ b/static/js/voice-clone.js @@ -15,7 +15,7 @@ window.initCloneSampleText = function () { const sel = $('clone-sample-lang'); const txt = $('clone-sample-text'); if (!sel || !txt) return; - if (!txt.value.trim()) txt.value = CLONE_SAMPLE_TEXTS[sel.value] || CLONE_SAMPLE_TEXTS.EN; + txt.value = CLONE_SAMPLE_TEXTS[sel.value] || CLONE_SAMPLE_TEXTS.EN; if (!sel._cloneSampleBound) { sel.addEventListener('change', () => { txt.value = CLONE_SAMPLE_TEXTS[sel.value] || CLONE_SAMPLE_TEXTS.EN; @@ -903,6 +903,9 @@ $('clone-refresh-stt-btn')?.addEventListener('click', async () => { try { await refreshSttBackends($('clone-stt-backend')?.value); } finally { $('clone-refresh-stt-btn').disabled = false; } }); +// Populate STT dropdown on load (refreshSttBackends is defined in stt.js which loads after us) +if (typeof refreshSttBackends === 'function') refreshSttBackends().catch(() => {}); +else window.addEventListener('sttReady', () => refreshSttBackends().catch(() => {})); $('transcribe-btn').addEventListener('click', async () => { const id = trimmedFileId||designedFileId||currentFileId; diff --git a/static/loader.js b/static/loader.js index d3e992b..a8940fa 100644 --- a/static/loader.js +++ b/static/loader.js @@ -21,6 +21,9 @@ } catch (_) {} var _ts = Date.now(); // sections always fresh during a session + // Append session timestamp so that a version bump + container restart + // always invalidates previously cached JS, even on the same version string. + _appVersion = _appVersion + '-' + _ts; function _inject(id, html) { var el = document.getElementById(id); diff --git a/static/sections/s-clone.html b/static/sections/s-clone.html index c600fee..44eb98c 100644 --- a/static/sections/s-clone.html +++ b/static/sections/s-clone.html @@ -44,7 +44,7 @@ - +