frigate/web-new/src/components/card/HistoryCard.tsx

114 lines
4.4 KiB
TypeScript
Raw Normal View History

2023-12-05 16:04:22 +03:00
import useSWR from "swr";
2023-12-08 17:02:14 +03:00
import PreviewThumbnailPlayer from "../player/PreviewThumbnailPlayer";
2023-12-05 16:04:22 +03:00
import { Card } from "../ui/card";
import { FrigateConfig } from "@/types/frigateConfig";
import ActivityIndicator from "../ui/activity-indicator";
import { LuCircle, LuClock, LuPlay, LuPlayCircle, LuTruck } from "react-icons/lu";
import { IoMdExit } from "react-icons/io"
import { MdFaceUnlock, MdOutlineLocationOn, MdOutlinePictureInPictureAlt } from "react-icons/md";
import { HiOutlineVideoCamera } from "react-icons/hi";
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
2023-12-08 17:02:14 +03:00
type HistoryCardProps = {
2023-12-05 16:04:22 +03:00
timeline: Card,
allPreviews?: Preview[],
}
2023-12-08 17:02:14 +03:00
export default function HistoryCard({ allPreviews, timeline }: HistoryCardProps) {
2023-12-05 16:04:22 +03:00
const { data: config } = useSWR<FrigateConfig>("config");
if (!config) {
return <ActivityIndicator />
}
return (
<Card className="my-2 mr-2 bg-secondary">
2023-12-08 17:02:14 +03:00
<PreviewThumbnailPlayer
2023-12-05 16:04:22 +03:00
camera={timeline.camera}
allPreviews={allPreviews || []}
startTs={Object.values(timeline.entries)[0].timestamp}
mode="thumbnail"
/>
<div className="p-2">
<div className="text-sm flex">
<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' })}
</div>
<div className="capitalize text-sm flex align-center mt-1">
<HiOutlineVideoCamera className="h-5 w-5 mr-2 inline" />
{timeline.camera.replaceAll('_', ' ')}
</div>
2023-12-08 06:50:59 +03:00
<div className="my-2 text-sm font-medium">
2023-12-05 16:04:22 +03:00
Activity:
2023-12-08 06:50:59 +03:00
</div>
2023-12-05 16:04:22 +03:00
{Object.entries(timeline.entries).map(([_, entry]) => {
return (
2023-12-08 06:50:59 +03:00
<div key={entry.timestamp} className="flex text-xs capitalize my-1 items-center">
2023-12-05 16:04:22 +03:00
{getTimelineIcon(entry)}
{getTimelineItemDescription(entry)}
</div>
);
})}
</div>
</Card>
);
}
function getTimelineIcon(timelineItem: Timeline) {
switch (timelineItem.class_type) {
case 'visible':
return <LuPlay className="w-4 mr-1" />;
case 'gone':
return <IoMdExit className="w-4 mr-1" />;
case 'active':
return <LuPlayCircle className="w-4 mr-1" />;
case 'stationary':
return <LuCircle className="w-4 mr-1" />;
case 'entered_zone':
return <MdOutlineLocationOn className="w-4 mr-1" />;
case 'attribute':
switch (timelineItem.data.attribute) {
case 'face':
return <MdFaceUnlock className="w-4 mr-1" />;
case 'license_plate':
return <MdOutlinePictureInPictureAlt className="w-4 mr-1" />;
default:
return <LuTruck className="w-4 mr-1" />;
}
case 'sub_label':
switch (timelineItem.data.label) {
case 'person':
return <MdFaceUnlock className="w-4 mr-1" />;
case 'car':
return <MdOutlinePictureInPictureAlt className="w-4 mr-1" />;
}
}
}
function getTimelineItemDescription(timelineItem: Timeline) {
const label = ((Array.isArray(timelineItem.data.sub_label) ? timelineItem.data.sub_label[0] : timelineItem.data.sub_label) || timelineItem.data.label).replaceAll('_', ' ');
switch (timelineItem.class_type) {
case 'visible':
return `${label} detected`;
case 'entered_zone':
return `${label} entered ${timelineItem.data.zones.join(' and ').replaceAll('_', ' ')}`;
case 'active':
return `${label} became active`;
case 'stationary':
return `${label} became stationary`;
case 'attribute': {
let title = '';
if (timelineItem.data.attribute == 'face' || timelineItem.data.attribute == 'license_plate') {
title = `${timelineItem.data.attribute.replaceAll('_', ' ')} detected for ${label}`;
} else {
title = `${timelineItem.data.sub_label} recognized as ${timelineItem.data.attribute.replaceAll('_', ' ')}`;
}
return title;
}
case 'sub_label':
return `${timelineItem.data.label} recognized as ${timelineItem.data.sub_label}`;
case 'gone':
return `${label} left`;
}
}