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>
Neutralino.init() establishes an internal WebSocket asynchronously.
Calling storage.getData() before the "ready" event fires could stall
silently, meaning init() never reached connect(). Also, "ready" can
fire before DOMContentLoaded, so DOM refs would be null.
Fix: wait for both "ready" AND DOMContentLoaded before calling init(),
guaranteeing native APIs and DOM are both available.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Lightweight alternative to the Electron build (~5MB vs ~300MB).
Uses system webview (WebKit2GTK on Linux, WKWebView on macOS,
WebView2 on Windows). Same UI and feature set as the Electron build:
WebSocket audio client, volume control, host/port settings, tray icon,
hide-to-tray on close, CLI args (--host, --port, --volume).
Note: Linux requires libwebkit2gtk-4.0 or libwebkit2gtk-4.1.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>