mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-09 04:35:25 +03:00
* Ensure viewport is always full screen * Protect against hour with no cards and ensure data is consistent * Reduce grouped up image refreshes * Include current hour and fix scrubbing bugginess * Scroll initially selected timeline in to view * Expand timelne class type * Use poster image for preview on video player instead of using separate image view * Fix available streaming modes * Incrase timing for grouping timline items * Fix audio activity listener * Fix player not switching views correctly * Use player time to convert to timeline time * Update sub labels for previous timeline items * Show mini timeline bar for non selected items * Rewrite desktop timeline to use separate dynamic video player component * Extend improvements to mobile as well * Improve time formatting * Fix scroll * Fix no preview case * Mobile fixes * Audio toggle fixes * More fixes for mobile * Improve scaling of graph motion activity * Add keyboard shortcut hook and support shortcuts for playback page * Fix sizing of dialog * Improve height scaling of dialog * simplify and fix layout system for timeline * Fix timeilne items not working * Implement basic Frigate+ submitting from timeline
121 lines
3.3 KiB
TypeScript
121 lines
3.3 KiB
TypeScript
import {
|
|
LuCamera,
|
|
LuCar,
|
|
LuCat,
|
|
LuCircle,
|
|
LuCircleDot,
|
|
LuDog,
|
|
LuEar,
|
|
LuPackage,
|
|
LuPersonStanding,
|
|
LuPlay,
|
|
LuPlayCircle,
|
|
LuTruck,
|
|
} from "react-icons/lu";
|
|
import { GiDeer } from "react-icons/gi";
|
|
import { IoMdExit } from "react-icons/io";
|
|
import {
|
|
MdFaceUnlock,
|
|
MdOutlineLocationOn,
|
|
MdOutlinePictureInPictureAlt,
|
|
} from "react-icons/md";
|
|
import { FaBicycle } from "react-icons/fa";
|
|
|
|
export 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 "heard":
|
|
return <LuEar className="w-4 mr-1" />;
|
|
case "external":
|
|
return <LuCircleDot className="w-4 mr-1" />;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get icon representing detection, either label specific or generic detection icon
|
|
* @param timelineItem timeline item
|
|
* @returns icon for label
|
|
*/
|
|
export function getTimelineDetectionIcon(timelineItem: Timeline) {
|
|
switch (timelineItem.data.label) {
|
|
case "bicycle":
|
|
return <FaBicycle className="w-4 mr-1" />;
|
|
case "car":
|
|
return <LuCar className="w-4 mr-1" />;
|
|
case "cat":
|
|
return <LuCat className="w-4 mr-1" />;
|
|
case "deer":
|
|
return <GiDeer className="w-4 mr-1" />;
|
|
case "dog":
|
|
return <LuDog className="w-4 mr-1" />;
|
|
case "package":
|
|
return <LuPackage className="w-4 mr-1" />;
|
|
case "person":
|
|
return <LuPersonStanding className="w-4 mr-1" />;
|
|
default:
|
|
return <LuCamera className="w-4 mr-1" />;
|
|
}
|
|
}
|
|
|
|
export 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 "gone":
|
|
return `${label} left`;
|
|
case "heard":
|
|
return `${label} heard`;
|
|
case "external":
|
|
return `${label} detected`;
|
|
}
|
|
}
|