initial implementation of review timeline

This commit is contained in:
Josh Hawkins 2024-02-19 22:53:39 -06:00
parent fa384a7f9d
commit 81397c79a5
2 changed files with 72 additions and 18 deletions

View File

@ -27,3 +27,14 @@
font-family: "Inter"; font-family: "Inter";
src: url("../fonts/Inter-VariableFont_slnt,wght.ttf"); src: url("../fonts/Inter-VariableFont_slnt,wght.ttf");
} }
/* Hide scrollbar for Chrome, Safari and Opera */
.no-scrollbar::-webkit-scrollbar {
display: none;
}
/* Hide scrollbar for IE, Edge and Firefox */
.no-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}

View File

@ -1,4 +1,4 @@
import { useCallback, useMemo, useState } from "react"; import { useCallback, useMemo, useRef, useState } from "react";
import Heading from "@/components/ui/heading"; import Heading from "@/components/ui/heading";
import ActivityScrubber, { import ActivityScrubber, {
ScrubberItem, ScrubberItem,
@ -9,6 +9,7 @@ import { Event } from "@/types/event";
import ActivityIndicator from "@/components/ui/activity-indicator"; import ActivityIndicator from "@/components/ui/activity-indicator";
import { useApiHost } from "@/api"; import { useApiHost } from "@/api";
import TimelineScrubber from "@/components/playground/TimelineScrubber"; import TimelineScrubber from "@/components/playground/TimelineScrubber";
import { ReviewTimeline } from "@/components/timeline/ReviewTimeline";
// Color data // Color data
const colors = [ const colors = [
@ -57,9 +58,21 @@ function eventsToScrubberItems(events: Event[]): ScrubberItem[] {
})); }));
} }
const generateRandomEvent = (): Event => {
const start_time = Date.now() - Math.random() * 3600000 * 3;
const end_time = start_time + Math.random() * 36000;
const severities = ["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).toISOString(); // Date string as mock ID
return { id, start_time, end_time, severity, has_been_reviewed };
};
function UIPlayground() { function UIPlayground() {
const { data: config } = useSWR<FrigateConfig>("config"); const { data: config } = useSWR<FrigateConfig>("config");
const [timeline, setTimeline] = useState<string | undefined>(undefined); const [timeline, setTimeline] = useState<string | undefined>(undefined);
const contentRef = useRef<HTMLDivElement>(null);
const [mockEvents, setMockEvents] = useState<Event[]>([]);
const onSelect = useCallback(({ items }: { items: string[] }) => { const onSelect = useCallback(({ items }: { items: string[] }) => {
setTimeline(items[0]); setTimeline(items[0]);
@ -75,6 +88,11 @@ function UIPlayground() {
{ limit: 10, after: recentTimestamp }, { limit: 10, after: recentTimestamp },
]); ]);
useMemo(() => {
const initialEvents = Array.from({ length: 50 }, generateRandomEvent);
setMockEvents(initialEvents);
}, []);
return ( return (
<> <>
<Heading as="h2">UI Playground</Heading> <Heading as="h2">UI Playground</Heading>
@ -111,12 +129,18 @@ function UIPlayground() {
</div> </div>
)} )}
<div className="flex">
<div className="flex-grow">
<div ref={contentRef}>
<Heading as="h4" className="my-5"> <Heading as="h4" className="my-5">
Color scheme Color scheme
</Heading> </Heading>
<p className="text-small"> <p className="text-small">
Colors as set by the current theme. See the{" "} Colors as set by the current theme. See the{" "}
<a className="underline" href="https://ui.shadcn.com/docs/theming"> <a
className="underline"
href="https://ui.shadcn.com/docs/theming"
>
shadcn theming docs shadcn theming docs
</a>{" "} </a>{" "}
for usage. for usage.
@ -131,6 +155,25 @@ function UIPlayground() {
/> />
))} ))}
</div> </div>
</div>
</div>
<div className="flex-none">
<ReviewTimeline
segmentDuration={60}
timestampSpread={15}
timelineStart={Date.now()}
timelineDuration={24 * 60 * 60}
showHandlebar
handlebarTime={Date.now() - 27 * 60 * 1000}
showMinimap
minimapStartTime={Date.now() - 35 * 60 * 1000}
minimapEndTime={Date.now() - 21 * 60 * 1000}
events={mockEvents}
severityType={"alert"}
contentRef={contentRef}
/>
</div>
</div>
</> </>
); );
} }