Tweak camera group layout editor buttons (#11317)

* tweak layout editor buttons

* remove bubble

* spacing

* button backgrounds
This commit is contained in:
Josh Hawkins
2024-05-09 16:08:22 -05:00
committed by GitHub
parent 8b344cea81
commit 386ffbf5a6
3 changed files with 191 additions and 57 deletions

View File

@@ -24,15 +24,18 @@ import useSWR from "swr";
import { isDesktop, isMobile, isSafari } from "react-device-detect";
import BirdseyeLivePlayer from "@/components/player/BirdseyeLivePlayer";
import LivePlayer from "@/components/player/LivePlayer";
import { IoClose } from "react-icons/io5";
import { LuLayoutDashboard, LuPencil } from "react-icons/lu";
import { cn } from "@/lib/utils";
import { EditGroupDialog } from "@/components/filter/CameraGroupSelector";
import { usePersistedOverlayState } from "@/hooks/use-overlay-state";
import { FaCompress, FaExpand } from "react-icons/fa";
import { Button } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
TooltipContent,
} from "@/components/ui/tooltip";
import { IoClose } from "react-icons/io5";
import { LuMove } from "react-icons/lu";
import { cn } from "@/lib/utils";
type DraggableGridLayoutProps = {
cameras: CameraConfig[];
@@ -67,6 +70,20 @@ export default function DraggableGridLayout({
Layout[]
>(`${cameraGroup}-draggable-layout`);
const [group] = usePersistedOverlayState("cameraGroup", "default" as string);
const groups = useMemo(() => {
if (!config) {
return [];
}
return Object.entries(config.camera_groups).sort(
(a, b) => a[1].order - b[1].order,
);
}, [config]);
const [editGroup, setEditGroup] = useState(false);
const [currentCameras, setCurrentCameras] = useState<CameraConfig[]>();
const [currentIncludeBirdseye, setCurrentIncludeBirdseye] =
useState<boolean>();
@@ -252,6 +269,25 @@ export default function DraggableGridLayout({
);
}, [containerRef, gridContainerRef, containerHeight]);
// fullscreen state
useEffect(() => {
if (gridContainerRef.current == null) {
return;
}
const listener = () => {
setFullscreen(document.fullscreenElement != null);
};
document.addEventListener("fullscreenchange", listener);
return () => {
document.removeEventListener("fullscreenchange", listener);
};
}, [gridContainerRef]);
const [fullscreen, setFullscreen] = useState(false);
const cellHeight = useMemo(() => {
const aspectRatio = 16 / 9;
// subtract container margin, 1 camera takes up at least 4 rows
@@ -286,6 +322,12 @@ export default function DraggableGridLayout({
className="my-2 px-2 pb-8 no-scrollbar overflow-x-hidden"
ref={gridContainerRef}
>
<EditGroupDialog
open={editGroup}
setOpen={setEditGroup}
currentGroups={groups}
activeGroup={group}
/>
<ResponsiveGridLayout
className="grid-layout"
layouts={{
@@ -352,12 +394,86 @@ export default function DraggableGridLayout({
);
})}
</ResponsiveGridLayout>
{isDesktop && (
<DesktopEditLayoutButton
isEditMode={isEditMode}
setIsEditMode={setIsEditMode}
hasScrollbar={hasScrollbar}
/>
{isDesktop && !fullscreen && (
<div
className={cn(
"fixed",
isDesktop && "bottom-12 lg:bottom-9",
isMobile && "bottom-12 lg:bottom-16",
hasScrollbar && isDesktop ? "right-6" : "right-3",
"z-50 flex flex-row gap-2",
)}
>
<Tooltip>
<TooltipTrigger asChild>
<Button
className="px-2 py-1 bg-secondary-foreground rounded-lg opacity-30 hover:opacity-100 transition-all duration-300"
onClick={() =>
setIsEditMode((prevIsEditMode) => !prevIsEditMode)
}
>
{isEditMode ? (
<>
<IoClose className="size-5" />
</>
) : (
<>
<LuLayoutDashboard className="size-5" />
</>
)}
</Button>
</TooltipTrigger>
<TooltipContent>
{isEditMode ? "Exit Editing" : "Edit Layout"}
</TooltipContent>
</Tooltip>
{!isEditMode && (
<>
<Tooltip>
<TooltipTrigger asChild>
<Button
className="px-2 py-1 bg-secondary-foreground rounded-lg opacity-30 hover:opacity-100 transition-all duration-300"
onClick={() =>
setEditGroup((prevEditGroup) => !prevEditGroup)
}
>
<LuPencil className="size-5" />
</Button>
</TooltipTrigger>
<TooltipContent>
{isEditMode ? "Exit Editing" : "Edit Camera Group"}
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button
className="px-2 py-1 bg-secondary-foreground rounded-lg opacity-30 hover:opacity-100 transition-all duration-300"
onClick={() => {
if (fullscreen) {
document.exitFullscreen();
} else {
gridContainerRef.current?.requestFullscreen();
}
}}
>
{fullscreen ? (
<>
<FaCompress className="size-5" />
</>
) : (
<>
<FaExpand className="size-5" />
</>
)}
</Button>
</TooltipTrigger>
<TooltipContent>
{fullscreen ? "Exit Fullscreen" : "Fullscreen"}
</TooltipContent>
</Tooltip>
</>
)}
</div>
)}
</div>
)}
@@ -365,47 +481,6 @@ export default function DraggableGridLayout({
);
}
type DesktopEditLayoutButtonProps = {
isEditMode?: boolean;
setIsEditMode: React.Dispatch<React.SetStateAction<boolean>>;
hasScrollbar?: boolean | 0 | null;
};
function DesktopEditLayoutButton({
isEditMode,
setIsEditMode,
hasScrollbar,
}: DesktopEditLayoutButtonProps) {
return (
<div className="flex flex-row gap-2 items-center text-primary">
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="default"
className={cn(
"fixed",
isDesktop && "bottom-12 lg:bottom-9",
isMobile && "bottom-12 lg:bottom-16",
hasScrollbar && isDesktop ? "right-6" : "right-1",
"z-50 h-8 w-8 p-0 rounded-full opacity-30 hover:opacity-100 transition-all duration-300",
)}
onClick={() => setIsEditMode((prevIsEditMode) => !prevIsEditMode)}
>
{isEditMode ? (
<IoClose className="size-5" />
) : (
<LuMove className="size-5" />
)}
</Button>
</TooltipTrigger>
<TooltipContent side="left">
{isEditMode ? "Exit Editing" : "Edit Layout"}
</TooltipContent>
</Tooltip>
</div>
);
}
function CornerCircles() {
return (
<>