mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-14 15:15:22 +03:00
Cleanup mobile filters
This commit is contained in:
parent
d49aecc1cf
commit
3a8d4a0cc5
@ -110,7 +110,7 @@ export function CalendarRangeFilterButton({
|
|||||||
className={`${range == undefined ? "text-secondary-foreground" : "text-selected-foreground"}`}
|
className={`${range == undefined ? "text-secondary-foreground" : "text-selected-foreground"}`}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={`hidden md:block ${range == undefined ? "text-primary" : "text-selected-foreground"}`}
|
className={`${range == undefined ? "text-primary" : "text-selected-foreground"}`}
|
||||||
>
|
>
|
||||||
{range == undefined ? defaultText : selectedDate}
|
{range == undefined ? defaultText : selectedDate}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
import { CameraGroupConfig } from "@/types/frigateConfig";
|
import { CameraGroupConfig } from "@/types/frigateConfig";
|
||||||
import { useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
@ -17,12 +17,14 @@ type CameraFilterButtonProps = {
|
|||||||
allCameras: string[];
|
allCameras: string[];
|
||||||
groups: [string, CameraGroupConfig][];
|
groups: [string, CameraGroupConfig][];
|
||||||
selectedCameras: string[] | undefined;
|
selectedCameras: string[] | undefined;
|
||||||
|
hideText?: boolean;
|
||||||
updateCameraFilter: (cameras: string[] | undefined) => void;
|
updateCameraFilter: (cameras: string[] | undefined) => void;
|
||||||
};
|
};
|
||||||
export function CamerasFilterButton({
|
export function CamerasFilterButton({
|
||||||
allCameras,
|
allCameras,
|
||||||
groups,
|
groups,
|
||||||
selectedCameras,
|
selectedCameras,
|
||||||
|
hideText = isMobile,
|
||||||
updateCameraFilter,
|
updateCameraFilter,
|
||||||
}: CameraFilterButtonProps) {
|
}: CameraFilterButtonProps) {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
@ -30,6 +32,18 @@ export function CamerasFilterButton({
|
|||||||
selectedCameras,
|
selectedCameras,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const buttonText = useMemo(() => {
|
||||||
|
if (isMobile) {
|
||||||
|
return "Cameras";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectedCameras || selectedCameras.length == 0) {
|
||||||
|
return "All Cameras";
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${selectedCameras.includes("birdseye") ? selectedCameras.length - 1 : selectedCameras.length} Camera${selectedCameras.length !== 1 ? "s" : ""}`;
|
||||||
|
}, [selectedCameras]);
|
||||||
|
|
||||||
const trigger = (
|
const trigger = (
|
||||||
<Button
|
<Button
|
||||||
className="flex items-center gap-2 capitalize"
|
className="flex items-center gap-2 capitalize"
|
||||||
@ -40,11 +54,9 @@ export function CamerasFilterButton({
|
|||||||
className={`${(selectedCameras?.length ?? 0) >= 1 ? "text-selected-foreground" : "text-secondary-foreground"}`}
|
className={`${(selectedCameras?.length ?? 0) >= 1 ? "text-selected-foreground" : "text-secondary-foreground"}`}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={`hidden md:block ${selectedCameras?.length ? "text-selected-foreground" : "text-primary"}`}
|
className={`${hideText ? "hidden" : ""} ${selectedCameras?.length ? "text-selected-foreground" : "text-primary"}`}
|
||||||
>
|
>
|
||||||
{selectedCameras == undefined
|
{buttonText}
|
||||||
? "All Cameras"
|
|
||||||
: `${selectedCameras.includes("birdseye") ? selectedCameras.length - 1 : selectedCameras.length} Camera${selectedCameras.length !== 1 ? "s" : ""}`}
|
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { FrigateConfig } from "@/types/frigateConfig";
|
|||||||
import { useCallback, useMemo, useState } from "react";
|
import { useCallback, useMemo, useState } from "react";
|
||||||
import { DropdownMenuSeparator } from "../ui/dropdown-menu";
|
import { DropdownMenuSeparator } from "../ui/dropdown-menu";
|
||||||
import { getEndOfDayTimestamp } from "@/utils/dateUtil";
|
import { getEndOfDayTimestamp } from "@/utils/dateUtil";
|
||||||
import { isMobile } from "react-device-detect";
|
import { isDesktop, isMobile } from "react-device-detect";
|
||||||
import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer";
|
import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer";
|
||||||
import { Switch } from "../ui/switch";
|
import { Switch } from "../ui/switch";
|
||||||
import { Label } from "../ui/label";
|
import { Label } from "../ui/label";
|
||||||
@ -155,12 +155,13 @@ export default function SearchFilterGroup({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn("flex justify-center gap-2", className)}>
|
<div className={cn("flex justify-center gap-2 overflow-x-auto", className)}>
|
||||||
{filters.includes("cameras") && (
|
{filters.includes("cameras") && (
|
||||||
<CamerasFilterButton
|
<CamerasFilterButton
|
||||||
allCameras={filterValues.cameras}
|
allCameras={filterValues.cameras}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
selectedCameras={filter?.cameras}
|
selectedCameras={filter?.cameras}
|
||||||
|
hideText={false}
|
||||||
updateCameraFilter={(newCameras) => {
|
updateCameraFilter={(newCameras) => {
|
||||||
onUpdateFilter({ ...filter, cameras: newCameras });
|
onUpdateFilter({ ...filter, cameras: newCameras });
|
||||||
}}
|
}}
|
||||||
@ -176,7 +177,7 @@ export default function SearchFilterGroup({
|
|||||||
to: new Date(filter.before * 1000),
|
to: new Date(filter.before * 1000),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defaultText="All Dates"
|
defaultText={isMobile ? "Dates" : "All Dates"}
|
||||||
updateSelectedRange={onUpdateSelectedRange}
|
updateSelectedRange={onUpdateSelectedRange}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -236,6 +237,22 @@ function GeneralFilterButton({
|
|||||||
selectedLabels,
|
selectedLabels,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const buttonText = useMemo(() => {
|
||||||
|
if (isMobile) {
|
||||||
|
return "Labels";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectedLabels || selectedLabels.length == 0) {
|
||||||
|
return "All Labels";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedLabels.length == 1) {
|
||||||
|
return selectedLabels[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${selectedLabels.length} Labels`;
|
||||||
|
}, [selectedLabels]);
|
||||||
|
|
||||||
const trigger = (
|
const trigger = (
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
@ -246,9 +263,9 @@ function GeneralFilterButton({
|
|||||||
className={`${selectedLabels?.length ? "text-selected-foreground" : "text-secondary-foreground"}`}
|
className={`${selectedLabels?.length ? "text-selected-foreground" : "text-secondary-foreground"}`}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={`hidden md:block ${selectedLabels?.length ? "text-selected-foreground" : "text-primary"}`}
|
className={`${selectedLabels?.length ? "text-selected-foreground" : "text-primary"}`}
|
||||||
>
|
>
|
||||||
All Labels
|
{buttonText}
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
@ -406,6 +423,22 @@ function ZoneFilterButton({
|
|||||||
selectedZones,
|
selectedZones,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const buttonText = useMemo(() => {
|
||||||
|
if (isMobile) {
|
||||||
|
return "Zones";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectedZones || selectedZones.length == 0) {
|
||||||
|
return "All Zones";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedZones.length == 1) {
|
||||||
|
return selectedZones[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${selectedZones.length} Zones`;
|
||||||
|
}, [selectedZones]);
|
||||||
|
|
||||||
const trigger = (
|
const trigger = (
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
@ -416,11 +449,9 @@ function ZoneFilterButton({
|
|||||||
className={`${selectedZones?.length ? "text-selected-foreground" : "text-secondary-foreground"}`}
|
className={`${selectedZones?.length ? "text-selected-foreground" : "text-secondary-foreground"}`}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={`hidden md:block ${selectedZones?.length ? "text-selected-foreground" : "text-primary"}`}
|
className={`${selectedZones?.length ? "text-selected-foreground" : "text-primary"}`}
|
||||||
>
|
>
|
||||||
{selectedZones?.length
|
{buttonText}
|
||||||
? `${selectedZones.length} Zone${selectedZones.length > 1 ? "s" : ""}`
|
|
||||||
: "All Zones"}
|
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
@ -586,6 +617,22 @@ function SubFilterButton({
|
|||||||
string[] | undefined
|
string[] | undefined
|
||||||
>(selectedSubLabels);
|
>(selectedSubLabels);
|
||||||
|
|
||||||
|
const buttonText = useMemo(() => {
|
||||||
|
if (isMobile) {
|
||||||
|
return "Sub Labels";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectedSubLabels || selectedSubLabels.length == 0) {
|
||||||
|
return "All Sub Labels";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedSubLabels.length == 1) {
|
||||||
|
return selectedSubLabels[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${selectedSubLabels.length} Sub Labels`;
|
||||||
|
}, [selectedSubLabels]);
|
||||||
|
|
||||||
const trigger = (
|
const trigger = (
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
@ -596,11 +643,9 @@ function SubFilterButton({
|
|||||||
className={`${selectedSubLabels?.length || selectedSubLabels?.length ? "text-selected-foreground" : "text-secondary-foreground"}`}
|
className={`${selectedSubLabels?.length || selectedSubLabels?.length ? "text-selected-foreground" : "text-secondary-foreground"}`}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={`hidden md:block ${selectedSubLabels?.length ? "text-selected-foreground" : "text-primary"}`}
|
className={`${selectedSubLabels?.length ? "text-selected-foreground" : "text-primary"}`}
|
||||||
>
|
>
|
||||||
{selectedSubLabels?.length
|
{buttonText}
|
||||||
? `${selectedSubLabels.length} Sub Labels`
|
|
||||||
: "All Sub Labels"}
|
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
@ -758,6 +803,22 @@ function SearchTypeButton({
|
|||||||
SearchSource[]
|
SearchSource[]
|
||||||
>(selectedSearchSources);
|
>(selectedSearchSources);
|
||||||
|
|
||||||
|
const buttonText = useMemo(() => {
|
||||||
|
if (isMobile) {
|
||||||
|
return "Sources";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectedSearchSources || selectedSearchSources.length == 0) {
|
||||||
|
return "All Search Sources";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedSearchSources.length == 1) {
|
||||||
|
return selectedSearchSources[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${selectedSearchSources.length} Search Sources`;
|
||||||
|
}, [selectedSearchSources]);
|
||||||
|
|
||||||
const trigger = (
|
const trigger = (
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
@ -768,11 +829,9 @@ function SearchTypeButton({
|
|||||||
className={`${selectedSearchSources?.length != 2 ? "text-selected-foreground" : "text-secondary-foreground"}`}
|
className={`${selectedSearchSources?.length != 2 ? "text-selected-foreground" : "text-secondary-foreground"}`}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={`hidden md:block ${selectedSearchSources?.length != 2 ? "text-selected-foreground" : "text-primary"}`}
|
className={`${selectedSearchSources?.length != 2 ? "text-selected-foreground" : "text-primary"}`}
|
||||||
>
|
>
|
||||||
{selectedSearchSources?.length != 2
|
{buttonText}
|
||||||
? `${selectedSearchSources[0]}`
|
|
||||||
: "All Search Sources"}
|
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -16,8 +16,8 @@ const SubFilterIcon = forwardRef<HTMLDivElement, SubFilterIconProps>(
|
|||||||
className={cn("relative flex items-center", className)}
|
className={cn("relative flex items-center", className)}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
<FaCog className="absolute size-3 translate-x-4 translate-y-[62%]" />
|
<FaCog className="absolute size-3 translate-x-[14px] translate-y-[62%]" />
|
||||||
<MdLabelOutline className="size-full" />
|
<MdLabelOutline className="size-5" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user