Handle time range in am/pm based on browser

This commit is contained in:
Nicolas Mowen 2024-09-25 08:29:44 -06:00
parent 28d2f72a96
commit ce2bb45c55
3 changed files with 72 additions and 7 deletions

View File

@ -17,6 +17,8 @@ import {
SearchFilter,
SearchFilters,
SearchSource,
DEFAULT_TIME_RANGE_AFTER,
DEFAULT_TIME_RANGE_BEFORE,
} from "@/types/search";
import { DateRange } from "react-day-picker";
import { cn } from "@/lib/utils";
@ -26,6 +28,7 @@ import { MdLabel } from "react-icons/md";
import SearchSourceIcon from "../icons/SearchSourceIcon";
import PlatformAwareDialog from "../overlay/dialog/PlatformAwareDialog";
import { FaArrowRight, FaClock } from "react-icons/fa";
import { useFormattedHour } from "@/hooks/use-date-utils";
type SearchFilterGroupProps = {
className: string;
@ -172,6 +175,7 @@ export default function SearchFilterGroup({
)}
{filters.includes("time") && (
<TimeRangeFilterButton
config={config}
timeRange={filter?.time_range}
updateTimeRange={(time_range) =>
onUpdateFilter({ ...filter, time_range })
@ -395,10 +399,12 @@ export function GeneralFilterContent({
}
type TimeRangeFilterButtonProps = {
config?: FrigateConfig;
timeRange?: string;
updateTimeRange: (range: string | undefined) => void;
};
function TimeRangeFilterButton({
config,
timeRange,
updateTimeRange,
}: TimeRangeFilterButtonProps) {
@ -408,7 +414,7 @@ function TimeRangeFilterButton({
const [afterHour, beforeHour] = useMemo(() => {
if (!timeRange || !timeRange.includes(",")) {
return ["00:00", "24:00"];
return [DEFAULT_TIME_RANGE_AFTER, DEFAULT_TIME_RANGE_BEFORE];
}
return timeRange.split(",");
@ -417,6 +423,13 @@ function TimeRangeFilterButton({
const [selectedAfterHour, setSelectedAfterHour] = useState(afterHour);
const [selectedBeforeHour, setSelectedBeforeHour] = useState(beforeHour);
// format based on locale
const formattedAfter = useFormattedHour(config, afterHour);
const formattedBefore = useFormattedHour(config, beforeHour);
const formattedSelectedAfter = useFormattedHour(config, selectedAfterHour);
const formattedSelectedBefore = useFormattedHour(config, selectedBeforeHour);
const trigger = (
<Button
size="sm"
@ -429,7 +442,7 @@ function TimeRangeFilterButton({
<div
className={`${timeRange ? "text-selected-foreground" : "text-primary"}`}
>
{timeRange ? `${afterHour} - ${beforeHour}` : "All Times"}
{timeRange ? `${formattedAfter} - ${formattedBefore}` : "All Times"}
</div>
</Button>
);
@ -456,7 +469,7 @@ function TimeRangeFilterButton({
setEndOpen(false);
}}
>
{selectedAfterHour}
{formattedSelectedAfter}
</Button>
</PopoverTrigger>
<PopoverContent className="flex flex-col items-center">
@ -493,7 +506,7 @@ function TimeRangeFilterButton({
setStartOpen(false);
}}
>
{selectedBeforeHour}
{formattedSelectedBefore}
</Button>
</PopoverTrigger>
<PopoverContent className="flex flex-col items-center">
@ -519,7 +532,10 @@ function TimeRangeFilterButton({
<Button
variant="select"
onClick={() => {
if (selectedAfterHour == "00:00" && selectedBeforeHour == "24:00") {
if (
selectedAfterHour == DEFAULT_TIME_RANGE_AFTER &&
selectedBeforeHour == DEFAULT_TIME_RANGE_BEFORE
) {
updateTimeRange(undefined);
} else {
updateTimeRange(`${selectedAfterHour},${selectedBeforeHour}`);
@ -532,8 +548,8 @@ function TimeRangeFilterButton({
</Button>
<Button
onClick={() => {
setSelectedAfterHour("00:00");
setSelectedBeforeHour("24:00");
setSelectedAfterHour(DEFAULT_TIME_RANGE_AFTER);
setSelectedBeforeHour(DEFAULT_TIME_RANGE_BEFORE);
}}
>
Reset

View File

@ -43,3 +43,49 @@ export function useTimezone(config: FrigateConfig | undefined) {
);
}, [config]);
}
function use24HourTime(config: FrigateConfig | undefined) {
const localeUses24HourTime = useMemo(
() =>
new Intl.DateTimeFormat(undefined, {
hour: "numeric",
})
?.formatToParts(new Date(2020, 0, 1, 13))
?.find((part) => part.type === "hour")?.value?.length === 2,
[],
);
return useMemo(() => {
if (!config) {
return false;
}
if (config.ui.time_format != "browser") {
return config.ui.time_format == "24hour";
}
return localeUses24HourTime;
}, [config, localeUses24HourTime]);
}
export function useFormattedHour(
config: FrigateConfig | undefined,
time: string, // hour is assumed to be in 24 hour format per the Date object
) {
const hour24 = use24HourTime(config);
return useMemo(() => {
if (hour24) {
return time;
}
const [hour, minute] = time.includes(":") ? time.split(":") : [time, "00"];
const hourNum = parseInt(hour);
if (hourNum < 12) {
return `${hourNum}:${minute} AM`;
} else {
return `${hourNum - 12}:${minute} PM`;
}
}, [hour24, time]);
}

View File

@ -61,6 +61,9 @@ export type SearchFilter = {
event_id?: string;
};
export const DEFAULT_TIME_RANGE_AFTER = "00:00";
export const DEFAULT_TIME_RANGE_BEFORE = "23:59";
export type SearchQueryParams = {
cameras?: string[];
labels?: string[];