fix(desktop): isolate app theme from Claude CLI #987

Keep the desktop appearance in cc-haha local storage instead of reading or writing the user-owned Claude settings theme.

Tested: bun run test -- src/stores/settingsStore.test.ts
Tested: bun run check:desktop
Tested: bun run check:coverage
Tested: agent-browser theme isolation smoke with temporary CLAUDE_CONFIG_DIR
Confidence: high
Scope-risk: narrow
This commit is contained in:
程序员阿江(Relakkes) 2026-07-11 00:44:20 +08:00
parent 43d6776270
commit 8320a36195
2 changed files with 15 additions and 16 deletions

View File

@ -1112,11 +1112,13 @@ describe('settingsStore theme persistence', () => {
expect(document.documentElement.style.colorScheme).toBe('light')
})
it('hydrates the pure white theme from user settings', async () => {
it('keeps the desktop theme independent from the Claude user theme', async () => {
window.localStorage.setItem('cc-haha-theme', 'dark')
const updateUser = vi.fn()
vi.doMock('../api/settings', () => ({
settingsApi: {
getUser: vi.fn().mockResolvedValue({ theme: 'white' }),
updateUser: vi.fn(),
getUser: vi.fn().mockResolvedValue({ theme: 'light', unknownField: 'keep-me' }),
updateUser,
getPermissionMode: vi.fn().mockResolvedValue({ mode: 'default' }),
setPermissionMode: vi.fn(),
getCliLauncherStatus: vi.fn(),
@ -1153,10 +1155,15 @@ describe('settingsStore theme persistence', () => {
await useSettingsStore.getState().fetchAll()
expect(useSettingsStore.getState().theme).toBe('white')
expect(useUIStore.getState().theme).toBe('white')
expect(document.documentElement.getAttribute('data-theme')).toBe('white')
expect(document.documentElement.style.colorScheme).toBe('light')
expect(useSettingsStore.getState().theme).toBe('dark')
expect(useUIStore.getState().theme).toBe('dark')
expect(document.documentElement.getAttribute('data-theme')).toBe('dark')
expect(document.documentElement.style.colorScheme).toBe('dark')
await useSettingsStore.getState().setTheme('light')
expect(window.localStorage.getItem('cc-haha-theme')).toBe('light')
expect(updateUser).not.toHaveBeenCalled()
})
})

View File

@ -5,7 +5,6 @@ import { modelsApi } from '../api/models'
import { h5AccessApi } from '../api/h5Access'
import { tracesApi } from '../api/traces'
import {
isThemeMode,
type AppMode,
type AppModeConfig,
type ChatSendBehavior,
@ -230,7 +229,7 @@ export const useSettingsStore = create<SettingsStore>((set, get) => ({
loadH5AccessSettings(previousH5Access),
loadTraceCaptureSettings(),
])
const theme = isThemeMode(userSettings.theme) ? userSettings.theme : 'white'
const theme = useUIStore.getState().theme
useUIStore.getState().setTheme(theme)
set({
permissionMode: mode,
@ -327,15 +326,8 @@ export const useSettingsStore = create<SettingsStore>((set, get) => ({
},
setTheme: async (theme) => {
const prev = get().theme
set({ theme })
useUIStore.getState().setTheme(theme)
try {
await settingsApi.updateUser({ theme })
} catch {
set({ theme: prev })
useUIStore.getState().setTheme(prev)
}
},
setChatSendBehavior: async (behavior) => {