chores: remove config manager (#10856)

* refactor: migrate from configManager to preferenceService

- Replace configManager with preferenceService for app settings
- Update zoom factor management to use preferenceService
- Migrate spell check settings to preferenceService
- Update language subscription in NodeTraceService
- Move client ID generation to systemInfo utility
- Keep shortcuts management in configManager (not migrated)
- Mark legacy Config_Set/Config_Get as deprecated
- Update AppUpdater test mock to include getClientId

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: migrate from configManager to preferenceService

- Replace configManager with preferenceService for app settings
- Update zoom factor management to use preferenceService
- Migrate spell check settings to preferenceService
- Update language subscription in NodeTraceService
- Move client ID generation to systemInfo utility
- Keep shortcuts management in configManager (not migrated)
- Mark legacy Config_Set/Config_Get as deprecated
- Update AppUpdater test mock to include getClientId

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
beyondkmp 2025-10-21 13:46:05 +08:00 committed by GitHub
parent e59990d24e
commit fb62ae18b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 59 additions and 34 deletions

View File

@ -19,7 +19,6 @@ import process from 'node:process'
import { registerIpc } from './ipc'
import { agentService } from './services/agents'
import { apiServerService } from './services/ApiServerService'
import { configManager } from './services/ConfigManager'
import mcpService from './services/MCPService'
import { nodeTraceService } from './services/NodeTraceService'
import {
@ -42,12 +41,12 @@ const logger = loggerService.withContext('MainEntry')
/**
* Disable hardware acceleration if setting is enabled
*/
//FIXME should not use configManager, use usePreference instead
//FIXME should not use preferenceService before initialization
//TODO 我们需要调整配置管理的加载位置,以保证其在 preferenceService 初始化之前被调用
const disableHardwareAcceleration = configManager.getDisableHardwareAcceleration()
if (disableHardwareAcceleration) {
app.disableHardwareAcceleration()
}
// const disableHardwareAcceleration = preferenceService.get('app.disable_hardware_acceleration')
// if (disableHardwareAcceleration) {
// app.disableHardwareAcceleration()
// }
/**
* Disable chromium's window animations

View File

@ -169,7 +169,7 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
windows.forEach((window) => {
window.webContents.session.setSpellCheckerLanguages(languages)
})
configManager.set('spellCheckLanguages', languages)
preferenceService.set('app.spell_check.languages', languages)
})
// launch on boot
@ -264,12 +264,15 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
}
})
ipcMain.handle(IpcChannel.Config_Set, (_, key: string, value: any, isNotify: boolean = false) => {
configManager.set(key, value, isNotify)
ipcMain.handle(IpcChannel.Config_Set, (_, key: string) => {
// Legacy config handler - will be deprecated
logger.warn(`Legacy Config_Set called for key: ${key}`)
})
ipcMain.handle(IpcChannel.Config_Get, (_, key: string) => {
return configManager.get(key)
// Legacy config handler - will be deprecated
logger.warn(`Legacy Config_Get called for key: ${key}`)
return undefined
})
// // theme
@ -280,7 +283,7 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
ipcMain.handle(IpcChannel.App_HandleZoomFactor, (_, delta: number, reset: boolean = false) => {
const windows = BrowserWindow.getAllWindows()
handleZoomFactor(windows, delta, reset)
return configManager.getZoomFactor()
return preferenceService.get('app.zoom_factor')
})
// clear cache

View File

@ -1,9 +1,8 @@
import { preferenceService } from '@data/PreferenceService'
import { loggerService } from '@logger'
import { isWin } from '@main/constant'
import { configManager } from '@main/services/ConfigManager'
import { getIpCountry } from '@main/utils/ipService'
import { generateUserAgent } from '@main/utils/systemInfo'
import { generateUserAgent, getClientId } from '@main/utils/systemInfo'
import { FeedUrl } from '@shared/config/constant'
import { UpgradeChannel } from '@shared/data/preference/preferenceTypes'
import { IpcChannel } from '@shared/IpcChannel'
@ -39,7 +38,7 @@ export default class AppUpdater {
autoUpdater.requestHeaders = {
...autoUpdater.requestHeaders,
'User-Agent': generateUserAgent(),
'X-Client-Id': configManager.getClientId()
'X-Client-Id': getClientId()
}
autoUpdater.on('error', (error) => {

View File

@ -1,3 +1,4 @@
import { preferenceService } from '@data/PreferenceService'
import { loggerService } from '@logger'
import { isDev } from '@main/constant'
import { CacheBatchSpanProcessor, FunctionSpanExporter } from '@mcp-trace/trace-core'
@ -7,7 +8,6 @@ import { context, trace } from '@opentelemetry/api'
import { BrowserWindow, ipcMain } from 'electron'
import * as path from 'path'
import { ConfigKeys, configManager } from './ConfigManager'
import { spanCacheService } from './SpanCacheService'
export const TRACER_NAME = 'CherryStudio'
@ -91,8 +91,13 @@ export function openTraceWindow(topicId: string, traceId: string, autoOpen = tru
} else {
traceWin.loadFile(path.join(__dirname, '../renderer/traceWindow.html'))
}
let unsubscribeLanguage: (() => void) | null = null
traceWin.on('closed', () => {
configManager.unsubscribe(ConfigKeys.Language, setLanguageCallback)
if (unsubscribeLanguage) {
unsubscribeLanguage()
unsubscribeLanguage = null
}
try {
traceWin?.destroy()
} finally {
@ -106,13 +111,15 @@ export function openTraceWindow(topicId: string, traceId: string, autoOpen = tru
topicId,
modelName
})
traceWin!.webContents.send('set-language', { lang: configManager.get(ConfigKeys.Language) })
configManager.subscribe(ConfigKeys.Language, setLanguageCallback)
traceWin!.webContents.send('set-language', { lang: preferenceService.get('app.language') })
unsubscribeLanguage = preferenceService.subscribeChange('app.language', setLanguageCallback)
})
}
const setLanguageCallback = (lang: string) => {
traceWin!.webContents.send('set-language', { lang })
const setLanguageCallback = (lang: string | null) => {
if (lang) {
traceWin?.webContents.send('set-language', { lang })
}
}
export const setTraceWindowTitle = (title: string) => {

View File

@ -14,7 +14,6 @@ import { join } from 'path'
import icon from '../../../build/icon.png?asset'
import { titleBarOverlayDark, titleBarOverlayLight } from '../config'
import { configManager } from './ConfigManager'
import { contextMenu } from './ContextMenu'
import { initSessionUserAgent } from './WebviewService'
@ -87,7 +86,7 @@ export class WindowService {
webSecurity: false,
webviewTag: true,
allowRunningInsecureContent: true,
zoomFactor: configManager.getZoomFactor(),
zoomFactor: preferenceService.get('app.zoom_factor'),
backgroundThrottling: false
}
})
@ -120,10 +119,10 @@ export class WindowService {
}
private setupSpellCheck(mainWindow: BrowserWindow) {
const enableSpellCheck = configManager.get('enableSpellCheck', false)
const enableSpellCheck = preferenceService.get('app.spell_check.enabled')
if (enableSpellCheck) {
try {
const spellCheckLanguages = configManager.get('spellCheckLanguages', []) as string[]
const spellCheckLanguages = preferenceService.get('app.spell_check.languages')
spellCheckLanguages.length > 0 && mainWindow.webContents.session.setSpellCheckerLanguages(spellCheckLanguages)
} catch (error) {
logger.error('Failed to set spell check languages:', error as Error)
@ -175,7 +174,7 @@ export class WindowService {
private setupWindowEvents(mainWindow: BrowserWindow) {
mainWindow.once('ready-to-show', () => {
mainWindow.webContents.setZoomFactor(configManager.getZoomFactor())
mainWindow.webContents.setZoomFactor(preferenceService.get('app.zoom_factor'))
// show window only when laucn to tray not set
const isLaunchToTray = preferenceService.get('app.tray.on_launch')
@ -204,14 +203,14 @@ export class WindowService {
// and resize ipc
//
mainWindow.on('will-resize', () => {
mainWindow.webContents.setZoomFactor(configManager.getZoomFactor())
mainWindow.webContents.setZoomFactor(preferenceService.get('app.zoom_factor'))
mainWindow.webContents.send(IpcChannel.Windows_Resize, mainWindow.getSize())
})
// set the zoom factor again when the window is going to restore
// minimize and restore will cause zoom reset
mainWindow.on('restore', () => {
mainWindow.webContents.setZoomFactor(configManager.getZoomFactor())
mainWindow.webContents.setZoomFactor(preferenceService.get('app.zoom_factor'))
})
// ARCH: as `will-resize` is only for Win & Mac,
@ -219,7 +218,7 @@ export class WindowService {
// but `resize` will fliker the ui
if (isLinux) {
mainWindow.on('resize', () => {
mainWindow.webContents.setZoomFactor(configManager.getZoomFactor())
mainWindow.webContents.setZoomFactor(preferenceService.get('app.zoom_factor'))
mainWindow.webContents.send(IpcChannel.Windows_Resize, mainWindow.getSize())
})
}

View File

@ -40,7 +40,8 @@ vi.mock('@main/utils/locales', () => ({
}))
vi.mock('@main/utils/systemInfo', () => ({
generateUserAgent: vi.fn(() => 'test-user-agent')
generateUserAgent: vi.fn(() => 'test-user-agent'),
getClientId: vi.fn(() => 'test-client-id')
}))
vi.mock('electron', () => ({

View File

@ -1,6 +1,8 @@
import { preferenceService } from '@data/PreferenceService'
import { app } from 'electron'
import macosRelease from 'macos-release'
import os from 'os'
import { v4 as uuidv4 } from 'uuid'
/**
* System information interface
@ -90,3 +92,19 @@ export function generateUserAgent(): string {
return `Mozilla/5.0 (${systemInfo.osString}; ${systemInfo.archString}) AppleWebKit/537.36 (KHTML, like Gecko) CherryStudio/${systemInfo.appVersion} Chrome/124.0.0.0 Safari/537.36`
}
/**
* Get or generate a unique client ID
* @returns {string} Client ID
*/
export function getClientId(): string {
let clientId = preferenceService.get('app.user.id')
// If it's the placeholder value, generate a new UUID
if (!clientId || clientId.length === 0) {
clientId = uuidv4()
preferenceService.set('app.user.id', clientId)
}
return clientId
}

View File

@ -1,13 +1,12 @@
import { preferenceService } from '@data/PreferenceService'
import type { BrowserWindow } from 'electron'
import { configManager } from '../services/ConfigManager'
export function handleZoomFactor(wins: BrowserWindow[], delta: number, reset: boolean = false) {
if (reset) {
wins.forEach((win) => {
win.webContents.setZoomFactor(1)
})
configManager.setZoomFactor(1)
preferenceService.set('app.zoom_factor', 1)
return
}
@ -15,12 +14,12 @@ export function handleZoomFactor(wins: BrowserWindow[], delta: number, reset: bo
return
}
const currentZoom = configManager.getZoomFactor()
const currentZoom = preferenceService.get('app.zoom_factor')
const newZoom = Number((currentZoom + delta).toFixed(1))
if (newZoom >= 0.5 && newZoom <= 2.0) {
wins.forEach((win) => {
win.webContents.setZoomFactor(newZoom)
})
configManager.setZoomFactor(newZoom)
preferenceService.set('app.zoom_factor', newZoom)
}
}