Fix status flicker during WebSocket reconnect loop
connect() was unconditionally calling setStatus('connecting', ...) at the
top of each attempt, causing a visible flicker over "Disconnected —
retrying..." every 3 seconds during the retry loop.
Fix: add everConnected flag (was missing from Neutralino version);
connect() only shows "Connecting..." on the first attempt. onclose now
uses everConnected instead of _hadError to determine state. onerror no
longer sets its own status — onclose is the sole status updater on
disconnect, eliminating a second flicker source. everConnected is reset
on Save so pointing at a new server shows "Connecting..." cleanly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
20
www/app.js
20
www/app.js
@@ -11,6 +11,7 @@ const STORAGE_KEY = 'kokoro-config';
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
let config = { ...CONFIG_DEFAULTS };
|
let config = { ...CONFIG_DEFAULTS };
|
||||||
let ws = null;
|
let ws = null;
|
||||||
|
let everConnected = false; // true after first successful onopen
|
||||||
let reconnectTimer = null;
|
let reconnectTimer = null;
|
||||||
const audioQueue = [];
|
const audioQueue = [];
|
||||||
const AUDIO_QUEUE_MAX = 25;
|
const AUDIO_QUEUE_MAX = 25;
|
||||||
@@ -138,13 +139,19 @@ function connect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearReconnectTimer();
|
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 {
|
try {
|
||||||
ws = new WebSocket(getWsUrl());
|
ws = new WebSocket(getWsUrl());
|
||||||
ws.binaryType = 'arraybuffer';
|
ws.binaryType = 'arraybuffer';
|
||||||
|
|
||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
|
everConnected = true;
|
||||||
setStatus('connected', 'Connected — waiting for audio');
|
setStatus('connected', 'Connected — waiting for audio');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -171,16 +178,17 @@ function connect() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ws.onclose = () => {
|
ws.onclose = () => {
|
||||||
const hadError = ws && ws._hadError;
|
|
||||||
ws = null;
|
ws = null;
|
||||||
setStatus(hadError ? 'error' : 'connecting',
|
if (everConnected) {
|
||||||
hadError ? 'Disconnected — retrying...' : 'Reconnecting...');
|
setStatus('error', 'Disconnected — retrying...');
|
||||||
|
} else {
|
||||||
|
setStatus('connecting', 'Connecting...');
|
||||||
|
}
|
||||||
scheduleReconnect();
|
scheduleReconnect();
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onerror = () => {
|
ws.onerror = () => {
|
||||||
if (ws) ws._hadError = true;
|
if (ws) ws._hadError = true;
|
||||||
setStatus('error', 'Connection error');
|
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('WebSocket connection failed:', e);
|
console.error('WebSocket connection failed:', e);
|
||||||
@@ -312,6 +320,8 @@ async function init() {
|
|||||||
saveBtn.classList.remove('saved');
|
saveBtn.classList.remove('saved');
|
||||||
}, 1500);
|
}, 1500);
|
||||||
|
|
||||||
|
// Treat as fresh connection to the new server
|
||||||
|
everConnected = false;
|
||||||
connect();
|
connect();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user