mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-05 20:41:30 +08:00
136 lines
4.0 KiB
TypeScript
136 lines
4.0 KiB
TypeScript
import { preferenceService } from '@data/PreferenceService'
|
|
import { isLinux, isMac, isWin } from '@main/constant'
|
|
import { getI18n } from '@main/utils/language'
|
|
import type { MenuItemConstructorOptions } from 'electron'
|
|
import { app, Menu, nativeImage, nativeTheme, Tray } from 'electron'
|
|
|
|
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 selectionService from './SelectionService'
|
|
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()
|
|
TrayService.instance = this
|
|
}
|
|
|
|
public static getInstance() {
|
|
return TrayService.instance
|
|
}
|
|
|
|
private createTray() {
|
|
this.destroyTray()
|
|
|
|
const iconPath = isMac ? (nativeTheme.shouldUseDarkColors ? iconLight : iconDark) : icon
|
|
const tray = new Tray(iconPath)
|
|
|
|
if (isWin) {
|
|
tray.setImage(iconPath)
|
|
} else if (isMac) {
|
|
const image = nativeImage.createFromPath(iconPath)
|
|
const resizedImage = image.resize({ width: 16, height: 16 })
|
|
resizedImage.setTemplateImage(true)
|
|
tray.setImage(resizedImage)
|
|
} else if (isLinux) {
|
|
const image = nativeImage.createFromPath(iconPath)
|
|
const resizedImage = image.resize({ width: 16, height: 16 })
|
|
tray.setImage(resizedImage)
|
|
}
|
|
|
|
this.tray = tray
|
|
|
|
this.updateContextMenu()
|
|
|
|
if (isLinux) {
|
|
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', () => {
|
|
const quickAssistantEnabled = preferenceService.get('feature.quick_assistant.enabled')
|
|
const clickTrayToShowQuickAssistant = preferenceService.get('feature.quick_assistant.click_tray_to_show')
|
|
|
|
if (quickAssistantEnabled && clickTrayToShowQuickAssistant) {
|
|
windowService.showMiniWindow()
|
|
} else {
|
|
windowService.showMainWindow()
|
|
}
|
|
})
|
|
}
|
|
|
|
private updateContextMenu() {
|
|
const i18n = getI18n()
|
|
const { tray: trayLocale, selection: selectionLocale } = i18n.translation
|
|
|
|
const quickAssistantEnabled = preferenceService.get('feature.quick_assistant.enabled')
|
|
const selectionAssistantEnabled = preferenceService.get('feature.selection.enabled')
|
|
|
|
const template = [
|
|
{
|
|
label: trayLocale.show_window,
|
|
click: () => windowService.showMainWindow()
|
|
},
|
|
quickAssistantEnabled && {
|
|
label: trayLocale.show_mini_window,
|
|
click: () => windowService.showMiniWindow()
|
|
},
|
|
(isWin || isMac) && {
|
|
label: selectionLocale.name + (selectionAssistantEnabled ? ' - On' : ' - Off'),
|
|
click: () => {
|
|
if (selectionService) {
|
|
selectionService.toggleEnabled()
|
|
this.updateContextMenu()
|
|
}
|
|
}
|
|
},
|
|
{ type: 'separator' },
|
|
{
|
|
label: trayLocale.quit,
|
|
click: () => this.quit()
|
|
}
|
|
].filter(Boolean) as MenuItemConstructorOptions[]
|
|
|
|
this.contextMenu = Menu.buildFromTemplate(template)
|
|
}
|
|
|
|
private updateTray() {
|
|
const showTray = preferenceService.get('app.tray.enabled')
|
|
if (showTray) {
|
|
this.createTray()
|
|
} else {
|
|
this.destroyTray()
|
|
}
|
|
}
|
|
|
|
private destroyTray() {
|
|
if (this.tray) {
|
|
this.tray.destroy()
|
|
this.tray = null
|
|
}
|
|
}
|
|
|
|
private watchConfigChanges() {
|
|
preferenceService.subscribeChange('app.tray.enabled', () => this.updateTray())
|
|
preferenceService.subscribeChange('app.language', () => this.updateContextMenu())
|
|
preferenceService.subscribeChange('feature.quick_assistant.enabled', () => this.updateContextMenu())
|
|
preferenceService.subscribeChange('feature.selection.enabled', () => this.updateContextMenu())
|
|
}
|
|
|
|
private quit() {
|
|
app.quit()
|
|
}
|
|
}
|