import { useEffect, useRef, useState } from "react"; import type { JSX, SVGProps } from "react"; import { GridBottomLinedIcon } from "../../../app/renderer/components/icons/GridBottomLinedIcon"; import { GridLeftLinedIcon } from "../../../app/renderer/components/icons/GridLeftLinedIcon"; import { GridRightLinedIcon } from "../../../app/renderer/components/icons/GridRightLinedIcon"; import { GridTopLinedIcon } from "../../../app/renderer/components/icons/GridTopLinedIcon"; import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "@tutti-os/ui-system"; import { Button } from "../../../app/renderer/components/ui/button"; import { useTranslation } from "../../../i18n/index"; import { CanvasNodeGhostIconButton } from "../../shared/CanvasNodeGhostIconButton"; import { CanvasNodeLayoutLinedIcon, CanvasNodeMaximizeLinedIcon, CanvasNodeMinimizeLinedIcon } from "../../shared/canvasNodeChromeIcons"; import { useDesktopStore } from "../store"; import type { DesktopSize, WindowQuickLayoutTarget } from "../types"; const QUICK_LAYOUT_OPTIONS: Array<{ target: WindowQuickLayoutTarget; icon: (props: SVGProps) => JSX.Element; labelKey: string; }> = [ { target: "left", icon: GridLeftLinedIcon, labelKey: "workspaceWindowLayout.left" }, { target: "right", icon: GridRightLinedIcon, labelKey: "workspaceWindowLayout.right" }, { target: "top", icon: GridTopLinedIcon, labelKey: "workspaceWindowLayout.top" }, { target: "bottom", icon: GridBottomLinedIcon, labelKey: "workspaceWindowLayout.bottom" } ]; const WINDOW_LAYOUT_MENU_HOVER_OPEN_DELAY_MS = 300; interface WindowLayoutMenuButtonProps { windowId: string; desktopSize: DesktopSize; className?: string; "data-window-header"?: string; } export function WindowLayoutMenuButton({ windowId, desktopSize, className, "data-window-header": windowHeader }: WindowLayoutMenuButtonProps): JSX.Element { "use memo"; const { t } = useTranslation(); const [open, setOpen] = useState(false); const hoverOpenTimeoutRef = useRef(null); const applyQuickLayout = useDesktopStore((state) => state.applyQuickLayout); const enterFullscreenWindow = useDesktopStore( (state) => state.enterFullscreenWindow ); const exitFullscreenWindow = useDesktopStore( (state) => state.exitFullscreenWindow ); const isFullscreen = useDesktopStore( (state) => state.windows.find((window) => window.id === windowId)?.displayMode === "fullscreen" ); const fullscreenLabelKey = isFullscreen ? "workspaceWindowLayout.restore" : "workspaceWindowLayout.fullscreen"; const fullscreenIconState = isFullscreen ? "restore" : "fullscreen"; const FullscreenIcon = isFullscreen ? CanvasNodeMinimizeLinedIcon : CanvasNodeMaximizeLinedIcon; const applyLayout = (target: WindowQuickLayoutTarget) => { applyQuickLayout(windowId, target, desktopSize); setOpen(false); }; const clearHoverOpenTimeout = () => { if (hoverOpenTimeoutRef.current !== null) { window.clearTimeout(hoverOpenTimeoutRef.current); hoverOpenTimeoutRef.current = null; } }; const scheduleHoverOpen = () => { if (open || hoverOpenTimeoutRef.current !== null) { return; } hoverOpenTimeoutRef.current = window.setTimeout(() => { hoverOpenTimeoutRef.current = null; setOpen(true); }, WINDOW_LAYOUT_MENU_HOVER_OPEN_DELAY_MS); }; const toggleFullscreen = () => { if (isFullscreen) { exitFullscreenWindow(windowId, desktopSize); } else { enterFullscreenWindow(windowId, desktopSize); } setOpen(false); }; useEffect(() => clearHoverOpenTimeout, []); return ( { if (!nextOpen) { clearHoverOpenTimeout(); } setOpen(nextOpen); }} >
{t("workspaceWindowLayout.moveAndResize")}
{QUICK_LAYOUT_OPTIONS.map((option) => { const Icon = option.icon; return ( ); })}
); }