mirror of
https://github.com/qier222/YesPlayMusic.git
synced 2024-11-28 11:16:23 +08:00
feat: refactor tray (#1227)
* feat: support set tray icon tooltip info * fix: name * refactor tray impl and add tray playing state change * fix: linux impl * add pause icon * add tray like state * fix * fix: linux impl * better pause icon
This commit is contained in:
parent
3cbb8d9b25
commit
d716bb8cde
BIN
public/img/icons/pause.png
Normal file
BIN
public/img/icons/pause.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 953 B |
BIN
public/img/icons/unlike.png
Normal file
BIN
public/img/icons/unlike.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 932 B |
|
@ -8,6 +8,13 @@ import {
|
||||||
globalShortcut,
|
globalShortcut,
|
||||||
nativeTheme,
|
nativeTheme,
|
||||||
} from 'electron';
|
} from 'electron';
|
||||||
|
import {
|
||||||
|
isWindows,
|
||||||
|
isMac,
|
||||||
|
isLinux,
|
||||||
|
isDevelopment,
|
||||||
|
isCreateTray,
|
||||||
|
} from '@/utils/platform';
|
||||||
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib';
|
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib';
|
||||||
import { startNeteaseMusicApi } from './electron/services';
|
import { startNeteaseMusicApi } from './electron/services';
|
||||||
import { initIpcMain } from './electron/ipcMain.js';
|
import { initIpcMain } from './electron/ipcMain.js';
|
||||||
|
@ -18,6 +25,7 @@ import { createDockMenu } from './electron/dockMenu';
|
||||||
import { registerGlobalShortcut } from './electron/globalShortcut';
|
import { registerGlobalShortcut } from './electron/globalShortcut';
|
||||||
import { autoUpdater } from 'electron-updater';
|
import { autoUpdater } from 'electron-updater';
|
||||||
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer';
|
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer';
|
||||||
|
import { EventEmitter } from 'events';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import expressProxy from 'express-http-proxy';
|
import expressProxy from 'express-http-proxy';
|
||||||
import Store from 'electron-store';
|
import Store from 'electron-store';
|
||||||
|
@ -69,15 +77,10 @@ const closeOnLinux = (e, win, store) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const isWindows = process.platform === 'win32';
|
|
||||||
const isMac = process.platform === 'darwin';
|
|
||||||
const isLinux = process.platform === 'linux';
|
|
||||||
const isDevelopment = process.env.NODE_ENV === 'development';
|
|
||||||
|
|
||||||
class Background {
|
class Background {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.window = null;
|
this.window = null;
|
||||||
this.tray = null;
|
this.ypmTrayImpl = null;
|
||||||
this.store = new Store({
|
this.store = new Store({
|
||||||
windowWidth: {
|
windowWidth: {
|
||||||
width: { type: 'number', default: 1440 },
|
width: { type: 'number', default: 1440 },
|
||||||
|
@ -324,8 +327,14 @@ class Background {
|
||||||
});
|
});
|
||||||
this.handleWindowEvents();
|
this.handleWindowEvents();
|
||||||
|
|
||||||
|
// create tray
|
||||||
|
if (isCreateTray) {
|
||||||
|
this.trayEventEmitter = new EventEmitter();
|
||||||
|
this.ypmTrayImpl = createTray(this.window, this.trayEventEmitter);
|
||||||
|
}
|
||||||
|
|
||||||
// init ipcMain
|
// init ipcMain
|
||||||
initIpcMain(this.window, this.store);
|
initIpcMain(this.window, this.store, this.trayEventEmitter);
|
||||||
|
|
||||||
// set proxy
|
// set proxy
|
||||||
const proxyRules = this.store.get('proxy');
|
const proxyRules = this.store.get('proxy');
|
||||||
|
@ -341,11 +350,6 @@ class Background {
|
||||||
// create menu
|
// create menu
|
||||||
createMenu(this.window, this.store);
|
createMenu(this.window, this.store);
|
||||||
|
|
||||||
// create tray
|
|
||||||
if (isWindows || isLinux || isDevelopment) {
|
|
||||||
this.tray = createTray(this.window);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create dock menu for macOS
|
// create dock menu for macOS
|
||||||
const createdDockMenu = createDockMenu(this.window);
|
const createdDockMenu = createDockMenu(this.window);
|
||||||
if (createDockMenu && app.dock) app.dock.setMenu(createdDockMenu);
|
if (createDockMenu && app.dock) app.dock.setMenu(createdDockMenu);
|
||||||
|
|
|
@ -4,12 +4,73 @@ import { registerGlobalShortcut } from '@/electron/globalShortcut';
|
||||||
import cloneDeep from 'lodash/cloneDeep';
|
import cloneDeep from 'lodash/cloneDeep';
|
||||||
import shortcuts from '@/utils/shortcuts';
|
import shortcuts from '@/utils/shortcuts';
|
||||||
import { createMenu } from './menu';
|
import { createMenu } from './menu';
|
||||||
|
import { isCreateTray, isMac } from '@/utils/platform';
|
||||||
|
|
||||||
const clc = require('cli-color');
|
const clc = require('cli-color');
|
||||||
const log = text => {
|
const log = text => {
|
||||||
console.log(`${clc.blueBright('[ipcMain.js]')} ${text}`);
|
console.log(`${clc.blueBright('[ipcMain.js]')} ${text}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const exitAsk = (e, win) => {
|
||||||
|
e.preventDefault(); //阻止默认行为
|
||||||
|
dialog
|
||||||
|
.showMessageBox({
|
||||||
|
type: 'info',
|
||||||
|
title: 'Information',
|
||||||
|
cancelId: 2,
|
||||||
|
defaultId: 0,
|
||||||
|
message: '确定要关闭吗?',
|
||||||
|
buttons: ['最小化', '直接退出'],
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
if (result.response == 0) {
|
||||||
|
e.preventDefault(); //阻止默认行为
|
||||||
|
win.minimize(); //调用 最小化实例方法
|
||||||
|
} else if (result.response == 1) {
|
||||||
|
win = null;
|
||||||
|
//app.quit();
|
||||||
|
app.exit(); //exit()直接关闭客户端,不会执行quit();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
log(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const exitAskWithoutMac = (e, win) => {
|
||||||
|
e.preventDefault(); //阻止默认行为
|
||||||
|
dialog
|
||||||
|
.showMessageBox({
|
||||||
|
type: 'info',
|
||||||
|
title: 'Information',
|
||||||
|
cancelId: 2,
|
||||||
|
defaultId: 0,
|
||||||
|
message: '确定要关闭吗?',
|
||||||
|
buttons: ['最小化到托盘', '直接退出'],
|
||||||
|
checkboxLabel: '记住我的选择',
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
if (result.checkboxChecked && result.response !== 2) {
|
||||||
|
win.webContents.send(
|
||||||
|
'rememberCloseAppOption',
|
||||||
|
result.response === 0 ? 'minimizeToTray' : 'exit'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.response === 0) {
|
||||||
|
e.preventDefault(); //阻止默认行为
|
||||||
|
win.hide(); //调用 最小化实例方法
|
||||||
|
} else if (result.response === 1) {
|
||||||
|
win = null;
|
||||||
|
//app.quit();
|
||||||
|
app.exit(); //exit()直接关闭客户端,不会执行quit();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
log(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const client = require('discord-rich-presence')('818936529484906596');
|
const client = require('discord-rich-presence')('818936529484906596');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,7 +119,7 @@ function parseSourceStringToList(sourceString) {
|
||||||
return sourceString.split(',').map(s => s.trim());
|
return sourceString.split(',').map(s => s.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initIpcMain(win, store) {
|
export function initIpcMain(win, store, trayEventEmitter) {
|
||||||
ipcMain.handle('unblock-music', async (_, track, source) => {
|
ipcMain.handle('unblock-music', async (_, track, source) => {
|
||||||
// 兼容 unblockneteasemusic 所使用的 api 字段
|
// 兼容 unblockneteasemusic 所使用的 api 字段
|
||||||
track.alias = track.alia || [];
|
track.alias = track.alia || [];
|
||||||
|
@ -102,9 +163,9 @@ export function initIpcMain(win, store) {
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('close', e => {
|
ipcMain.on('close', e => {
|
||||||
if (process.platform === 'darwin') {
|
if (isMac) {
|
||||||
win.hide();
|
win.hide();
|
||||||
exitAsk(e);
|
exitAsk(e, win);
|
||||||
} else {
|
} else {
|
||||||
let closeOpt = store.get('settings.closeAppOption');
|
let closeOpt = store.get('settings.closeAppOption');
|
||||||
if (closeOpt === 'exit') {
|
if (closeOpt === 'exit') {
|
||||||
|
@ -115,7 +176,7 @@ export function initIpcMain(win, store) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
win.hide();
|
win.hide();
|
||||||
} else {
|
} else {
|
||||||
exitAskWithoutMac(e);
|
exitAskWithoutMac(e, win);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -214,63 +275,15 @@ export function initIpcMain(win, store) {
|
||||||
registerGlobalShortcut(win, store);
|
registerGlobalShortcut(win, store);
|
||||||
});
|
});
|
||||||
|
|
||||||
const exitAsk = e => {
|
if (isCreateTray) {
|
||||||
e.preventDefault(); //阻止默认行为
|
ipcMain.on('updateTrayTooltip', (_, title) => {
|
||||||
dialog
|
trayEventEmitter.emit('updateTooltip', title);
|
||||||
.showMessageBox({
|
|
||||||
type: 'info',
|
|
||||||
title: 'Information',
|
|
||||||
cancelId: 2,
|
|
||||||
defaultId: 0,
|
|
||||||
message: '确定要关闭吗?',
|
|
||||||
buttons: ['最小化', '直接退出'],
|
|
||||||
})
|
|
||||||
.then(result => {
|
|
||||||
if (result.response == 0) {
|
|
||||||
e.preventDefault(); //阻止默认行为
|
|
||||||
win.minimize(); //调用 最小化实例方法
|
|
||||||
} else if (result.response == 1) {
|
|
||||||
win = null;
|
|
||||||
//app.quit();
|
|
||||||
app.exit(); //exit()直接关闭客户端,不会执行quit();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
log(err);
|
|
||||||
});
|
});
|
||||||
};
|
ipcMain.on('updateTrayPlayState', (_, isPlaying) => {
|
||||||
|
trayEventEmitter.emit('updatePlayState', isPlaying);
|
||||||
const exitAskWithoutMac = e => {
|
|
||||||
e.preventDefault(); //阻止默认行为
|
|
||||||
dialog
|
|
||||||
.showMessageBox({
|
|
||||||
type: 'info',
|
|
||||||
title: 'Information',
|
|
||||||
cancelId: 2,
|
|
||||||
defaultId: 0,
|
|
||||||
message: '确定要关闭吗?',
|
|
||||||
buttons: ['最小化到托盘', '直接退出'],
|
|
||||||
checkboxLabel: '记住我的选择',
|
|
||||||
})
|
|
||||||
.then(result => {
|
|
||||||
if (result.checkboxChecked && result.response !== 2) {
|
|
||||||
win.webContents.send(
|
|
||||||
'rememberCloseAppOption',
|
|
||||||
result.response === 0 ? 'minimizeToTray' : 'exit'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.response === 0) {
|
|
||||||
e.preventDefault(); //阻止默认行为
|
|
||||||
win.hide(); //调用 最小化实例方法
|
|
||||||
} else if (result.response === 1) {
|
|
||||||
win = null;
|
|
||||||
//app.quit();
|
|
||||||
app.exit(); //exit()直接关闭客户端,不会执行quit();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
log(err);
|
|
||||||
});
|
});
|
||||||
};
|
ipcMain.on('updateTrayLikeState', (_, isLiked) => {
|
||||||
|
trayEventEmitter.emit('updateLikeState', isLiked);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,30 @@
|
||||||
/* global __static */
|
/* global __static */
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { app, nativeImage, Tray, Menu } from 'electron';
|
import { app, nativeImage, Tray, Menu } from 'electron';
|
||||||
|
import { isLinux } from '@/utils/platform';
|
||||||
|
|
||||||
export function createTray(win) {
|
function createMenuTemplate(win) {
|
||||||
let icon = nativeImage
|
return [
|
||||||
.createFromPath(path.join(__static, 'img/icons/menu@88.png'))
|
|
||||||
.resize({
|
|
||||||
height: 20,
|
|
||||||
width: 20,
|
|
||||||
});
|
|
||||||
|
|
||||||
let contextMenu = Menu.buildFromTemplate([
|
|
||||||
//setContextMenu破坏了预期的click行为
|
|
||||||
//在linux下,鼠标左右键都会呼出contextMenu
|
|
||||||
//所以此处单独为linux添加一个 显示主面板 选项
|
|
||||||
...(process.platform === 'linux'
|
|
||||||
? [
|
|
||||||
{
|
{
|
||||||
label: '显示主面板',
|
label: '播放',
|
||||||
click: () => {
|
|
||||||
win.show();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'separator',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: []),
|
|
||||||
{
|
|
||||||
label: '播放/暂停',
|
|
||||||
icon: nativeImage.createFromPath(
|
icon: nativeImage.createFromPath(
|
||||||
path.join(__static, 'img/icons/play.png')
|
path.join(__static, 'img/icons/play.png')
|
||||||
),
|
),
|
||||||
click: () => {
|
click: () => {
|
||||||
win.webContents.send('play');
|
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: '上一首',
|
label: '上一首',
|
||||||
|
@ -75,6 +65,19 @@ export function createTray(win) {
|
||||||
click: () => {
|
click: () => {
|
||||||
win.webContents.send('like');
|
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: '退出',
|
label: '退出',
|
||||||
|
@ -86,28 +89,117 @@ export function createTray(win) {
|
||||||
app.exit();
|
app.exit();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// linux下托盘的实现方式比较迷惑
|
||||||
|
// right-click无法在linux下使用
|
||||||
|
// click在默认行为下会弹出一个contextMenu,里面的唯一选项才会调用click事件
|
||||||
|
// setContextMenu应该是目前唯一能在linux下使用托盘菜单api
|
||||||
|
// 但是无法区分鼠标左右键
|
||||||
|
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.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 icon = nativeImage
|
||||||
|
.createFromPath(path.join(__static, 'img/icons/menu@88.png'))
|
||||||
|
.resize({
|
||||||
|
height: 20,
|
||||||
|
width: 20,
|
||||||
|
});
|
||||||
|
|
||||||
let tray = new Tray(icon);
|
let tray = new Tray(icon);
|
||||||
tray.setToolTip('YesPlayMusic');
|
tray.setToolTip('YesPlayMusic');
|
||||||
|
|
||||||
if (process.platform === 'linux') {
|
return isLinux
|
||||||
//linux下托盘的实现方式比较迷惑
|
? new YPMTrayLinuxImpl(tray, win, eventEmitter)
|
||||||
//right-click无法在linux下使用
|
: new YPMTrayWindowsImpl(tray, win, eventEmitter);
|
||||||
//click在默认行为下会弹出一个contextMenu,里面的唯一选项才会调用click事件
|
|
||||||
//setContextMenu应该是目前唯一能在linux下使用托盘菜单api
|
|
||||||
//但是无法区分鼠标左右键
|
|
||||||
|
|
||||||
tray.setContextMenu(contextMenu);
|
|
||||||
} else {
|
|
||||||
//windows and macos
|
|
||||||
tray.on('click', () => {
|
|
||||||
win.show();
|
|
||||||
});
|
|
||||||
|
|
||||||
tray.on('right-click', () => {
|
|
||||||
tray.popUpContextMenu(contextMenu);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return tray;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { personalFM, fmTrash } from '@/api/others';
|
||||||
import store from '@/store';
|
import store from '@/store';
|
||||||
import { isAccountLoggedIn } from '@/utils/auth';
|
import { isAccountLoggedIn } from '@/utils/auth';
|
||||||
import { trackUpdateNowPlaying, trackScrobble } from '@/api/lastfm';
|
import { trackUpdateNowPlaying, trackScrobble } from '@/api/lastfm';
|
||||||
|
import { isCreateTray } from '@/utils/platform';
|
||||||
|
|
||||||
const electron =
|
const electron =
|
||||||
process.env.IS_ELECTRON === true ? window.require('electron') : null;
|
process.env.IS_ELECTRON === true ? window.require('electron') : null;
|
||||||
|
@ -20,6 +21,21 @@ const excludeSaveKeys = [
|
||||||
'_personalFMNextLoading',
|
'_personalFMNextLoading',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function setTitle(track) {
|
||||||
|
document.title = track
|
||||||
|
? `${track.name} · ${track.ar[0].name} - YesPlayMusic`
|
||||||
|
: 'YesPlayMusic';
|
||||||
|
if (isCreateTray) {
|
||||||
|
ipcRenderer.send('updateTrayTooltip', document.title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTrayLikeState(isLiked) {
|
||||||
|
if (isCreateTray) {
|
||||||
|
ipcRenderer.send('updateTrayLikeState', isLiked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default class {
|
export default class {
|
||||||
constructor() {
|
constructor() {
|
||||||
// 播放器状态
|
// 播放器状态
|
||||||
|
@ -194,6 +210,12 @@ export default class {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_setPlaying(isPlaying) {
|
||||||
|
this._playing = isPlaying;
|
||||||
|
if (isCreateTray) {
|
||||||
|
ipcRenderer.send('updateTrayPlayState', this._playing);
|
||||||
|
}
|
||||||
|
}
|
||||||
_setIntervals() {
|
_setIntervals() {
|
||||||
// 同步播放进度
|
// 同步播放进度
|
||||||
// TODO: 如果 _progress 在别的地方被改变了,这个定时器会覆盖之前改变的值,是bug
|
// TODO: 如果 _progress 在别的地方被改变了,这个定时器会覆盖之前改变的值,是bug
|
||||||
|
@ -284,8 +306,9 @@ export default class {
|
||||||
if (autoplay) {
|
if (autoplay) {
|
||||||
this.play();
|
this.play();
|
||||||
if (this._currentTrack.name) {
|
if (this._currentTrack.name) {
|
||||||
document.title = `${this._currentTrack.name} · ${this._currentTrack.ar[0].name} - YesPlayMusic`;
|
setTitle(this._currentTrack);
|
||||||
}
|
}
|
||||||
|
setTrayLikeState(store.state.liked.songs.includes(this.currentTrack.id));
|
||||||
}
|
}
|
||||||
this.setOutputDevice();
|
this.setOutputDevice();
|
||||||
this._howler.once('end', () => {
|
this._howler.once('end', () => {
|
||||||
|
@ -539,7 +562,7 @@ export default class {
|
||||||
const [trackID, index] = this._getNextTrack();
|
const [trackID, index] = this._getNextTrack();
|
||||||
if (trackID === undefined) {
|
if (trackID === undefined) {
|
||||||
this._howler?.stop();
|
this._howler?.stop();
|
||||||
this._playing = false;
|
this._setPlaying(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.current = index;
|
this.current = index;
|
||||||
|
@ -593,16 +616,16 @@ export default class {
|
||||||
|
|
||||||
pause() {
|
pause() {
|
||||||
this._howler?.pause();
|
this._howler?.pause();
|
||||||
this._playing = false;
|
this._setPlaying(false);
|
||||||
document.title = 'YesPlayMusic';
|
setTitle(null);
|
||||||
this._pauseDiscordPresence(this._currentTrack);
|
this._pauseDiscordPresence(this._currentTrack);
|
||||||
}
|
}
|
||||||
play() {
|
play() {
|
||||||
if (this._howler?.playing()) return;
|
if (this._howler?.playing()) return;
|
||||||
this._howler?.play();
|
this._howler?.play();
|
||||||
this._playing = true;
|
this._setPlaying(true);
|
||||||
if (this._currentTrack.name) {
|
if (this._currentTrack.name) {
|
||||||
document.title = `${this._currentTrack.name} · ${this._currentTrack.ar[0].name} - YesPlayMusic`;
|
setTitle(this._currentTrack);
|
||||||
}
|
}
|
||||||
this._playDiscordPresence(this._currentTrack, this.seek());
|
this._playDiscordPresence(this._currentTrack, this.seek());
|
||||||
if (store.state.lastfm.key !== undefined) {
|
if (store.state.lastfm.key !== undefined) {
|
||||||
|
@ -737,10 +760,12 @@ export default class {
|
||||||
|
|
||||||
sendSelfToIpcMain() {
|
sendSelfToIpcMain() {
|
||||||
if (process.env.IS_ELECTRON !== true) return false;
|
if (process.env.IS_ELECTRON !== true) return false;
|
||||||
|
let liked = store.state.liked.songs.includes(this.currentTrack.id);
|
||||||
ipcRenderer.send('player', {
|
ipcRenderer.send('player', {
|
||||||
playing: this.playing,
|
playing: this.playing,
|
||||||
likedCurrentTrack: store.state.liked.songs.includes(this.currentTrack.id),
|
likedCurrentTrack: liked,
|
||||||
});
|
});
|
||||||
|
setTrayLikeState(liked);
|
||||||
}
|
}
|
||||||
|
|
||||||
switchRepeatMode() {
|
switchRepeatMode() {
|
||||||
|
|
6
src/utils/platform.js
Normal file
6
src/utils/platform.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export const isWindows = process.platform === 'win32';
|
||||||
|
export const isMac = process.platform === 'darwin';
|
||||||
|
export const isLinux = process.platform === 'linux';
|
||||||
|
export const isDevelopment = process.env.NODE_ENV === 'development';
|
||||||
|
|
||||||
|
export const isCreateTray = isWindows || isLinux || isDevelopment;
|
Loading…
Reference in New Issue
Block a user