From 6e500302370499635e6e4e52ccb50cd86b3cadb0 Mon Sep 17 00:00:00 2001 From: fullex <106392080+0xfullex@users.noreply.github.com> Date: Tue, 27 May 2025 21:11:49 +0800 Subject: [PATCH] refactor: TrayService & ConfigManager (#6526) * refactor: TrayService - Removed the App_RestartTray channel from IpcChannel and its usage in ipc.ts and preload/index.ts. - Updated TrayService to handle configuration changes without the need for a restart. - Enhanced ConfigManager to notify subscribers on language and quick assistant settings changes. - Adjusted QuickAssistantSettings to close the mini window based on the quick assistant's enable state. * refactor: enhance configuration management - Updated ConfigManager to consolidate setting and notification logic into a single method, setAndNotify. - Modified IPC handler to accept an additional parameter for notification control. - Adjusted QuickAssistantSettings to utilize the new parameter for enabling notifications during configuration changes. --- packages/shared/IpcChannel.ts | 1 - src/main/ipc.ts | 7 +- src/main/services/ConfigManager.ts | 31 ++++----- src/main/services/TrayService.ts | 68 +++++++++++-------- src/preload/index.ts | 4 +- .../pages/settings/QuickAssistantSettings.tsx | 7 +- 6 files changed, 60 insertions(+), 58 deletions(-) diff --git a/packages/shared/IpcChannel.ts b/packages/shared/IpcChannel.ts index 50d9aa248c..c09f988fde 100644 --- a/packages/shared/IpcChannel.ts +++ b/packages/shared/IpcChannel.ts @@ -11,7 +11,6 @@ export enum IpcChannel { App_SetLaunchToTray = 'app:set-launch-to-tray', App_SetTray = 'app:set-tray', App_SetTrayOnClose = 'app:set-tray-on-close', - App_RestartTray = 'app:restart-tray', App_SetTheme = 'app:set-theme', App_SetAutoUpdate = 'app:set-auto-update', App_HandleZoomFactor = 'app:handle-zoom-factor', diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 94de990c5d..7773589bed 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -28,7 +28,6 @@ import { searchService } from './services/SearchService' import { SelectionService } from './services/SelectionService' import { registerShortcuts, unregisterAllShortcuts } from './services/ShortcutService' import storeSyncService from './services/StoreSyncService' -import { TrayService } from './services/TrayService' import { setOpenLinkExternal } from './services/WebviewService' import { windowService } from './services/WindowService' import { calculateDirectorySize, getResourcePath } from './utils' @@ -113,10 +112,8 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { configManager.setAutoUpdate(isActive) }) - ipcMain.handle(IpcChannel.App_RestartTray, () => TrayService.getInstance().restartTray()) - - ipcMain.handle(IpcChannel.Config_Set, (_, key: string, value: any) => { - configManager.set(key, value) + ipcMain.handle(IpcChannel.Config_Set, (_, key: string, value: any, isNotify: boolean = false) => { + configManager.set(key, value, isNotify) }) ipcMain.handle(IpcChannel.Config_Get, (_, key: string) => { diff --git a/src/main/services/ConfigManager.ts b/src/main/services/ConfigManager.ts index 996b976f0c..6249322019 100644 --- a/src/main/services/ConfigManager.ts +++ b/src/main/services/ConfigManager.ts @@ -35,8 +35,8 @@ export class ConfigManager { return this.get(ConfigKeys.Language, locale) as LanguageVarious } - setLanguage(theme: LanguageVarious) { - this.set(ConfigKeys.Language, theme) + setLanguage(lang: LanguageVarious) { + this.setAndNotify(ConfigKeys.Language, lang) } getTheme(): ThemeMode { @@ -60,8 +60,7 @@ export class ConfigManager { } setTray(value: boolean) { - this.set(ConfigKeys.Tray, value) - this.notifySubscribers(ConfigKeys.Tray, value) + this.setAndNotify(ConfigKeys.Tray, value) } getTrayOnClose(): boolean { @@ -77,8 +76,7 @@ export class ConfigManager { } setZoomFactor(factor: number) { - this.set(ConfigKeys.ZoomFactor, factor) - this.notifySubscribers(ConfigKeys.ZoomFactor, factor) + this.setAndNotify(ConfigKeys.ZoomFactor, factor) } subscribe(key: string, callback: (newValue: T) => void) { @@ -110,11 +108,10 @@ export class ConfigManager { } setShortcuts(shortcuts: Shortcut[]) { - this.set( + this.setAndNotify( ConfigKeys.Shortcuts, shortcuts.filter((shortcut) => shortcut.system) ) - this.notifySubscribers(ConfigKeys.Shortcuts, shortcuts) } getClickTrayToShowQuickAssistant(): boolean { @@ -130,7 +127,7 @@ export class ConfigManager { } setEnableQuickAssistant(value: boolean) { - this.set(ConfigKeys.EnableQuickAssistant, value) + this.setAndNotify(ConfigKeys.EnableQuickAssistant, value) } getAutoUpdate(): boolean { @@ -155,8 +152,7 @@ export class ConfigManager { } setSelectionAssistantEnabled(value: boolean) { - this.set(ConfigKeys.SelectionAssistantEnabled, value) - this.notifySubscribers(ConfigKeys.SelectionAssistantEnabled, value) + this.setAndNotify(ConfigKeys.SelectionAssistantEnabled, value) } // Selection Assistant: trigger mode (selected, ctrlkey) @@ -165,8 +161,7 @@ export class ConfigManager { } setSelectionAssistantTriggerMode(value: string) { - this.set(ConfigKeys.SelectionAssistantTriggerMode, value) - this.notifySubscribers(ConfigKeys.SelectionAssistantTriggerMode, value) + this.setAndNotify(ConfigKeys.SelectionAssistantTriggerMode, value) } // Selection Assistant: if action window position follow toolbar @@ -175,12 +170,16 @@ export class ConfigManager { } setSelectionAssistantFollowToolbar(value: boolean) { - this.set(ConfigKeys.SelectionAssistantFollowToolbar, value) - this.notifySubscribers(ConfigKeys.SelectionAssistantFollowToolbar, value) + this.setAndNotify(ConfigKeys.SelectionAssistantFollowToolbar, value) } - set(key: string, value: unknown) { + setAndNotify(key: string, value: unknown) { + this.set(key, value, true) + } + + set(key: string, value: unknown, isNotify: boolean = false) { this.store.set(key, value) + isNotify && this.notifySubscribers(key, value) } get(key: string, defaultValue?: T) { diff --git a/src/main/services/TrayService.ts b/src/main/services/TrayService.ts index 0d8d58ba70..abfb6c037b 100644 --- a/src/main/services/TrayService.ts +++ b/src/main/services/TrayService.ts @@ -5,16 +5,17 @@ import { app, Menu, MenuItemConstructorOptions, nativeImage, nativeTheme, Tray } import icon from '../../../build/tray_icon.png?asset' import iconDark from '../../../build/tray_icon_dark.png?asset' import iconLight from '../../../build/tray_icon_light.png?asset' -import { configManager } from './ConfigManager' +import { ConfigKeys, configManager } from './ConfigManager' import { windowService } from './WindowService' export class TrayService { private static instance: TrayService private tray: Tray | null = null + private contextMenu: Menu | null = null constructor() { + this.watchConfigChanges() this.updateTray() - this.watchTrayChanges() TrayService.instance = this } @@ -43,6 +44,30 @@ export class TrayService { this.tray = tray + this.updateContextMenu() + + if (process.platform === 'linux') { + this.tray.setContextMenu(this.contextMenu) + } + + this.tray.setToolTip('Cherry Studio') + + this.tray.on('right-click', () => { + if (this.contextMenu) { + this.tray?.popUpContextMenu(this.contextMenu) + } + }) + + this.tray.on('click', () => { + if (configManager.getEnableQuickAssistant() && configManager.getClickTrayToShowQuickAssistant()) { + windowService.showMiniWindow() + } else { + windowService.showMainWindow() + } + }) + } + + private updateContextMenu() { const locale = locales[configManager.getLanguage()] const { tray: trayLocale } = locale.translation @@ -64,25 +89,7 @@ export class TrayService { } ].filter(Boolean) as MenuItemConstructorOptions[] - const contextMenu = Menu.buildFromTemplate(template) - - if (process.platform === 'linux') { - this.tray.setContextMenu(contextMenu) - } - - this.tray.setToolTip('Cherry Studio') - - this.tray.on('right-click', () => { - this.tray?.popUpContextMenu(contextMenu) - }) - - this.tray.on('click', () => { - if (enableQuickAssistant && configManager.getClickTrayToShowQuickAssistant()) { - windowService.showMiniWindow() - } else { - windowService.showMainWindow() - } - }) + this.contextMenu = Menu.buildFromTemplate(template) } private updateTray() { @@ -94,13 +101,6 @@ export class TrayService { } } - public restartTray() { - if (configManager.getTray()) { - this.destroyTray() - this.createTray() - } - } - private destroyTray() { if (this.tray) { this.tray.destroy() @@ -108,8 +108,16 @@ export class TrayService { } } - private watchTrayChanges() { - configManager.subscribe('tray', () => this.updateTray()) + private watchConfigChanges() { + configManager.subscribe(ConfigKeys.Tray, () => this.updateTray()) + + configManager.subscribe(ConfigKeys.Language, () => { + this.updateContextMenu() + }) + + configManager.subscribe(ConfigKeys.EnableQuickAssistant, () => { + this.updateContextMenu() + }) } private quit() { diff --git a/src/preload/index.ts b/src/preload/index.ts index f5a4a85f12..f209191bbe 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -20,7 +20,6 @@ const api = { setLaunchToTray: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetLaunchToTray, isActive), setTray: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTray, isActive), setTrayOnClose: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTrayOnClose, isActive), - restartTray: () => ipcRenderer.invoke(IpcChannel.App_RestartTray), setTheme: (theme: 'light' | 'dark' | 'auto') => ipcRenderer.invoke(IpcChannel.App_SetTheme, theme), handleZoomFactor: (delta: number, reset: boolean = false) => ipcRenderer.invoke(IpcChannel.App_HandleZoomFactor, delta, reset), @@ -128,7 +127,8 @@ const api = { deleteFile: (fileId: string, apiKey: string) => ipcRenderer.invoke(IpcChannel.Gemini_DeleteFile, fileId, apiKey) }, config: { - set: (key: string, value: any) => ipcRenderer.invoke(IpcChannel.Config_Set, key, value), + set: (key: string, value: any, isNotify: boolean = false) => + ipcRenderer.invoke(IpcChannel.Config_Set, key, value, isNotify), get: (key: string) => ipcRenderer.invoke(IpcChannel.Config_Get, key) }, miniWindow: { diff --git a/src/renderer/src/pages/settings/QuickAssistantSettings.tsx b/src/renderer/src/pages/settings/QuickAssistantSettings.tsx index 35ae48bd4d..18ab1794e6 100644 --- a/src/renderer/src/pages/settings/QuickAssistantSettings.tsx +++ b/src/renderer/src/pages/settings/QuickAssistantSettings.tsx @@ -23,10 +23,9 @@ const QuickAssistantSettings: FC = () => { const handleEnableQuickAssistant = async (enable: boolean) => { dispatch(setEnableQuickAssistant(enable)) - await window.api.config.set('enableQuickAssistant', enable) - window.api.restartTray() - const disable = !enable - disable && window.api.miniWindow.close() + await window.api.config.set('enableQuickAssistant', enable, true) + + !enable && window.api.miniWindow.close() if (enable && !clickTrayToShowQuickAssistant) { window.message.info({