feat: implement tray functionality with status updates and localization support
This commit is contained in:
@@ -1,100 +0,0 @@
|
||||
import { Tray, Menu, ipcMain, app } from 'electron'
|
||||
import { createTranslator, createLogo } from '@electron/utils'
|
||||
import { CONFIG_KEYS, IPC_EVENTS, WINDOW_NAMES, MAIN_WIN_SIZE } from '@runtime/lib/constants'
|
||||
|
||||
import logManager from '@electron/service/logger'
|
||||
// TODO: shortcutManager
|
||||
import windowManager from '@electron/service/window-service'
|
||||
import configManager from '@electron/service/config-service'
|
||||
|
||||
let t: ReturnType<typeof createTranslator> = createTranslator();
|
||||
|
||||
class TrayService {
|
||||
private static _instance: TrayService;
|
||||
private _tray: Tray | null = null;
|
||||
private _removeLanguageListener?: () => void;
|
||||
|
||||
private _setupLanguageChangeListener() {
|
||||
this._removeLanguageListener = configManager.onConfigChange((config) => {
|
||||
if (!config[CONFIG_KEYS.LANGUAGE]) return;
|
||||
|
||||
// 切换语言后,重新创建翻译器
|
||||
t = createTranslator();
|
||||
|
||||
|
||||
if (this._tray) {
|
||||
this._updateTray();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private _updateTray() {
|
||||
if (!this._tray) {
|
||||
this._tray = new Tray(createLogo());
|
||||
}
|
||||
|
||||
const showWindow = () => {
|
||||
const mainWindow = windowManager.get(WINDOW_NAMES.MAIN);
|
||||
|
||||
if (mainWindow && !mainWindow?.isDestroyed() && mainWindow?.isVisible() && !mainWindow?.isFocused()) {
|
||||
return mainWindow.focus();
|
||||
}
|
||||
|
||||
if (mainWindow?.isMinimized()) {
|
||||
return mainWindow?.restore();
|
||||
}
|
||||
|
||||
if (mainWindow?.isVisible() && mainWindow?.isFocused()) return;
|
||||
|
||||
windowManager.create(WINDOW_NAMES.MAIN, MAIN_WIN_SIZE);
|
||||
}
|
||||
|
||||
this._tray.setToolTip(t('tray.tooltip') ?? 'Diona Application');
|
||||
|
||||
// TODO: 依赖快捷键Service
|
||||
this._tray.setContextMenu(Menu.buildFromTemplate([
|
||||
{ label: t('tray.showWindow'), accelerator: 'CmdOrCtrl+N', click: showWindow },
|
||||
{ type: 'separator' },
|
||||
{ label: t('settings.title'), click: () => ipcMain.emit(`${IPC_EVENTS.OPEN_WINDOW}:${WINDOW_NAMES.SETTING}`) },
|
||||
{ role: 'quit', label: t('tray.exit') }
|
||||
]));
|
||||
|
||||
this._tray.removeAllListeners('click');
|
||||
this._tray.on('click', showWindow);
|
||||
}
|
||||
|
||||
private constructor() {
|
||||
this._setupLanguageChangeListener();
|
||||
logManager.info('TrayService initialized successfully.');
|
||||
}
|
||||
|
||||
public static getInstance() {
|
||||
if (!this._instance) {
|
||||
this._instance = new TrayService();
|
||||
}
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
public create() {
|
||||
if (this._tray) return;
|
||||
this._updateTray();
|
||||
app.on('quit', () => {
|
||||
this.destroy();
|
||||
//TODO: 移除快捷键
|
||||
})
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this._tray?.destroy();
|
||||
this._tray = null;
|
||||
//TODO: 移除快捷键
|
||||
if (this._removeLanguageListener) {
|
||||
this._removeLanguageListener();
|
||||
this._removeLanguageListener = void 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const trayManager = TrayService.getInstance();
|
||||
export default trayManager;
|
||||
|
||||
@@ -47,18 +47,7 @@ export class AppUpdater {
|
||||
}
|
||||
|
||||
private registerHandlers() {
|
||||
ipcMain.handle(IPC_EVENTS.UPDATE_CHECK, () => {
|
||||
if (app.isPackaged) {
|
||||
return autoUpdater.checkForUpdates();
|
||||
} else {
|
||||
// 在开发环境下模拟
|
||||
this.sendToRenderer(IPC_EVENTS.UPDATE_STATUS_CHANGED, { status: 'checking' });
|
||||
setTimeout(() => {
|
||||
this.sendToRenderer(IPC_EVENTS.UPDATE_STATUS_CHANGED, { status: 'not-available' });
|
||||
}, 1500);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
ipcMain.handle(IPC_EVENTS.UPDATE_CHECK, () => this.checkForUpdates());
|
||||
|
||||
ipcMain.handle(IPC_EVENTS.UPDATE_DOWNLOAD, () => {
|
||||
if (app.isPackaged) {
|
||||
@@ -78,6 +67,18 @@ export class AppUpdater {
|
||||
return app.getVersion();
|
||||
});
|
||||
}
|
||||
|
||||
public checkForUpdates() {
|
||||
if (app.isPackaged) {
|
||||
return autoUpdater.checkForUpdates();
|
||||
}
|
||||
|
||||
this.sendToRenderer(IPC_EVENTS.UPDATE_STATUS_CHANGED, { status: 'checking' });
|
||||
setTimeout(() => {
|
||||
this.sendToRenderer(IPC_EVENTS.UPDATE_STATUS_CHANGED, { status: 'not-available' });
|
||||
}, 1500);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export const appUpdater = AppUpdater.getInstance();
|
||||
|
||||
Reference in New Issue
Block a user