- StatusBar: 全 MUI Table 布局,左侧状态/Provider/Token,右侧版本+设置 - Header: 已删除(功能合并到 StatusBar) - App.tsx: 移除 Header 引用
71 lines
2.6 KiB
TypeScript
71 lines
2.6 KiB
TypeScript
/**
|
|
* 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 (
|
|
<ThemeProvider theme={muiTheme}>
|
|
<CssBaseline />
|
|
<div
|
|
className="h-screen w-screen flex flex-col overflow-hidden select-none"
|
|
style={{ background: muiTheme.palette.background.default, color: muiTheme.palette.text.primary }}
|
|
>
|
|
<div className="flex-1 flex overflow-hidden min-h-0">
|
|
<Sidebar />
|
|
<ChatPanel />
|
|
<DetailPanel />
|
|
</div>
|
|
<StatusBar />
|
|
<SettingsModal />
|
|
<OnboardingWizard />
|
|
<CommandPalette />
|
|
<ToastContainer />
|
|
</div>
|
|
</ThemeProvider>
|
|
);
|
|
}
|