From 5fdb9bc29f5f68410671313d7ffa4c3b26665d4a Mon Sep 17 00:00:00 2001 From: "bahawal.baloch" Date: Wed, 1 Apr 2026 12:51:44 +0500 Subject: [PATCH] Add camera selection feature to dashboard - Introduced a dropdown for selecting cameras in the dashboard. - Implemented functions to load available cameras and handle camera selection. - Updated polling logic to reflect the currently selected camera. - Enhanced styling for the camera selection dropdown. --- templates/dashboard.html | 51 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/templates/dashboard.html b/templates/dashboard.html index 6311a6b..0e3bdea 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -78,6 +78,15 @@ @keyframes pulse { 0%,100%{ opacity:1 } 50%{ opacity:.35 } } .clock { font-size: .85rem; color: var(--text-dim); font-variant-numeric: tabular-nums; } + .camera-select { + background: var(--surface-2); + color: var(--text); + border: 1px solid var(--border); + border-radius: 8px; + padding: 6px 10px; + font-size: .85rem; + min-width: 170px; + } /* -------- Layout -------- */ .container { @@ -292,6 +301,7 @@ Surveillance Dashboard
+
Connecting @@ -368,6 +378,33 @@ updateClock(); let prevAlertActive = false; let bannerTimeout = null; +let camerasLoaded = false; + +async function loadCameras() { + try { + const res = await fetch('/api/cameras'); + const data = await res.json(); + const select = document.getElementById('cameraSelect'); + select.innerHTML = data.cameras + .map(c => ``) + .join(''); + camerasLoaded = true; + } catch (e) { + console.error('Failed to load cameras', e); + } +} + +async function selectCamera(cameraId) { + try { + await fetch('/api/camera/select', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ camera_id: cameraId }) + }); + } catch (e) { + console.error('Failed to switch camera', e); + } +} async function poll() { try { @@ -387,6 +424,16 @@ async function poll() { badge.className = 'status-badge ' + d.stream_status; stext.textContent = d.stream_status === 'live' ? 'Live' : d.stream_status === 'error' ? 'Error' : 'Connecting'; + if (d.active_camera_name) { + stext.textContent = `${stext.textContent} - ${d.active_camera_name}`; + } + + if (camerasLoaded) { + const cameraSelect = document.getElementById('cameraSelect'); + if (cameraSelect.value !== d.selected_camera_id) { + cameraSelect.value = d.selected_camera_id; + } + } // Alert KPI glow const kpiAlerts = document.getElementById('kpiAlerts'); @@ -446,6 +493,10 @@ function openLightbox(src) { } setInterval(poll, 1000); +document.getElementById('cameraSelect').addEventListener('change', (e) => { + selectCamera(e.target.value); +}); +loadCameras().then(poll); poll();