mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-12-23 19:11:14 +01:00
Add ability to use 12 hour time in input time filter (#13961)
This commit is contained in:
parent
45aceea53b
commit
be3e1831d4
@ -38,6 +38,7 @@ import {
|
||||
convertTo12Hour,
|
||||
getIntlDateFormat,
|
||||
isValidTimeRange,
|
||||
to24Hour,
|
||||
} from "@/utils/dateUtil";
|
||||
import { toast } from "sonner";
|
||||
import useSWR from "swr";
|
||||
@ -191,7 +192,8 @@ export default function InputWithTags({
|
||||
if (
|
||||
allSuggestions[type as FilterType]?.includes(value) ||
|
||||
type == "before" ||
|
||||
type == "after"
|
||||
type == "after" ||
|
||||
type == "time_range"
|
||||
) {
|
||||
const newFilters = { ...filters };
|
||||
let timestamp = 0;
|
||||
@ -235,23 +237,6 @@ export default function InputWithTags({
|
||||
}
|
||||
break;
|
||||
case "time_range":
|
||||
if (!value.includes(",")) {
|
||||
toast.error(
|
||||
"The correct format is after,before. Example: 15:00,18:00.",
|
||||
{
|
||||
position: "top-center",
|
||||
},
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isValidTimeRange(value)) {
|
||||
toast.error("Time range is not valid.", {
|
||||
position: "top-center",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
newFilters[type] = value;
|
||||
break;
|
||||
case "search_type":
|
||||
@ -299,7 +284,9 @@ export default function InputWithTags({
|
||||
: (filterValues as number)) * 1000,
|
||||
).toLocaleDateString(window.navigator?.language || "en-US");
|
||||
} else if (filterType === "time_range") {
|
||||
const [startTime, endTime] = (filterValues as string).split(",");
|
||||
const [startTime, endTime] = (filterValues as string)
|
||||
.replace("-", ",")
|
||||
.split(",");
|
||||
return `${
|
||||
config?.ui.time_format === "24hour"
|
||||
? startTime
|
||||
@ -320,9 +307,23 @@ export default function InputWithTags({
|
||||
if (
|
||||
allSuggestions[filterType]?.includes(trimmedValue) ||
|
||||
((filterType === "before" || filterType === "after") &&
|
||||
trimmedValue.match(/^\d{8}$/))
|
||||
trimmedValue.match(/^\d{8}$/)) ||
|
||||
(filterType === "time_range" &&
|
||||
isValidTimeRange(
|
||||
trimmedValue.replace("-", ","),
|
||||
config?.ui.time_format,
|
||||
))
|
||||
) {
|
||||
createFilter(filterType, trimmedValue);
|
||||
createFilter(
|
||||
filterType,
|
||||
filterType === "time_range"
|
||||
? trimmedValue
|
||||
.replace("-", ",")
|
||||
.split(",")
|
||||
.map((time) => to24Hour(time.trim(), config?.ui.time_format))
|
||||
.join(",")
|
||||
: trimmedValue,
|
||||
);
|
||||
setInputValue((prev) => {
|
||||
const regex = new RegExp(
|
||||
`${filterType}:${filterValue.trim()}[,\\s]*`,
|
||||
@ -335,7 +336,7 @@ export default function InputWithTags({
|
||||
setCurrentFilterType(null);
|
||||
}
|
||||
},
|
||||
[allSuggestions, createFilter],
|
||||
[allSuggestions, createFilter, config],
|
||||
);
|
||||
|
||||
const handleInputChange = useCallback(
|
||||
@ -362,18 +363,11 @@ export default function InputWithTags({
|
||||
if (filterType in allSuggestions) {
|
||||
setCurrentFilterType(filterType);
|
||||
|
||||
if (filterType === "before" || filterType === "after") {
|
||||
// For before and after, we don't need to update suggestions
|
||||
if (filterValue.match(/^\d{8}$/)) {
|
||||
handleFilterCreation(filterType, filterValue);
|
||||
}
|
||||
} else {
|
||||
updateSuggestions(filterValue, filterType);
|
||||
updateSuggestions(filterValue, filterType);
|
||||
|
||||
// Check if the last character is a space or comma
|
||||
if (isLastCharSpaceOrComma) {
|
||||
handleFilterCreation(filterType, filterValue);
|
||||
}
|
||||
// Check if the last character is a space or comma
|
||||
if (isLastCharSpaceOrComma) {
|
||||
handleFilterCreation(filterType, filterValue);
|
||||
}
|
||||
} else {
|
||||
resetSuggestions(value);
|
||||
@ -413,6 +407,13 @@ export default function InputWithTags({
|
||||
(suggestion: string) => {
|
||||
if (currentFilterType) {
|
||||
// Apply the selected suggestion to the current filter type
|
||||
if (currentFilterType == "time_range") {
|
||||
suggestion = suggestion
|
||||
.replace("-", ",")
|
||||
.split(",")
|
||||
.map((time) => to24Hour(time.trim(), config?.ui.time_format))
|
||||
.join(",");
|
||||
}
|
||||
createFilter(currentFilterType, suggestion);
|
||||
setInputValue((prev) => {
|
||||
const regex = new RegExp(`${currentFilterType}:[^\\s,]*`, "g");
|
||||
@ -439,7 +440,7 @@ export default function InputWithTags({
|
||||
|
||||
inputRef.current?.focus();
|
||||
},
|
||||
[createFilter, currentFilterType, allSuggestions],
|
||||
[createFilter, currentFilterType, allSuggestions, config],
|
||||
);
|
||||
|
||||
const handleSearch = useCallback(
|
||||
@ -565,7 +566,7 @@ export default function InputWithTags({
|
||||
<h3 className="font-medium">How to use text filters</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Filters help you narrow down your search results. Here's how
|
||||
to use them:
|
||||
to use them in the input field:
|
||||
</p>
|
||||
<ul className="list-disc pl-5 text-sm text-primary-variant">
|
||||
<li>
|
||||
@ -575,11 +576,21 @@ export default function InputWithTags({
|
||||
Select a value from the suggestions or type your own.
|
||||
</li>
|
||||
<li>
|
||||
Use multiple filters by adding them one after another.
|
||||
Use multiple filters by adding them one after another with
|
||||
a space in between.
|
||||
</li>
|
||||
<li>
|
||||
Date filters (before: and after:) use{" "}
|
||||
{getIntlDateFormat()} format.
|
||||
<em>{getIntlDateFormat()}</em> format.
|
||||
</li>
|
||||
<li>
|
||||
Time range filter uses{" "}
|
||||
<em>
|
||||
{config?.ui.time_format == "24hour"
|
||||
? "15:00-16:00"
|
||||
: "3:00PM-4:00PM"}{" "}
|
||||
</em>
|
||||
format.
|
||||
</li>
|
||||
<li>Remove filters by clicking the 'x' next to them.</li>
|
||||
</ul>
|
||||
@ -587,6 +598,7 @@ export default function InputWithTags({
|
||||
Example:{" "}
|
||||
<code className="text-primary">
|
||||
cameras:front_door label:person before:01012024
|
||||
time_range:3:00PM-4:00PM
|
||||
</code>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -387,22 +387,54 @@ export function formatDateToLocaleString(daysOffset: number = 0): string {
|
||||
.replace(/[^\d]/g, "");
|
||||
}
|
||||
|
||||
export function isValidTimeRange(rangeString: string): boolean {
|
||||
const range = rangeString.split(",");
|
||||
export function to24Hour(
|
||||
time: string,
|
||||
time_format: "12hour" | "24hour" | "browser" = "24hour",
|
||||
): string {
|
||||
const is24HourFormat = time_format === "24hour";
|
||||
|
||||
if (is24HourFormat) return time;
|
||||
|
||||
const [timePart, ampm] = time.split(/([AP]M)/i);
|
||||
|
||||
if (!timePart || !ampm) {
|
||||
throw new Error(`Invalid time format: ${time}`);
|
||||
}
|
||||
|
||||
let hours = Number(timePart.split(":")[0]);
|
||||
const minutes = Number(timePart.split(":")[1]);
|
||||
|
||||
if (ampm.toUpperCase() === "PM" && hours !== 12) hours += 12;
|
||||
if (ampm.toUpperCase() === "AM" && hours === 12) hours = 0;
|
||||
|
||||
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
export function isValidTimeRange(
|
||||
rangeString: string,
|
||||
time_format?: "12hour" | "24hour" | "browser",
|
||||
): boolean {
|
||||
const range = rangeString.split(",");
|
||||
if (range.length !== 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const is24HourFormat = time_format === "24hour";
|
||||
|
||||
const toMinutes = (time: string): number => {
|
||||
const [h, m] = time.split(":").map(Number);
|
||||
const [h, m] = to24Hour(time, time_format).split(":").map(Number);
|
||||
return h * 60 + m;
|
||||
};
|
||||
|
||||
const isValidTime = (time: string): boolean =>
|
||||
/^(?:([01]\d|2[0-3]):([0-5]\d)|24:00)$/.test(time);
|
||||
const isValidTime = (time: string): boolean => {
|
||||
if (is24HourFormat) {
|
||||
return /^(?:([01]\d|2[0-3]):([0-5]\d)|24:00)$/.test(time);
|
||||
} else {
|
||||
return /^(0?[1-9]|1[0-2]):[0-5][0-9](A|P)M$/i.test(time);
|
||||
}
|
||||
};
|
||||
|
||||
const [startTime, endTime] = range;
|
||||
const [startTime, endTime] = range.map((t) => t.trim());
|
||||
|
||||
return (
|
||||
isValidTime(startTime) &&
|
||||
|
@ -121,7 +121,10 @@ export default function SearchView({
|
||||
zones: Object.values(allZones || {}),
|
||||
sub_labels: allSubLabels,
|
||||
search_type: ["thumbnail", "description"] as SearchSource[],
|
||||
time_range: ["00:00,24:00"],
|
||||
time_range:
|
||||
config?.ui.time_format == "24hour"
|
||||
? ["00:00-23:59"]
|
||||
: ["12:00AM-11:59PM"],
|
||||
before: [formatDateToLocaleString()],
|
||||
after: [formatDateToLocaleString(-5)],
|
||||
}),
|
||||
|
Loading…
Reference in New Issue
Block a user