// Header components: Clock and Backend Status Indicator "use strict"; // ========================================================================= // Global Variables // ========================================================================= var clockInterval = null; var statusUpdateCallback = null; // ========================================================================= // Clock // ========================================================================= function initClock() { function updateClock() { var now = new Date(); var hours = String(now.getHours()).padStart(2, '0'); var minutes = String(now.getMinutes()).padStart(2, '0'); var seconds = String(now.getSeconds()).padStart(2, '0'); var timeString = hours + ':' + minutes + ':' + seconds; var clockElement = document.getElementById('clockTime'); if (clockElement) { clockElement.textContent = timeString; } } updateClock(); if (clockInterval) { clearInterval(clockInterval); } clockInterval = setInterval(updateClock, 1000); } // ========================================================================= // Status Indicator // ========================================================================= function initStatusIndicator() { updateStatusIndicator('connecting', 'Connecting...'); function registerStatusCallback() { if (typeof wsManager !== 'undefined' && wsManager) { wsManager.onStatusChange(function(state, text) { updateStatusIndicator(state, text); }); var currentState = wsManager.getConnectionState(); var currentText = 'Connecting...'; if (currentState === 'connected' && wsManager.isConnected) { currentText = 'Connected'; } else if (currentState === 'connecting') { currentText = 'Connecting...'; } else if (currentState === 'disconnected') { currentText = 'Disconnected'; } else if (currentState === 'disconnecting') { currentText = 'Disconnecting...'; } updateStatusIndicator(currentState, currentText); return true; } return false; } if (!registerStatusCallback()) { var checkInterval = setInterval(function() { if (registerStatusCallback()) { clearInterval(checkInterval); } }, 100); setTimeout(function() { clearInterval(checkInterval); }, 5000); } } function updateStatusIndicator(state, text) { var statusDot = document.getElementById('statusDot'); var statusText = document.getElementById('statusText'); if (!statusDot || !statusText) { return; } statusDot.classList.remove('bg-green-500', 'bg-yellow-500', 'bg-red-500', 'bg-gray-400'); switch (state) { case 'connected': statusDot.classList.add('bg-green-500'); statusText.textContent = text || 'Connected'; break; case 'connecting': case 'reconnecting': statusDot.classList.add('bg-yellow-500'); statusText.textContent = text || 'Connecting...'; break; case 'disconnected': case 'error': statusDot.classList.add('bg-red-500'); statusText.textContent = text || 'Disconnected'; break; default: statusDot.classList.add('bg-gray-400'); statusText.textContent = text || 'Unknown'; } } // ========================================================================= // WebSocket Tooltip // ========================================================================= function createWebSocketTooltip() { const tooltip = document.createElement('div'); tooltip.id = 'wsTooltip'; tooltip.className = 'fixed z-50 px-3 py-2 bg-gray-900 text-white text-xs rounded shadow-lg pointer-events-none opacity-0 transition-opacity duration-200'; tooltip.style.display = 'none'; tooltip.style.minWidth = '200px'; document.body.appendChild(tooltip); const statusEl = document.getElementById('backendStatus'); if (!statusEl) { return; } let tooltipUpdateInterval = null; function updateTooltipContent() { if (!wsManager || !wsManager.isConnected) { return; } const info = wsManager.getConnectionInfo(); if (!info) { return; } tooltip.innerHTML = `