import { createRootRoute, Outlet, useRouterState } from '@tanstack/react-router' // import { TanStackRouterDevtools } from '@tanstack/react-router-devtools' import LeftPanel from '@/containers/LeftPanel' import DialogAppUpdater from '@/containers/dialogs/AppUpdater' import BackendUpdater from '@/containers/dialogs/BackendUpdater' import { Fragment } from 'react/jsx-runtime' import { AppearanceProvider } from '@/providers/AppearanceProvider' import { ThemeProvider } from '@/providers/ThemeProvider' import { KeyboardShortcutsProvider } from '@/providers/KeyboardShortcuts' import { DataProvider } from '@/providers/DataProvider' import { route } from '@/constants/routes' import { ExtensionProvider } from '@/providers/ExtensionProvider' import { ToasterProvider } from '@/providers/ToasterProvider' import { useAnalytic } from '@/hooks/useAnalytic' import { PromptAnalytic } from '@/containers/analytics/PromptAnalytic' import { AnalyticProvider } from '@/providers/AnalyticProvider' import { useLeftPanel } from '@/hooks/useLeftPanel' import { cn } from '@/lib/utils' import ToolApproval from '@/containers/dialogs/ToolApproval' import { TranslationProvider } from '@/i18n/TranslationContext' import OutOfContextPromiseModal from '@/containers/dialogs/OutOfContextDialog' import LoadModelErrorDialog from '@/containers/dialogs/LoadModelErrorDialog' import { useSmallScreen } from '@/hooks/useMediaQuery' import { ResizablePanelGroup, ResizablePanel, ResizableHandle, } from '@/components/ui/resizable' import { useCallback, useEffect } from 'react' import GlobalError from '@/containers/GlobalError' import { GlobalEventHandler } from '@/providers/GlobalEventHandler' import ErrorDialog from '@/containers/dialogs/ErrorDialog' import { ServiceHubProvider } from '@/providers/ServiceHubProvider' import { PlatformFeatures } from '@/lib/platform/const' import { PlatformFeature } from '@/lib/platform/types' export const Route = createRootRoute({ component: RootLayout, errorComponent: ({ error }) => , }) const AppLayout = () => { const { productAnalyticPrompt } = useAnalytic() const { open: isLeftPanelOpen, setLeftPanel, size: leftPanelSize, setLeftPanelSize, } = useLeftPanel() const isSmallScreen = useSmallScreen() // Minimum width threshold for auto-close (10% of screen width) const MIN_PANEL_WIDTH_THRESHOLD = 14 // Handle panel size changes const handlePanelLayout = useCallback( (sizes: number[]) => { if (sizes.length > 0) { const newSize = sizes[0] // Close panel if resized below minimum threshold if (newSize < MIN_PANEL_WIDTH_THRESHOLD) { setLeftPanel(false) } else { setLeftPanelSize(newSize) } } }, [setLeftPanelSize, setLeftPanel] ) // Prevent default drag and drop behavior globally useEffect(() => { const preventDefaults = (e: DragEvent) => { e.preventDefault() e.stopPropagation() } const handleGlobalDrop = (e: DragEvent) => { e.preventDefault() e.stopPropagation() // Only prevent if the target is not within a chat input or other valid drop zone const target = e.target as Element const isValidDropZone = target?.closest('[data-drop-zone="true"]') || target?.closest('.chat-input-drop-zone') || target?.closest('[data-tauri-drag-region]') if (!isValidDropZone) { // Prevent the file from opening in the window return false } } // Add event listeners to prevent default drag/drop behavior window.addEventListener('dragenter', preventDefaults) window.addEventListener('dragover', preventDefaults) window.addEventListener('drop', handleGlobalDrop) return () => { window.removeEventListener('dragenter', preventDefaults) window.removeEventListener('dragover', preventDefaults) window.removeEventListener('drop', handleGlobalDrop) } }, []) return ( {/* Fake absolute panel top to enable window drag */} {PlatformFeatures[PlatformFeature.LOCAL_INFERENCE] && } {/* Use ResizablePanelGroup only on larger screens */} {!isSmallScreen && isLeftPanelOpen ? ( {/* Left Panel */} {/* Resize Handle */} {/* Main Content Panel */} ) : ( {/* left content panel - only show if not logs route */} {/* Main content panel */} )} {PlatformFeatures[PlatformFeature.ANALYTICS] && productAnalyticPrompt && ( )} ) } const LogsLayout = () => { return ( {/* Main content panel */} ) } function RootLayout() { const router = useRouterState() const isLocalAPIServerLogsRoute = router.location.pathname === route.localApiServerlogs || router.location.pathname === route.systemMonitor || router.location.pathname === route.appLogs return ( {isLocalAPIServerLogsRoute ? : } {/* {isLocalAPIServerLogsRoute ? : } */} {/* */} ) }