Files
radio-explorer/web/shared/ws.js
Marco Mooren b86dcfbb8d Add master display UI with audio output management and styling
- Implement main.js for the master display functionality, including WebSocket connection, audio output management, and state handling.
- Create style.css for the master display's visual design, ensuring a cohesive look and feel with a dark theme and responsive layout.
- Integrate device management with a fallback for non-Electron environments, allowing users to select audio outputs.
- Add features for managing favorites, including toggling favorites and filtering by genre.
- Enhance user experience with a responsive favorites grid and drag-to-scroll functionality.
2026-05-11 17:55:09 +02:00

29 lines
1.1 KiB
JavaScript

export function connectWs(onMessage, opts = {}) {
let ws, retry = 0, closed = false;
function open() {
const proto = location.protocol === 'https:' ? 'wss' : 'ws';
const params = new URLSearchParams();
if (opts.room) params.set('room', opts.room);
if (opts.kind) params.set('kind', opts.kind);
const qs = params.toString();
ws = new WebSocket(`${proto}://${location.host}/ws${qs ? '?' + qs : ''}`);
ws.addEventListener('open', () => { retry = 0; opts.onOpen?.(); });
ws.addEventListener('message', (ev) => {
try { onMessage(JSON.parse(ev.data)); } catch { }
});
ws.addEventListener('close', () => {
opts.onClose?.();
if (closed) return;
retry = Math.min(retry + 1, 6);
setTimeout(open, 500 * 2 ** retry);
});
ws.addEventListener('error', () => ws.close());
}
open();
return {
send(msg) { if (ws?.readyState === WebSocket.OPEN) ws.send(JSON.stringify(msg)); },
close() { closed = true; ws?.close(); },
get readyState() { return ws?.readyState; }
};
}