diff --git a/web/src/components/filter/CameraGroupSelector.tsx b/web/src/components/filter/CameraGroupSelector.tsx index 6b2594a36..9da2fc293 100644 --- a/web/src/components/filter/CameraGroupSelector.tsx +++ b/web/src/components/filter/CameraGroupSelector.tsx @@ -6,11 +6,37 @@ import { FaCar, FaCat, FaCircle, FaDog, FaLeaf } from "react-icons/fa"; import useOverlayState from "@/hooks/use-overlay-state"; import { Button } from "../ui/button"; import { useNavigate } from "react-router-dom"; -import { useMemo } from "react"; +import { useCallback, useMemo, useState } from "react"; +import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; -export function CameraGroupSelector() { +type CameraGroupSelectorProps = { + className?: string; +}; +export function CameraGroupSelector({ className }: CameraGroupSelectorProps) { const { data: config } = useSWR("config"); const navigate = useNavigate(); + + // tooltip + + const [tooltip, setTooltip] = useState(); + const [timeoutId, setTimeoutId] = useState(); + const showTooltip = useCallback( + (newTooltip: string | undefined) => { + if (!newTooltip) { + setTooltip(newTooltip); + + if (timeoutId) { + clearTimeout(timeoutId); + } + } else { + setTimeoutId(setTimeout(() => setTooltip(newTooltip), 500)); + } + }, + [timeoutId], + ); + + // groups + const [group, setGroup] = useOverlayState("cameraGroup"); const groups = useMemo(() => { @@ -25,33 +51,50 @@ export function CameraGroupSelector() { return (
- - {groups.map(([name, config]) => { - return ( + + + + + Home + + + {groups.map(([name, config]) => { + return ( + + + + + + {name} + + ); })}
diff --git a/web/src/components/navigation/NavItem.tsx b/web/src/components/navigation/NavItem.tsx index e19ff92a2..48004c684 100644 --- a/web/src/components/navigation/NavItem.tsx +++ b/web/src/components/navigation/NavItem.tsx @@ -6,9 +6,10 @@ import { TooltipContent, TooltipTrigger, } from "@/components/ui/tooltip"; -import { useState } from "react"; +import { useCallback, useState } from "react"; import { isDesktop } from "react-device-detect"; import { TooltipPortal } from "@radix-ui/react-tooltip"; +import { CameraGroupSelector } from "../filter/CameraGroupSelector"; const variants = { primary: { @@ -43,6 +44,21 @@ export default function NavItem({ const shouldRender = dev ? ENV !== "production" : true; const [showTooltip, setShowTooltip] = useState(false); + const [timeoutId, setTimeoutId] = useState(); + const showTooltipTimer = useCallback( + (showTooltip: boolean) => { + if (!showTooltip) { + setShowTooltip(showTooltip); + + if (timeoutId) { + clearTimeout(timeoutId); + } + } else { + setTimeoutId(setTimeout(() => setShowTooltip(showTooltip), 500)); + } + }, + [timeoutId], + ); return ( shouldRender && ( @@ -50,17 +66,28 @@ export default function NavItem({ - `${className} flex flex-col justify-center items-center rounded-lg ${ - variants[variant][isActive ? "active" : "inactive"] - }` - } - onMouseEnter={() => (isDesktop ? setShowTooltip(true) : null)} - onMouseLeave={() => (isDesktop ? setShowTooltip(false) : null)} + className={`${className} flex flex-col justify-center items-center rounded-lg`} > - - - + {({ isActive }) => ( + <> + + + isDesktop ? showTooltipTimer(true) : null + } + onMouseLeave={() => + isDesktop ? showTooltipTimer(false) : null + } + /> + + {isDesktop && title == "Live" && isActive && ( + + )} + + )} diff --git a/web/src/components/navigation/Sidebar.tsx b/web/src/components/navigation/Sidebar.tsx index c4b53087e..1fdea0c41 100644 --- a/web/src/components/navigation/Sidebar.tsx +++ b/web/src/components/navigation/Sidebar.tsx @@ -2,7 +2,6 @@ import Logo from "../Logo"; import { navbarLinks } from "@/pages/site-navigation"; import SettingsNavItems from "../settings/SettingsNavItems"; import NavItem from "./NavItem"; -import { CameraGroupSelector } from "../filter/CameraGroupSelector"; function Sidebar() { return ( @@ -11,16 +10,14 @@ function Sidebar() {
{navbarLinks.map((item) => ( -
- - {item.id == 1 && } -
+ ))}