123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- // tray = 系统托盘
- import path from 'path';
- import {Tray, Menu, app, dialog, nativeImage, BrowserWindow, Notification} from 'electron';
- import {_PATHS} from '../paths';
- import {$env, isDev} from '../env';
- const TrayIcons = {
- normal: nativeImage.createFromPath(path.join(_PATHS.publicRoot, 'logo.png')),
- empty: nativeImage.createEmpty(),
- };
- // 创建托盘图标
- export function createTray(win: BrowserWindow) {
- const tray = new Tray(TrayIcons.normal);
- const TrayUtils = useTray(tray, win);
- tray.setToolTip($env.VITE_GLOB_APP_TITLE! + (isDev ? ' (开发环境)' : ''));
- // 左键托盘图标显示主窗口
- tray.on('click', () => TrayUtils.showMainWindow());
- // 右键托盘图标显示托盘菜单
- tray.on('right-click', () => showTrayContextMenu());
- function showTrayContextMenu() {
- const trayContextMenu = getTrayMenus(win, TrayUtils);
- // 弹出托盘菜单,不使用 setContextMenu 方法是因为要实时更新菜单内容
- tray.popUpContextMenu(trayContextMenu);
- }
- }
- export function useTray(tray: Tray, win: BrowserWindow) {
- let isBlinking = false;
- let blinkTimer: NodeJS.Timeout | null = null;
- function showMainWindow() {
- win.show();
- }
- // 开始闪动
- function startBlink() {
- isBlinking = true;
- tray.setImage(TrayIcons.empty);
- blinkTimer = setTimeout(() => {
- tray.setImage(TrayIcons.normal);
- setTimeout(() => {
- if (isBlinking) {
- startBlink();
- }
- }, 500);
- }, 500);
- }
- // 结束闪动
- function stopBlink() {
- isBlinking = false;
- if (blinkTimer) {
- clearTimeout(blinkTimer);
- blinkTimer = null;
- }
- tray.setImage(TrayIcons.normal);
- }
- // 发送桌面通知
- function sendDesktopNotice() {
- // 判断是否支持桌面通知
- if (!Notification.isSupported()) {
- // todo 实际开发中不需要提示,直接返回或者换一种提示方式
- dialog.showMessageBoxSync(win, {
- type: 'error',
- title: '错误',
- message: '当前系统不支持桌面通知',
- });
- return;
- }
- const ins = new Notification({
- title: '通知标题',
- subtitle: '通知副标题',
- body: '通知内容第一行\n通知内容第二行',
- icon: TrayIcons.normal.resize({width: 32, height: 32}),
- });
- ins.on('click', () => {
- dialog.showMessageBoxSync(win, {
- type: 'info',
- title: '提示',
- message: '通知被点击',
- });
- });
- ins.show();
- }
- return {
- showMainWindow,
- startBlink,
- stopBlink,
- isBlinking: () => isBlinking,
- sendDesktopNotice,
- };
- }
- const MenuIcon = {
- exit: nativeImage
- .createFromDataURL(
- 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACJ0lEQVR4nH1TzWvUQBRP7fpxsWqVXsSLiAevRWhhN28msRJo981kay4WRBCF/QdEFJpbaUHw4kFBQTwUKX4gKh48KPiBBcGLJ1F0uzPZ7ibWXf0DIjObielS+mDIm/fxm9/85sWyBixN06E0CIaV3wB2XhC8puOWNZSG4Y7B+k2mi7Kl9l2n9rHnzvbWJoLRYn7r5jTViQjwzM8ynlC+AFyVgN2NU8G+Rnn6QETx3FfP223A/jeHfWqCsAUJ7Hlryh9Te0nYqiDsz9rE6VHVIABvNwEf/ADYk4OsZPeVFbwiCHtcZBVR9k4CJhJmDuUxwEVJ8H4fINOkC9Vjbeq/UTR1IgPturX3f93Z35+B7ddxgJL6dih/skF9zE9KCJ//5bDLpii1+npIuzolKTubC5gBxzarJo6vWWjrUP+etFlF+ds9lRFOXalN+NPEmxvRDS3KH34v8+PFIgNmTh0EahH+InGCwzoQEbYcuTMnlR8aYbaxGHFvRNiznssP6sA65UsxrdU1+hYnFhlpAGAkdvzlPLFu88mY8pcrVjCsxcqGapC2eYW249/tUH4xS4QaVQLeigi/YWJqPl4DlNRSrAwzSaoXIspeWUYrI9qXINglgT1qAt5JPG+kkNN5BSAJuyoJfhAVdmST4PlPBFASNs6rIgnspqC8HlF+SQAuRQTfKpYiEy6fwuIdP42P71T+t0l/TBKcE8AXm4DXBfB6w50+apgUhf4HZ5j+Z5+zNTAAAAAASUVORK5CYII='
- )
- .resize({
- width: 16,
- height: 16,
- }),
- };
- // 设置托盘菜单
- function getTrayMenus(win: BrowserWindow, TrayUtils: ReturnType<typeof useTray>) {
- const {startBlink, stopBlink, sendDesktopNotice} = TrayUtils;
- const isBlinking = TrayUtils.isBlinking();
- return Menu.buildFromTemplate([
- ...(isDev
- ? [
- {
- label: '开发工具',
- submenu: [
- {
- label: '以下菜单仅显示在开发环境',
- sublabel: '当前为开发环境',
- enabled: false,
- },
- {type: 'separator'},
- {
- label: '切换 DevTools',
- click: () => win.webContents.toggleDevTools(),
- },
- {
- label: `托盘图标${isBlinking ? '停止' : '开始'}闪烁`,
- sublabel: '模拟新消息提醒',
- click: () => (isBlinking ? stopBlink() : startBlink()),
- },
- {
- label: '发送桌面通知示例',
- click: () => sendDesktopNotice(),
- },
- ],
- },
- {type: 'separator'},
- ]
- : ([] as any)),
- {
- label: '显示主窗口',
- // 文件图标
- icon: TrayIcons.normal.resize({width: 16, height: 16}),
- click: () => win.show(),
- },
- {type: 'separator'},
- {
- label: '退出',
- // base64图标
- icon: MenuIcon.exit,
- click: () => {
- // 弹出是否确认退出提示框
- const choice = dialog.showMessageBoxSync(win, {
- type: 'question',
- title: '提示',
- message: '确定要退出应用吗?',
- buttons: ['退出', '取消'],
- defaultId: 1,
- cancelId: 1,
- noLink: true,
- });
- // 用户选择了退出,直接 exit
- if (choice === 0) {
- // global.isQuitting = true;
- app.exit(0);
- }
- },
- },
- ]);
- }
|