diff --git a/www/app.js b/www/app.js index 93d71e5..811fe32 100644 --- a/www/app.js +++ b/www/app.js @@ -11,6 +11,7 @@ const STORAGE_KEY = 'kokoro-config'; // --------------------------------------------------------------------------- let config = { ...CONFIG_DEFAULTS }; let ws = null; +let everConnected = false; // true after first successful onopen let reconnectTimer = null; const audioQueue = []; const AUDIO_QUEUE_MAX = 25; @@ -138,13 +139,19 @@ function connect() { } clearReconnectTimer(); - setStatus('connecting', 'Connecting...'); + // Only show "Connecting..." on the very first attempt. + // Once we've ever connected, preserve "Disconnected — retrying..." until + // onopen fires so there's no flicker during the reconnect loop. + if (!everConnected) { + setStatus('connecting', 'Connecting...'); + } try { ws = new WebSocket(getWsUrl()); ws.binaryType = 'arraybuffer'; ws.onopen = () => { + everConnected = true; setStatus('connected', 'Connected — waiting for audio'); }; @@ -171,16 +178,17 @@ function connect() { }; ws.onclose = () => { - const hadError = ws && ws._hadError; ws = null; - setStatus(hadError ? 'error' : 'connecting', - hadError ? 'Disconnected — retrying...' : 'Reconnecting...'); + if (everConnected) { + setStatus('error', 'Disconnected — retrying...'); + } else { + setStatus('connecting', 'Connecting...'); + } scheduleReconnect(); }; ws.onerror = () => { if (ws) ws._hadError = true; - setStatus('error', 'Connection error'); }; } catch (e) { console.error('WebSocket connection failed:', e); @@ -312,6 +320,8 @@ async function init() { saveBtn.classList.remove('saved'); }, 1500); + // Treat as fresh connection to the new server + everConnected = false; connect(); });