Merge pull request #21 from th-ch/add-options-and-tray

Add options and tray
This commit is contained in:
th-ch
2020-04-12 19:32:42 +02:00
committed by GitHub
6 changed files with 207 additions and 58 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -1,13 +1,19 @@
"use strict"; "use strict";
const path = require("path"); const path = require("path");
const electron = require("electron"); const electron = require("electron");
const is = require("electron-is"); const is = require("electron-is");
const { autoUpdater } = require("electron-updater"); const { autoUpdater } = require("electron-updater");
const { setApplicationMenu } = require("./menu"); const { setApplicationMenu } = require("./menu");
const { getEnabledPlugins, store } = require("./store"); const {
const { fileExists, injectCSS } = require("./plugins/utils"); autoUpdate,
getEnabledPlugins,
isAppVisible,
store,
} = require("./store");
const { fileExists, injectCSS } = require("./plugins/utils");
const { setUpTray } = require("./tray");
const app = electron.app; const app = electron.app;
@ -32,23 +38,23 @@ function onClosed() {
} }
function createMainWindow() { function createMainWindow() {
const windowSize = store.get("window-size"); const windowSize = store.get("window-size");
const windowMaximized = store.get("window-maximized"); const windowMaximized = store.get("window-maximized");
const win = new electron.BrowserWindow({ const win = new electron.BrowserWindow({
icon : icon, icon: icon,
width : windowSize.width, width: windowSize.width,
height : windowSize.height, height: windowSize.height,
backgroundColor: "#000", backgroundColor: "#000",
show : false, show: false,
webPreferences : { webPreferences: {
nodeIntegration : false, nodeIntegration: false,
preload : path.join(__dirname, "preload.js"), preload: path.join(__dirname, "preload.js"),
nativeWindowOpen: true, // window.open return Window object(like in regular browsers), not BrowserWindowProxy nativeWindowOpen: true, // window.open return Window object(like in regular browsers), not BrowserWindowProxy
affinity : "main-window" // main window, and addition windows should work in one process affinity: "main-window", // main window, and addition windows should work in one process
}, },
frame : !is.macOS(), frame: !is.macOS(),
titleBarStyle: is.macOS() ? "hiddenInset": "default" titleBarStyle: is.macOS() ? "hiddenInset" : "default",
}); });
if (windowMaximized) { if (windowMaximized) {
win.maximize(); win.maximize();
@ -65,7 +71,7 @@ function createMainWindow() {
} }
}); });
getEnabledPlugins().forEach(plugin => { getEnabledPlugins().forEach((plugin) => {
console.log("Loaded plugin - " + plugin); console.log("Loaded plugin - " + plugin);
const pluginPath = path.join(__dirname, "plugins", plugin, "back.js"); const pluginPath = path.join(__dirname, "plugins", plugin, "back.js");
fileExists(pluginPath, () => { fileExists(pluginPath, () => {
@ -114,7 +120,9 @@ function createMainWindow() {
}); });
win.once("ready-to-show", () => { win.once("ready-to-show", () => {
win.show(); if (isAppVisible()) {
win.show();
}
}); });
return win; return win;
@ -142,16 +150,18 @@ app.on("activate", () => {
app.on("ready", () => { app.on("ready", () => {
setApplicationMenu(); setApplicationMenu();
mainWindow = createMainWindow(); mainWindow = createMainWindow();
if (!is.dev()) { setUpTray(app, mainWindow);
if (!is.dev() && autoUpdate()) {
autoUpdater.checkForUpdatesAndNotify(); autoUpdater.checkForUpdatesAndNotify();
autoUpdater.on("update-available", () => { autoUpdater.on("update-available", () => {
const dialogOpts = { const dialogOpts = {
type : "info", type: "info",
buttons: ["OK"], buttons: ["OK"],
title : "Application Update", title: "Application Update",
message: "A new version is available", message: "A new version is available",
detail : detail:
"A new version is available and can be downloaded at https://github.com/th-ch/youtube-music/releases/latest" "A new version is available and can be downloaded at https://github.com/th-ch/youtube-music/releases/latest",
}; };
electron.dialog.showMessageBox(dialogOpts); electron.dialog.showMessageBox(dialogOpts);
}); });
@ -159,11 +169,15 @@ app.on("ready", () => {
// Optimized for Mac OS X // Optimized for Mac OS X
if (process.platform === "darwin") { if (process.platform === "darwin") {
if (!isAppVisible()) {
app.dock.hide();
}
var forceQuit = false; var forceQuit = false;
app.on("before-quit", () => { app.on("before-quit", () => {
forceQuit = true; forceQuit = true;
}); });
mainWindow.on("close", event => { mainWindow.on("close", (event) => {
if (!forceQuit) { if (!forceQuit) {
event.preventDefault(); event.preventDefault();
mainWindow.hide(); mainWindow.hide();

98
menu.js
View File

@ -1,33 +1,79 @@
const { app, Menu } = require("electron"); const { app, Menu } = require("electron");
const { getAllPlugins } = require("./plugins/utils"); const { getAllPlugins } = require("./plugins/utils");
const { isPluginEnabled, enablePlugin, disablePlugin } = require("./store"); const {
isPluginEnabled,
enablePlugin,
disablePlugin,
autoUpdate,
isAppVisible,
isTrayEnabled,
setOptions,
} = require("./store");
module.exports.setApplicationMenu = () => { const mainMenuTemplate = [
const menuTemplate = [ {
{ label: "Plugins",
label : "Plugins", submenu: getAllPlugins().map((plugin) => {
submenu: getAllPlugins().map(plugin => { return {
return { label: plugin,
label : plugin, type: "checkbox",
type : "checkbox", checked: isPluginEnabled(plugin),
checked: isPluginEnabled(plugin), click: (item) => {
click : item => { if (item.checked) {
if (item.checked) { enablePlugin(plugin);
enablePlugin(plugin); } else {
} else { disablePlugin(plugin);
disablePlugin(plugin);
}
} }
}; },
}) };
} }),
]; },
{
label: "Options",
submenu: [
{
label: "Auto-update",
type: "checkbox",
checked: autoUpdate(),
click: (item) => {
setOptions({ autoUpdates: item.checked });
},
},
{
label: "Tray",
submenu: [
{
label: "Disabled",
type: "radio",
checked: !isTrayEnabled(),
click: () => setOptions({ tray: false, appVisible: true }),
},
{
label: "Enabled + app visible",
type: "radio",
checked: isTrayEnabled() && isAppVisible(),
click: () => setOptions({ tray: true, appVisible: true }),
},
{
label: "Enabled + app hidden",
type: "radio",
checked: isTrayEnabled() && !isAppVisible(),
click: () => setOptions({ tray: true, appVisible: false }),
},
],
},
],
},
];
module.exports.mainMenuTemplate = mainMenuTemplate;
module.exports.setApplicationMenu = () => {
const menuTemplate = [...mainMenuTemplate];
if (process.platform === "darwin") { if (process.platform === "darwin") {
const name = app.getName(); const name = app.getName();
menuTemplate.unshift({ menuTemplate.unshift({
label : name, label: name,
submenu: [ submenu: [
{ role: "about" }, { role: "about" },
{ type: "separator" }, { type: "separator" },
@ -36,9 +82,9 @@ module.exports.setApplicationMenu = () => {
{ role: "unhide" }, { role: "unhide" },
{ type: "separator" }, { type: "separator" },
{ {
label : "Select All", label: "Select All",
accelerator: "CmdOrCtrl+A", accelerator: "CmdOrCtrl+A",
selector : "selectAll:" selector: "selectAll:",
}, },
{ label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" }, { label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" },
{ label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" }, { label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" },
@ -46,8 +92,8 @@ module.exports.setApplicationMenu = () => {
{ type: "separator" }, { type: "separator" },
{ role: "minimize" }, { role: "minimize" },
{ role: "close" }, { role: "close" },
{ role: "quit" } { role: "quit" },
] ],
}); });
} }

View File

@ -4,18 +4,30 @@ const plugins = require("./plugins");
const store = new Store({ const store = new Store({
defaults: { defaults: {
"window-size": { "window-size": {
width : 1100, width: 1100,
height: 550 height: 550
}, },
url : "https://music.youtube.com", url: "https://music.youtube.com",
plugins: ["navigation", "shortcuts", "adblocker"] plugins: ["navigation", "shortcuts", "adblocker"],
options: {
tray: false,
appVisible: true,
autoUpdates: true
}
} }
}); });
module.exports = { module.exports = {
store : store, store: store,
isPluginEnabled : plugin => plugins.isEnabled(store, plugin), // Plugins
isPluginEnabled: plugin => plugins.isEnabled(store, plugin),
getEnabledPlugins: () => plugins.getEnabledPlugins(store), getEnabledPlugins: () => plugins.getEnabledPlugins(store),
enablePlugin : plugin => plugins.enablePlugin(store, plugin), enablePlugin: plugin => plugins.enablePlugin(store, plugin),
disablePlugin : plugin => plugins.disablePlugin(store, plugin) disablePlugin: plugin => plugins.disablePlugin(store, plugin),
// Options
setOptions: options =>
store.set("options", { ...store.get("options"), ...options }),
isTrayEnabled: () => store.get("options.tray"),
isAppVisible: () => store.get("options.appVisible"),
autoUpdate: () => store.get("options.autoUpdates")
}; };

69
tray.js Normal file
View File

@ -0,0 +1,69 @@
const path = require("path");
const { Menu, nativeImage, Tray } = require("electron");
const { mainMenuTemplate } = require("./menu");
const { isTrayEnabled } = require("./store");
const { clickInYoutubeMusic } = require("./utils/youtube-music");
// Prevent tray being garbage collected
let tray;
module.exports.setUpTray = (app, win) => {
if (!isTrayEnabled()) {
tray = undefined;
return;
}
const iconPath = path.join(__dirname, "assets", "youtube-music-tray.png");
let trayIcon = nativeImage.createFromPath(iconPath).resize({
width: 16,
height: 16,
});
tray = new Tray(trayIcon);
tray.setToolTip("Youtube Music");
const trayMenu = Menu.buildFromTemplate([
{
label: "Play/Pause",
click: () => {
clickInYoutubeMusic(
win,
"#left-controls > div > paper-icon-button.play-pause-button.style-scope.ytmusic-player-bar"
);
},
},
{
label: "Next",
click: () => {
clickInYoutubeMusic(
win,
"#left-controls > div > paper-icon-button.next-button.style-scope.ytmusic-player-bar"
);
},
},
{
label: "Previous",
click: () => {
clickInYoutubeMusic(
win,
"#left-controls > div > paper-icon-button.previous-button.style-scope.ytmusic-player-bar"
);
},
},
{
label: "Show",
click: () => {
win.show();
},
},
...mainMenuTemplate,
{
label: "Quit",
click: () => {
app.quit();
},
},
]);
tray.setContextMenu(trayMenu);
};

8
utils/youtube-music.js Normal file
View File

@ -0,0 +1,8 @@
const clickInYoutubeMusic = (win, selector) => {
win.webContents.executeJavaScript(
`document.querySelector("${selector}").click();`,
true
);
};
module.exports = { clickInYoutubeMusic };