Various fixes (#14786)

* Catch openvino error

* Remove clip deletion

* Update deletion text

* Fix timeline not respecting timezone config

* Tweaks

* More timezone fixes

* Fix

* More timezone fixes

* Fix shm docs
This commit is contained in:
Nicolas Mowen
2024-11-04 07:07:57 -07:00
committed by GitHub
parent 156e7cc628
commit a13b9815f6
11 changed files with 103 additions and 257 deletions

View File

@@ -1,191 +0,0 @@
import { FrigateConfig } from "@/types/frigateConfig";
import { GraphDataPoint } from "@/types/graph";
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
import useSWR from "swr";
import ActivityIndicator from "../indicators/activity-indicator";
type TimelineBarProps = {
startTime: number;
graphData:
| {
objects: number[];
motion: GraphDataPoint[];
}
| undefined;
onClick?: () => void;
};
export default function TimelineBar({
startTime,
graphData,
onClick,
}: TimelineBarProps) {
const { data: config } = useSWR<FrigateConfig>("config");
if (!config) {
return <ActivityIndicator />;
}
return (
<div
className="h-18 my-1 w-full cursor-pointer rounded border p-1 hover:bg-secondary hover:bg-opacity-30"
onClick={onClick}
>
{graphData != undefined && (
<div className="relative flex h-8 w-full">
{getHourBlocks().map((idx) => {
return (
<div
key={idx}
className={`h-2 flex-auto ${
(graphData.motion.at(idx)?.y || 0) == 0
? ""
: graphData.objects.includes(idx)
? "bg-object"
: "bg-motion"
}`}
/>
);
})}
<div className="absolute bottom-0 left-0 top-0 border-l border-gray-500 align-bottom">
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:00" : "%I:00%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
<div className="absolute bottom-0 left-[8.3%] top-0 border-l border-gray-500 align-bottom">
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:05" : "%I:05%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
<div className="absolute bottom-0 left-[16.7%] top-0 border-l border-gray-500 align-bottom">
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:10" : "%I:10%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
<div className="absolute bottom-0 left-[25%] top-0 border-l border-gray-500 align-bottom">
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:15" : "%I:15%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
<div className="absolute bottom-0 left-[33.3%] top-0 border-l border-gray-500 align-bottom">
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:20" : "%I:20%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
<div className="absolute bottom-0 left-[41.7%] top-0 border-l border-gray-500 align-bottom">
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:25" : "%I:25%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
<div className="absolute bottom-0 left-[50%] top-0 border-l border-gray-500 align-bottom">
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:30" : "%I:30%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
<div className="absolute bottom-0 left-[58.3%] top-0 border-l border-gray-500 align-bottom">
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:35" : "%I:35%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
<div className="absolute bottom-0 left-[66.7%] top-0 border-l border-gray-500 align-bottom">
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:40" : "%I:40%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
<div className="absolute bottom-0 left-[75%] top-0 border-l border-gray-500 align-bottom">
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:45" : "%I:45%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
<div className="absolute bottom-0 left-[83.3%] top-0 border-l border-gray-500 align-bottom">
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:50" : "%I:50%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
<div className="absolute bottom-0 left-[91.7%] top-0 border-l border-gray-500 align-bottom">
<div className="absolute bottom-0 ml-1 text-sm text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:55" : "%I:55%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
</div>
)}
<div className="text-gray-500">
{formatUnixTimestampToDateTime(startTime, {
strftime_fmt:
config.ui.time_format == "24hour" ? "%m/%d %H:%M" : "%m/%d %I:%M%P",
time_style: "medium",
date_style: "medium",
})}
</div>
</div>
);
}
function getHourBlocks() {
const arr = [];
for (let x = 0; x <= 59; x++) {
arr.push(x);
}
return arr;
}

View File

@@ -1,5 +1,6 @@
import { useTheme } from "@/context/theme-provider";
import { FrigateConfig } from "@/types/frigateConfig";
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
import { useCallback, useEffect, useMemo } from "react";
import Chart from "react-apexcharts";
import { isMobileOnly } from "react-device-detect";
@@ -42,12 +43,14 @@ export function CameraLineGraph({
const formatTime = useCallback(
(val: unknown) => {
const date = new Date(updateTimes[Math.round(val as number)] * 1000);
return date.toLocaleTimeString([], {
hour12: config?.ui.time_format != "24hour",
hour: "2-digit",
minute: "2-digit",
});
return formatUnixTimestampToDateTime(
updateTimes[Math.round(val as number)],
{
timezone: config?.ui.timezone,
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p",
},
);
},
[config, updateTimes],
);

View File

@@ -1,6 +1,7 @@
import { useTheme } from "@/context/theme-provider";
import { FrigateConfig } from "@/types/frigateConfig";
import { Threshold } from "@/types/graph";
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
import { useCallback, useEffect, useMemo } from "react";
import Chart from "react-apexcharts";
import { isMobileOnly } from "react-device-detect";
@@ -50,17 +51,17 @@ export function ThresholdBarGraph({
let timeOffset = 0;
if (dateIndex < 0) {
timeOffset = 5000 * Math.abs(dateIndex);
timeOffset = 5 * Math.abs(dateIndex);
}
const date = new Date(
updateTimes[Math.max(1, dateIndex) - 1] * 1000 - timeOffset,
return formatUnixTimestampToDateTime(
updateTimes[Math.max(1, dateIndex) - 1] - timeOffset,
{
timezone: config?.ui.timezone,
strftime_fmt:
config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p",
},
);
return date.toLocaleTimeString([], {
hour12: config?.ui.time_format != "24hour",
hour: "2-digit",
minute: "2-digit",
});
},
[config, updateTimes],
);

View File

@@ -159,7 +159,13 @@ export default function SearchResultActions({
<AlertDialogTitle>Confirm Delete</AlertDialogTitle>
</AlertDialogHeader>
<AlertDialogDescription>
Are you sure you want to delete this tracked object?
Deleting this tracked object removes the snapshot, any saved
embeddings, and any associated object lifecycle entries. Recorded
footage of this tracked object in History view will <em>NOT</em> be
deleted.
<br />
<br />
Are you sure you want to proceed?
</AlertDialogDescription>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>

View File

@@ -427,6 +427,7 @@ export default function ObjectLifecycle({
</div>
<div className="text-sm text-primary-variant">
{formatUnixTimestampToDateTime(item.timestamp, {
timezone: config.ui.timezone,
strftime_fmt:
config.ui.time_format == "24hour"
? "%d %b %H:%M:%S"

View File

@@ -1,4 +1,6 @@
import { FrigateConfig } from "@/types/frigateConfig";
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
import { useMemo } from "react";
import useSWR from "swr";
type MinimapSegmentProps = {
@@ -40,22 +42,22 @@ export function MinimapBounds({
className="pointer-events-none absolute inset-0 -bottom-7 z-20 flex w-full select-none scroll-mt-8 items-center justify-center text-center text-[10px] font-medium text-primary"
ref={firstMinimapSegmentRef}
>
{new Date(alignedMinimapStartTime * 1000).toLocaleTimeString([], {
hour12: config?.ui.time_format != "24hour",
hour: "2-digit",
minute: "2-digit",
...(!dense && { month: "short", day: "2-digit" }),
{formatUnixTimestampToDateTime(alignedMinimapStartTime, {
timezone: config?.ui.timezone,
strftime_fmt: !dense
? `%b %d, ${config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p"}`
: `${config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p"}`,
})}
</div>
)}
{isLastSegmentInMinimap && (
<div className="pointer-events-none absolute inset-0 -top-3 z-20 flex w-full select-none items-center justify-center text-center text-[10px] font-medium text-primary">
{new Date(alignedMinimapEndTime * 1000).toLocaleTimeString([], {
hour12: config?.ui.time_format != "24hour",
hour: "2-digit",
minute: "2-digit",
...(!dense && { month: "short", day: "2-digit" }),
{formatUnixTimestampToDateTime(alignedMinimapEndTime, {
timezone: config?.ui.timezone,
strftime_fmt: !dense
? `%b %d, ${config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p"}`
: `${config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p"}`,
})}
</div>
)}
@@ -92,6 +94,22 @@ export function Timestamp({
}: TimestampSegmentProps) {
const { data: config } = useSWR<FrigateConfig>("config");
const formattedTimestamp = useMemo(() => {
if (
!(
timestamp.getMinutes() % timestampSpread === 0 &&
timestamp.getSeconds() === 0
)
) {
return undefined;
}
return formatUnixTimestampToDateTime(timestamp.getTime() / 1000, {
timezone: config?.ui.timezone,
strftime_fmt: config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p",
});
}, [config, timestamp, timestampSpread]);
return (
<div className="absolute left-[15px] z-10 h-[8px]">
{!isFirstSegmentInMinimap && !isLastSegmentInMinimap && (
@@ -99,13 +117,7 @@ export function Timestamp({
key={`${segmentKey}_timestamp`}
className="pointer-events-none select-none text-[8px] text-neutral_variant dark:text-neutral"
>
{timestamp.getMinutes() % timestampSpread === 0 &&
timestamp.getSeconds() === 0 &&
timestamp.toLocaleTimeString([], {
hour12: config?.ui.time_format != "24hour",
hour: "2-digit",
minute: "2-digit",
})}
{formattedTimestamp}
</div>
)}
</div>

View File

@@ -10,6 +10,7 @@ import scrollIntoView from "scroll-into-view-if-needed";
import { useTimelineUtils } from "./use-timeline-utils";
import { FrigateConfig } from "@/types/frigateConfig";
import useSWR from "swr";
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
type DraggableElementProps = {
contentRef: React.RefObject<HTMLElement>;
@@ -168,6 +169,19 @@ function useDraggableElement({
[segmentDuration, timelineStartAligned, segmentHeight],
);
const getFormattedTimestamp = useCallback(
(segmentStartTime: number) => {
return formatUnixTimestampToDateTime(segmentStartTime, {
timezone: config?.ui.timezone,
strftime_fmt:
config?.ui.time_format == "24hour"
? `%H:%M${segmentDuration < 60 && !dense ? ":%S" : ""}`
: `%I:%M${segmentDuration < 60 && !dense ? ":%S" : ""} %p`,
});
},
[config, dense, segmentDuration],
);
const updateDraggableElementPosition = useCallback(
(
newElementPosition: number,
@@ -184,14 +198,8 @@ function useDraggableElement({
}
if (draggableElementTimeRef.current) {
draggableElementTimeRef.current.textContent = new Date(
segmentStartTime * 1000,
).toLocaleTimeString([], {
hour12: config?.ui.time_format != "24hour",
hour: "2-digit",
minute: "2-digit",
...(segmentDuration < 60 && !dense && { second: "2-digit" }),
});
draggableElementTimeRef.current.textContent =
getFormattedTimestamp(segmentStartTime);
if (scrollTimeline && !userInteracting) {
scrollIntoView(thumb, {
block: "center",
@@ -208,13 +216,11 @@ function useDraggableElement({
}
},
[
segmentDuration,
draggableElementTimeRef,
draggableElementRef,
setDraggableElementTime,
setDraggableElementPosition,
dense,
config,
getFormattedTimestamp,
userInteracting,
],
);