// Room Camera Panel // Purpose: Defines the Room Camera Panel module and the local helpers/components used in this file. // Scope: Keeps behavior unchanged while isolating this concern into a clear, single-responsibility unit. import { useEffect, useState } from 'react'; import { useSessionSelector } from '../../context/SessionContext.jsx'; import { useSettingsNamespace } from '../../settings/index.js'; import { useRoomCameraSnapshots } from '../../hooks/useRoomCameraSnapshots.js'; import RoomCameraFeed from '../RoomCameraFeed/index.jsx'; import CardFrame from '../CardFrame/index.jsx'; function EmptyState() { return (

No room cameras configured.

Add entries to server config to populate this list.

); } const ORIENTATIONS = ['horizontal', 'vertical']; function normalizeOrientation(value, fallback) { if (ORIENTATIONS.includes(value)) { return value; } return fallback; } export default function RoomCameraPanel({ defaultOrientation = 'horizontal', orientation: forcedOrientation, hideLayoutToggle = false, hideHeader = false, panelId = null, }) { const cameras = useSessionSelector((state) => state.session?.roomCameras || []); const feedMap = useRoomCameraSnapshots(cameras.map((camera) => ({ id: camera.id }))); const { value: orientationSettings, save: saveOrientationSettings } = useSettingsNamespace('roomCameraPanels', {}); const [orientation, setOrientation] = useState(() => normalizeOrientation( panelId ? orientationSettings?.[panelId] : defaultOrientation, 'horizontal', ), ); useEffect(() => { if (!panelId) return; const stored = orientationSettings?.[panelId]; if (!stored) return; setOrientation(normalizeOrientation(stored, 'horizontal')); // only respond to changes for this panel id }, [panelId, orientationSettings?.[panelId]]); const effectiveOrientation = forcedOrientation ? normalizeOrientation(forcedOrientation, 'horizontal') : orientation; const containerClass = effectiveOrientation === 'vertical' ? 'flex flex-col gap-0.5' : 'grid gap-0.5 md:grid-cols-2'; const showLayoutToggle = !hideLayoutToggle && !forcedOrientation && cameras.length > 0; const applyOrientation = (next) => { setOrientation(next); if (panelId) { saveOrientationSettings((current) => ({ ...(current || {}), [panelId]: next })); } }; if (cameras.length === 0) { return ; } const actions = showLayoutToggle ? (
Layout
{ORIENTATIONS.map((option) => ( ))}
) : null; return (
{cameras.map((camera) => { const feed = feedMap[camera.id] || null; return (
{/*

{camera.name || camera.id}

{camera.description &&

{camera.description}

}
*/}
); })}
); }