forked from Github/frigate
Fix linter and fix lint issues (#10141)
This commit is contained in:
@@ -38,7 +38,7 @@ function ConfigEditor() {
|
||||
editorRef.current.getValue(),
|
||||
{
|
||||
headers: { "Content-Type": "text/plain" },
|
||||
}
|
||||
},
|
||||
)
|
||||
.then((response) => {
|
||||
if (response.status === 200) {
|
||||
@@ -56,7 +56,7 @@ function ConfigEditor() {
|
||||
}
|
||||
});
|
||||
},
|
||||
[editorRef]
|
||||
[editorRef],
|
||||
);
|
||||
|
||||
const handleCopyConfig = useCallback(async () => {
|
||||
@@ -127,24 +127,20 @@ function ConfigEditor() {
|
||||
<div className="lg:flex justify-between mr-1">
|
||||
<Heading as="h2">Config</Heading>
|
||||
<div>
|
||||
<Button
|
||||
size="sm"
|
||||
className="mx-1"
|
||||
onClick={(_) => handleCopyConfig()}
|
||||
>
|
||||
<Button size="sm" className="mx-1" onClick={() => handleCopyConfig()}>
|
||||
Copy Config
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
className="mx-1"
|
||||
onClick={(_) => onHandleSaveConfig("restart")}
|
||||
onClick={() => onHandleSaveConfig("restart")}
|
||||
>
|
||||
Save & Restart
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
className="mx-1"
|
||||
onClick={(_) => onHandleSaveConfig("saveonly")}
|
||||
onClick={() => onHandleSaveConfig("saveonly")}
|
||||
>
|
||||
Save Only
|
||||
</Button>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import useApiFilter from "@/hooks/use-api-filter";
|
||||
import useOverlayState from "@/hooks/use-overlay-state";
|
||||
import { Preview } from "@/types/preview";
|
||||
import { ReviewFilter, ReviewSegment, ReviewSeverity } from "@/types/review";
|
||||
import DesktopRecordingView from "@/views/events/DesktopRecordingView";
|
||||
import EventView from "@/views/events/EventView";
|
||||
@@ -24,6 +25,8 @@ export default function Events() {
|
||||
const onUpdateFilter = useCallback((newFilter: ReviewFilter) => {
|
||||
setSize(1);
|
||||
setReviewFilter(newFilter);
|
||||
// we don't want this updating
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
// review paging
|
||||
@@ -41,9 +44,9 @@ export default function Events() {
|
||||
before: Math.floor(reviewSearchParams["before"]),
|
||||
after: Math.floor(reviewSearchParams["after"]),
|
||||
};
|
||||
}, [reviewSearchParams]);
|
||||
}, [last24Hours, reviewSearchParams]);
|
||||
|
||||
const reviewSegmentFetcher = useCallback((key: any) => {
|
||||
const reviewSegmentFetcher = useCallback((key: Array<string> | string) => {
|
||||
const [path, params] = Array.isArray(key) ? key : [key, undefined];
|
||||
return axios.get(path, { params }).then((res) => res.data);
|
||||
}, []);
|
||||
@@ -74,7 +77,7 @@ export default function Events() {
|
||||
};
|
||||
return ["review", params];
|
||||
},
|
||||
[reviewSearchParams, last24Hours]
|
||||
[reviewSearchParams, last24Hours],
|
||||
);
|
||||
|
||||
const {
|
||||
@@ -90,7 +93,7 @@ export default function Events() {
|
||||
|
||||
const isDone = useMemo(
|
||||
() => (reviewPages?.at(-1)?.length ?? 0) < API_LIMIT,
|
||||
[reviewPages]
|
||||
[reviewPages],
|
||||
);
|
||||
|
||||
const onLoadNextPage = useCallback(() => setSize(size + 1), [size, setSize]);
|
||||
@@ -103,7 +106,7 @@ export default function Events() {
|
||||
if (
|
||||
!reviewPages ||
|
||||
reviewPages.length == 0 ||
|
||||
reviewPages.at(-1)!!.length == 0
|
||||
reviewPages.at(-1)?.length == 0
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -111,7 +114,7 @@ export default function Events() {
|
||||
const startDate = new Date();
|
||||
startDate.setMinutes(0, 0, 0);
|
||||
|
||||
const endDate = new Date(reviewPages.at(-1)!!.at(-1)!!.end_time);
|
||||
const endDate = new Date(reviewPages.at(-1)?.at(-1)?.end_time || 0);
|
||||
endDate.setHours(0, 0, 0, 0);
|
||||
return {
|
||||
start: startDate.getTime() / 1000,
|
||||
@@ -122,7 +125,7 @@ export default function Events() {
|
||||
previewTimes
|
||||
? `preview/all/start/${previewTimes.start}/end/${previewTimes.end}`
|
||||
: null,
|
||||
{ revalidateOnFocus: false }
|
||||
{ revalidateOnFocus: false },
|
||||
);
|
||||
|
||||
// review status
|
||||
@@ -156,11 +159,11 @@ export default function Events() {
|
||||
|
||||
return newData;
|
||||
},
|
||||
{ revalidate: false, populateCache: true }
|
||||
{ revalidate: false, populateCache: true },
|
||||
);
|
||||
}
|
||||
},
|
||||
[updateSegments]
|
||||
[updateSegments],
|
||||
);
|
||||
|
||||
// selected items
|
||||
@@ -176,7 +179,7 @@ export default function Events() {
|
||||
|
||||
const allReviews = reviewPages.flat();
|
||||
const selectedReview = allReviews.find(
|
||||
(item) => item.id == selectedReviewId
|
||||
(item) => item.id == selectedReviewId,
|
||||
);
|
||||
|
||||
if (!selectedReview) {
|
||||
@@ -186,12 +189,15 @@ export default function Events() {
|
||||
return {
|
||||
selected: selectedReview,
|
||||
cameraSegments: allReviews.filter(
|
||||
(seg) => seg.camera == selectedReview.camera
|
||||
(seg) => seg.camera == selectedReview.camera,
|
||||
),
|
||||
cameraPreviews: allPreviews?.filter(
|
||||
(seg) => seg.camera == selectedReview.camera
|
||||
(seg) => seg.camera == selectedReview.camera,
|
||||
),
|
||||
};
|
||||
|
||||
// previews will not update after item is selected
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedReviewId, reviewPages]);
|
||||
|
||||
if (selectedData) {
|
||||
|
||||
@@ -51,7 +51,7 @@ function Export() {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
const { data: exports, mutate } = useSWR<ExportItem[]>(
|
||||
"exports/",
|
||||
(url: string) => axios({ baseURL: baseUrl, url }).then((res) => res.data)
|
||||
(url: string) => axios({ baseURL: baseUrl, url }).then((res) => res.data),
|
||||
);
|
||||
|
||||
// Export States
|
||||
@@ -96,7 +96,7 @@ function Export() {
|
||||
parseInt(startHour),
|
||||
parseInt(startMin),
|
||||
parseInt(startSec),
|
||||
0
|
||||
0,
|
||||
);
|
||||
const start = startDate.getTime() / 1000;
|
||||
const endDate = new Date((date.to || date.from).getTime());
|
||||
@@ -117,7 +117,7 @@ function Export() {
|
||||
if (response.status == 200) {
|
||||
toast.success(
|
||||
"Successfully started export. View the file in the /exports folder.",
|
||||
{ position: "top-center" }
|
||||
{ position: "top-center" },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ function Export() {
|
||||
if (error.response?.data?.message) {
|
||||
toast.error(
|
||||
`Failed to start export: ${error.response.data.message}`,
|
||||
{ position: "top-center" }
|
||||
{ position: "top-center" },
|
||||
);
|
||||
} else {
|
||||
toast.error(`Failed to start export: ${error.message}`, {
|
||||
@@ -148,7 +148,7 @@ function Export() {
|
||||
mutate();
|
||||
}
|
||||
});
|
||||
}, [deleteClip]);
|
||||
}, [deleteClip, mutate]);
|
||||
|
||||
return (
|
||||
<div className="w-full h-full overflow-hidden">
|
||||
@@ -156,7 +156,7 @@ function Export() {
|
||||
|
||||
<AlertDialog
|
||||
open={deleteClip != undefined}
|
||||
onOpenChange={(_) => setDeleteClip(undefined)}
|
||||
onOpenChange={() => setDeleteClip(undefined)}
|
||||
>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
@@ -176,7 +176,7 @@ function Export() {
|
||||
|
||||
<Dialog
|
||||
open={selectedClip != undefined}
|
||||
onOpenChange={(_) => setSelectedClip(undefined)}
|
||||
onOpenChange={() => setSelectedClip(undefined)}
|
||||
>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
|
||||
@@ -20,7 +20,7 @@ function Live() {
|
||||
|
||||
const [layout, setLayout] = usePersistence<"grid" | "list">(
|
||||
"live-layout",
|
||||
isDesktop ? "grid" : "list"
|
||||
isDesktop ? "grid" : "list",
|
||||
);
|
||||
|
||||
// recent events
|
||||
@@ -40,7 +40,7 @@ function Live() {
|
||||
updateEvents();
|
||||
return;
|
||||
}
|
||||
}, [eventUpdate]);
|
||||
}, [eventUpdate, updateEvents]);
|
||||
|
||||
const events = useMemo(() => {
|
||||
if (!allEvents) {
|
||||
@@ -76,7 +76,7 @@ function Live() {
|
||||
return () => {
|
||||
removeEventListener("visibilitychange", visibilityListener);
|
||||
};
|
||||
}, []);
|
||||
}, [visibilityListener]);
|
||||
|
||||
return (
|
||||
<div className="size-full overflow-y-scroll px-2">
|
||||
@@ -123,7 +123,7 @@ function Live() {
|
||||
>
|
||||
{cameras.map((camera) => {
|
||||
let grow;
|
||||
let aspectRatio = camera.detect.width / camera.detect.height;
|
||||
const aspectRatio = camera.detect.width / camera.detect.height;
|
||||
if (aspectRatio > 2) {
|
||||
grow = `${layout == "grid" ? "col-span-2" : ""} aspect-wide`;
|
||||
} else if (aspectRatio < 1) {
|
||||
|
||||
@@ -57,7 +57,7 @@ function Logs() {
|
||||
// no op
|
||||
}
|
||||
},
|
||||
[setEndVisible]
|
||||
[setEndVisible],
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -47,7 +47,7 @@ function Storage() {
|
||||
service["storage"]["/media/frigate/recordings"]["total"] !=
|
||||
service["storage"]["/media/frigate/clips"]["total"]
|
||||
);
|
||||
}, service);
|
||||
}, [service]);
|
||||
|
||||
const getUnitSize = (MB: number) => {
|
||||
if (isNaN(MB) || MB < 0) return "Invalid number";
|
||||
@@ -106,12 +106,12 @@ function Storage() {
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{getUnitSize(
|
||||
service["storage"]["/media/frigate/recordings"]["used"]
|
||||
service["storage"]["/media/frigate/recordings"]["used"],
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{getUnitSize(
|
||||
service["storage"]["/media/frigate/recordings"]["total"]
|
||||
service["storage"]["/media/frigate/recordings"]["total"],
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
@@ -120,12 +120,12 @@ function Storage() {
|
||||
<TableCell>Snapshots</TableCell>
|
||||
<TableCell>
|
||||
{getUnitSize(
|
||||
service["storage"]["/media/frigate/clips"]["used"]
|
||||
service["storage"]["/media/frigate/clips"]["used"],
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{getUnitSize(
|
||||
service["storage"]["/media/frigate/clips"]["total"]
|
||||
service["storage"]["/media/frigate/clips"]["total"],
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
@@ -2,7 +2,6 @@ import { useMemo, useRef, useState } from "react";
|
||||
import Heading from "@/components/ui/heading";
|
||||
import useSWR from "swr";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import { Event } from "@/types/event";
|
||||
import ActivityIndicator from "@/components/ui/activity-indicator";
|
||||
import EventReviewTimeline from "@/components/timeline/EventReviewTimeline";
|
||||
import { ReviewData, ReviewSegment, ReviewSeverity } from "@/types/review";
|
||||
@@ -84,19 +83,9 @@ function UIPlayground() {
|
||||
const contentRef = useRef<HTMLDivElement>(null);
|
||||
const [mockEvents, setMockEvents] = useState<ReviewSegment[]>([]);
|
||||
const [handlebarTime, setHandlebarTime] = useState(
|
||||
Math.floor(Date.now() / 1000) - 15 * 60
|
||||
Math.floor(Date.now() / 1000) - 15 * 60,
|
||||
);
|
||||
|
||||
const recentTimestamp = useMemo(() => {
|
||||
const now = new Date();
|
||||
now.setMinutes(now.getMinutes() - 240);
|
||||
return now.getTime() / 1000;
|
||||
}, []);
|
||||
const { data: events } = useSWR<Event[]>([
|
||||
"events",
|
||||
{ limit: 10, after: recentTimestamp },
|
||||
]);
|
||||
|
||||
useMemo(() => {
|
||||
const initialEvents = Array.from({ length: 50 }, generateRandomEvent);
|
||||
setMockEvents(initialEvents);
|
||||
@@ -108,16 +97,16 @@ function UIPlayground() {
|
||||
return Math.min(...mockEvents.map((event) => event.start_time));
|
||||
}
|
||||
return Math.floor(Date.now() / 1000); // Default to current time if no events
|
||||
}, [events]);
|
||||
}, [mockEvents]);
|
||||
|
||||
const minimapEndTime = useMemo(() => {
|
||||
if (mockEvents && mockEvents.length > 0) {
|
||||
return Math.max(
|
||||
...mockEvents.map((event) => event.end_time ?? event.start_time)
|
||||
...mockEvents.map((event) => event.end_time ?? event.start_time),
|
||||
);
|
||||
}
|
||||
return Math.floor(Date.now() / 1000); // Default to current time if no events
|
||||
}, [events]);
|
||||
}, [mockEvents]);
|
||||
|
||||
const [zoomLevel, setZoomLevel] = useState(0);
|
||||
const [zoomSettings, setZoomSettings] = useState({
|
||||
@@ -134,7 +123,7 @@ function UIPlayground() {
|
||||
function handleZoomIn() {
|
||||
const nextZoomLevel = Math.min(
|
||||
possibleZoomLevels.length - 1,
|
||||
zoomLevel + 1
|
||||
zoomLevel + 1,
|
||||
);
|
||||
setZoomLevel(nextZoomLevel);
|
||||
setZoomSettings(possibleZoomLevels[nextZoomLevel]);
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
import {
|
||||
LuConstruction,
|
||||
LuFileUp,
|
||||
LuFlag,
|
||||
LuVideo,
|
||||
} from "react-icons/lu";
|
||||
import { LuConstruction, LuFileUp, LuFlag, LuVideo } from "react-icons/lu";
|
||||
|
||||
export const navbarLinks = [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user