From 4c46bceb7d09738f6f6d4c72bbac966a35f0c0b2 Mon Sep 17 00:00:00 2001 From: TC Date: Sun, 12 Apr 2020 19:00:05 +0200 Subject: [PATCH 1/8] Formatting --- index.js | 44 ++++++++++++++++++++++---------------------- menu.js | 12 ++++++------ store/index.js | 14 +++++++------- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/index.js b/index.js index fe18f419..489e27a4 100644 --- a/index.js +++ b/index.js @@ -1,13 +1,13 @@ "use strict"; const path = require("path"); -const electron = require("electron"); -const is = require("electron-is"); +const electron = require("electron"); +const is = require("electron-is"); const { autoUpdater } = require("electron-updater"); -const { setApplicationMenu } = require("./menu"); const { getEnabledPlugins, store } = require("./store"); -const { fileExists, injectCSS } = require("./plugins/utils"); +const { setApplicationMenu } = require("./menu"); +const { fileExists, injectCSS } = require("./plugins/utils"); const app = electron.app; @@ -32,23 +32,23 @@ function onClosed() { } function createMainWindow() { - const windowSize = store.get("window-size"); + const windowSize = store.get("window-size"); const windowMaximized = store.get("window-maximized"); const win = new electron.BrowserWindow({ - icon : icon, - width : windowSize.width, - height : windowSize.height, + icon: icon, + width: windowSize.width, + height: windowSize.height, backgroundColor: "#000", - show : false, - webPreferences : { - nodeIntegration : false, - preload : path.join(__dirname, "preload.js"), - 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 + show: false, + webPreferences: { + nodeIntegration: false, + preload: path.join(__dirname, "preload.js"), + 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 }, - frame : !is.macOS(), - titleBarStyle: is.macOS() ? "hiddenInset": "default" + frame: !is.macOS(), + titleBarStyle: is.macOS() ? "hiddenInset" : "default", }); if (windowMaximized) { win.maximize(); @@ -65,7 +65,7 @@ function createMainWindow() { } }); - getEnabledPlugins().forEach(plugin => { + getEnabledPlugins().forEach((plugin) => { console.log("Loaded plugin - " + plugin); const pluginPath = path.join(__dirname, "plugins", plugin, "back.js"); fileExists(pluginPath, () => { @@ -146,12 +146,12 @@ app.on("ready", () => { autoUpdater.checkForUpdatesAndNotify(); autoUpdater.on("update-available", () => { const dialogOpts = { - type : "info", + type: "info", buttons: ["OK"], - title : "Application Update", + title: "Application Update", message: "A new version is available", - detail : - "A new version is available and can be downloaded at https://github.com/th-ch/youtube-music/releases/latest" + detail: + "A new version is available and can be downloaded at https://github.com/th-ch/youtube-music/releases/latest", }; electron.dialog.showMessageBox(dialogOpts); }); @@ -163,7 +163,7 @@ app.on("ready", () => { app.on("before-quit", () => { forceQuit = true; }); - mainWindow.on("close", event => { + mainWindow.on("close", (event) => { if (!forceQuit) { event.preventDefault(); mainWindow.hide(); diff --git a/menu.js b/menu.js index 6a864d33..56bd1623 100644 --- a/menu.js +++ b/menu.js @@ -1,7 +1,7 @@ const { app, Menu } = require("electron"); -const { getAllPlugins } = require("./plugins/utils"); const { isPluginEnabled, enablePlugin, disablePlugin } = require("./store"); +const { getAllPlugins } = require("./plugins/utils"); module.exports.setApplicationMenu = () => { const menuTemplate = [ @@ -27,7 +27,7 @@ module.exports.setApplicationMenu = () => { if (process.platform === "darwin") { const name = app.getName(); menuTemplate.unshift({ - label : name, + label: name, submenu: [ { role: "about" }, { type: "separator" }, @@ -36,9 +36,9 @@ module.exports.setApplicationMenu = () => { { role: "unhide" }, { type: "separator" }, { - label : "Select All", + label: "Select All", accelerator: "CmdOrCtrl+A", - selector : "selectAll:" + selector: "selectAll:", }, { label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" }, { label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" }, @@ -46,8 +46,8 @@ module.exports.setApplicationMenu = () => { { type: "separator" }, { role: "minimize" }, { role: "close" }, - { role: "quit" } - ] + { role: "quit" }, + ], }); } diff --git a/store/index.js b/store/index.js index 8d34c783..82cefaab 100644 --- a/store/index.js +++ b/store/index.js @@ -4,18 +4,18 @@ const plugins = require("./plugins"); const store = new Store({ defaults: { "window-size": { - width : 1100, + width: 1100, height: 550 }, - url : "https://music.youtube.com", - plugins: ["navigation", "shortcuts", "adblocker"] + url: "https://music.youtube.com", + plugins: ["navigation", "shortcuts", "adblocker"], } }); module.exports = { - store : store, - isPluginEnabled : plugin => plugins.isEnabled(store, plugin), + store: store, + isPluginEnabled: plugin => plugins.isEnabled(store, plugin), getEnabledPlugins: () => plugins.getEnabledPlugins(store), - enablePlugin : plugin => plugins.enablePlugin(store, plugin), - disablePlugin : plugin => plugins.disablePlugin(store, plugin) + enablePlugin: plugin => plugins.enablePlugin(store, plugin), + disablePlugin: plugin => plugins.disablePlugin(store, plugin), }; From 1c56e7fea641c069e75a80ba1255c58cac5b3764 Mon Sep 17 00:00:00 2001 From: TC Date: Sun, 12 Apr 2020 18:52:07 +0200 Subject: [PATCH 2/8] Add options in store (tray, app visible, auto-update) --- store/index.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/store/index.js b/store/index.js index 82cefaab..4ae9af01 100644 --- a/store/index.js +++ b/store/index.js @@ -9,13 +9,25 @@ const store = new Store({ }, url: "https://music.youtube.com", plugins: ["navigation", "shortcuts", "adblocker"], + options: { + tray: false, + appVisible: true, + autoUpdates: true + } } }); module.exports = { store: store, + // Plugins isPluginEnabled: plugin => plugins.isEnabled(store, plugin), getEnabledPlugins: () => plugins.getEnabledPlugins(store), enablePlugin: plugin => plugins.enablePlugin(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") }; From 1de6f3e2edf2fa4fe21e39814ce8a761e4bb7419 Mon Sep 17 00:00:00 2001 From: TC Date: Sun, 12 Apr 2020 18:52:43 +0200 Subject: [PATCH 3/8] Add options to menu, export menu config --- menu.js | 86 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/menu.js b/menu.js index 56bd1623..2c72da2e 100644 --- a/menu.js +++ b/menu.js @@ -1,29 +1,75 @@ const { app, Menu } = require("electron"); -const { isPluginEnabled, enablePlugin, disablePlugin } = require("./store"); const { getAllPlugins } = require("./plugins/utils"); +const { + isPluginEnabled, + enablePlugin, + disablePlugin, + autoUpdate, + isAppVisible, + isTrayEnabled, + setOptions, +} = require("./store"); -module.exports.setApplicationMenu = () => { - const menuTemplate = [ - { - label : "Plugins", - submenu: getAllPlugins().map(plugin => { - return { - label : plugin, - type : "checkbox", - checked: isPluginEnabled(plugin), - click : item => { - if (item.checked) { - enablePlugin(plugin); - } else { - disablePlugin(plugin); - } +const mainMenuTemplate = [ + { + label: "Plugins", + submenu: getAllPlugins().map((plugin) => { + return { + label: plugin, + type: "checkbox", + checked: isPluginEnabled(plugin), + click: (item) => { + if (item.checked) { + enablePlugin(plugin); + } else { + 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") { const name = app.getName(); menuTemplate.unshift({ From baa4f1727699bc626ffd07cd8d248e3c050eaa79 Mon Sep 17 00:00:00 2001 From: TC Date: Sun, 12 Apr 2020 18:53:38 +0200 Subject: [PATCH 4/8] Add tray icon in assets --- assets/youtube-music-tray.png | Bin 0 -> 3370 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/youtube-music-tray.png diff --git a/assets/youtube-music-tray.png b/assets/youtube-music-tray.png new file mode 100644 index 0000000000000000000000000000000000000000..5e947ca1f823705d0581a5c6c727114314603076 GIT binary patch literal 3370 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 Date: Sun, 12 Apr 2020 18:57:40 +0200 Subject: [PATCH 5/8] Add youtube-music util to interact with the window --- utils/youtube-music.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 utils/youtube-music.js diff --git a/utils/youtube-music.js b/utils/youtube-music.js new file mode 100644 index 00000000..3a7e848a --- /dev/null +++ b/utils/youtube-music.js @@ -0,0 +1,8 @@ +const clickInYoutubeMusic = (win, selector) => { + win.webContents.executeJavaScript( + `document.querySelector("${selector}").click();`, + true + ); +}; + +module.exports = { clickInYoutubeMusic }; From 876e52bb01771104315c36c7347e0fe26468c74f Mon Sep 17 00:00:00 2001 From: TC Date: Sun, 12 Apr 2020 18:58:22 +0200 Subject: [PATCH 6/8] Tray lib --- tray.js | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 tray.js diff --git a/tray.js b/tray.js new file mode 100644 index 00000000..d36c0911 --- /dev/null +++ b/tray.js @@ -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); +}; From 477202bf24d3a4ff99eaded19d5c9cc43869289b Mon Sep 17 00:00:00 2001 From: TC Date: Sun, 12 Apr 2020 18:59:14 +0200 Subject: [PATCH 7/8] Setup tray (based on options) --- index.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 489e27a4..6728f687 100644 --- a/index.js +++ b/index.js @@ -5,9 +5,14 @@ const electron = require("electron"); const is = require("electron-is"); const { autoUpdater } = require("electron-updater"); -const { getEnabledPlugins, store } = require("./store"); const { setApplicationMenu } = require("./menu"); +const { + getEnabledPlugins, + isAppVisible, + store, +} = require("./store"); const { fileExists, injectCSS } = require("./plugins/utils"); +const { setUpTray } = require("./tray"); const app = electron.app; @@ -114,7 +119,9 @@ function createMainWindow() { }); win.once("ready-to-show", () => { - win.show(); + if (isAppVisible()) { + win.show(); + } }); return win; @@ -143,6 +150,7 @@ app.on("ready", () => { setApplicationMenu(); mainWindow = createMainWindow(); if (!is.dev()) { + setUpTray(app, mainWindow); autoUpdater.checkForUpdatesAndNotify(); autoUpdater.on("update-available", () => { const dialogOpts = { @@ -159,6 +167,10 @@ app.on("ready", () => { // Optimized for Mac OS X if (process.platform === "darwin") { + if (!isAppVisible()) { + app.dock.hide(); + } + var forceQuit = false; app.on("before-quit", () => { forceQuit = true; From e051c4a9a225474ea1da2a0250969b84ffcb6f7a Mon Sep 17 00:00:00 2001 From: TC Date: Sun, 12 Apr 2020 18:59:41 +0200 Subject: [PATCH 8/8] Only checked for updates if configured in options --- index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 6728f687..f7dddafb 100644 --- a/index.js +++ b/index.js @@ -7,6 +7,7 @@ const { autoUpdater } = require("electron-updater"); const { setApplicationMenu } = require("./menu"); const { + autoUpdate, getEnabledPlugins, isAppVisible, store, @@ -149,8 +150,9 @@ app.on("activate", () => { app.on("ready", () => { setApplicationMenu(); mainWindow = createMainWindow(); - if (!is.dev()) { setUpTray(app, mainWindow); + + if (!is.dev() && autoUpdate()) { autoUpdater.checkForUpdatesAndNotify(); autoUpdater.on("update-available", () => { const dialogOpts = {