(function () { function updateSidebarStatus(status, label) { var dot = document.getElementById('sidebar-status-dot'); var text = document.getElementById('sidebar-status-text'); var pill = document.getElementById('sidebar-status-pill'); if (!dot && !text && !pill) { return; } var normalizedStatus = status === 'online' || status === 'offline' || status === 'unknown' ? status : (status ? 'online' : 'offline'); var statusLabel = normalizedStatus === 'online' ? (label || 'Connected to player feed') : normalizedStatus === 'offline' ? 'Disconnected from player feed' : (label || 'Connecting to player feed'); var pillLabel = normalizedStatus === 'online' ? 'Connected' : normalizedStatus === 'offline' ? 'Disconnected' : 'Connecting'; dot.classList.remove('status-dot--unknown', 'status-dot--online', 'status-dot--offline'); dot.classList.add(normalizedStatus === 'online' ? 'status-dot--online' : normalizedStatus === 'offline' ? 'status-dot--offline' : 'status-dot--unknown'); dot.setAttribute('aria-label', statusLabel); dot.setAttribute('title', statusLabel); if (text) { text.textContent = statusLabel; } if (pill) { pill.classList.remove('status-pill--unknown', 'status-pill--online', 'status-pill--offline'); pill.classList.add(normalizedStatus === 'online' ? 'status-pill--online' : normalizedStatus === 'offline' ? 'status-pill--offline' : 'status-pill--unknown'); pill.textContent = pillLabel; } } function connectDashboardSocket() { if (!window.WebSocket) { return; } var hasStatusIndicators = document.getElementById('sidebar-status-dot') || document.getElementById('sidebar-status-text') || document.getElementById('sidebar-status-pill'); if (!hasStatusIndicators) { return; } var socket = null; var reconnectTimer = null; function scheduleReconnect() { if (reconnectTimer) { return; } reconnectTimer = window.setTimeout(function () { reconnectTimer = null; connect(); }, 5000); } function connect() { var protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; socket = new WebSocket(protocol + '//' + window.location.host + '/ws/dashboard'); updateSidebarStatus('unknown', 'Connecting to player feed'); socket.onmessage = function (event) { try { var payload = JSON.parse(String(event.data || '{}')); if (payload && payload.type === 'dashboard-state') { if (typeof window.webHandleDashboardState === 'function') { window.webHandleDashboardState(payload.state); } updateSidebarStatus(Boolean(payload.state && payload.state.playerServiceConnected), 'Live player feed'); } } catch (_error) { // Ignore malformed dashboard payloads. } }; socket.onclose = function () { updateSidebarStatus('offline'); scheduleReconnect(); }; socket.onerror = function () { updateSidebarStatus('offline'); try { socket.close(); } catch (_error) { // ignore close errors } }; socket.onopen = function () { updateSidebarStatus('unknown', 'Connecting to player feed'); }; } connect(); } connectDashboardSocket(); }());