diff --git a/web/src/components/filter/ReviewFilterGroup.tsx b/web/src/components/filter/ReviewFilterGroup.tsx
index 3216dd409..e0e27a321 100644
--- a/web/src/components/filter/ReviewFilterGroup.tsx
+++ b/web/src/components/filter/ReviewFilterGroup.tsx
@@ -3,7 +3,7 @@ import { Button } from "../ui/button";
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
import useSWR from "swr";
import { FrigateConfig } from "@/types/frigateConfig";
-import { useMemo, useState } from "react";
+import { useCallback, useMemo, useState } from "react";
import {
DropdownMenu,
DropdownMenuContent,
@@ -13,7 +13,11 @@ import {
} from "../ui/dropdown-menu";
import { Calendar } from "../ui/calendar";
import { ReviewFilter } from "@/types/review";
-import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
+import {
+ formatUnixTimestampToDateTime,
+ getEndOfDayTimestamp,
+} from "@/utils/dateUtil";
+import { useFormattedTimestamp } from "@/hooks/use-date-utils";
const ATTRIBUTES = ["amazon", "face", "fedex", "license_plate", "ups"];
@@ -55,6 +59,19 @@ export default function ReviewFilterGroup({
[config, allLabels]
);
+ // handle updating filters
+
+ const onUpdateSelectedDay = useCallback(
+ (day?: Date) => {
+ onUpdateFilter({
+ ...filter,
+ after: day == undefined ? undefined : day.getTime() / 1000,
+ before: day == undefined ? undefined : getEndOfDayTimestamp(day),
+ });
+ },
+ [onUpdateFilter]
+ );
+
return (
-
+
setOpen(open)}>
-
-
-
-
-
-
-
-
-
-
-
- Filter Labels
-
- {
- if (isChecked) {
- setSelectedFilters({
- ...selectedFilters,
- labels: ["all"],
- });
- }
- }}
- />
-
- {filterValues.labels.map((item) => (
- {
- if (isChecked) {
- const selectedLabels = allItems.labels
- ? []
- : [...selectedFilters.labels];
- selectedLabels.push(item);
- setSelectedFilters({
- ...selectedFilters,
- labels: selectedLabels,
- });
- } else {
- const selectedLabelList = [...selectedFilters.labels];
-
- // can not deselect the last item
- if (selectedLabelList.length > 1) {
- selectedLabelList.splice(
- selectedLabelList.indexOf(item),
- 1
- );
- setSelectedFilters({
- ...selectedFilters,
- labels: selectedLabelList,
- });
- }
- }
- }}
- />
- ))}
-
-
-
-
-
-
-
- Detail Level
-
- {
- setSelectedFilters({
- ...selectedFilters,
- // @ts-ignore we know that value is one of the detailLevel
- detailLevel: value,
- });
- }}
- >
-
- Normal
-
-
- Extra
-
- Full
-
-
-
void;
};
-function CalendarFilterButton({ before, after }: CalendarFilterButtonProps) {
+function CalendarFilterButton({
+ day,
+ updateSelectedDay,
+}: CalendarFilterButtonProps) {
+ const [selectedDay, setSelectedDay] = useState(day);
const disabledDates = useMemo(() => {
const tomorrow = new Date();
tomorrow.setHours(tomorrow.getHours() + 24, -1, 0, 0);
@@ -308,28 +233,34 @@ function CalendarFilterButton({ before, after }: CalendarFilterButtonProps) {
future.setFullYear(tomorrow.getFullYear() + 10);
return { from: tomorrow, to: future };
}, []);
- // @ts-ignore
- const dateRange = useMemo(() => {
- return before == undefined || after == undefined
- ? undefined
- : {
- from: new Date(after * 1000),
- to: new Date(before * 1000),
- };
- }, [before, after]);
+ const selectedDate = useFormattedTimestamp(
+ day == undefined ? 0 : day?.getTime() / 1000,
+ "%b %-d"
+ );
return (
-
+ {
+ if (!open) {
+ updateSelectedDay(selectedDay);
+ }
+ }}
+ >
-
+ {
+ setSelectedDay(day);
+ }}
+ />
);
@@ -364,11 +295,18 @@ function GeneralFilterButton({
selectedLabels={selectedLabels}
updateLabelFilter={updateLabelFilter}
/>
- setShowReviewed(isChecked)}
- />
+
diff --git a/web/src/components/player/PreviewThumbnailPlayer.tsx b/web/src/components/player/PreviewThumbnailPlayer.tsx
index 598aa234b..5884f2c0b 100644
--- a/web/src/components/player/PreviewThumbnailPlayer.tsx
+++ b/web/src/components/player/PreviewThumbnailPlayer.tsx
@@ -18,6 +18,7 @@ import {
} from "../ui/context-menu";
import { LuCheckSquare, LuFileUp, LuTrash } from "react-icons/lu";
import axios from "axios";
+import { useFormattedTimestamp } from "@/hooks/use-date-utils";
type PreviewPlayerProps = {
review: ReviewSegment;
@@ -92,6 +93,13 @@ export default function PreviewThumbnailPlayer({
[hoverTimeout, review]
);
+ // date
+
+ const formattedDate = useFormattedTimestamp(
+ review.start_time,
+ config?.ui.time_format == "24hour" ? "%b %-d, %H:%M" : "%b %-d, %I:%M %p"
+ );
+
return (
@@ -137,13 +145,7 @@ export default function PreviewThumbnailPlayer({
{!playingBack && (
- {config &&
- formatUnixTimestampToDateTime(review.start_time, {
- strftime_fmt:
- config.ui.time_format == "24hour"
- ? "%b %-d, %H:%M"
- : "%b %-d, %I:%M %p",
- })}
+ {formattedDate}
)}
diff --git a/web/src/hooks/use-date-utils.ts b/web/src/hooks/use-date-utils.ts
new file mode 100644
index 000000000..99ee55f59
--- /dev/null
+++ b/web/src/hooks/use-date-utils.ts
@@ -0,0 +1,12 @@
+import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
+import { useMemo } from "react";
+
+export function useFormattedTimestamp(timestamp: number, format: string) {
+ const formattedTimestamp = useMemo(() => {
+ return formatUnixTimestampToDateTime(timestamp, {
+ strftime_fmt: format,
+ });
+ }, [format, timestamp]);
+
+ return formattedTimestamp;
+}
diff --git a/web/src/pages/Events.tsx b/web/src/pages/Events.tsx
index dcc549386..2d1cb66bc 100644
--- a/web/src/pages/Events.tsx
+++ b/web/src/pages/Events.tsx
@@ -21,6 +21,11 @@ export default function Events() {
const [reviewFilter, setReviewFilter, reviewSearchParams] =
useApiFilter();
+ const onUpdateFilter = useCallback((newFilter: ReviewFilter) => {
+ setSize(1);
+ setReviewFilter(newFilter);
+ }, [])
+
// review paging
const timeRange = useMemo(() => {
@@ -34,7 +39,6 @@ export default function Events() {
const getKey = useCallback(
(index: number, prevData: ReviewSegment[]) => {
- console.log("The params are " + JSON.stringify(reviewSearchParams))
if (index > 0) {
const lastDate = prevData[prevData.length - 1].start_time;
reviewSearchParams;
@@ -137,7 +141,7 @@ export default function Events() {
return newData;
},
- { revalidate: false }
+ { revalidate: false, populateCache: true }
);
}
},
@@ -209,7 +213,7 @@ export default function Events() {
markItemAsReviewed={markItemAsReviewed}
onSelectReview={setSelectedReviewId}
pullLatestData={updateSegments}
- updateFilter={setReviewFilter}
+ updateFilter={onUpdateFilter}
/>
);
}
diff --git a/web/src/utils/dateUtil.ts b/web/src/utils/dateUtil.ts
index f17a261fc..244dcb586 100644
--- a/web/src/utils/dateUtil.ts
+++ b/web/src/utils/dateUtil.ts
@@ -293,6 +293,11 @@ export function endOfHourOrCurrentTime(timestamp: number) {
return Math.min(timestamp, now.getTime() / 1000);
}
+export function getEndOfDayTimestamp(date: Date) {
+ date.setHours(23, 59, 59, 999);
+ return date.getTime() / 1000;
+}
+
export function isCurrentHour(timestamp: number) {
const now = new Date();
now.setMinutes(0, 0, 0);
diff --git a/web/vite.config.ts b/web/vite.config.ts
index a97dbd014..5d5bf8207 100644
--- a/web/vite.config.ts
+++ b/web/vite.config.ts
@@ -12,24 +12,24 @@ export default defineConfig({
server: {
proxy: {
'/api': {
- target: 'http://localhost:5000',
+ target: 'http://192.168.50.106:5000',
ws: true,
},
'/vod': {
- target: 'http://localhost:5000'
+ target: 'http://192.168.50.106:5000'
},
'/clips': {
- target: 'http://localhost:5000'
+ target: 'http://192.168.50.106:5000'
},
'/exports': {
- target: 'http://localhost:5000'
+ target: 'http://192.168.50.106:5000'
},
'/ws': {
- target: 'ws://localhost:5000',
+ target: 'ws://192.168.50.106:5000',
ws: true,
},
'/live': {
- target: 'ws://localhost:5000',
+ target: 'ws://192.168.50.106:5000',
changeOrigin: true,
ws: true,
},