YesPlayMusic/src/electron/tray.js

216 lines
5.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* global __static */
import path from 'path';
import { app, nativeImage, Tray, Menu, nativeTheme } from 'electron';
import { isLinux } from '@/utils/platform';
function createMenuTemplate(win) {
return [
{
label: '播放',
icon: nativeImage.createFromPath(
path.join(__static, 'img/icons/play.png')
),
click: () => {
win.webContents.send('play');
},
id: 'play',
},
{
label: '暂停',
icon: nativeImage.createFromPath(
path.join(__static, 'img/icons/pause.png')
),
click: () => {
win.webContents.send('play');
},
id: 'pause',
visible: false,
},
{
label: '上一首',
icon: nativeImage.createFromPath(
path.join(__static, 'img/icons/left.png')
),
accelerator: 'CmdOrCtrl+Left',
click: () => {
win.webContents.send('previous');
},
},
{
label: '下一首',
icon: nativeImage.createFromPath(
path.join(__static, 'img/icons/right.png')
),
accelerator: 'CmdOrCtrl+Right',
click: () => {
win.webContents.send('next');
},
},
{
label: '循环播放',
icon: nativeImage.createFromPath(
path.join(__static, 'img/icons/repeat.png')
),
accelerator: 'Alt+R',
click: () => {
win.webContents.send('repeat');
},
},
{
label: '加入喜欢',
icon: nativeImage.createFromPath(
path.join(__static, 'img/icons/like.png')
),
accelerator: 'CmdOrCtrl+L',
click: () => {
win.webContents.send('like');
},
id: 'like',
},
{
label: '取消喜欢',
icon: nativeImage.createFromPath(
path.join(__static, 'img/icons/unlike.png')
),
accelerator: 'CmdOrCtrl+L',
click: () => {
win.webContents.send('like');
},
id: 'unlike',
visible: false,
},
{
label: '退出',
icon: nativeImage.createFromPath(
path.join(__static, 'img/icons/exit.png')
),
accelerator: 'CmdOrCtrl+W',
click: () => {
app.exit();
},
},
];
}
// linux下托盘的实现方式比较迷惑
// right-click无法在linux下使用
// click在默认行为下会弹出一个contextMenu里面的唯一选项才会调用click事件
// setContextMenu应该是目前唯一能在linux下使用托盘菜单api
// 但是无法区分鼠标左右键
// 发现openSUSE KDE环境可以区分鼠标左右键
// 添加左键支持
// 2022.05.17
class YPMTrayLinuxImpl {
constructor(tray, win, emitter) {
this.tray = tray;
this.win = win;
this.emitter = emitter;
this.template = undefined;
this.initTemplate();
this.contextMenu = Menu.buildFromTemplate(this.template);
this.tray.setContextMenu(this.contextMenu);
this.handleEvents();
}
initTemplate() {
//在linux下鼠标左右键都会呼出contextMenu
//所以此处单独为linux添加一个 显示主面板 选项
this.template = [
{
label: '显示主面板',
click: () => {
this.win.show();
},
},
{
type: 'separator',
},
].concat(createMenuTemplate(this.win));
}
handleEvents() {
this.tray.on('click', () => {
this.win.show();
});
this.emitter.on('updateTooltip', title => this.tray.setToolTip(title));
this.emitter.on('updatePlayState', isPlaying => {
this.contextMenu.getMenuItemById('play').visible = !isPlaying;
this.contextMenu.getMenuItemById('pause').visible = isPlaying;
this.tray.setContextMenu(this.contextMenu);
});
this.emitter.on('updateLikeState', isLiked => {
this.contextMenu.getMenuItemById('like').visible = !isLiked;
this.contextMenu.getMenuItemById('unlike').visible = isLiked;
this.tray.setContextMenu(this.contextMenu);
});
}
}
class YPMTrayWindowsImpl {
constructor(tray, win, emitter) {
this.tray = tray;
this.win = win;
this.emitter = emitter;
this.template = createMenuTemplate(win);
this.contextMenu = Menu.buildFromTemplate(this.template);
this.isPlaying = false;
this.curDisplayPlaying = false;
this.isLiked = false;
this.curDisplayLiked = false;
this.handleEvents();
}
handleEvents() {
this.tray.on('click', () => {
this.win.show();
});
this.tray.on('right-click', () => {
if (this.isPlaying !== this.curDisplayPlaying) {
this.curDisplayPlaying = this.isPlaying;
this.contextMenu.getMenuItemById('play').visible = !this.isPlaying;
this.contextMenu.getMenuItemById('pause').visible = this.isPlaying;
}
if (this.isLiked !== this.curDisplayLiked) {
this.curDisplayLiked = this.isLiked;
this.contextMenu.getMenuItemById('like').visible = !this.isLiked;
this.contextMenu.getMenuItemById('unlike').visible = this.isLiked;
}
this.tray.popUpContextMenu(this.contextMenu);
});
this.emitter.on('updateTooltip', title => this.tray.setToolTip(title));
this.emitter.on(
'updatePlayState',
isPlaying => (this.isPlaying = isPlaying)
);
this.emitter.on('updateLikeState', isLiked => (this.isLiked = isLiked));
}
}
export function createTray(win, eventEmitter) {
// 感觉图标颜色应该不属于界面主题范畴,只需要跟随系统主题
let iconTheme = nativeTheme.shouldUseDarkColors ? 'light' : 'dark';
let icon = nativeImage
.createFromPath(path.join(__static, `img/icons/menu-${iconTheme}@88.png`))
.resize({
height: 20,
width: 20,
});
let tray = new Tray(icon);
tray.setToolTip('YesPlayMusic');
return isLinux
? new YPMTrayLinuxImpl(tray, win, eventEmitter)
: new YPMTrayWindowsImpl(tray, win, eventEmitter);
}