From a6cf755529858f723c0e205f196c3f461304fb7a Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Wed, 13 Nov 2024 07:40:18 -0600 Subject: [PATCH] manage persistent group streaming settings --- .../components/filter/CameraGroupSelector.tsx | 38 ++++++++++++++----- web/src/components/navigation/Sidebar.tsx | 23 ++++++++++- web/src/types/frigateConfig.ts | 6 ++- web/src/views/live/DraggableGridLayout.tsx | 6 +++ web/src/views/live/LiveDashboardView.tsx | 33 +++++++++++++++- 5 files changed, 92 insertions(+), 14 deletions(-) diff --git a/web/src/components/filter/CameraGroupSelector.tsx b/web/src/components/filter/CameraGroupSelector.tsx index e024b3c80..ea3a5b53f 100644 --- a/web/src/components/filter/CameraGroupSelector.tsx +++ b/web/src/components/filter/CameraGroupSelector.tsx @@ -1,7 +1,8 @@ import { + AllGroupsStreamingSettings, CameraGroupConfig, FrigateConfig, - GroupStreamingSettingsType, + GroupStreamingSettings, } from "@/types/frigateConfig"; import { isDesktop, isMobile } from "react-device-detect"; import useSWR from "swr"; @@ -75,8 +76,14 @@ import { CameraStreamingDialog } from "../settings/CameraStreamingDialog"; type CameraGroupSelectorProps = { className?: string; + setAllGroupsStreamingSettings: React.Dispatch< + React.SetStateAction + >; }; -export function CameraGroupSelector({ className }: CameraGroupSelectorProps) { +export function CameraGroupSelector({ + className, + setAllGroupsStreamingSettings, +}: CameraGroupSelectorProps) { const { data: config } = useSWR("config"); // tooltip @@ -130,6 +137,7 @@ export function CameraGroupSelector({ className }: CameraGroupSelectorProps) { activeGroup={group} setGroup={setGroup} deleteGroup={deleteGroup} + setAllGroupsStreamingSettings={setAllGroupsStreamingSettings} />
void; deleteGroup: () => void; + setAllGroupsStreamingSettings: React.Dispatch< + React.SetStateAction + >; }; function NewGroupDialog({ open, @@ -227,6 +238,7 @@ function NewGroupDialog({ activeGroup, setGroup, deleteGroup, + setAllGroupsStreamingSettings, }: NewGroupDialogProps) { const { mutate: updateConfig } = useSWR("config"); @@ -409,6 +421,7 @@ function NewGroupDialog({ setIsLoading={setIsLoading} onSave={onSave} onCancel={onCancel} + setAllGroupsStreamingSettings={setAllGroupsStreamingSettings} /> )} @@ -423,12 +436,16 @@ type EditGroupDialogProps = { setOpen: (open: boolean) => void; currentGroups: [string, CameraGroupConfig][]; activeGroup?: string; + setAllGroupsStreamingSettings: React.Dispatch< + React.SetStateAction + >; }; export function EditGroupDialog({ open, setOpen, currentGroups, activeGroup, + setAllGroupsStreamingSettings, }: EditGroupDialogProps) { const Overlay = isDesktop ? Dialog : MobilePage; const Content = isDesktop ? DialogContent : MobilePageContent; @@ -480,6 +497,7 @@ export function EditGroupDialog({ setIsLoading={setIsLoading} onSave={() => setOpen(false)} onCancel={() => setOpen(false)} + setAllGroupsStreamingSettings={setAllGroupsStreamingSettings} />
@@ -600,6 +618,9 @@ type CameraGroupEditProps = { setIsLoading: React.Dispatch>; onSave?: () => void; onCancel?: () => void; + setAllGroupsStreamingSettings: React.Dispatch< + React.SetStateAction + >; }; export function CameraGroupEdit({ @@ -609,17 +630,16 @@ export function CameraGroupEdit({ setIsLoading, onSave, onCancel, + setAllGroupsStreamingSettings, }: CameraGroupEditProps) { const { data: config, mutate: updateConfig } = useSWR("config"); const [groupStreamingSettings, setGroupStreamingSettings] = - useState({}); + useState({}); const [persistedGroupStreamingSettings, setPersistedGroupStreamingSettings] = - usePersistence<{ [groupName: string]: GroupStreamingSettingsType }>( - "streaming-settings", - ); + usePersistence("streaming-settings"); const birdseyeConfig = useMemo(() => config?.birdseye, [config]); @@ -671,9 +691,7 @@ export function CameraGroupEdit({ setIsLoading(true); // update streaming settings - const updatedSettings: { - [groupName: string]: GroupStreamingSettingsType; - } = { + const updatedSettings: AllGroupsStreamingSettings = { ...Object.fromEntries( Object.entries(persistedGroupStreamingSettings || {}).filter( ([key]) => key !== editingGroup?.[0], @@ -715,6 +733,7 @@ export function CameraGroupEdit({ onSave(); } await setPersistedGroupStreamingSettings(updatedSettings); + setAllGroupsStreamingSettings(updatedSettings); } else { toast.error(`Failed to save config changes: ${res.statusText}`, { position: "top-center", @@ -740,6 +759,7 @@ export function CameraGroupEdit({ groupStreamingSettings, setPersistedGroupStreamingSettings, persistedGroupStreamingSettings, + setAllGroupsStreamingSettings, ], ); diff --git a/web/src/components/navigation/Sidebar.tsx b/web/src/components/navigation/Sidebar.tsx index af9a3bc5c..c3fdd7fd5 100644 --- a/web/src/components/navigation/Sidebar.tsx +++ b/web/src/components/navigation/Sidebar.tsx @@ -6,7 +6,9 @@ import GeneralSettings from "../menu/GeneralSettings"; import AccountSettings from "../menu/AccountSettings"; import useNavigation from "@/hooks/use-navigation"; import { baseUrl } from "@/api/baseUrl"; -import { useMemo } from "react"; +import { useEffect, useMemo, useState } from "react"; +import { usePersistence } from "@/hooks/use-persistence"; +import { AllGroupsStreamingSettings } from "@/types/frigateConfig"; function Sidebar() { const basePath = useMemo(() => new URL(baseUrl).pathname, []); @@ -16,6 +18,18 @@ function Sidebar() { const navbarLinks = useNavigation(); + const [, setAllGroupsStreamingSettings] = + useState({}); + + const [persistedStreamingSettings, _, isStreamingSettingsLoaded] = + usePersistence("streaming-settings"); + + useEffect(() => { + if (isStreamingSettingsLoaded) { + setAllGroupsStreamingSettings(persistedStreamingSettings ?? {}); + } + }, [isStreamingSettingsLoaded, persistedStreamingSettings]); + return (