No cameras linked yet
Viewing
${Array.from(connectedPeers).includes(link.cameraDeviceId) ? 'Live Stream Active' : (requestedStreams.has(link.cameraDeviceId) ? 'Connecting...' : 'Click to view')}
${escapedCameraName}
${cameraStatus}
No recordings found
No notifications yet
${msg}
`; list.prepend(item); // Also update camera logs if applicable if ($('cameraLogs')) { const logLine = document.createElement('div'); logLine.textContent = `[${new Date().toLocaleTimeString()}] ${type}: ${msg}`; $('cameraLogs').prepend(logLine); } }; const updateNotificationDot = (show) => { const dot = $('notificationDot'); if (show) dot.classList.remove('hidden'); else dot.classList.add('hidden'); }; // --- 6. Event Listeners --- $('toggleAuthModeBtn').addEventListener('click', Actions.toggleAuthMode); $('signInBtn').addEventListener('click', Actions.submitAuth); $('registerBtn').addEventListener('click', Actions.registerDevice); $('loadSavedBtn').addEventListener('click', () => { /* Handle legacy loading if needed */ }); $$('#screen-onboarding [data-role]').forEach((btn) => { btn.addEventListener('click', () => Actions.selectRole(btn.dataset.role)); }); $('recordingsList').addEventListener('click', (event) => { const target = event.target.closest('.download-recording-btn'); if (!target || target.disabled) return; const recordingId = target.dataset.recordingId; if (!recordingId) return; Actions.openRecording(recordingId); }); $('activityFeedList').addEventListener('click', (event) => { const target = event.target.closest('.motion-notification-btn'); if (!target) return; const notificationId = target.dataset.notificationId; const cameraDeviceId = target.dataset.cameraDeviceId; if (!notificationId || !cameraDeviceId) return; Actions.openMotionNotificationTarget(notificationId, cameraDeviceId); }); $('linkedCamerasList')?.addEventListener('click', (event) => { const menuToggleBtn = event.target.closest('.linked-camera-menu-toggle'); if (menuToggleBtn) { event.stopPropagation(); const linkId = menuToggleBtn.dataset.linkId; if (!linkId) return; const { openLinkedCameraMenuId } = store.get(); store.update({ openLinkedCameraMenuId: openLinkedCameraMenuId === linkId ? null : linkId, }); return; } const renameBtn = event.target.closest('.linked-camera-rename-btn'); if (renameBtn) { event.stopPropagation(); const cameraId = renameBtn.dataset.cameraId; if (cameraId) { store.update({ openLinkedCameraMenuId: null }); void Actions.renameLinkedCamera(cameraId); } return; } const deleteBtn = event.target.closest('.linked-camera-delete-btn'); if (deleteBtn) { event.stopPropagation(); const linkId = deleteBtn.dataset.linkId; if (linkId) { store.update({ openLinkedCameraMenuId: null }); void Actions.deleteLinkedCamera(linkId); } return; } const card = event.target.closest('.camera-card'); if (!card) return; const camId = card.dataset.cameraId; if (camId) { const sessions = store.get().cameraSessions || {}; store.update({ activeCameraDeviceId: camId, activeStreamSessionId: sessions[camId] || null, openLinkedCameraMenuId: null, }); // If not currently streamed or requested, kick off request if (!requestedStreams.has(camId)) { requestedStreams.add(camId); Actions.requestStream(camId); } else { // Just re-render store.notify(); } } }); document.addEventListener('click', (event) => { if (!event.target.closest('.linked-camera-menu')) { const { openLinkedCameraMenuId } = store.get(); if (openLinkedCameraMenuId) { store.update({ openLinkedCameraMenuId: null }); } } }); // Navbar $$('.nav-btn').forEach(btn => { btn.addEventListener('click', () => { if (btn.dataset.target === 'activity') { markAllNotificationsRead(); } store.update({ screen: btn.dataset.target }); }); }); // Camera Controls $('cameraGoOnlineBtn').addEventListener('click', async () => { if (store.get().device?.role === 'camera') { await startCameraPreview(); } connectSocket(); }); $('startMotionBtn').addEventListener('click', Actions.startMotion); $('endMotionBtn').addEventListener('click', Actions.endMotion); // Client Controls $('linkCameraBtn').addEventListener('click', Actions.linkCamera); $('refreshClientBtn').addEventListener('click', startPolling); // Settings $('signOutBtn').addEventListener('click', Actions.signOut); $('clearActivityBtn').addEventListener('click', () => { store.update({ motionNotifications: [] }); }); $('recordingModalCloseBtn').addEventListener('click', Actions.closeRecordingModal); $('recordingModal').addEventListener('click', (event) => { if (event.target === $('recordingModal')) { Actions.closeRecordingModal(); } }); $('closeStreamViewerBtn')?.addEventListener('click', () => { store.update({ activeCameraDeviceId: null, activeStreamSessionId: null }); }); // Init store.subscribe(render); init(); window.addEventListener('beforeunload', () => { stopFrameRelay(); void stopLocalRecording(); teardownPeerConnection(); stopCameraPreview(); }); window.Actions = Actions;