mirror of
https://github.com/alexhopeoconnor/frigate.git
synced 2026-10-18 09:21:44 +10:00
* Add ui for events * Display data for review items * Use preview thumbnails * Implement paging * Show icons for what was detected * Show progress bar on preview thumbnail * Hide the overlays on hover and update reviewed status * Dim previews that have been reviewed * Show audio icons * Cleanup preview thumb player * initial implementation of review timeline * Use timeout for hover playback * Break apart mobile and desktop views * Show icons for sub labels * autoplay first video on mobile * Only show the last 24 hours by default * Rework scrolling to fix nested scrolling * Final scroll cleanups --------- Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
88 lines
2.5 KiB
TypeScript
88 lines
2.5 KiB
TypeScript
import useSWR from "swr";
|
|
import { Card } from "../ui/card";
|
|
import { FrigateConfig } from "@/types/frigateConfig";
|
|
import ActivityIndicator from "../ui/activity-indicator";
|
|
import { LuClock, LuTrash } from "react-icons/lu";
|
|
import { HiOutlineVideoCamera } from "react-icons/hi";
|
|
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
|
import {
|
|
getTimelineIcon,
|
|
getTimelineItemDescription,
|
|
} from "@/utils/timelineUtil";
|
|
import { Button } from "../ui/button";
|
|
|
|
type HistoryCardProps = {
|
|
timeline: Card;
|
|
relevantPreview?: Preview;
|
|
isMobile: boolean;
|
|
onClick?: () => void;
|
|
onDelete?: () => void;
|
|
};
|
|
|
|
export default function HistoryCard({
|
|
// @ts-ignore
|
|
relevantPreview,
|
|
timeline,
|
|
// @ts-ignore
|
|
isMobile,
|
|
onClick,
|
|
onDelete,
|
|
}: HistoryCardProps) {
|
|
const { data: config } = useSWR<FrigateConfig>("config");
|
|
|
|
if (!config) {
|
|
return <ActivityIndicator />;
|
|
}
|
|
|
|
return (
|
|
<Card
|
|
className="cursor-pointer my-2 xs:mr-2 w-full xs:w-[48%] sm:w-[284px]"
|
|
onClick={onClick}
|
|
>
|
|
<>
|
|
<div className="text-sm flex justify-between items-center">
|
|
<div className="pl-1 pt-1">
|
|
<LuClock className="h-5 w-5 mr-2 inline" />
|
|
{formatUnixTimestampToDateTime(timeline.time, {
|
|
strftime_fmt:
|
|
config.ui.time_format == "24hour" ? "%H:%M:%S" : "%I:%M:%S %p",
|
|
time_style: "medium",
|
|
date_style: "medium",
|
|
})}
|
|
</div>
|
|
<Button className="px-2 py-2" variant="ghost" size="xs">
|
|
<LuTrash
|
|
className="w-5 h-5 stroke-danger"
|
|
onClick={(e: Event) => {
|
|
e.stopPropagation();
|
|
|
|
if (onDelete) {
|
|
onDelete();
|
|
}
|
|
}}
|
|
/>
|
|
</Button>
|
|
</div>
|
|
<div className="pl-1 capitalize text-sm flex items-center mt-1">
|
|
<HiOutlineVideoCamera className="h-5 w-5 mr-2 inline" />
|
|
{timeline.camera.replaceAll("_", " ")}
|
|
</div>
|
|
<div className="pl-1 my-2">
|
|
<div className="text-sm font-medium">Activity:</div>
|
|
{Object.entries(timeline.entries).map(([_, entry], idx) => {
|
|
return (
|
|
<div
|
|
key={idx}
|
|
className="flex text-xs capitalize my-1 items-center"
|
|
>
|
|
{getTimelineIcon(entry)}
|
|
{getTimelineItemDescription(entry)}
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</>
|
|
</Card>
|
|
);
|
|
}
|