"use client" import * as React from "react" import { useLocation, useNavigate } from "react-router" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Tooltip, TooltipContent, TooltipTrigger, } from "@/components/ui/tooltip" import { useAskLeo } from "@/components/ask-leo-context" // Context, not `leo-ambience-window`: the window carries the whole settings // form, and this menu renders on the landing route. import { useLeoAmbience } from "@/components/leo-ambience-context" import { useProduct } from "@/contexts/product-context" import { useProductDashboardHref } from "@/contexts/product-route-sync" import { productSlug } from "@/stores/app-store" import { isProductsHomePath } from "@/lib/product-home" import { cn } from "@/lib/utils" /** * Panel and window are stored preferences; full screen is the `//leo` * route. Three shells, one switch — a second control for "float this" would * leave the user hunting for which of two menus owns which mode. */ type AskLeoViewMode = "panel" | "window" | "fullscreen" const MODE_ICON: Record = { panel: "fa-light fa-sidebar", window: "fa-light fa-window", fullscreen: "fa-light fa-expand", } const MODE_LABEL: Record = { panel: "Panel", window: "Window", fullscreen: "Full screen", } function isLeoLandingPath(pathname: string, leoHref: string) { return pathname === leoHref || pathname.startsWith(`${leoHref}/`) } /** * Panel / window / full-screen Leo view switcher. Kept separate from the heavy * sidebar panel so the landing route can render it without pulling the panel * implementation into the app shell chunk. * * Also the only keyboard route to Leo appearance: the header gear is gone, and * double-clicking a header is pointer-only (P6). * * @param onResetWindow Passed by the floating window only — adds the geometry * escape hatch to this menu instead of spending another slot in its title bar. */ export function AskLeoViewToggle({ className, onResetWindow, }: { className?: string onResetWindow?: () => void }) { const navigate = useNavigate() const { pathname } = useLocation() const { open, setOpen, dock, setDock, setMinimized } = useAskLeo() const { setSettingsOpen } = useLeoAmbience() const { product } = useProduct() const dashboardHref = useProductDashboardHref() const leoHref = `/${productSlug(product)}/leo` const onProductsHome = isProductsHomePath(pathname) const viewMode: AskLeoViewMode = isLeoLandingPath(pathname, leoHref) ? "fullscreen" : dock // Full screen is a product route. On the products home the reader has not // picked a product yet, so offering it would drop them into one they were // still deciding about. const modes: AskLeoViewMode[] = onProductsHome ? ["panel", "window"] : ["panel", "window", "fullscreen"] const handleViewChange = React.useCallback( (next: AskLeoViewMode) => { if (next === viewMode) return if (next === "fullscreen") { setOpen(false) navigate(leoHref) return } setDock(next) setMinimized(false) if (viewMode === "fullscreen") { navigate(dashboardHref) queueMicrotask(() => setOpen(true)) return } if (!open) setOpen(true) }, [dashboardHref, leoHref, navigate, open, setDock, setMinimized, setOpen, viewMode], ) return (