From 2f3885ab4a3a29cdac09e381128727cc772e50e6 Mon Sep 17 00:00:00 2001 From: phantom5099 <1011668688@qq.com> Date: Sun, 7 Jun 2026 16:13:35 +0800 Subject: [PATCH 1/7] add switchable theme styles --- packages/desktop/electron/main.ts | 22 ++ packages/desktop/electron/preload.ts | 3 + packages/desktop/src/App.tsx | 9 +- packages/desktop/src/TitleBar.tsx | 12 +- packages/desktop/src/agent/AgentSidebar.tsx | 36 +-- packages/desktop/src/agent/AgentWorkspace.tsx | 46 ++-- packages/desktop/src/agent/ApprovalPanel.tsx | 10 +- packages/desktop/src/agent/MessageStream.tsx | 60 ++--- packages/desktop/src/agent/ProjectStrip.tsx | 28 +-- packages/desktop/src/agent/TodoPanel.tsx | 20 +- packages/desktop/src/layouts/IDELayout.tsx | 8 +- packages/desktop/src/prismjs.d.ts | 7 + packages/desktop/src/settings/HooksPanel.tsx | 70 +++--- packages/desktop/src/settings/McpPanel.tsx | 46 ++-- packages/desktop/src/settings/MemoryPanel.tsx | 50 ++--- .../desktop/src/settings/SettingsPage.tsx | 50 ++++- packages/desktop/src/settings/SkillPanel.tsx | 12 +- .../desktop/src/settings/SubagentsPanel.tsx | 74 +++---- packages/desktop/src/settings/Toggle.tsx | 4 +- packages/desktop/src/shared/CodeBlock.tsx | 4 +- packages/desktop/src/shared/DiffBlock.tsx | 14 +- packages/desktop/src/shared/ErrorBoundary.tsx | 8 +- .../desktop/src/shared/MarkdownRenderer.tsx | 30 +-- packages/desktop/src/shared/MessageItem.tsx | 32 +-- packages/desktop/src/shared/ToolCallCard.tsx | 20 +- packages/desktop/src/shared/ToolSummary.tsx | 10 +- .../desktop/src/shared/UnifiedDiffView.tsx | 26 +-- packages/desktop/src/stores/global.store.ts | 7 + packages/desktop/src/styles/index.css | 206 ------------------ 29 files changed, 398 insertions(+), 526 deletions(-) create mode 100644 packages/desktop/src/prismjs.d.ts delete mode 100644 packages/desktop/src/styles/index.css diff --git a/packages/desktop/electron/main.ts b/packages/desktop/electron/main.ts index 2598aa9..d980d9e 100644 --- a/packages/desktop/electron/main.ts +++ b/packages/desktop/electron/main.ts @@ -86,6 +86,28 @@ app.whenReady().then(async () => { currentWorkspaceCwd = cwd; }); + // Theme sync: update window background and title bar overlay + const themeColors = { + dark: { bg: '#1e1e1e', overlay: '#1a1a1a', symbol: '#858585' }, + light: { bg: '#ffffff', overlay: '#f5f5f5', symbol: '#666666' }, + paper: { bg: '#f5f0e8', overlay: '#ede8de', symbol: '#7a7872' }, + }; + + ipcMain.on('theme:change', (_e, theme: string) => { + if (!mainWindow) return; + const c = themeColors[theme as keyof typeof themeColors]; + if (!c) return; + + mainWindow.setBackgroundColor(c.bg); + + if (process.platform === 'win32') { + mainWindow.setTitleBarOverlay({ + color: c.overlay, + symbolColor: c.symbol, + }); + } + }); + registerFsHandlers(); registerGitHandlers(); diff --git a/packages/desktop/electron/preload.ts b/packages/desktop/electron/preload.ts index 3d9c39e..df5eb1a 100644 --- a/packages/desktop/electron/preload.ts +++ b/packages/desktop/electron/preload.ts @@ -31,6 +31,9 @@ const api = { // Workspace cwd sync (renderer -> main) setWorkspaceCwd: (cwd: string): void => ipcRenderer.send('workspace:setCwd', cwd), + // Theme sync (renderer -> main) + setTheme: (theme: string): void => ipcRenderer.send('theme:change', theme), + // Git (explicit cwd) gitStatus: (cwd: string): Promise => ipcRenderer.invoke('git:status', cwd), gitBranches: (cwd: string): Promise => ipcRenderer.invoke('git:branches', cwd), diff --git a/packages/desktop/src/App.tsx b/packages/desktop/src/App.tsx index f26ba79..6b99368 100644 --- a/packages/desktop/src/App.tsx +++ b/packages/desktop/src/App.tsx @@ -7,6 +7,7 @@ import ErrorBoundary from './shared/ErrorBoundary'; export default function App() { const mode = useGlobalStore((s) => s.ui.mode); + const theme = useGlobalStore((s) => s.ui.theme); const setMode = useGlobalStore((s) => s.setMode); const rootPath = useGlobalStore((s) => s.workspace.rootPath); @@ -17,6 +18,12 @@ export default function App() { } }, [rootPath]); + // Sync theme to document and main process + useEffect(() => { + document.documentElement.dataset.theme = theme; + window.electronAPI?.setTheme?.(theme); + }, [theme]); + useEffect(() => { const off = window.electronAPI?.onFsChange?.(() => {}); const handler = ((e: CustomEvent<'agent' | 'ide'>) => { @@ -31,7 +38,7 @@ export default function App() { return ( -
+
{/* Both layouts stay mounted; visibility toggled via display to preserve Monaco + PTY state */}
diff --git a/packages/desktop/src/TitleBar.tsx b/packages/desktop/src/TitleBar.tsx index 4be9197..fa2e11d 100644 --- a/packages/desktop/src/TitleBar.tsx +++ b/packages/desktop/src/TitleBar.tsx @@ -10,7 +10,7 @@ export default function TitleBar() { return (
- Coding Code + Coding Code
setMode('agent')} className={`px-3 h-6 text-xs rounded transition-colors ${ mode === 'agent' - ? 'bg-[#0e639c] text-white' - : 'text-[#858585] hover:text-[#cccccc] hover:bg-[#2d2d2d]' + ? 'bg-[var(--accent-primary)] text-[var(--text-inverse)]' + : 'text-[var(--text-tertiary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-hover)]' }`} > Agent @@ -37,8 +37,8 @@ export default function TitleBar() { onClick={() => setMode('ide')} className={`px-3 h-6 text-xs rounded transition-colors ${ mode === 'ide' - ? 'bg-[#0e639c] text-white' - : 'text-[#858585] hover:text-[#cccccc] hover:bg-[#2d2d2d]' + ? 'bg-[var(--accent-primary)] text-[var(--text-inverse)]' + : 'text-[var(--text-tertiary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-hover)]' }`} > IDE diff --git a/packages/desktop/src/agent/AgentSidebar.tsx b/packages/desktop/src/agent/AgentSidebar.tsx index 103c6cf..8923e02 100644 --- a/packages/desktop/src/agent/AgentSidebar.tsx +++ b/packages/desktop/src/agent/AgentSidebar.tsx @@ -69,12 +69,12 @@ export default function AgentSidebar() { if (sidebarCollapsed) { return ( -
+
@@ -83,17 +83,17 @@ export default function AgentSidebar() { } return ( -
+
{/* 顶部栏:项目名 + 收起按钮 */}
- + {projectName || '项目'} @@ -104,7 +104,7 @@ export default function AgentSidebar() { ) : ( - + {relativeTime(t.updatedAt)} )} @@ -177,24 +177,24 @@ export default function AgentSidebar() { {threadList.length > 15 && ( )} {threadList.length === 0 && ( -
暂无对话
+
暂无对话
)}
-
+
{/* 底部 */}
); } diff --git a/packages/desktop/src/agent/AgentWorkspace.tsx b/packages/desktop/src/agent/AgentWorkspace.tsx index d45796c..0355c5a 100644 --- a/packages/desktop/src/agent/AgentWorkspace.tsx +++ b/packages/desktop/src/agent/AgentWorkspace.tsx @@ -29,13 +29,13 @@ function ContextIndicator({ threadId }: { threadId: string }) { className="w-5 h-5 flex items-center justify-center animate-pulse cursor-default" > - + - + setOpen((v) => !v)} - className="flex items-center gap-1.5 px-2.5 py-1.5 text-[13px] text-[#555] hover:text-[#aaa] hover:bg-[#252525] rounded-lg transition-colors" + className="flex items-center gap-1.5 px-2.5 py-1.5 text-[13px] text-[var(--text-placeholder)] hover:text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] rounded-lg transition-colors" > {displayName || '选择模型'} - + {open && createPortal( @@ -150,11 +150,11 @@ function ModelSelector() {
setOpen(false)} />
{Object.entries(groups).map(([provider, providerModels]) => (
-
+
{provider}
{providerModels.map((m) => ( @@ -172,13 +172,13 @@ function ModelSelector() { console.error('Failed to switch model:', e); }); }} - className={`w-full text-left px-3 py-2 text-[14px] hover:bg-[#094771] transition-colors flex items-center gap-2 ${m.id === model ? 'text-[#4ec9b0]' : 'text-[#ccc]'}`} + className={`w-full text-left px-3 py-2 text-[14px] hover:bg-[var(--bg-selected-hover)] transition-colors flex items-center gap-2 ${m.id === model ? 'text-[var(--accent-success)]' : 'text-[var(--text-primary)]'}`} > {m.id === model ? '✓' : ''} {m.name} - + {(m.context_window / 1000).toFixed(0)}k @@ -186,7 +186,7 @@ function ModelSelector() {
))} {models.length === 0 && ( -
无可用模型
+
无可用模型
)}
, @@ -260,7 +260,7 @@ function InputBox({ return (
-
+
{/* Row 1: textarea + send button side by side */}