refactor: 移除顶部栏,设置按钮移至底部栏右侧,StatusBar 全面改 MUI Table

- StatusBar: 全 MUI Table 布局,左侧状态/Provider/Token,右侧版本+设置
- Header: 已删除(功能合并到 StatusBar)
- App.tsx: 移除 Header 引用
This commit is contained in:
thzxx
2026-06-27 22:41:59 +08:00
parent a5ef816763
commit 239bd8703b
3 changed files with 53 additions and 76 deletions
-2
View File
@@ -9,7 +9,6 @@
import { ThemeProvider, CssBaseline } from '@mui/material';
import { useEffect } from 'react';
import { Header } from '@renderer/components/layout/Header';
import { Sidebar } from '@renderer/components/layout/Sidebar';
import { DetailPanel } from '@renderer/components/layout/DetailPanel';
import { StatusBar } from '@renderer/components/layout/StatusBar';
@@ -55,7 +54,6 @@ export default function App(): React.JSX.Element {
className="h-screen w-screen flex flex-col overflow-hidden select-none"
style={{ background: muiTheme.palette.background.default, color: muiTheme.palette.text.primary }}
>
<Header />
<div className="flex-1 flex overflow-hidden min-h-0">
<Sidebar />
<ChatPanel />
-44
View File
@@ -1,44 +0,0 @@
/**
* Header — 标题栏
*
* Logo + 会话标题 + 设置按钮。
*/
import { Box, IconButton, Tooltip, Stack, Typography } from '@mui/material';
import { Settings } from 'lucide-react';
import { useUIStore } from '@renderer/stores/ui-store';
import { useSessionStore } from '@renderer/stores/session-store';
type WebkitCSS = React.CSSProperties & { WebkitAppRegion?: string };
export function Header(): React.JSX.Element {
const openSettings = useUIStore((s) => s.openSettings);
const currentSessionId = useSessionStore((s) => s.currentSessionId);
const sessions = useSessionStore((s) => s.sessions);
const currentSession = sessions.find((s) => s.id === currentSessionId);
return (
<header
style={{
flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'space-between',
padding: '0 16px', height: 40, userSelect: 'none',
background: 'var(--bg-secondary)', borderBottom: '1px solid var(--border-color)',
WebkitAppRegion: 'drag',
} as WebkitCSS}
>
<Stack direction="row" spacing={1} alignItems="center" sx={{ minWidth: 0 }}>
<Box component="img" src="./assets/logo.png" alt="Metona" sx={{ width: 20, height: 20, borderRadius: 0.5 }} />
<Typography variant="body2" sx={{ fontWeight: 600, color: 'primary.main', fontSize: 13 }}>MetonaAI</Typography>
{currentSession && (
<>
<Typography variant="body2" sx={{ color: 'divider' }}>·</Typography>
<Typography variant="caption" sx={{ color: 'text.secondary', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{currentSession.title}</Typography>
</>
)}
</Stack>
<Stack direction="row" spacing={0.5} sx={{ WebkitAppRegion: 'no-drag' } as WebkitCSS}>
<Tooltip title="设置 (Ctrl+,)"><IconButton size="small" onClick={openSettings} sx={{ color: 'text.secondary' }}><Settings size={14} /></IconButton></Tooltip>
</Stack>
</header>
);
}
+43 -20
View File
@@ -1,11 +1,13 @@
/**
* StatusBar — 底部状态栏
*
* 显示 Agent 状态指示灯、Provider 名称、Token 统计、版本号
* 完全使用 MUI 组件:Table 展示状态/Provider/Token,右侧设置按钮
*/
import { Box, Typography, Stack, Chip } from '@mui/material';
import { Box, Typography, IconButton, Tooltip, Table, TableBody, TableRow, TableCell } from '@mui/material';
import { Settings } from 'lucide-react';
import { useAgentStore } from '@renderer/stores/agent-store';
import { useUIStore } from '@renderer/stores/ui-store';
import { AGENT_STATUS_COLORS, AGENT_STATUS_LABELS, PROVIDER_LABELS } from '@renderer/lib/constants';
import { formatTokens } from '@renderer/lib/formatters';
@@ -14,42 +16,63 @@ export function StatusBar(): React.JSX.Element {
const provider = useAgentStore((s) => s.provider);
const model = useAgentStore((s) => s.model);
const tokenUsage = useAgentStore((s) => s.tokenUsage);
const openSettings = useUIStore((s) => s.openSettings);
return (
<Box
component="footer"
sx={{
flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'space-between',
px: 2, height: 24, bgcolor: 'background.paper', borderTop: 1, borderColor: 'divider', userSelect: 'none',
flexShrink: 0, display: 'flex', alignItems: 'center',
px: 1.5, height: 28, bgcolor: 'background.paper',
borderTop: 1, borderColor: 'divider', userSelect: 'none',
}}
>
<Stack direction="row" spacing={1.5} alignItems="center">
<Stack direction="row" spacing={0.75} alignItems="center">
{/* 左侧:状态信息表格 */}
<Table size="small" sx={{
flex: 1, width: 'auto',
'& .MuiTableCell-root': { border: 0, py: 0, px: 1, fontSize: 10, whiteSpace: 'nowrap' },
}}>
<TableBody>
<TableRow>
<TableCell sx={{ width: 'auto', py: 0, px: 1 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75 }}>
<Box
sx={{
width: 8, height: 8, borderRadius: '50%', flexShrink: 0,
width: 7, height: 7, borderRadius: '50%', flexShrink: 0,
bgcolor: AGENT_STATUS_COLORS[agentStatus],
animation: (agentStatus === 'thinking' || agentStatus === 'executing') ? 'pulse 2s infinite' : 'none',
}}
/>
<Typography variant="caption" sx={{ color: 'text.secondary', fontSize: 11, lineHeight: 1 }}>
<Typography variant="caption" sx={{ color: 'text.secondary', fontSize: 10, lineHeight: 1 }}>
{AGENT_STATUS_LABELS[agentStatus]}
</Typography>
</Stack>
<Typography variant="caption" sx={{ color: 'divider' }}>|</Typography>
<Typography variant="caption" sx={{ color: 'text.secondary', fontSize: 11 }}>
</Box>
</TableCell>
<TableCell sx={{ color: 'divider', width: 1, p: 0 }}>|</TableCell>
<TableCell sx={{ color: 'text.secondary', fontSize: 10 }}>
{PROVIDER_LABELS[provider] ?? provider} {model}
</Typography>
</Stack>
<Stack direction="row" spacing={1.5} alignItems="center">
</TableCell>
{tokenUsage.totalTokens > 0 && (
<Typography variant="caption" sx={{ color: 'text.secondary', fontSize: 11 }}>
Tokens: {formatTokens(tokenUsage.inputTokens)} {formatTokens(tokenUsage.outputTokens)}
</Typography>
<>
<TableCell sx={{ color: 'divider', width: 1, p: 0 }}>|</TableCell>
<TableCell sx={{ fontFamily: 'monospace', color: 'text.secondary', fontSize: 10 }}>
{formatTokens(tokenUsage.inputTokens)} {formatTokens(tokenUsage.outputTokens)}
</TableCell>
</>
)}
<Typography variant="caption" sx={{ color: 'text.secondary', fontSize: 11 }}>MetonaAI v0.1.0</Typography>
</Stack>
</TableRow>
</TableBody>
</Table>
{/* 右侧:版本 + 设置 */}
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5, flexShrink: 0 }}>
<Typography variant="caption" sx={{ color: 'text.disabled', fontSize: 9 }}>v0.1.0</Typography>
<Tooltip title="设置 (Ctrl+,)">
<IconButton size="small" onClick={openSettings} sx={{ color: 'text.secondary', width: 24, height: 24 }}>
<Settings size={12} />
</IconButton>
</Tooltip>
</Box>
</Box>
);
}