mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-03-31 20:34:53 +03:00
Fix browser time format handling (#22694)
* implement hook to return resolved "24hour" | "12hour" string delegate to existing use24HourTime(), which correctly detects the browser's locale preference via Intl.DateTimeFormat * update frontend to use use24HourTime(config) or useTimeFormat(config) instead of directly comparing config.ui.time_format
This commit is contained in:
parent
f44f485f48
commit
257dae11c1
@ -8,6 +8,7 @@ import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
|||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useTimeFormat } from "@/hooks/use-date-utils";
|
||||||
|
|
||||||
const GRAPH_COLORS = ["#3b82f6", "#ef4444"]; // RMS, dBFS
|
const GRAPH_COLORS = ["#3b82f6", "#ef4444"]; // RMS, dBFS
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ export function AudioLevelGraph({ cameraName }: AudioLevelGraphProps) {
|
|||||||
return [last.rms, last.dBFS];
|
return [last.rms, last.dBFS];
|
||||||
}, [audioData]);
|
}, [audioData]);
|
||||||
|
|
||||||
const timeFormat = config?.ui.time_format === "24hour" ? "24hour" : "12hour";
|
const timeFormat = useTimeFormat(config);
|
||||||
const formatString = useMemo(
|
const formatString = useMemo(
|
||||||
() =>
|
() =>
|
||||||
t(`time.formattedTimestampHourMinuteSecond.${timeFormat}`, {
|
t(`time.formattedTimestampHourMinuteSecond.${timeFormat}`, {
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { useDateLocale } from "@/hooks/use-date-locale";
|
import { useDateLocale } from "@/hooks/use-date-locale";
|
||||||
|
import { useTimeFormat } from "@/hooks/use-date-utils";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
|
|
||||||
type DownloadVideoButtonProps = {
|
type DownloadVideoButtonProps = {
|
||||||
@ -26,7 +27,7 @@ export function DownloadVideoButton({
|
|||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
const locale = useDateLocale();
|
const locale = useDateLocale();
|
||||||
|
|
||||||
const timeFormat = config?.ui.time_format === "24hour" ? "24hour" : "12hour";
|
const timeFormat = useTimeFormat(config);
|
||||||
const format = useMemo(() => {
|
const format = useMemo(() => {
|
||||||
return t(`time.formattedTimestampFilename.${timeFormat}`, { ns: "common" });
|
return t(`time.formattedTimestampFilename.${timeFormat}`, { ns: "common" });
|
||||||
}, [t, timeFormat]);
|
}, [t, timeFormat]);
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { baseUrl } from "@/api/baseUrl";
|
import { baseUrl } from "@/api/baseUrl";
|
||||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
import { useFormattedTimestamp, use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { REVIEW_PADDING, ReviewSegment } from "@/types/review";
|
import { REVIEW_PADDING, ReviewSegment } from "@/types/review";
|
||||||
import { getIconForLabel } from "@/utils/iconUtil";
|
import { getIconForLabel } from "@/utils/iconUtil";
|
||||||
@ -55,9 +55,10 @@ export default function ReviewCard({
|
|||||||
const { t } = useTranslation(["components/dialog"]);
|
const { t } = useTranslation(["components/dialog"]);
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
const [imgRef, imgLoaded, onImgLoad] = useImageLoaded();
|
const [imgRef, imgLoaded, onImgLoad] = useImageLoaded();
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
const formattedDate = useFormattedTimestamp(
|
const formattedDate = useFormattedTimestamp(
|
||||||
event.start_time,
|
event.start_time,
|
||||||
config?.ui.time_format == "24hour"
|
is24Hour
|
||||||
? t("time.formattedTimestampHourMinute.24hour", { ns: "common" })
|
? t("time.formattedTimestampHourMinute.24hour", { ns: "common" })
|
||||||
: t("time.formattedTimestampHourMinute.12hour", { ns: "common" }),
|
: t("time.formattedTimestampHourMinute.12hour", { ns: "common" }),
|
||||||
config?.ui.timezone,
|
config?.ui.timezone,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import TimeAgo from "../dynamic/TimeAgo";
|
import TimeAgo from "../dynamic/TimeAgo";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
import { useFormattedTimestamp, use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import { SearchResult } from "@/types/search";
|
import { SearchResult } from "@/types/search";
|
||||||
import ActivityIndicator from "../indicators/activity-indicator";
|
import ActivityIndicator from "../indicators/activity-indicator";
|
||||||
import SearchResultActions from "../menu/SearchResultActions";
|
import SearchResultActions from "../menu/SearchResultActions";
|
||||||
@ -29,9 +29,10 @@ export default function SearchThumbnailFooter({
|
|||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
|
|
||||||
// date
|
// date
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
const formattedDate = useFormattedTimestamp(
|
const formattedDate = useFormattedTimestamp(
|
||||||
searchResult.start_time,
|
searchResult.start_time,
|
||||||
config?.ui.time_format == "24hour"
|
is24Hour
|
||||||
? t("time.formattedTimestampMonthDayHourMinute.24hour", { ns: "common" })
|
? t("time.formattedTimestampMonthDayHourMinute.24hour", { ns: "common" })
|
||||||
: t("time.formattedTimestampMonthDayHourMinute.12hour", { ns: "common" }),
|
: t("time.formattedTimestampMonthDayHourMinute.12hour", { ns: "common" }),
|
||||||
config?.ui.timezone,
|
config?.ui.timezone,
|
||||||
|
|||||||
@ -43,6 +43,7 @@ import {
|
|||||||
SelectItem,
|
SelectItem,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
||||||
|
import { use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import FilterSwitch from "@/components/filter/FilterSwitch";
|
import FilterSwitch from "@/components/filter/FilterSwitch";
|
||||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
@ -752,6 +753,7 @@ export function CameraNotificationSwitch({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const locale = useDateLocale();
|
const locale = useDateLocale();
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
|
|
||||||
const formatSuspendedUntil = (timestamp: string) => {
|
const formatSuspendedUntil = (timestamp: string) => {
|
||||||
if (timestamp === "0") return t("time.untilForRestart", { ns: "common" });
|
if (timestamp === "0") return t("time.untilForRestart", { ns: "common" });
|
||||||
@ -760,14 +762,13 @@ export function CameraNotificationSwitch({
|
|||||||
time_style: "medium",
|
time_style: "medium",
|
||||||
date_style: "medium",
|
date_style: "medium",
|
||||||
timezone: config?.ui.timezone,
|
timezone: config?.ui.timezone,
|
||||||
date_format:
|
date_format: is24Hour
|
||||||
config?.ui.time_format == "24hour"
|
? t("time.formattedTimestampMonthDayHourMinute.24hour", {
|
||||||
? t("time.formattedTimestampMonthDayHourMinute.24hour", {
|
ns: "common",
|
||||||
ns: "common",
|
})
|
||||||
})
|
: t("time.formattedTimestampMonthDayHourMinute.12hour", {
|
||||||
: t("time.formattedTimestampMonthDayHourMinute.12hour", {
|
ns: "common",
|
||||||
ns: "common",
|
}),
|
||||||
}),
|
|
||||||
locale: locale,
|
locale: locale,
|
||||||
});
|
});
|
||||||
return t("time.untilForTime", { ns: "common", time });
|
return t("time.untilForTime", { ns: "common", time });
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { isMobileOnly } from "react-device-detect";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { MdCircle } from "react-icons/md";
|
import { MdCircle } from "react-icons/md";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
import { useTimeFormat } from "@/hooks/use-date-utils";
|
||||||
|
|
||||||
const GRAPH_COLORS = ["#5C7CFA", "#ED5CFA", "#FAD75C"];
|
const GRAPH_COLORS = ["#5C7CFA", "#ED5CFA", "#FAD75C"];
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ export function CameraLineGraph({
|
|||||||
|
|
||||||
const locale = useDateLocale();
|
const locale = useDateLocale();
|
||||||
|
|
||||||
const timeFormat = config?.ui.time_format === "24hour" ? "24hour" : "12hour";
|
const timeFormat = useTimeFormat(config);
|
||||||
const format = useMemo(() => {
|
const format = useMemo(() => {
|
||||||
return t(`time.formattedTimestampHourMinute.${timeFormat}`, {
|
return t(`time.formattedTimestampHourMinute.${timeFormat}`, {
|
||||||
ns: "common",
|
ns: "common",
|
||||||
@ -203,7 +204,7 @@ export function EventsPerSecondsLineGraph({
|
|||||||
const locale = useDateLocale();
|
const locale = useDateLocale();
|
||||||
const { t } = useTranslation(["common"]);
|
const { t } = useTranslation(["common"]);
|
||||||
|
|
||||||
const timeFormat = config?.ui.time_format === "24hour" ? "24hour" : "12hour";
|
const timeFormat = useTimeFormat(config);
|
||||||
const format = useMemo(() => {
|
const format = useMemo(() => {
|
||||||
return t(`time.formattedTimestampHourMinute.${timeFormat}`, {
|
return t(`time.formattedTimestampHourMinute.${timeFormat}`, {
|
||||||
ns: "common",
|
ns: "common",
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import Chart from "react-apexcharts";
|
|||||||
import { isMobileOnly } from "react-device-detect";
|
import { isMobileOnly } from "react-device-detect";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
import { useTimeFormat } from "@/hooks/use-date-utils";
|
||||||
|
|
||||||
type ThresholdBarGraphProps = {
|
type ThresholdBarGraphProps = {
|
||||||
graphId: string;
|
graphId: string;
|
||||||
@ -53,7 +54,7 @@ export function ThresholdBarGraph({
|
|||||||
const locale = useDateLocale();
|
const locale = useDateLocale();
|
||||||
const { t } = useTranslation(["common"]);
|
const { t } = useTranslation(["common"]);
|
||||||
|
|
||||||
const timeFormat = config?.ui.time_format === "24hour" ? "24hour" : "12hour";
|
const timeFormat = useTimeFormat(config);
|
||||||
const format = useMemo(() => {
|
const format = useMemo(() => {
|
||||||
return t(`time.formattedTimestampHourMinute.${timeFormat}`, {
|
return t(`time.formattedTimestampHourMinute.${timeFormat}`, {
|
||||||
ns: "common",
|
ns: "common",
|
||||||
|
|||||||
@ -50,6 +50,7 @@ import {
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
|
import { use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import { MdImageSearch } from "react-icons/md";
|
import { MdImageSearch } from "react-icons/md";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { getTranslatedLabel } from "@/utils/i18n";
|
import { getTranslatedLabel } from "@/utils/i18n";
|
||||||
@ -80,6 +81,8 @@ export default function InputWithTags({
|
|||||||
const { data: config } = useSWR<FrigateConfig>("config", {
|
const { data: config } = useSWR<FrigateConfig>("config", {
|
||||||
revalidateOnFocus: false,
|
revalidateOnFocus: false,
|
||||||
});
|
});
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
|
const resolvedTimeFormat = is24Hour ? "24hour" : ("12hour" as const);
|
||||||
|
|
||||||
const allAudioListenLabels = useMemo<Set<string>>(() => {
|
const allAudioListenLabels = useMemo<Set<string>>(() => {
|
||||||
if (!config) {
|
if (!config) {
|
||||||
@ -431,12 +434,8 @@ export default function InputWithTags({
|
|||||||
const [startTime, endTime] = (filterValues as string)
|
const [startTime, endTime] = (filterValues as string)
|
||||||
.replace("-", ",")
|
.replace("-", ",")
|
||||||
.split(",");
|
.split(",");
|
||||||
return `${
|
return `${is24Hour ? startTime : convertTo12Hour(startTime)} - ${
|
||||||
config?.ui.time_format === "24hour"
|
is24Hour ? endTime : convertTo12Hour(endTime)
|
||||||
? startTime
|
|
||||||
: convertTo12Hour(startTime)
|
|
||||||
} - ${
|
|
||||||
config?.ui.time_format === "24hour" ? endTime : convertTo12Hour(endTime)
|
|
||||||
}`;
|
}`;
|
||||||
} else if (filterType === "min_score" || filterType === "max_score") {
|
} else if (filterType === "min_score" || filterType === "max_score") {
|
||||||
return Math.round(Number(filterValues) * 100).toString() + "%";
|
return Math.round(Number(filterValues) * 100).toString() + "%";
|
||||||
@ -478,7 +477,7 @@ export default function InputWithTags({
|
|||||||
(filterType === "time_range" &&
|
(filterType === "time_range" &&
|
||||||
isValidTimeRange(
|
isValidTimeRange(
|
||||||
trimmedValue.replace("-", ","),
|
trimmedValue.replace("-", ","),
|
||||||
config?.ui.time_format,
|
resolvedTimeFormat,
|
||||||
)) ||
|
)) ||
|
||||||
((filterType === "min_score" || filterType === "max_score") &&
|
((filterType === "min_score" || filterType === "max_score") &&
|
||||||
!isNaN(Number(trimmedValue)) &&
|
!isNaN(Number(trimmedValue)) &&
|
||||||
@ -495,7 +494,7 @@ export default function InputWithTags({
|
|||||||
? trimmedValue
|
? trimmedValue
|
||||||
.replace("-", ",")
|
.replace("-", ",")
|
||||||
.split(",")
|
.split(",")
|
||||||
.map((time) => to24Hour(time.trim(), config?.ui.time_format))
|
.map((time) => to24Hour(time.trim(), resolvedTimeFormat))
|
||||||
.join(",")
|
.join(",")
|
||||||
: trimmedValue,
|
: trimmedValue,
|
||||||
);
|
);
|
||||||
@ -511,7 +510,7 @@ export default function InputWithTags({
|
|||||||
setCurrentFilterType(null);
|
setCurrentFilterType(null);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[allSuggestions, createFilter, config],
|
[allSuggestions, createFilter, resolvedTimeFormat],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleInputChange = useCallback(
|
const handleInputChange = useCallback(
|
||||||
@ -598,7 +597,7 @@ export default function InputWithTags({
|
|||||||
suggestion = suggestion
|
suggestion = suggestion
|
||||||
.replace("-", ",")
|
.replace("-", ",")
|
||||||
.split(",")
|
.split(",")
|
||||||
.map((time) => to24Hour(time.trim(), config?.ui.time_format))
|
.map((time) => to24Hour(time.trim(), resolvedTimeFormat))
|
||||||
.join(",");
|
.join(",");
|
||||||
}
|
}
|
||||||
createFilter(currentFilterType, suggestion);
|
createFilter(currentFilterType, suggestion);
|
||||||
@ -627,7 +626,7 @@ export default function InputWithTags({
|
|||||||
|
|
||||||
inputRef.current?.focus();
|
inputRef.current?.focus();
|
||||||
},
|
},
|
||||||
[createFilter, currentFilterType, allSuggestions, config],
|
[createFilter, currentFilterType, allSuggestions, resolvedTimeFormat],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSearch = useCallback(
|
const handleSearch = useCallback(
|
||||||
@ -779,10 +778,7 @@ export default function InputWithTags({
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
{t("filter.tips.desc.step5", {
|
{t("filter.tips.desc.step5", {
|
||||||
exampleTime:
|
exampleTime: is24Hour ? "15:00-16:00" : "3:00PM-4:00PM",
|
||||||
config?.ui.time_format == "24hour"
|
|
||||||
? "15:00-16:00"
|
|
||||||
: "3:00PM-4:00PM",
|
|
||||||
})}
|
})}
|
||||||
</li>
|
</li>
|
||||||
<li>{t("filter.tips.desc.step6")}</li>
|
<li>{t("filter.tips.desc.step6")}</li>
|
||||||
|
|||||||
@ -46,6 +46,7 @@ import {
|
|||||||
} from "@/api/ws";
|
} from "@/api/ws";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useDateLocale } from "@/hooks/use-date-locale";
|
import { useDateLocale } from "@/hooks/use-date-locale";
|
||||||
|
import { use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import { useIsAdmin } from "@/hooks/use-is-admin";
|
import { useIsAdmin } from "@/hooks/use-is-admin";
|
||||||
import { CameraNameLabel } from "../camera/FriendlyNameLabel";
|
import { CameraNameLabel } from "../camera/FriendlyNameLabel";
|
||||||
import { LiveStreamMetadata } from "@/types/live";
|
import { LiveStreamMetadata } from "@/types/live";
|
||||||
@ -247,6 +248,8 @@ export default function LiveContextMenu({
|
|||||||
|
|
||||||
const locale = useDateLocale();
|
const locale = useDateLocale();
|
||||||
|
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
|
|
||||||
const formatSuspendedUntil = (timestamp: string) => {
|
const formatSuspendedUntil = (timestamp: string) => {
|
||||||
// Some languages require a change in word order
|
// Some languages require a change in word order
|
||||||
if (timestamp === "0") return t("time.untilForRestart", { ns: "common" });
|
if (timestamp === "0") return t("time.untilForRestart", { ns: "common" });
|
||||||
@ -255,14 +258,13 @@ export default function LiveContextMenu({
|
|||||||
time_style: "medium",
|
time_style: "medium",
|
||||||
date_style: "medium",
|
date_style: "medium",
|
||||||
timezone: config?.ui.timezone,
|
timezone: config?.ui.timezone,
|
||||||
date_format:
|
date_format: is24Hour
|
||||||
config?.ui.time_format == "24hour"
|
? t("time.formattedTimestampMonthDayHourMinute.24hour", {
|
||||||
? t("time.formattedTimestampMonthDayHourMinute.24hour", {
|
ns: "common",
|
||||||
ns: "common",
|
})
|
||||||
})
|
: t("time.formattedTimestampMonthDayHourMinute.12hour", {
|
||||||
: t("time.formattedTimestampMonthDayHourMinute.12hour", {
|
ns: "common",
|
||||||
ns: "common",
|
}),
|
||||||
}),
|
|
||||||
locale: locale,
|
locale: locale,
|
||||||
});
|
});
|
||||||
return t("time.untilForTime", { ns: "common", time });
|
return t("time.untilForTime", { ns: "common", time });
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { Button } from "../ui/button";
|
|||||||
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
||||||
import { SelectSeparator } from "../ui/select";
|
import { SelectSeparator } from "../ui/select";
|
||||||
import { TimeRange } from "@/types/timeline";
|
import { TimeRange } from "@/types/timeline";
|
||||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
import { useFormattedTimestamp, use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import { getUTCOffset } from "@/utils/dateUtil";
|
import { getUTCOffset } from "@/utils/dateUtil";
|
||||||
import { TimezoneAwareCalendar } from "./ReviewActivityCalendar";
|
import { TimezoneAwareCalendar } from "./ReviewActivityCalendar";
|
||||||
import { FaArrowRight, FaCalendarAlt } from "react-icons/fa";
|
import { FaArrowRight, FaCalendarAlt } from "react-icons/fa";
|
||||||
@ -69,16 +69,18 @@ export function CustomTimeSelector({
|
|||||||
return time;
|
return time;
|
||||||
}, [range, latestTime, timezoneOffset, localTimeOffset]);
|
}, [range, latestTime, timezoneOffset, localTimeOffset]);
|
||||||
|
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
|
|
||||||
const formattedStart = useFormattedTimestamp(
|
const formattedStart = useFormattedTimestamp(
|
||||||
startTime,
|
startTime,
|
||||||
config?.ui.time_format == "24hour"
|
is24Hour
|
||||||
? t("time.formattedTimestamp.24hour")
|
? t("time.formattedTimestamp.24hour")
|
||||||
: t("time.formattedTimestamp.12hour"),
|
: t("time.formattedTimestamp.12hour"),
|
||||||
);
|
);
|
||||||
|
|
||||||
const formattedEnd = useFormattedTimestamp(
|
const formattedEnd = useFormattedTimestamp(
|
||||||
endTime,
|
endTime,
|
||||||
config?.ui.time_format == "24hour"
|
is24Hour
|
||||||
? t("time.formattedTimestamp.24hour")
|
? t("time.formattedTimestamp.24hour")
|
||||||
: t("time.formattedTimestamp.12hour"),
|
: t("time.formattedTimestamp.12hour"),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { isDesktop, isIOS, isMobile, isSafari } from "react-device-detect";
|
|||||||
import { SearchResult } from "@/types/search";
|
import { SearchResult } from "@/types/search";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
import { useFormattedTimestamp, use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import { getIconForLabel } from "@/utils/iconUtil";
|
import { getIconForLabel } from "@/utils/iconUtil";
|
||||||
import { useApiHost } from "@/api";
|
import { useApiHost } from "@/api";
|
||||||
import { Button } from "../../ui/button";
|
import { Button } from "../../ui/button";
|
||||||
@ -769,9 +769,10 @@ function ObjectDetailsTab({
|
|||||||
setShowNavigationButtons,
|
setShowNavigationButtons,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
const formattedDate = useFormattedTimestamp(
|
const formattedDate = useFormattedTimestamp(
|
||||||
search?.start_time ?? 0,
|
search?.start_time ?? 0,
|
||||||
config?.ui.time_format == "24hour"
|
is24Hour
|
||||||
? t("time.formattedTimestampMonthDayYearHourMinute.24hour", {
|
? t("time.formattedTimestampMonthDayYearHourMinute.24hour", {
|
||||||
ns: "common",
|
ns: "common",
|
||||||
})
|
})
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import ActivityIndicator from "@/components/indicators/activity-indicator";
|
|||||||
import { TrackingDetailsSequence } from "@/types/timeline";
|
import { TrackingDetailsSequence } from "@/types/timeline";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
||||||
|
import { use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import { getIconForLabel } from "@/utils/iconUtil";
|
import { getIconForLabel } from "@/utils/iconUtil";
|
||||||
import { LuCircle, LuFolderX } from "react-icons/lu";
|
import { LuCircle, LuFolderX } from "react-icons/lu";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
@ -428,17 +429,18 @@ export function TrackingDetails({
|
|||||||
[annotationOffset, displaySource, timestampToVideoTime],
|
[annotationOffset, displaySource, timestampToVideoTime],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
|
|
||||||
const formattedStart = config
|
const formattedStart = config
|
||||||
? formatUnixTimestampToDateTime(event.start_time ?? 0, {
|
? formatUnixTimestampToDateTime(event.start_time ?? 0, {
|
||||||
timezone: config.ui.timezone,
|
timezone: config.ui.timezone,
|
||||||
date_format:
|
date_format: is24Hour
|
||||||
config.ui.time_format == "24hour"
|
? t("time.formattedTimestamp.24hour", {
|
||||||
? t("time.formattedTimestamp.24hour", {
|
ns: "common",
|
||||||
ns: "common",
|
})
|
||||||
})
|
: t("time.formattedTimestamp.12hour", {
|
||||||
: t("time.formattedTimestamp.12hour", {
|
ns: "common",
|
||||||
ns: "common",
|
}),
|
||||||
}),
|
|
||||||
time_style: "medium",
|
time_style: "medium",
|
||||||
date_style: "medium",
|
date_style: "medium",
|
||||||
})
|
})
|
||||||
@ -448,14 +450,13 @@ export function TrackingDetails({
|
|||||||
config && event.end_time != null
|
config && event.end_time != null
|
||||||
? formatUnixTimestampToDateTime(event.end_time, {
|
? formatUnixTimestampToDateTime(event.end_time, {
|
||||||
timezone: config.ui.timezone,
|
timezone: config.ui.timezone,
|
||||||
date_format:
|
date_format: is24Hour
|
||||||
config.ui.time_format == "24hour"
|
? t("time.formattedTimestamp.24hour", {
|
||||||
? t("time.formattedTimestamp.24hour", {
|
ns: "common",
|
||||||
ns: "common",
|
})
|
||||||
})
|
: t("time.formattedTimestamp.12hour", {
|
||||||
: t("time.formattedTimestamp.12hour", {
|
ns: "common",
|
||||||
ns: "common",
|
}),
|
||||||
}),
|
|
||||||
time_style: "medium",
|
time_style: "medium",
|
||||||
date_style: "medium",
|
date_style: "medium",
|
||||||
})
|
})
|
||||||
@ -917,24 +918,25 @@ function LifecycleIconRow({
|
|||||||
[effectiveTime, item.timestamp],
|
[effectiveTime, item.timestamp],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
|
|
||||||
const formattedEventTimestamp = useMemo(
|
const formattedEventTimestamp = useMemo(
|
||||||
() =>
|
() =>
|
||||||
config
|
config
|
||||||
? formatUnixTimestampToDateTime(item.timestamp ?? 0, {
|
? formatUnixTimestampToDateTime(item.timestamp ?? 0, {
|
||||||
timezone: config.ui.timezone,
|
timezone: config.ui.timezone,
|
||||||
date_format:
|
date_format: is24Hour
|
||||||
config.ui.time_format == "24hour"
|
? t("time.formattedTimestampHourMinuteSecond.24hour", {
|
||||||
? t("time.formattedTimestampHourMinuteSecond.24hour", {
|
ns: "common",
|
||||||
ns: "common",
|
})
|
||||||
})
|
: t("time.formattedTimestampHourMinuteSecond.12hour", {
|
||||||
: t("time.formattedTimestampHourMinuteSecond.12hour", {
|
ns: "common",
|
||||||
ns: "common",
|
}),
|
||||||
}),
|
|
||||||
time_style: "medium",
|
time_style: "medium",
|
||||||
date_style: "medium",
|
date_style: "medium",
|
||||||
})
|
})
|
||||||
: "",
|
: "",
|
||||||
[config, item.timestamp, t],
|
[config, is24Hour, item.timestamp, t],
|
||||||
);
|
);
|
||||||
|
|
||||||
const ratio = useMemo(
|
const ratio = useMemo(
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import useSWR from "swr";
|
|||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { isIOS, isMobile, isSafari } from "react-device-detect";
|
import { isIOS, isMobile, isSafari } from "react-device-detect";
|
||||||
import Chip from "@/components/indicators/Chip";
|
import Chip from "@/components/indicators/Chip";
|
||||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
import { useFormattedTimestamp, use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import useImageLoaded from "@/hooks/use-image-loaded";
|
import useImageLoaded from "@/hooks/use-image-loaded";
|
||||||
import { useSwipeable } from "react-swipeable";
|
import { useSwipeable } from "react-swipeable";
|
||||||
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
|
||||||
@ -174,9 +174,10 @@ export default function PreviewThumbnailPlayer({
|
|||||||
|
|
||||||
// date
|
// date
|
||||||
|
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
const formattedDate = useFormattedTimestamp(
|
const formattedDate = useFormattedTimestamp(
|
||||||
review.start_time,
|
review.start_time,
|
||||||
config?.ui.time_format == "24hour"
|
is24Hour
|
||||||
? t("time.formattedTimestampMonthDayHourMinute.24hour", { ns: "common" })
|
? t("time.formattedTimestampMonthDayHourMinute.24hour", { ns: "common" })
|
||||||
: t("time.formattedTimestampMonthDayHourMinute.12hour", { ns: "common" }),
|
: t("time.formattedTimestampMonthDayHourMinute.12hour", { ns: "common" }),
|
||||||
config?.ui?.timezone,
|
config?.ui?.timezone,
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import {
|
|||||||
formatUnixTimestampToDateTime,
|
formatUnixTimestampToDateTime,
|
||||||
getDurationFromTimestamps,
|
getDurationFromTimestamps,
|
||||||
} from "@/utils/dateUtil";
|
} from "@/utils/dateUtil";
|
||||||
|
import { use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import AnnotationOffsetSlider from "@/components/overlay/detail/AnnotationOffsetSlider";
|
import AnnotationOffsetSlider from "@/components/overlay/detail/AnnotationOffsetSlider";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
@ -398,12 +399,12 @@ function ReviewGroup({
|
|||||||
}
|
}
|
||||||
}, [isActive, alwaysExpandActive]);
|
}, [isActive, alwaysExpandActive]);
|
||||||
|
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
const displayTime = formatUnixTimestampToDateTime(start, {
|
const displayTime = formatUnixTimestampToDateTime(start, {
|
||||||
timezone: config.ui.timezone,
|
timezone: config.ui.timezone,
|
||||||
date_format:
|
date_format: is24Hour
|
||||||
config.ui.time_format == "24hour"
|
? t("time.formattedTimestampHourMinuteSecond.24hour", { ns: "common" })
|
||||||
? t("time.formattedTimestampHourMinuteSecond.24hour", { ns: "common" })
|
: t("time.formattedTimestampHourMinuteSecond.12hour", { ns: "common" }),
|
||||||
: t("time.formattedTimestampHourMinuteSecond.12hour", { ns: "common" }),
|
|
||||||
time_style: "medium",
|
time_style: "medium",
|
||||||
date_style: "medium",
|
date_style: "medium",
|
||||||
});
|
});
|
||||||
@ -787,17 +788,17 @@ function LifecycleItem({
|
|||||||
);
|
);
|
||||||
}, [config, item]);
|
}, [config, item]);
|
||||||
|
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
const formattedEventTimestamp = config
|
const formattedEventTimestamp = config
|
||||||
? formatUnixTimestampToDateTime(item?.timestamp ?? 0, {
|
? formatUnixTimestampToDateTime(item?.timestamp ?? 0, {
|
||||||
timezone: config.ui.timezone,
|
timezone: config.ui.timezone,
|
||||||
date_format:
|
date_format: is24Hour
|
||||||
config.ui.time_format == "24hour"
|
? t("time.formattedTimestampHourMinuteSecond.24hour", {
|
||||||
? t("time.formattedTimestampHourMinuteSecond.24hour", {
|
ns: "common",
|
||||||
ns: "common",
|
})
|
||||||
})
|
: t("time.formattedTimestampHourMinuteSecond.12hour", {
|
||||||
: t("time.formattedTimestampHourMinuteSecond.12hour", {
|
ns: "common",
|
||||||
ns: "common",
|
}),
|
||||||
}),
|
|
||||||
time_style: "medium",
|
time_style: "medium",
|
||||||
date_style: "medium",
|
date_style: "medium",
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
import { useFormattedTimestamp, useTimeFormat } from "@/hooks/use-date-utils";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@ -36,7 +36,7 @@ export function MinimapBounds({
|
|||||||
}: MinimapSegmentProps) {
|
}: MinimapSegmentProps) {
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
const { t } = useTranslation(["common"]);
|
const { t } = useTranslation(["common"]);
|
||||||
const timeFormat = config?.ui.time_format === "24hour" ? "24hour" : "12hour";
|
const timeFormat = useTimeFormat(config);
|
||||||
|
|
||||||
const formatKey = dense
|
const formatKey = dense
|
||||||
? `time.formattedTimestampHourMinute.${timeFormat}`
|
? `time.formattedTimestampHourMinute.${timeFormat}`
|
||||||
@ -104,7 +104,7 @@ export function Timestamp({
|
|||||||
const { t } = useTranslation(["common"]);
|
const { t } = useTranslation(["common"]);
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
|
|
||||||
const timeFormat = config?.ui.time_format === "24hour" ? "24hour" : "12hour";
|
const timeFormat = useTimeFormat(config);
|
||||||
const format = t(`time.formattedTimestampHourMinute.${timeFormat}`);
|
const format = t(`time.formattedTimestampHourMinute.${timeFormat}`);
|
||||||
|
|
||||||
const formattedTimestamp = useFormattedTimestamp(
|
const formattedTimestamp = useFormattedTimestamp(
|
||||||
|
|||||||
@ -84,6 +84,18 @@ export function use24HourTime(config: FrigateConfig | undefined) {
|
|||||||
}, [config, localeUses24HourTime]);
|
}, [config, localeUses24HourTime]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the resolved time format key ("24hour" | "12hour") based on config
|
||||||
|
* and browser locale. Use this instead of checking config.ui.time_format directly
|
||||||
|
* to correctly handle the "browser" setting.
|
||||||
|
*/
|
||||||
|
export function useTimeFormat(
|
||||||
|
config: FrigateConfig | undefined,
|
||||||
|
): "24hour" | "12hour" {
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
|
return is24Hour ? "24hour" : "12hour";
|
||||||
|
}
|
||||||
|
|
||||||
export function useFormattedHour(
|
export function useFormattedHour(
|
||||||
config: FrigateConfig | undefined,
|
config: FrigateConfig | undefined,
|
||||||
time: string, // hour is assumed to be in 24 hour format per the Date object
|
time: string, // hour is assumed to be in 24 hour format per the Date object
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { FrigateConfig } from "@/types/frigateConfig";
|
|||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
||||||
import { useDateLocale } from "./use-date-locale";
|
import { useDateLocale } from "./use-date-locale";
|
||||||
|
import { useTimeFormat } from "./use-date-utils";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import useUserInteraction from "./use-user-interaction";
|
import useUserInteraction from "./use-user-interaction";
|
||||||
|
|
||||||
@ -168,7 +169,7 @@ function useDraggableElement({
|
|||||||
const { t } = useTranslation(["common"]);
|
const { t } = useTranslation(["common"]);
|
||||||
const locale = useDateLocale();
|
const locale = useDateLocale();
|
||||||
|
|
||||||
const timeFormat = config?.ui.time_format === "24hour" ? "24hour" : "12hour";
|
const timeFormat = useTimeFormat(config);
|
||||||
const format = useMemo(() => {
|
const format = useMemo(() => {
|
||||||
const formatKey = `time.${
|
const formatKey = `time.${
|
||||||
segmentDuration < 60 && !dense
|
segmentDuration < 60 && !dense
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import { useResizeObserver } from "@/hooks/resize-observer";
|
|||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import ActivityIndicator from "@/components/indicators/activity-indicator";
|
import ActivityIndicator from "@/components/indicators/activity-indicator";
|
||||||
import TimeAgo from "@/components/dynamic/TimeAgo";
|
import TimeAgo from "@/components/dynamic/TimeAgo";
|
||||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
import { useFormattedTimestamp, use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
|
|
||||||
const MOTION_HEATMAP_GRID_SIZE = 16;
|
const MOTION_HEATMAP_GRID_SIZE = 16;
|
||||||
@ -165,9 +165,10 @@ function MotionPreviewClip({
|
|||||||
const [fallbackFrameIndex, setFallbackFrameIndex] = useState(0);
|
const [fallbackFrameIndex, setFallbackFrameIndex] = useState(0);
|
||||||
const [fallbackFramesReady, setFallbackFramesReady] = useState(false);
|
const [fallbackFramesReady, setFallbackFramesReady] = useState(false);
|
||||||
|
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
const formattedDate = useFormattedTimestamp(
|
const formattedDate = useFormattedTimestamp(
|
||||||
range.start_time,
|
range.start_time,
|
||||||
config?.ui.time_format == "24hour"
|
is24Hour
|
||||||
? t("time.formattedTimestampMonthDayHourMinute.24hour", {
|
? t("time.formattedTimestampMonthDayHourMinute.24hour", {
|
||||||
ns: "common",
|
ns: "common",
|
||||||
})
|
})
|
||||||
|
|||||||
@ -43,8 +43,9 @@ import { TimezoneAwareCalendar } from "@/components/overlay/ReviewActivityCalend
|
|||||||
|
|
||||||
import { useApiHost } from "@/api";
|
import { useApiHost } from "@/api";
|
||||||
import { useResizeObserver } from "@/hooks/resize-observer";
|
import { useResizeObserver } from "@/hooks/resize-observer";
|
||||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
import { useFormattedTimestamp, use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import { getUTCOffset } from "@/utils/dateUtil";
|
import { getUTCOffset } from "@/utils/dateUtil";
|
||||||
|
import useSWR from "swr";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import MotionSearchROICanvas from "./MotionSearchROICanvas";
|
import MotionSearchROICanvas from "./MotionSearchROICanvas";
|
||||||
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
|
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
|
||||||
@ -452,7 +453,6 @@ export default function MotionSearchDialog({
|
|||||||
range={searchRange}
|
range={searchRange}
|
||||||
setRange={setSearchRange}
|
setRange={setSearchRange}
|
||||||
defaultRange={defaultRange}
|
defaultRange={defaultRange}
|
||||||
timeFormat={config.ui?.time_format}
|
|
||||||
timezone={timezone}
|
timezone={timezone}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -476,7 +476,6 @@ type SearchRangeSelectorProps = {
|
|||||||
range?: TimeRange;
|
range?: TimeRange;
|
||||||
setRange: React.Dispatch<React.SetStateAction<TimeRange | undefined>>;
|
setRange: React.Dispatch<React.SetStateAction<TimeRange | undefined>>;
|
||||||
defaultRange: TimeRange;
|
defaultRange: TimeRange;
|
||||||
timeFormat?: "browser" | "12hour" | "24hour";
|
|
||||||
timezone?: string;
|
timezone?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -484,7 +483,6 @@ function SearchRangeSelector({
|
|||||||
range,
|
range,
|
||||||
setRange,
|
setRange,
|
||||||
defaultRange,
|
defaultRange,
|
||||||
timeFormat,
|
|
||||||
timezone,
|
timezone,
|
||||||
}: SearchRangeSelectorProps) {
|
}: SearchRangeSelectorProps) {
|
||||||
const { t } = useTranslation(["views/motionSearch", "common"]);
|
const { t } = useTranslation(["views/motionSearch", "common"]);
|
||||||
@ -527,15 +525,18 @@ function SearchRangeSelector({
|
|||||||
return time;
|
return time;
|
||||||
}, [range, defaultRange, timezoneOffset, localTimeOffset]);
|
}, [range, defaultRange, timezoneOffset, localTimeOffset]);
|
||||||
|
|
||||||
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
|
|
||||||
const formattedStart = useFormattedTimestamp(
|
const formattedStart = useFormattedTimestamp(
|
||||||
startTime,
|
startTime,
|
||||||
timeFormat === "24hour"
|
is24Hour
|
||||||
? t("time.formattedTimestamp.24hour", { ns: "common" })
|
? t("time.formattedTimestamp.24hour", { ns: "common" })
|
||||||
: t("time.formattedTimestamp.12hour", { ns: "common" }),
|
: t("time.formattedTimestamp.12hour", { ns: "common" }),
|
||||||
);
|
);
|
||||||
const formattedEnd = useFormattedTimestamp(
|
const formattedEnd = useFormattedTimestamp(
|
||||||
endTime,
|
endTime,
|
||||||
timeFormat === "24hour"
|
is24Hour
|
||||||
? t("time.formattedTimestamp.24hour", { ns: "common" })
|
? t("time.formattedTimestamp.24hour", { ns: "common" })
|
||||||
: t("time.formattedTimestamp.12hour", { ns: "common" }),
|
: t("time.formattedTimestamp.12hour", { ns: "common" }),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -51,7 +51,7 @@ import {
|
|||||||
RecordingSegment,
|
RecordingSegment,
|
||||||
} from "@/types/record";
|
} from "@/types/record";
|
||||||
import { VideoResolutionType } from "@/types/live";
|
import { VideoResolutionType } from "@/types/live";
|
||||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
import { useFormattedTimestamp, use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import MotionSearchROICanvas from "./MotionSearchROICanvas";
|
import MotionSearchROICanvas from "./MotionSearchROICanvas";
|
||||||
import MotionSearchDialog from "./MotionSearchDialog";
|
import MotionSearchDialog from "./MotionSearchDialog";
|
||||||
import { IoMdArrowRoundBack } from "react-icons/io";
|
import { IoMdArrowRoundBack } from "react-icons/io";
|
||||||
@ -94,12 +94,13 @@ export default function MotionSearchView({
|
|||||||
]);
|
]);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
const resultTimestampFormat = useMemo(
|
const resultTimestampFormat = useMemo(
|
||||||
() =>
|
() =>
|
||||||
config.ui?.time_format === "24hour"
|
is24Hour
|
||||||
? t("time.formattedTimestamp.24hour", { ns: "common" })
|
? t("time.formattedTimestamp.24hour", { ns: "common" })
|
||||||
: t("time.formattedTimestamp.12hour", { ns: "common" }),
|
: t("time.formattedTimestamp.12hour", { ns: "common" }),
|
||||||
[config.ui?.time_format, t],
|
[is24Hour, t],
|
||||||
);
|
);
|
||||||
|
|
||||||
// Refs
|
// Refs
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import Chip from "@/components/indicators/Chip";
|
|||||||
import { TooltipPortal } from "@radix-ui/react-tooltip";
|
import { TooltipPortal } from "@radix-ui/react-tooltip";
|
||||||
import SearchActionGroup from "@/components/filter/SearchActionGroup";
|
import SearchActionGroup from "@/components/filter/SearchActionGroup";
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
|
import { use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useAllowedCameras } from "@/hooks/use-allowed-cameras";
|
import { useAllowedCameras } from "@/hooks/use-allowed-cameras";
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ export default function SearchView({
|
|||||||
const { data: config } = useSWR<FrigateConfig>("config", {
|
const { data: config } = useSWR<FrigateConfig>("config", {
|
||||||
revalidateOnFocus: false,
|
revalidateOnFocus: false,
|
||||||
});
|
});
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const { data: exploreEvents } = useSWR<SearchResult[]>(
|
const { data: exploreEvents } = useSWR<SearchResult[]>(
|
||||||
@ -191,10 +193,7 @@ export default function SearchView({
|
|||||||
sub_labels: allSubLabels,
|
sub_labels: allSubLabels,
|
||||||
...(hasCustomClassificationModels && { attributes: allAttributes }),
|
...(hasCustomClassificationModels && { attributes: allAttributes }),
|
||||||
search_type: ["thumbnail", "description"] as SearchSource[],
|
search_type: ["thumbnail", "description"] as SearchSource[],
|
||||||
time_range:
|
time_range: is24Hour ? ["00:00-23:59"] : ["12:00AM-11:59PM"],
|
||||||
config?.ui.time_format == "24hour"
|
|
||||||
? ["00:00-23:59"]
|
|
||||||
: ["12:00AM-11:59PM"],
|
|
||||||
before: [formatDateToLocaleString()],
|
before: [formatDateToLocaleString()],
|
||||||
after: [formatDateToLocaleString(-5)],
|
after: [formatDateToLocaleString(-5)],
|
||||||
min_score: ["50"],
|
min_score: ["50"],
|
||||||
@ -209,6 +208,7 @@ export default function SearchView({
|
|||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
config,
|
config,
|
||||||
|
is24Hour,
|
||||||
allLabels,
|
allLabels,
|
||||||
allZones,
|
allZones,
|
||||||
allSubLabels,
|
allSubLabels,
|
||||||
|
|||||||
@ -39,6 +39,7 @@ import { Trigger, TriggerAction, TriggerType } from "@/types/trigger";
|
|||||||
import { useSearchEffect } from "@/hooks/use-overlay-state";
|
import { useSearchEffect } from "@/hooks/use-overlay-state";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
|
||||||
|
import { use24HourTime } from "@/hooks/use-date-utils";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { useTriggers } from "@/api/ws";
|
import { useTriggers } from "@/api/ws";
|
||||||
import { useCameraFriendlyName } from "@/hooks/use-camera-friendly-name";
|
import { useCameraFriendlyName } from "@/hooks/use-camera-friendly-name";
|
||||||
@ -89,6 +90,7 @@ export default function TriggerView({
|
|||||||
const { t } = useTranslation("views/settings");
|
const { t } = useTranslation("views/settings");
|
||||||
const { data: config, mutate: updateConfig } =
|
const { data: config, mutate: updateConfig } =
|
||||||
useSWR<FrigateConfig>("config");
|
useSWR<FrigateConfig>("config");
|
||||||
|
const is24Hour = use24HourTime(config);
|
||||||
const { data: trigger_status, mutate } = useSWR(
|
const { data: trigger_status, mutate } = useSWR(
|
||||||
config?.cameras[selectedCamera]?.semantic_search?.triggers &&
|
config?.cameras[selectedCamera]?.semantic_search?.triggers &&
|
||||||
Object.keys(config.cameras[selectedCamera].semantic_search.triggers)
|
Object.keys(config.cameras[selectedCamera].semantic_search.triggers)
|
||||||
@ -581,20 +583,19 @@ export default function TriggerView({
|
|||||||
?.last_triggered,
|
?.last_triggered,
|
||||||
{
|
{
|
||||||
timezone: config.ui.timezone,
|
timezone: config.ui.timezone,
|
||||||
date_format:
|
date_format: is24Hour
|
||||||
config.ui.time_format == "24hour"
|
? t(
|
||||||
? t(
|
"time.formattedTimestamp2.24hour",
|
||||||
"time.formattedTimestamp2.24hour",
|
{
|
||||||
{
|
ns: "common",
|
||||||
ns: "common",
|
},
|
||||||
},
|
)
|
||||||
)
|
: t(
|
||||||
: t(
|
"time.formattedTimestamp2.12hour",
|
||||||
"time.formattedTimestamp2.12hour",
|
{
|
||||||
{
|
ns: "common",
|
||||||
ns: "common",
|
},
|
||||||
},
|
),
|
||||||
),
|
|
||||||
time_style: "medium",
|
time_style: "medium",
|
||||||
date_style: "medium",
|
date_style: "medium",
|
||||||
},
|
},
|
||||||
@ -742,20 +743,19 @@ export default function TriggerView({
|
|||||||
?.last_triggered,
|
?.last_triggered,
|
||||||
{
|
{
|
||||||
timezone: config.ui.timezone,
|
timezone: config.ui.timezone,
|
||||||
date_format:
|
date_format: is24Hour
|
||||||
config.ui.time_format == "24hour"
|
? t(
|
||||||
? t(
|
"time.formattedTimestamp2.24hour",
|
||||||
"time.formattedTimestamp2.24hour",
|
{
|
||||||
{
|
ns: "common",
|
||||||
ns: "common",
|
},
|
||||||
},
|
)
|
||||||
)
|
: t(
|
||||||
: t(
|
"time.formattedTimestamp2.12hour",
|
||||||
"time.formattedTimestamp2.12hour",
|
{
|
||||||
{
|
ns: "common",
|
||||||
ns: "common",
|
},
|
||||||
},
|
),
|
||||||
),
|
|
||||||
time_style: "medium",
|
time_style: "medium",
|
||||||
date_style: "medium",
|
date_style: "medium",
|
||||||
},
|
},
|
||||||
|
|||||||
@ -10,7 +10,11 @@ import {
|
|||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { CiCircleAlert } from "react-icons/ci";
|
import { CiCircleAlert } from "react-icons/ci";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { useFormattedTimestamp, useTimezone } from "@/hooks/use-date-utils";
|
import {
|
||||||
|
useFormattedTimestamp,
|
||||||
|
useTimeFormat,
|
||||||
|
useTimezone,
|
||||||
|
} from "@/hooks/use-date-utils";
|
||||||
import { RecordingsSummary } from "@/types/review";
|
import { RecordingsSummary } from "@/types/review";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { TZDate } from "react-day-picker";
|
import { TZDate } from "react-day-picker";
|
||||||
@ -81,7 +85,7 @@ export default function StorageMetrics({
|
|||||||
: null;
|
: null;
|
||||||
}, [recordingsSummary, timezone]);
|
}, [recordingsSummary, timezone]);
|
||||||
|
|
||||||
const timeFormat = config?.ui.time_format === "24hour" ? "24hour" : "12hour";
|
const timeFormat = useTimeFormat(config);
|
||||||
const format = useMemo(() => {
|
const format = useMemo(() => {
|
||||||
return t(`time.formattedTimestampMonthDayYear.${timeFormat}`, {
|
return t(`time.formattedTimestampMonthDayYear.${timeFormat}`, {
|
||||||
ns: "common",
|
ns: "common",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user