/** * MetonaAI Desktop — 根组件 * * 三栏布局:Header + [Sidebar | Chat | DetailPanel] + StatusBar * + ToastContainer + SettingsModal + OnboardingWizard * * 连接所有 Store,注册快捷键,初始化主题。 */ import { ThemeProvider, CssBaseline } from '@mui/material'; import { useEffect } from 'react'; import { Sidebar } from '@renderer/components/layout/Sidebar'; import { DetailPanel } from '@renderer/components/layout/DetailPanel'; import { StatusBar } from '@renderer/components/layout/StatusBar'; import { ChatPanel } from '@renderer/components/chat/ChatPanel'; import { SettingsModal } from '@renderer/components/settings/SettingsModal'; import { OnboardingWizard } from '@renderer/components/onboarding/OnboardingWizard'; import { CommandPalette } from '@renderer/components/CommandPalette'; import { ToastContainer } from '@renderer/components/ToastContainer'; import { useTheme } from '@renderer/hooks/useTheme'; import { useKeyboardShortcuts } from '@renderer/hooks/useKeyboardShortcuts'; import { useAgentStream } from '@renderer/hooks/useAgentStream'; import { useUIStore } from '@renderer/stores/ui-store'; import { useAgentStore } from '@renderer/stores/agent-store'; import { metonaDarkTheme, metonaLightTheme } from '@renderer/lib/theme'; export default function App(): React.JSX.Element { useTheme(); useKeyboardShortcuts(); useAgentStream(); const resolvedTheme = useUIStore((s) => s.resolvedTheme); const muiTheme = resolvedTheme === 'dark' ? metonaDarkTheme : metonaLightTheme; // 启动时从数据库恢复状态 useEffect(() => { if (window.metona?.config?.get) { window.metona.config.get('onboarding.completed').then((v) => { if (v === true) useUIStore.getState().setOnboardingCompleted(true); }).catch(() => {}); Promise.all([ window.metona.config.get('llm.provider'), window.metona.config.get('llm.model'), ]).then(([provider, model]) => { if (provider || model) useAgentStore.getState().setProvider(provider ?? '', model ?? ''); }).catch(() => {}); } }, []); return (
); }