import { useCallback, useMemo, useRef, useState } from "react";
import Heading from "@/components/ui/heading";
import ActivityScrubber, {
ScrubberItem,
} from "@/components/scrubber/ActivityScrubber";
import useSWR from "swr";
import { FrigateConfig } from "@/types/frigateConfig";
import { Event } from "@/types/event";
import ActivityIndicator from "@/components/ui/activity-indicator";
import { useApiHost } from "@/api";
import TimelineScrubber from "@/components/playground/TimelineScrubber";
import EventReviewTimeline from "@/components/timeline/EventReviewTimeline";
import { ReviewData, ReviewSegment, ReviewSeverity } from "@/types/review";
// Color data
const colors = [
"background",
"foreground",
"card",
"card-foreground",
"popover",
"popover-foreground",
"primary",
"primary-foreground",
"secondary",
"secondary-foreground",
"muted",
"muted-foreground",
"accent",
"accent-foreground",
"destructive",
"destructive-foreground",
"border",
"input",
"ring",
];
function ColorSwatch({ name, value }: { name: string; value: string }) {
return (
);
}
function eventsToScrubberItems(events: Event[]): ScrubberItem[] {
const apiHost = useApiHost();
return events.map((event: Event) => ({
id: event.id,
content: `${event.label} `,
start: new Date(event.start_time * 1000),
end: event.end_time ? new Date(event.end_time * 1000) : undefined,
type: "box",
}));
}
const generateRandomEvent = (): ReviewSegment => {
const start_time = Math.floor(Date.now() / 1000) - Math.random() * 60 * 60;
const end_time = Math.floor(start_time + Math.random() * 60 * 10);
const severities: ReviewSeverity[] = [
"significant_motion",
"detection",
"alert",
];
const severity = severities[Math.floor(Math.random() * severities.length)];
const has_been_reviewed = Math.random() < 0.2;
const id = new Date(start_time * 1000).toISOString(); // Date string as mock ID
// You need to provide values for camera, thumb_path, and data
const camera = "CameraXYZ";
const thumb_path = "/path/to/thumb";
const data: ReviewData = {
audio: [],
detections: [],
objects: [],
significant_motion_areas: [],
zones: [],
};
return {
id,
start_time,
end_time,
severity,
has_been_reviewed,
camera,
thumb_path,
data,
};
};
function UIPlayground() {
const { data: config } = useSWR("config");
const [timeline, setTimeline] = useState(undefined);
const contentRef = useRef(null);
const [mockEvents, setMockEvents] = useState([]);
const [handlebarTime, setHandlebarTime] = useState(
Math.floor(Date.now() / 1000) - 27 * 60
);
const onSelect = useCallback(({ items }: { items: string[] }) => {
setTimeline(items[0]);
}, []);
const recentTimestamp = useMemo(() => {
const now = new Date();
now.setMinutes(now.getMinutes() - 240);
return now.getTime() / 1000;
}, []);
const { data: events } = useSWR([
"events",
{ limit: 10, after: recentTimestamp },
]);
useMemo(() => {
const initialEvents = Array.from({ length: 50 }, generateRandomEvent);
setMockEvents(initialEvents);
}, []);
return (
<>
UI Playground
Scrubber
Shows the 10 most recent events within the last 4 hours
{!config && }
{config && (
{events && events.length > 0 && (
<>
>
)}
)}
{config && (
{timeline && (
<>
>
)}
)}
Handlebar time
{handlebarTime}
Color scheme
Colors as set by the current theme. See the{" "}
shadcn theming docs
{" "}
for usage.
{colors.map((color, index) => (
))}
>
);
}
export default UIPlayground;