mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-11 16:39:15 +08:00
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.
This commit is contained in:
parent
af6145600a
commit
80c09a07dc
@ -11,7 +11,6 @@ export enum IpcChannel {
|
|||||||
App_SetLaunchToTray = 'app:set-launch-to-tray',
|
App_SetLaunchToTray = 'app:set-launch-to-tray',
|
||||||
App_SetTray = 'app:set-tray',
|
App_SetTray = 'app:set-tray',
|
||||||
App_SetTrayOnClose = 'app:set-tray-on-close',
|
App_SetTrayOnClose = 'app:set-tray-on-close',
|
||||||
App_RestartTray = 'app:restart-tray',
|
|
||||||
App_SetTheme = 'app:set-theme',
|
App_SetTheme = 'app:set-theme',
|
||||||
App_SetAutoUpdate = 'app:set-auto-update',
|
App_SetAutoUpdate = 'app:set-auto-update',
|
||||||
App_HandleZoomFactor = 'app:handle-zoom-factor',
|
App_HandleZoomFactor = 'app:handle-zoom-factor',
|
||||||
|
|||||||
@ -28,7 +28,6 @@ import { searchService } from './services/SearchService'
|
|||||||
import { SelectionService } from './services/SelectionService'
|
import { SelectionService } from './services/SelectionService'
|
||||||
import { registerShortcuts, unregisterAllShortcuts } from './services/ShortcutService'
|
import { registerShortcuts, unregisterAllShortcuts } from './services/ShortcutService'
|
||||||
import storeSyncService from './services/StoreSyncService'
|
import storeSyncService from './services/StoreSyncService'
|
||||||
import { TrayService } from './services/TrayService'
|
|
||||||
import { setOpenLinkExternal } from './services/WebviewService'
|
import { setOpenLinkExternal } from './services/WebviewService'
|
||||||
import { windowService } from './services/WindowService'
|
import { windowService } from './services/WindowService'
|
||||||
import { calculateDirectorySize, getResourcePath } from './utils'
|
import { calculateDirectorySize, getResourcePath } from './utils'
|
||||||
@ -113,10 +112,8 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
|
|||||||
configManager.setAutoUpdate(isActive)
|
configManager.setAutoUpdate(isActive)
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle(IpcChannel.App_RestartTray, () => TrayService.getInstance().restartTray())
|
ipcMain.handle(IpcChannel.Config_Set, (_, key: string, value: any, isNotify: boolean = false) => {
|
||||||
|
configManager.set(key, value, isNotify)
|
||||||
ipcMain.handle(IpcChannel.Config_Set, (_, key: string, value: any) => {
|
|
||||||
configManager.set(key, value)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle(IpcChannel.Config_Get, (_, key: string) => {
|
ipcMain.handle(IpcChannel.Config_Get, (_, key: string) => {
|
||||||
|
|||||||
@ -35,8 +35,8 @@ export class ConfigManager {
|
|||||||
return this.get(ConfigKeys.Language, locale) as LanguageVarious
|
return this.get(ConfigKeys.Language, locale) as LanguageVarious
|
||||||
}
|
}
|
||||||
|
|
||||||
setLanguage(theme: LanguageVarious) {
|
setLanguage(lang: LanguageVarious) {
|
||||||
this.set(ConfigKeys.Language, theme)
|
this.setAndNotify(ConfigKeys.Language, lang)
|
||||||
}
|
}
|
||||||
|
|
||||||
getTheme(): ThemeMode {
|
getTheme(): ThemeMode {
|
||||||
@ -60,8 +60,7 @@ export class ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setTray(value: boolean) {
|
setTray(value: boolean) {
|
||||||
this.set(ConfigKeys.Tray, value)
|
this.setAndNotify(ConfigKeys.Tray, value)
|
||||||
this.notifySubscribers(ConfigKeys.Tray, value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getTrayOnClose(): boolean {
|
getTrayOnClose(): boolean {
|
||||||
@ -77,8 +76,7 @@ export class ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setZoomFactor(factor: number) {
|
setZoomFactor(factor: number) {
|
||||||
this.set(ConfigKeys.ZoomFactor, factor)
|
this.setAndNotify(ConfigKeys.ZoomFactor, factor)
|
||||||
this.notifySubscribers(ConfigKeys.ZoomFactor, factor)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribe<T>(key: string, callback: (newValue: T) => void) {
|
subscribe<T>(key: string, callback: (newValue: T) => void) {
|
||||||
@ -110,11 +108,10 @@ export class ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setShortcuts(shortcuts: Shortcut[]) {
|
setShortcuts(shortcuts: Shortcut[]) {
|
||||||
this.set(
|
this.setAndNotify(
|
||||||
ConfigKeys.Shortcuts,
|
ConfigKeys.Shortcuts,
|
||||||
shortcuts.filter((shortcut) => shortcut.system)
|
shortcuts.filter((shortcut) => shortcut.system)
|
||||||
)
|
)
|
||||||
this.notifySubscribers(ConfigKeys.Shortcuts, shortcuts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getClickTrayToShowQuickAssistant(): boolean {
|
getClickTrayToShowQuickAssistant(): boolean {
|
||||||
@ -130,7 +127,7 @@ export class ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setEnableQuickAssistant(value: boolean) {
|
setEnableQuickAssistant(value: boolean) {
|
||||||
this.set(ConfigKeys.EnableQuickAssistant, value)
|
this.setAndNotify(ConfigKeys.EnableQuickAssistant, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
getAutoUpdate(): boolean {
|
getAutoUpdate(): boolean {
|
||||||
@ -155,8 +152,7 @@ export class ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setSelectionAssistantEnabled(value: boolean) {
|
setSelectionAssistantEnabled(value: boolean) {
|
||||||
this.set(ConfigKeys.SelectionAssistantEnabled, value)
|
this.setAndNotify(ConfigKeys.SelectionAssistantEnabled, value)
|
||||||
this.notifySubscribers(ConfigKeys.SelectionAssistantEnabled, value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Selection Assistant: trigger mode (selected, ctrlkey)
|
// Selection Assistant: trigger mode (selected, ctrlkey)
|
||||||
@ -165,8 +161,7 @@ export class ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setSelectionAssistantTriggerMode(value: string) {
|
setSelectionAssistantTriggerMode(value: string) {
|
||||||
this.set(ConfigKeys.SelectionAssistantTriggerMode, value)
|
this.setAndNotify(ConfigKeys.SelectionAssistantTriggerMode, value)
|
||||||
this.notifySubscribers(ConfigKeys.SelectionAssistantTriggerMode, value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Selection Assistant: if action window position follow toolbar
|
// Selection Assistant: if action window position follow toolbar
|
||||||
@ -175,12 +170,16 @@ export class ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setSelectionAssistantFollowToolbar(value: boolean) {
|
setSelectionAssistantFollowToolbar(value: boolean) {
|
||||||
this.set(ConfigKeys.SelectionAssistantFollowToolbar, value)
|
this.setAndNotify(ConfigKeys.SelectionAssistantFollowToolbar, value)
|
||||||
this.notifySubscribers(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)
|
this.store.set(key, value)
|
||||||
|
isNotify && this.notifySubscribers(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
get<T>(key: string, defaultValue?: T) {
|
get<T>(key: string, defaultValue?: T) {
|
||||||
|
|||||||
@ -5,16 +5,17 @@ import { app, Menu, MenuItemConstructorOptions, nativeImage, nativeTheme, Tray }
|
|||||||
import icon from '../../../build/tray_icon.png?asset'
|
import icon from '../../../build/tray_icon.png?asset'
|
||||||
import iconDark from '../../../build/tray_icon_dark.png?asset'
|
import iconDark from '../../../build/tray_icon_dark.png?asset'
|
||||||
import iconLight from '../../../build/tray_icon_light.png?asset'
|
import iconLight from '../../../build/tray_icon_light.png?asset'
|
||||||
import { configManager } from './ConfigManager'
|
import { ConfigKeys, configManager } from './ConfigManager'
|
||||||
import { windowService } from './WindowService'
|
import { windowService } from './WindowService'
|
||||||
|
|
||||||
export class TrayService {
|
export class TrayService {
|
||||||
private static instance: TrayService
|
private static instance: TrayService
|
||||||
private tray: Tray | null = null
|
private tray: Tray | null = null
|
||||||
|
private contextMenu: Menu | null = null
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
this.watchConfigChanges()
|
||||||
this.updateTray()
|
this.updateTray()
|
||||||
this.watchTrayChanges()
|
|
||||||
TrayService.instance = this
|
TrayService.instance = this
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +44,30 @@ export class TrayService {
|
|||||||
|
|
||||||
this.tray = tray
|
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 locale = locales[configManager.getLanguage()]
|
||||||
const { tray: trayLocale } = locale.translation
|
const { tray: trayLocale } = locale.translation
|
||||||
|
|
||||||
@ -64,25 +89,7 @@ export class TrayService {
|
|||||||
}
|
}
|
||||||
].filter(Boolean) as MenuItemConstructorOptions[]
|
].filter(Boolean) as MenuItemConstructorOptions[]
|
||||||
|
|
||||||
const contextMenu = Menu.buildFromTemplate(template)
|
this.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()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateTray() {
|
private updateTray() {
|
||||||
@ -94,13 +101,6 @@ export class TrayService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public restartTray() {
|
|
||||||
if (configManager.getTray()) {
|
|
||||||
this.destroyTray()
|
|
||||||
this.createTray()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private destroyTray() {
|
private destroyTray() {
|
||||||
if (this.tray) {
|
if (this.tray) {
|
||||||
this.tray.destroy()
|
this.tray.destroy()
|
||||||
@ -108,8 +108,16 @@ export class TrayService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private watchTrayChanges() {
|
private watchConfigChanges() {
|
||||||
configManager.subscribe<boolean>('tray', () => this.updateTray())
|
configManager.subscribe(ConfigKeys.Tray, () => this.updateTray())
|
||||||
|
|
||||||
|
configManager.subscribe(ConfigKeys.Language, () => {
|
||||||
|
this.updateContextMenu()
|
||||||
|
})
|
||||||
|
|
||||||
|
configManager.subscribe(ConfigKeys.EnableQuickAssistant, () => {
|
||||||
|
this.updateContextMenu()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private quit() {
|
private quit() {
|
||||||
|
|||||||
@ -20,7 +20,6 @@ const api = {
|
|||||||
setLaunchToTray: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetLaunchToTray, isActive),
|
setLaunchToTray: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetLaunchToTray, isActive),
|
||||||
setTray: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTray, isActive),
|
setTray: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTray, isActive),
|
||||||
setTrayOnClose: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTrayOnClose, 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),
|
setTheme: (theme: 'light' | 'dark' | 'auto') => ipcRenderer.invoke(IpcChannel.App_SetTheme, theme),
|
||||||
handleZoomFactor: (delta: number, reset: boolean = false) =>
|
handleZoomFactor: (delta: number, reset: boolean = false) =>
|
||||||
ipcRenderer.invoke(IpcChannel.App_HandleZoomFactor, delta, reset),
|
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)
|
deleteFile: (fileId: string, apiKey: string) => ipcRenderer.invoke(IpcChannel.Gemini_DeleteFile, fileId, apiKey)
|
||||||
},
|
},
|
||||||
config: {
|
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)
|
get: (key: string) => ipcRenderer.invoke(IpcChannel.Config_Get, key)
|
||||||
},
|
},
|
||||||
miniWindow: {
|
miniWindow: {
|
||||||
|
|||||||
@ -23,10 +23,9 @@ const QuickAssistantSettings: FC = () => {
|
|||||||
|
|
||||||
const handleEnableQuickAssistant = async (enable: boolean) => {
|
const handleEnableQuickAssistant = async (enable: boolean) => {
|
||||||
dispatch(setEnableQuickAssistant(enable))
|
dispatch(setEnableQuickAssistant(enable))
|
||||||
await window.api.config.set('enableQuickAssistant', enable)
|
await window.api.config.set('enableQuickAssistant', enable, true)
|
||||||
window.api.restartTray()
|
|
||||||
const disable = !enable
|
!enable && window.api.miniWindow.close()
|
||||||
disable && window.api.miniWindow.close()
|
|
||||||
|
|
||||||
if (enable && !clickTrayToShowQuickAssistant) {
|
if (enable && !clickTrayToShowQuickAssistant) {
|
||||||
window.message.info({
|
window.message.info({
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user