import { h } from 'preact'; import { useState, useMemo } from 'preact/hooks'; import { getUnixTime, fromUnixTime, format, parseISO, intervalToDuration, formatDuration, endOfDay, startOfDay, isSameDay, } from 'date-fns'; import ArrowDropdown from '../icons/ArrowDropdown'; import ArrowDropup from '../icons/ArrowDropup'; import Link from '../components/Link'; import ActivityIndicator from '../components/ActivityIndicator'; import Menu from '../icons/Menu'; import MenuOpen from '../icons/MenuOpen'; import { useApiHost } from '../api'; import useSWR from 'swr'; export default function RecordingPlaylist({ camera, recordings, selectedDate }) { const [active, setActive] = useState(true); const toggle = () => setActive(!active); const result = []; for (const recording of recordings) { const date = parseISO(recording.day); result.push( ); } const openClass = active ? '-left-6' : 'right-0'; return (
{active ? : }
{result}
); } export function DayOfEvents({ camera, day, hours }) { const date = parseISO(day); const { data: events } = useSWR([ `events`, { before: getUnixTime(endOfDay(date)), after: getUnixTime(startOfDay(date)), camera, has_clip: '1', include_thumbnails: 0, limit: 5000, }, ]); // maps all the events under the keys for the hour by hour recordings view const eventMap = useMemo(() => { const eventMap = {}; for (const hour of hours) { eventMap[`${day}-${hour.hour}`] = []; } if (!events) { return eventMap; } for (const event of events) { const key = format(fromUnixTime(event.start_time), 'yyyy-MM-dd-HH'); // if the hour of recordings is missing for the event start time, skip it if (key in eventMap) { eventMap[key].push(event); } } return eventMap; }, [events, day, hours]); if (!events) { return ; } return ( <> {hours.map((hour, i) => (
{hour.hour}:00
{hour.events} Events
{eventMap[`${day}-${hour.hour}`].map((event) => ( ))}
))} ); } export function ExpandableList({ title, events = 0, children, selected = false }) { const [active, setActive] = useState(selected); const toggle = () => setActive(!active); return (
{title}
{events} Events
{active ? : }
{/* Only render the child when expanded to lazy load events for the day */} {active &&
{children}
}
); } export function EventCard({ camera, event }) { const apiHost = useApiHost(); const start = fromUnixTime(event.start_time); const end = fromUnixTime(event.end_time); let duration = 'In Progress'; if (event.end_time) { duration = formatDuration(intervalToDuration({ start, end })); } return (
{event.label}
Start: {format(start, 'HH:mm:ss')}
Duration: {duration}
{(event.top_score * 100).toFixed(1)}%
); }