mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Persist selected camera group for live (#10448)
* Persist camera group selected * Cleanup
This commit is contained in:
parent
a660e3ae27
commit
2decdeadb4
@ -6,9 +6,8 @@ import {
|
||||
import { isDesktop } from "react-device-detect";
|
||||
import useSWR from "swr";
|
||||
import { MdHome } from "react-icons/md";
|
||||
import useOverlayState from "@/hooks/use-overlay-state";
|
||||
import { usePersistedOverlayState } from "@/hooks/use-overlay-state";
|
||||
import { Button } from "../ui/button";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
|
||||
import { getIconForGroup } from "@/utils/iconUtil";
|
||||
@ -31,7 +30,6 @@ type CameraGroupSelectorProps = {
|
||||
};
|
||||
export function CameraGroupSelector({ className }: CameraGroupSelectorProps) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
const navigate = useNavigate();
|
||||
|
||||
// tooltip
|
||||
|
||||
@ -54,7 +52,7 @@ export function CameraGroupSelector({ className }: CameraGroupSelectorProps) {
|
||||
|
||||
// groups
|
||||
|
||||
const [group, setGroup] = useOverlayState("cameraGroup");
|
||||
const [group, setGroup] = usePersistedOverlayState("cameraGroup");
|
||||
|
||||
const groups = useMemo(() => {
|
||||
if (!config) {
|
||||
@ -89,7 +87,7 @@ export function CameraGroupSelector({ className }: CameraGroupSelectorProps) {
|
||||
: "text-muted-foreground bg-secondary focus:text-muted-foreground focus:bg-secondary"
|
||||
}
|
||||
size="xs"
|
||||
onClick={() => (group ? navigate(-1) : null)}
|
||||
onClick={() => (group ? setGroup(undefined, true) : null)}
|
||||
onMouseEnter={() => (isDesktop ? showTooltip("home") : null)}
|
||||
onMouseLeave={() => (isDesktop ? showTooltip(undefined) : null)}
|
||||
>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { usePersistence } from "./use-persistence";
|
||||
|
||||
export default function useOverlayState<S extends string>(
|
||||
key: string,
|
||||
@ -27,3 +28,38 @@ export default function useOverlayState<S extends string>(
|
||||
|
||||
return [overlayStateValue ?? defaultValue, setOverlayStateValue];
|
||||
}
|
||||
|
||||
export function usePersistedOverlayState<S extends string>(
|
||||
key: string,
|
||||
defaultValue: S | undefined = undefined,
|
||||
): [S | undefined, (value: S | undefined, replace?: boolean) => void] {
|
||||
const [persistedValue, setPersistedValue] = usePersistence<S>(
|
||||
key,
|
||||
defaultValue,
|
||||
);
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const currentLocationState = location.state;
|
||||
|
||||
const setOverlayStateValue = useCallback(
|
||||
(value: S | undefined, replace: boolean = false) => {
|
||||
setPersistedValue(value);
|
||||
const newLocationState = { ...currentLocationState };
|
||||
newLocationState[key] = value;
|
||||
navigate(location.pathname, { state: newLocationState, replace });
|
||||
},
|
||||
// we know that these deps are correct
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[key, navigate],
|
||||
);
|
||||
|
||||
const overlayStateValue = useMemo<S | undefined>(
|
||||
() => location.state && location.state[key],
|
||||
[location, key],
|
||||
);
|
||||
|
||||
return [
|
||||
overlayStateValue ?? persistedValue ?? defaultValue,
|
||||
setOverlayStateValue,
|
||||
];
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import { get as getData, set as setData } from "idb-keyval";
|
||||
|
||||
type usePersistenceReturn<S> = [
|
||||
value: S | undefined,
|
||||
setValue: (value: S) => void,
|
||||
setValue: (value: S | undefined) => void,
|
||||
loaded: boolean,
|
||||
];
|
||||
|
||||
@ -15,7 +15,7 @@ export function usePersistence<S>(
|
||||
const [loaded, setLoaded] = useState<boolean>(false);
|
||||
|
||||
const setValue = useCallback(
|
||||
(value: S) => {
|
||||
(value: S | undefined) => {
|
||||
setInternalValue(value);
|
||||
async function update() {
|
||||
await setData(key, value);
|
||||
|
@ -1,4 +1,6 @@
|
||||
import useOverlayState from "@/hooks/use-overlay-state";
|
||||
import useOverlayState, {
|
||||
usePersistedOverlayState,
|
||||
} from "@/hooks/use-overlay-state";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import LiveCameraView from "@/views/live/LiveCameraView";
|
||||
import LiveDashboardView from "@/views/live/LiveDashboardView";
|
||||
@ -9,7 +11,7 @@ function Live() {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
|
||||
const [selectedCameraName, setSelectedCameraName] = useOverlayState("camera");
|
||||
const [cameraGroup] = useOverlayState("cameraGroup");
|
||||
const [cameraGroup] = usePersistedOverlayState("cameraGroup");
|
||||
|
||||
const includesBirdseye = useMemo(() => {
|
||||
if (config && cameraGroup) {
|
||||
|
Loading…
Reference in New Issue
Block a user