Cleanup mobile filters

This commit is contained in:
Nicolas Mowen 2024-09-11 07:02:25 -06:00
parent d49aecc1cf
commit 3a8d4a0cc5
4 changed files with 96 additions and 25 deletions

View File

@ -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>

View File

@ -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>
); );

View File

@ -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>
); );

View File

@ -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>
); );
}, },