* spacing, mobile navbar, and minor color updates

* tab scrolling behavior
This commit is contained in:
Josh Hawkins 2024-04-19 12:17:23 -05:00 committed by GitHub
parent d6dfa596de
commit 3b0f9988df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 56 additions and 33 deletions

View File

@ -154,7 +154,7 @@ export default function MotionTuner({
return ( return (
<div className="flex flex-col md:flex-row size-full"> <div className="flex flex-col md:flex-row size-full">
<Toaster position="top-center" /> <Toaster position="top-center" />
<div className="flex flex-col w-full overflow-y-auto mt-2 md:mt-0 md:w-3/12 order-last md:order-none md:mr-2 rounded-lg border-secondary-foreground border-[1px] p-2 bg-background_alt"> <div className="flex flex-col h-full w-full overflow-y-auto mt-2 md:mt-0 mb-10 md:mb-0 md:w-3/12 order-last md:order-none md:mr-2 rounded-lg border-secondary-foreground border-[1px] p-2 bg-background_alt">
<Heading as="h3" className="my-2"> <Heading as="h3" className="my-2">
Motion Detection Tuner Motion Detection Tuner
</Heading> </Heading>

View File

@ -352,7 +352,7 @@ function Logs() {
{Object.values(logTypes).map((item) => ( {Object.values(logTypes).map((item) => (
<ToggleGroupItem <ToggleGroupItem
key={item} key={item}
className={`flex items-center justify-between gap-2 ${logService == item ? "" : "text-gray-500"}`} className={`flex items-center justify-between gap-2 ${logService == item ? "" : "text-muted-foreground"}`}
value={item} value={item}
aria-label={`Select ${item}`} aria-label={`Select ${item}`}
> >

View File

@ -20,7 +20,7 @@ import { Drawer, DrawerContent, DrawerTrigger } from "@/components/ui/drawer";
import MotionTuner from "@/components/settings/MotionTuner"; import MotionTuner from "@/components/settings/MotionTuner";
import MasksAndZones from "@/components/settings/MasksAndZones"; import MasksAndZones from "@/components/settings/MasksAndZones";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { useCallback, useEffect, useMemo, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import useOptimisticState from "@/hooks/use-optimistic-state"; import useOptimisticState from "@/hooks/use-optimistic-state";
import { isMobile } from "react-device-detect"; import { isMobile } from "react-device-detect";
import { FaVideo } from "react-icons/fa"; import { FaVideo } from "react-icons/fa";
@ -31,6 +31,8 @@ import FilterSwitch from "@/components/filter/FilterSwitch";
import { ZoneMaskFilterButton } from "@/components/filter/ZoneMaskFilter"; import { ZoneMaskFilterButton } from "@/components/filter/ZoneMaskFilter";
import { PolygonType } from "@/types/canvas"; import { PolygonType } from "@/types/canvas";
import ObjectSettings from "@/components/settings/ObjectSettings"; import ObjectSettings from "@/components/settings/ObjectSettings";
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
import scrollIntoView from "scroll-into-view-if-needed";
export default function Settings() { export default function Settings() {
const settingsViews = [ const settingsViews = [
@ -43,6 +45,7 @@ export default function Settings() {
type SettingsType = (typeof settingsViews)[number]; type SettingsType = (typeof settingsViews)[number];
const [page, setPage] = useState<SettingsType>("general"); const [page, setPage] = useState<SettingsType>("general");
const [pageToggle, setPageToggle] = useOptimisticState(page, setPage, 100); const [pageToggle, setPageToggle] = useOptimisticState(page, setPage, 100);
const tabsRef = useRef<HTMLDivElement | null>(null);
const { data: config } = useSWR<FrigateConfig>("config"); const { data: config } = useSWR<FrigateConfig>("config");
@ -83,33 +86,51 @@ export default function Settings() {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
useEffect(() => {
if (tabsRef.current) {
const element = tabsRef.current.querySelector(
`[data-nav-item="${pageToggle}"]`,
);
if (element instanceof HTMLElement) {
scrollIntoView(element, {
behavior: "smooth",
inline: "start",
});
}
}
}, [tabsRef, pageToggle]);
return ( return (
<div className="size-full p-2 flex flex-col"> <div className="size-full p-2 flex flex-col">
<div className="w-full h-11 relative flex justify-between items-center"> <div className="w-full h-11 relative flex justify-between items-center">
<div className="flex flex-row overflow-x-auto"> <ScrollArea className="w-full whitespace-nowrap">
<ToggleGroup <div ref={tabsRef} className="flex flex-row">
className="*:px-3 *:py-4 *:rounded-md flex-shrink-0" <ToggleGroup
type="single" className="*:px-3 *:py-4 *:rounded-md"
size="sm" type="single"
value={pageToggle} size="sm"
onValueChange={(value: SettingsType) => { value={pageToggle}
if (value) { onValueChange={(value: SettingsType) => {
setPageToggle(value); if (value) {
} setPageToggle(value);
}} }
> }}
{Object.values(settingsViews).map((item) => ( >
<ToggleGroupItem {Object.values(settingsViews).map((item) => (
key={item} <ToggleGroupItem
className={`flex items-center justify-between gap-2 ${pageToggle == item ? "" : "*:text-muted-foreground"}`} key={item}
value={item} className={`flex items-center justify-between gap-2 scroll-mx-10 ${page == "general" ? "last:mr-20" : ""} ${pageToggle == item ? "" : "*:text-muted-foreground"}`}
aria-label={`Select ${item}`} value={item}
> data-nav-item={item}
<div className="capitalize">{item}</div> aria-label={`Select ${item}`}
</ToggleGroupItem> >
))} <div className="capitalize">{item}</div>
</ToggleGroup> </ToggleGroupItem>
</div> ))}
</ToggleGroup>
<ScrollBar orientation="horizontal" className="h-0" />
</div>
</ScrollArea>
{(page == "objects" || {(page == "objects" ||
page == "masks / zones" || page == "masks / zones" ||
page == "motion tuner") && ( page == "motion tuner") && (

View File

@ -52,7 +52,7 @@ function System() {
{Object.values(metrics).map((item) => ( {Object.values(metrics).map((item) => (
<ToggleGroupItem <ToggleGroupItem
key={item} key={item}
className={`flex items-center justify-between gap-2 ${pageToggle == item ? "" : "*:text-gray-500"}`} className={`flex items-center justify-between gap-2 ${pageToggle == item ? "" : "*:text-muted-foreground"}`}
value={item} value={item}
aria-label={`Select ${item}`} aria-label={`Select ${item}`}
> >

View File

@ -228,7 +228,7 @@ export default function EventView({
} // don't allow the severity to be unselected } // don't allow the severity to be unselected
> >
<ToggleGroupItem <ToggleGroupItem
className={`${severityToggle == "alert" ? "" : "text-gray-500"}`} className={`${severityToggle == "alert" ? "" : "text-muted-foreground"}`}
value="alert" value="alert"
aria-label="Select alerts" aria-label="Select alerts"
> >
@ -238,7 +238,7 @@ export default function EventView({
</div> </div>
</ToggleGroupItem> </ToggleGroupItem>
<ToggleGroupItem <ToggleGroupItem
className={`${severityToggle == "detection" ? "" : "text-gray-500"}`} className={`${severityToggle == "detection" ? "" : "text-muted-foreground"}`}
value="detection" value="detection"
aria-label="Select detections" aria-label="Select detections"
> >
@ -250,7 +250,9 @@ export default function EventView({
</ToggleGroupItem> </ToggleGroupItem>
<ToggleGroupItem <ToggleGroupItem
className={`px-3 py-4 rounded-2xl ${ className={`px-3 py-4 rounded-2xl ${
severityToggle == "significant_motion" ? "" : "text-gray-500" severityToggle == "significant_motion"
? ""
: "text-muted-foreground"
}`} }`}
value="significant_motion" value="significant_motion"
aria-label="Select motion" aria-label="Select motion"

View File

@ -321,14 +321,14 @@ export function RecordingView({
} // don't allow the severity to be unselected } // don't allow the severity to be unselected
> >
<ToggleGroupItem <ToggleGroupItem
className={`${timelineType == "timeline" ? "" : "text-gray-500"}`} className={`${timelineType == "timeline" ? "" : "text-muted-foreground"}`}
value="timeline" value="timeline"
aria-label="Select timeline" aria-label="Select timeline"
> >
<div className="">Timeline</div> <div className="">Timeline</div>
</ToggleGroupItem> </ToggleGroupItem>
<ToggleGroupItem <ToggleGroupItem
className={`${timelineType == "events" ? "" : "text-gray-500"}`} className={`${timelineType == "events" ? "" : "text-muted-foreground"}`}
value="events" value="events"
aria-label="Select events" aria-label="Select events"
> >