/** * AppShell — 应用壳 * * 窗口拖拽约定(Tauri overlay title bar): * - 仅使用 data-tauri-drag-region 处理拖拽和双击缩放 * - 不叠加 CSS app-region 或 React 双击处理,避免一次双击切换两次 * - 标签栏空白区也由 Tauri 原生拖拽区处理 */ import type { ReactNode } from 'react' import { PanelLeft } from 'lucide-react' import Sidebar from '../components/layout/Sidebar' import TabBar from '../components/layout/TabBar' import TabContent from '../components/layout/TabContent' import StatusBar from '../components/layout/StatusBar' import type { Session } from '../stores' import { getDesktopPlatform } from '../platform/runtime' export interface AppShellProps { activeTabId: string | null isMobile: boolean sidebarCollapsed: boolean mobileSidebarOpen: boolean onToggleSidebar: () => void onToggleMobileSidebar: () => void onCloseMobileSidebar: () => void onNewSession: () => void onQuickConnect: () => void onOpenLauncher: () => void onEditSession: (session: Session) => void children?: ReactNode } function TitleBar() { const platform = getDesktopPlatform() // Overlay title bar is macOS-only; Win/Linux keep the native chrome. if (platform !== 'macos') return null return (
OpsXShell
) } function MobileMenuButton({ onClick }: { onClick: () => void }) { return ( ) } function ExpandSidebarButton({ onClick }: { onClick: () => void }) { return ( ) } export default function AppShell({ activeTabId, isMobile, sidebarCollapsed, mobileSidebarOpen, onToggleSidebar, onToggleMobileSidebar, onCloseMobileSidebar, onNewSession, onQuickConnect, onOpenLauncher, onEditSession, children, }: AppShellProps) { const handleSidebarNewSession = () => { onNewSession() if (isMobile) onCloseMobileSidebar() } const handleSidebarQuickConnect = () => { onQuickConnect() if (isMobile) onCloseMobileSidebar() } const handleSidebarEditSession = (session: Session) => { onEditSession(session) if (isMobile) onCloseMobileSidebar() } const desktopSidebarHidden = !isMobile && sidebarCollapsed return (
{isMobile && mobileSidebarOpen && (
)}
{isMobile && } {desktopSidebarHidden && }
{children}
) }