limit cameras in review/history

This commit is contained in:
Josh Hawkins 2025-09-10 07:31:49 -05:00
parent 8e79d34aac
commit 8976b061a4
2 changed files with 33 additions and 21 deletions

View File

@ -25,6 +25,7 @@ import { CamerasFilterButton } from "./CamerasFilterButton";
import PlatformAwareDialog from "../overlay/dialog/PlatformAwareDialog"; import PlatformAwareDialog from "../overlay/dialog/PlatformAwareDialog";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { getTranslatedLabel } from "@/utils/i18n"; import { getTranslatedLabel } from "@/utils/i18n";
import { useAllowedCameras } from "@/hooks/use-allowed-cameras";
const REVIEW_FILTERS = [ const REVIEW_FILTERS = [
"cameras", "cameras",
@ -72,6 +73,7 @@ export default function ReviewFilterGroup({
setMotionOnly, setMotionOnly,
}: ReviewFilterGroupProps) { }: ReviewFilterGroupProps) {
const { data: config } = useSWR<FrigateConfig>("config"); const { data: config } = useSWR<FrigateConfig>("config");
const allowedCameras = useAllowedCameras();
const allLabels = useMemo<string[]>(() => { const allLabels = useMemo<string[]>(() => {
if (filterList?.labels) { if (filterList?.labels) {
@ -83,7 +85,9 @@ export default function ReviewFilterGroup({
} }
const labels = new Set<string>(); const labels = new Set<string>();
const cameras = filter?.cameras || Object.keys(config.cameras); const cameras = (filter?.cameras || allowedCameras).filter((camera) =>
allowedCameras.includes(camera),
);
cameras.forEach((camera) => { cameras.forEach((camera) => {
if (camera == "birdseye") { if (camera == "birdseye") {
@ -106,7 +110,7 @@ export default function ReviewFilterGroup({
}); });
return [...labels].sort(); return [...labels].sort();
}, [config, filterList, filter]); }, [config, filterList, filter, allowedCameras]);
const allZones = useMemo<string[]>(() => { const allZones = useMemo<string[]>(() => {
if (filterList?.zones) { if (filterList?.zones) {
@ -118,7 +122,9 @@ export default function ReviewFilterGroup({
} }
const zones = new Set<string>(); const zones = new Set<string>();
const cameras = filter?.cameras || Object.keys(config.cameras); const cameras = (filter?.cameras || allowedCameras).filter((camera) =>
allowedCameras.includes(camera),
);
cameras.forEach((camera) => { cameras.forEach((camera) => {
if (camera == "birdseye") { if (camera == "birdseye") {
@ -134,11 +140,11 @@ export default function ReviewFilterGroup({
}); });
return [...zones].sort(); return [...zones].sort();
}, [config, filterList, filter]); }, [config, filterList, filter, allowedCameras]);
const filterValues = useMemo( const filterValues = useMemo(
() => ({ () => ({
cameras: Object.keys(config?.cameras ?? {}).sort( cameras: allowedCameras.sort(
(a, b) => (a, b) =>
(config?.cameras[a]?.ui?.order ?? 0) - (config?.cameras[a]?.ui?.order ?? 0) -
(config?.cameras[b]?.ui?.order ?? 0), (config?.cameras[b]?.ui?.order ?? 0),
@ -146,7 +152,7 @@ export default function ReviewFilterGroup({
labels: Object.values(allLabels || {}), labels: Object.values(allLabels || {}),
zones: Object.values(allZones || {}), zones: Object.values(allZones || {}),
}), }),
[config, allLabels, allZones], [config, allLabels, allZones, allowedCameras],
); );
const groups = useMemo(() => { const groups = useMemo(() => {

View File

@ -65,6 +65,7 @@ import {
TooltipTrigger, TooltipTrigger,
} from "@/components/ui/tooltip"; } from "@/components/ui/tooltip";
import { CameraNameLabel } from "@/components/camera/CameraNameLabel"; import { CameraNameLabel } from "@/components/camera/CameraNameLabel";
import { useAllowedCameras } from "@/hooks/use-allowed-cameras";
type RecordingViewProps = { type RecordingViewProps = {
startCamera: string; startCamera: string;
@ -97,11 +98,17 @@ export function RecordingView({
const timezone = useTimezone(config); const timezone = useTimezone(config);
const allowedCameras = useAllowedCameras();
const effectiveCameras = useMemo(
() => allCameras.filter((camera) => allowedCameras.includes(camera)),
[allCameras, allowedCameras],
);
const { data: recordingsSummary } = useSWR<RecordingsSummary>([ const { data: recordingsSummary } = useSWR<RecordingsSummary>([
"recordings/summary", "recordings/summary",
{ {
timezone: timezone, timezone: timezone,
cameras: allCameras.join(",") ?? null, cameras: effectiveCameras.join(",") ?? null,
}, },
]); ]);
@ -276,14 +283,16 @@ export function RecordingView({
const onSelectCamera = useCallback( const onSelectCamera = useCallback(
(newCam: string) => { (newCam: string) => {
setMainCamera(newCam); if (allowedCameras.includes(newCam)) {
setFullResolution({ setMainCamera(newCam);
width: 0, setFullResolution({
height: 0, width: 0,
}); height: 0,
setPlaybackStart(currentTime); });
setPlaybackStart(currentTime);
}
}, },
[currentTime], [currentTime, allowedCameras],
); );
// fullscreen // fullscreen
@ -488,12 +497,9 @@ export function RecordingView({
</div> </div>
<div className="flex items-center justify-end gap-2"> <div className="flex items-center justify-end gap-2">
<MobileCameraDrawer <MobileCameraDrawer
allCameras={allCameras} allCameras={effectiveCameras}
selected={mainCamera} selected={mainCamera}
onSelectCamera={(cam) => { onSelectCamera={onSelectCamera}
setPlaybackStart(currentTime);
setMainCamera(cam);
}}
/> />
{isDesktop && ( {isDesktop && (
<ExportDialog <ExportDialog
@ -674,7 +680,7 @@ export function RecordingView({
containerRef={mainLayoutRef} containerRef={mainLayoutRef}
/> />
</div> </div>
{isDesktop && allCameras.length > 1 && ( {isDesktop && effectiveCameras.length > 1 && (
<div <div
ref={previewRowRef} ref={previewRowRef}
className={cn( className={cn(
@ -686,7 +692,7 @@ export function RecordingView({
)} )}
> >
<div className="w-2" /> <div className="w-2" />
{allCameras.map((cam) => { {effectiveCameras.map((cam) => {
if (cam == mainCamera || cam == "birdseye") { if (cam == mainCamera || cam == "birdseye") {
return; return;
} }