mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-10 21:25:24 +03:00
implement custom hook
This commit is contained in:
parent
4f0a7d961a
commit
f91116df52
@ -2,7 +2,7 @@ import { Button } from "../ui/button";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
||||
import useSWR from "swr";
|
||||
import { CameraGroupConfig, FrigateConfig } from "@/types/frigateConfig";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@ -29,6 +29,7 @@ import ReviewActivityCalendar from "../overlay/ReviewActivityCalendar";
|
||||
import MobileReviewSettingsDrawer, {
|
||||
DrawerFeatures,
|
||||
} from "../overlay/MobileReviewSettingsDrawer";
|
||||
import useOptimisticState from "@/hooks/use-optimistic-state";
|
||||
|
||||
const REVIEW_FILTERS = [
|
||||
"cameras",
|
||||
@ -631,12 +632,10 @@ function ShowMotionOnlyButton({
|
||||
motionOnly,
|
||||
setMotionOnly,
|
||||
}: ShowMotionOnlyButtonProps) {
|
||||
const [motionOnlyButton, setMotionOnlyButton] = useState(motionOnly);
|
||||
|
||||
useEffect(() => {
|
||||
const timeoutId = setTimeout(() => setMotionOnly(motionOnlyButton), 10);
|
||||
return () => clearTimeout(timeoutId);
|
||||
}, [motionOnlyButton, setMotionOnly]);
|
||||
const [motionOnlyButton, setMotionOnlyButton] = useOptimisticState(
|
||||
motionOnly,
|
||||
setMotionOnly,
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
43
web/src/hooks/use-optimistic-state.ts
Normal file
43
web/src/hooks/use-optimistic-state.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { useState, useEffect, useCallback, useRef } from "react";
|
||||
|
||||
type OptimisticStateResult<T> = [T, (newValue: T) => void];
|
||||
|
||||
const useOptimisticState = <T>(
|
||||
initialState: T,
|
||||
setState: (newValue: T) => void,
|
||||
delay: number = 20,
|
||||
): OptimisticStateResult<T> => {
|
||||
const [optimisticValue, setOptimisticValue] = useState<T>(initialState);
|
||||
const debounceTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
|
||||
const handleValueChange = useCallback(
|
||||
(newValue: T) => {
|
||||
// Update the optimistic value immediately
|
||||
setOptimisticValue(newValue);
|
||||
|
||||
// Clear any pending debounce timeout
|
||||
if (debounceTimeout.current) {
|
||||
clearTimeout(debounceTimeout.current);
|
||||
}
|
||||
|
||||
// Set a new debounce timeout
|
||||
debounceTimeout.current = setTimeout(() => {
|
||||
// Update the actual value using the provided setter function
|
||||
setState(newValue);
|
||||
}, delay);
|
||||
},
|
||||
[delay, setState],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (debounceTimeout.current) {
|
||||
clearTimeout(debounceTimeout.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return [optimisticValue, handleValueChange];
|
||||
};
|
||||
|
||||
export default useOptimisticState;
|
||||
@ -41,6 +41,7 @@ import { RecordingStartingPoint } from "@/types/record";
|
||||
import VideoControls from "@/components/player/VideoControls";
|
||||
import { TimeRange } from "@/types/timeline";
|
||||
import { useCameraMotionNextTimestamp } from "@/hooks/use-camera-activity";
|
||||
import useOptimisticState from "@/hooks/use-optimistic-state";
|
||||
|
||||
type EventViewProps = {
|
||||
reviews?: ReviewSegment[];
|
||||
@ -199,6 +200,10 @@ export default function EventView({
|
||||
);
|
||||
|
||||
const [motionOnly, setMotionOnly] = useState(false);
|
||||
const [severityToggle, setSeverityToggle] = useOptimisticState(
|
||||
severity,
|
||||
setSeverity,
|
||||
);
|
||||
|
||||
if (!config) {
|
||||
return <ActivityIndicator />;
|
||||
@ -214,9 +219,9 @@ export default function EventView({
|
||||
className="*:px-3 *:py-4 *:rounded-md"
|
||||
type="single"
|
||||
size="sm"
|
||||
value={severity}
|
||||
value={severityToggle}
|
||||
onValueChange={(value: ReviewSeverity) =>
|
||||
value ? setSeverity(value) : null
|
||||
value ? setSeverityToggle(value) : null
|
||||
} // don't allow the severity to be unselected
|
||||
>
|
||||
<ToggleGroupItem
|
||||
|
||||
Loading…
Reference in New Issue
Block a user