From e4eed2e51979378e62dab902e425218cae5108dc Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 28 Apr 2021 02:41:44 +0300 Subject: [PATCH 01/67] add custom-electron-prompt also use it to set proxy option --- index.js | 6 +- menu.js | 193 +++++++++++------- package.json | 1 + plugins/in-app-menu/prompt-custom-titlebar.js | 14 ++ yarn.lock | 16 ++ 5 files changed, 154 insertions(+), 76 deletions(-) create mode 100644 plugins/in-app-menu/prompt-custom-titlebar.js diff --git a/index.js b/index.js index 82bb3320..a21f45f4 100644 --- a/index.js +++ b/index.js @@ -37,7 +37,9 @@ if (config.get("options.proxy")) { } // Adds debug features like hotkeys for triggering dev tools and reload -require("electron-debug")(); +require("electron-debug")({ + showDevTools: false, //disable automatic devTools on new window +}); // Prevent window being garbage collected let mainWindow; @@ -58,7 +60,7 @@ function onClosed() { function loadPlugins(win) { injectCSS(win.webContents, path.join(__dirname, "youtube-music.css")); - win.webContents.on("did-finish-load", () => { + win.webContents.once("did-finish-load", () => { if (is.dev()) { console.log("did finish load"); win.webContents.openDevTools(); diff --git a/menu.js b/menu.js index f974c4e4..438fe4cb 100644 --- a/menu.js +++ b/menu.js @@ -6,6 +6,7 @@ const is = require("electron-is"); const { getAllPlugins } = require("./plugins/utils"); const config = require("./config"); +const prompt = require("custom-electron-prompt"); const pluginEnabledMenu = (win, plugin, label = "", hasSubmenu = false) => ({ label: label || plugin, @@ -103,30 +104,38 @@ const mainMenuTemplate = (win, withRoles = true, isTray = false) => [ }, ...(is.windows() || is.linux() ? [ - { - label: "Hide menu", - type: "checkbox", - checked: config.get("options.hideMenu"), - click: (item) => { - config.set("options.hideMenu", item.checked); - }, + { + label: "Hide menu", + type: "checkbox", + checked: config.get("options.hideMenu"), + click: (item) => { + config.set("options.hideMenu", item.checked); }, - ] + }, + ] : []), ...(is.windows() || is.macOS() ? // Only works on Win/Mac - // https://www.electronjs.org/docs/api/app#appsetloginitemsettingssettings-macos-windows - [ - { - label: "Start at login", - type: "checkbox", - checked: config.get("options.startAtLogin"), - click: (item) => { - config.set("options.startAtLogin", item.checked); - }, + // https://www.electronjs.org/docs/api/app#appsetloginitemsettingssettings-macos-windows + [ + { + label: "Start at login", + type: "checkbox", + checked: config.get("options.startAtLogin"), + click: (item) => { + config.set("options.startAtLogin", item.checked); }, - ] + }, + ] : []), + { + label: "Proxy", + type: "checkbox", + checked: !!config.get("options.proxy"), + click: (item) => { + setProxy(item, win); + } + }, { label: "Tray", submenu: [ @@ -194,56 +203,56 @@ const mainMenuTemplate = (win, withRoles = true, isTray = false) => [ }, ...(!isTray ? [ - { - label: "View", - submenu: withRoles - ? [ - { role: "reload" }, - { role: "forceReload" }, - { type: "separator" }, - { role: "zoomIn" }, - { role: "zoomOut" }, - { role: "resetZoom" }, - ] - : [ - { - label: "Reload", - click: () => { - win.webContents.reload(); - }, - }, - { - label: "Force Reload", - click: () => { - win.webContents.reloadIgnoringCache(); - }, - }, - { type: "separator" }, - { - label: "Zoom In", - click: () => { - win.webContents.setZoomLevel( - win.webContents.getZoomLevel() + 1 - ); - }, - }, - { - label: "Zoom Out", - click: () => { - win.webContents.setZoomLevel( - win.webContents.getZoomLevel() - 1 - ); - }, - }, - { - label: "Reset Zoom", - click: () => { - win.webContents.setZoomLevel(0); - }, - }, - ], - }, - ] + { + label: "View", + submenu: withRoles + ? [ + { role: "reload" }, + { role: "forceReload" }, + { type: "separator" }, + { role: "zoomIn" }, + { role: "zoomOut" }, + { role: "resetZoom" }, + ] + : [ + { + label: "Reload", + click: () => { + win.webContents.reload(); + }, + }, + { + label: "Force Reload", + click: () => { + win.webContents.reloadIgnoringCache(); + }, + }, + { type: "separator" }, + { + label: "Zoom In", + click: () => { + win.webContents.setZoomLevel( + win.webContents.getZoomLevel() + 1 + ); + }, + }, + { + label: "Zoom Out", + click: () => { + win.webContents.setZoomLevel( + win.webContents.getZoomLevel() - 1 + ); + }, + }, + { + label: "Reset Zoom", + click: () => { + win.webContents.setZoomLevel(0); + }, + }, + ], + }, + ] : []), { label: "Navigation", @@ -273,13 +282,13 @@ const mainMenuTemplate = (win, withRoles = true, isTray = false) => [ }, ...(!isTray ? [ - { - label: "Quit App", - click: () => { - app.quit(); - }, + { + label: "Quit App", + click: () => { + app.quit(); }, - ] + }, + ] : []), ], }, @@ -318,3 +327,39 @@ module.exports.setApplicationMenu = (win) => { const menu = Menu.buildFromTemplate(menuTemplate); Menu.setApplicationMenu(menu); }; + +const iconPath = path.join(__dirname, "assets", "youtube-music-tray.png"); +const example = `Example: "socks5://127.0.0.1:9999"`; +function setProxy(item, win) { + let options = { + title: 'Set Proxy', + label: 'Enter Proxy Address: (leave empty to disable)', + value: config.get("options.proxy") || example, + inputAttrs: { + type: 'text' + }, + type: 'input', + icon: iconPath, + customStylesheet: "dark", + }; + //TODO: custom bar on prompt need testing on macOS + if (!is.macOS()) { + Object.assign(options, { + frame: false, + customScript: path.join(__dirname, "plugins", "in-app-menu", "prompt-custom-titlebar.js"), + enableRemoteModule: true, + height: 200, + width: 450, + }); + } + prompt(options, win) + .then(input => { + if (input !== null && input !== example) { + config.set("options.proxy", input); + item.checked = input !== ""; + } else { //user pressed cancel + item.checked = !item.checked; //reset checkbox + } + }) + .catch(console.error); +} diff --git a/package.json b/package.json index ce144c38..e498c410 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "YoutubeNonStop": "git://github.com/lawfx/YoutubeNonStop.git#v0.8.1", "async-mutex": "^0.3.1", "browser-id3-writer": "^4.4.0", + "custom-electron-prompt": "^1.0.2", "custom-electron-titlebar": "^3.2.6", "discord-rpc": "^3.2.0", "downloads-folder": "^3.0.1", diff --git a/plugins/in-app-menu/prompt-custom-titlebar.js b/plugins/in-app-menu/prompt-custom-titlebar.js new file mode 100644 index 00000000..c36ce5f5 --- /dev/null +++ b/plugins/in-app-menu/prompt-custom-titlebar.js @@ -0,0 +1,14 @@ +const customTitlebar = require("custom-electron-titlebar"); + +module.exports = () => { + const bar = new customTitlebar.Titlebar({ + backgroundColor: customTitlebar.Color.fromHex("#050505"), + minimizable: false, + maximizable: false, + menu: null + }); + const mainStyle = document.querySelector("#container").style; + mainStyle.width = "100%"; + mainStyle.position = "fixed"; + mainStyle.border = "unset"; +}; diff --git a/yarn.lock b/yarn.lock index c969527e..7371b7cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2636,6 +2636,13 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" +custom-electron-prompt@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-electron-prompt/-/custom-electron-prompt-1.0.1.tgz#6d11c6e5130a444a9425bd27864777b36f1fef11" + integrity sha512-ldEiZ1t3rBDOb0nfvVpxQOjWJvkkUO3B/sD9IIYr2C/VG9COkc6IJNO2E3rXMPdDDIwejXEQx3CTWp2N2d4moQ== + dependencies: + electron "^11.4.4" + custom-electron-titlebar@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/custom-electron-titlebar/-/custom-electron-titlebar-3.2.6.tgz#4cd064efa5020954c09732efa8c667a7ee3636e3" @@ -3140,6 +3147,15 @@ electron@^11.2.3: "@types/node" "^12.0.12" extract-zip "^1.0.3" +electron@^11.4.4: + version "11.4.4" + resolved "https://registry.yarnpkg.com/electron/-/electron-11.4.4.tgz#d6c046dedd9e22df5f6408841c3f8ae1a1d59414" + integrity sha512-m52nF85VADCmL9DpzJfgmkvc9fNiGZPYwptv/4fTYrYhAMiO+hmClGMXncCoSAzoULQjl+f+0b9CY4yd6nRFlQ== + dependencies: + "@electron/get" "^1.0.1" + "@types/node" "^12.0.12" + extract-zip "^1.0.3" + elliptic@^6.5.3: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" From a229ba9c15a8a034726915f7423aefa42ef65b05 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 28 Apr 2021 02:46:13 +0300 Subject: [PATCH 02/67] disable reload of plugins on window created --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index a21f45f4..9cdc0ceb 100644 --- a/index.js +++ b/index.js @@ -38,7 +38,7 @@ if (config.get("options.proxy")) { // Adds debug features like hotkeys for triggering dev tools and reload require("electron-debug")({ - showDevTools: false, //disable automatic devTools on new window + showDevTools: false //disable automatic devTools on new window }); // Prevent window being garbage collected @@ -154,7 +154,7 @@ function createMainWindow() { return win; } -app.on("browser-window-created", (event, win) => { +app.once("browser-window-created", (event, win) => { loadPlugins(win); win.webContents.on("did-fail-load", () => { From 964974c142837429d4003fca38c7a8c4fb237121 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Fri, 30 Apr 2021 03:04:38 +0300 Subject: [PATCH 03/67] add keybind changer v1 --- config/defaults.js | 1 + menu.js | 3 - plugins/shortcuts/back.js | 9 ++- plugins/shortcuts/menu.js | 118 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 plugins/shortcuts/menu.js diff --git a/config/defaults.js b/config/defaults.js index fb87e566..ccd6976a 100644 --- a/config/defaults.js +++ b/config/defaults.js @@ -30,6 +30,7 @@ const defaultConfig = { // Disabled plugins shortcuts: { enabled: false, + overrideMediaKeys: false, }, downloader: { enabled: false, diff --git a/menu.js b/menu.js index 438fe4cb..a178a575 100644 --- a/menu.js +++ b/menu.js @@ -335,9 +335,6 @@ function setProxy(item, win) { title: 'Set Proxy', label: 'Enter Proxy Address: (leave empty to disable)', value: config.get("options.proxy") || example, - inputAttrs: { - type: 'text' - }, type: 'input', icon: iconPath, customStylesheet: "dark", diff --git a/plugins/shortcuts/back.js b/plugins/shortcuts/back.js index 59ebd737..9a1481d8 100644 --- a/plugins/shortcuts/back.js +++ b/plugins/shortcuts/back.js @@ -19,9 +19,12 @@ function registerShortcuts(win, options) { const songControls = getSongControls(win); const { playPause, next, previous, search } = songControls; - _registerGlobalShortcut(win.webContents, "MediaPlayPause", playPause); - _registerGlobalShortcut(win.webContents, "MediaNextTrack", next); - _registerGlobalShortcut(win.webContents, "MediaPreviousTrack", previous); + if (options.overrideMediaKeys) { + _registerGlobalShortcut(win.webContents, "MediaPlayPause", playPause); + _registerGlobalShortcut(win.webContents, "MediaNextTrack", next); + _registerGlobalShortcut(win.webContents, "MediaPreviousTrack", previous); + } + _registerLocalShortcut(win, "CommandOrControl+F", search); _registerLocalShortcut(win, "CommandOrControl+L", search); diff --git a/plugins/shortcuts/menu.js b/plugins/shortcuts/menu.js new file mode 100644 index 00000000..443e052a --- /dev/null +++ b/plugins/shortcuts/menu.js @@ -0,0 +1,118 @@ +const { setOptions } = require("../../config/plugins"); +const prompt = require("custom-electron-prompt"); +const path = require("path"); +const is = require("electron-is"); + +function setOption(options, key = null, newValue = null) { + if (key && newValue) { + options[key] = newValue; + } + setOptions("shortcuts", options) +} + +module.exports = (win, options) => [ + { + label: "Set Global Song Controls", + type: "checkbox", + checked: true, + click: () => promptKeybind(options, win) + }, + { + label: "Override MediaKeys", + type: "checkbox", + checked: options.overrideMediaKeys, + click: (item) => setOption(options, "overrideMediaKeys", item.checked) + } +]; + +function getGlobalKeybinds(options) { + let playPause, next, previous; + if (options.global) { + for (const global of options.global) { + switch (global.action) { + case "playPause": + playPause = global.shortcut; + break; + case "previous": + previous = global.shortcut; + break; + case "next": + next = global.shortcut; + } + } + } + return { playPause, next, previous }; +} + +function setGlobalKeybinds(options, newShortcuts) { + let didSet = {}; + for (const shortcut in newShortcuts) { + didSet[shortcut] = false; + } + if (!options.global) { + options.global = []; + } + for (let i in options.global) { + switch (options.global[i].action) { + case "playPause": + options.global[i].shortcut = newShortcuts.playPause; + didSet["playPause"] = true; + break; + case "previous": + options.global[i].shortcut = newShortcuts.previous; + didSet["previous"] = true; + break; + case "next": + options.global[i].shortcut = newShortcuts.next; + didSet["next"] = true; + break; + } + } + for (const action in didSet) { + if (!didSet[action]) { + options.global.push({ action: action, shortcut: newShortcuts[action] }); + } + } + options.global.forEach((obj) => console.log(obj)); + setOption(options); +} + +const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || "" } }; +const iconPath = path.join(process.cwd(), "assets", "youtube-music-tray.png"); + +function promptKeybind(options, win) { + let globalKeybinds = getGlobalKeybinds(options); + let promptOptions = { + title: "Global Keybinds", + icon: iconPath, + label: "Choose Global Keybinds for Songs Control:", + type: "keybind", + keybindOptions: [ + kb("Previous", "previous", globalKeybinds.previous), + kb("Play / Pause", "playPause", globalKeybinds.playPause), + kb("Next", "next", globalKeybinds.next), + ], + customStylesheet: "dark", + height: 250 + }; + if (!is.macOS()) { + Object.assign(promptOptions, { + frame: false, + customScript: path.join(process.cwd(), "plugins", "in-app-menu", "prompt-custom-titlebar.js"), + enableRemoteModule: true, + height: 270 + }); + } + prompt(promptOptions, win) + .then(output => { + if (output) { + let toSave = {}; + for (const keybindObj of output) { + toSave[keybindObj.value] = keybindObj.accelerator; + } + setGlobalKeybinds(options, toSave); + } + //else = pressed cancel + }) + .catch(console.error) +} \ No newline at end of file From e456035f295107382dae7b58ac302551146ad41a Mon Sep 17 00:00:00 2001 From: Araxeus Date: Fri, 30 Apr 2021 03:22:36 +0300 Subject: [PATCH 04/67] fix typo --- plugins/shortcuts/menu.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/shortcuts/menu.js b/plugins/shortcuts/menu.js index 443e052a..f7edabb6 100644 --- a/plugins/shortcuts/menu.js +++ b/plugins/shortcuts/menu.js @@ -13,8 +13,6 @@ function setOption(options, key = null, newValue = null) { module.exports = (win, options) => [ { label: "Set Global Song Controls", - type: "checkbox", - checked: true, click: () => promptKeybind(options, win) }, { @@ -25,6 +23,7 @@ module.exports = (win, options) => [ } ]; +//will not be needed if globalKeybinds will be an object function getGlobalKeybinds(options) { let playPause, next, previous; if (options.global) { @@ -44,6 +43,7 @@ function getGlobalKeybinds(options) { return { playPause, next, previous }; } +//will not be needed if globalKeybinds will be an object function setGlobalKeybinds(options, newShortcuts) { let didSet = {}; for (const shortcut in newShortcuts) { From 49e51de27424b108e0375f2eb13acd049f244702 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Fri, 30 Apr 2021 04:13:03 +0300 Subject: [PATCH 05/67] update shortcuts config --- plugins/shortcuts/back.js | 63 ++++++++++++++++++++++++++--------- plugins/shortcuts/menu.js | 69 ++++----------------------------------- 2 files changed, 55 insertions(+), 77 deletions(-) diff --git a/plugins/shortcuts/back.js b/plugins/shortcuts/back.js index 9a1481d8..a187ded8 100644 --- a/plugins/shortcuts/back.js +++ b/plugins/shortcuts/back.js @@ -1,5 +1,6 @@ const { globalShortcut } = require("electron"); const electronLocalshortcut = require("electron-localshortcut"); +const { setOptions } = require("../../config/plugins"); const getSongControls = require("../../providers/song-controls"); @@ -19,6 +20,8 @@ function registerShortcuts(win, options) { const songControls = getSongControls(win); const { playPause, next, previous, search } = songControls; + updateOptions(options); + if (options.overrideMediaKeys) { _registerGlobalShortcut(win.webContents, "MediaPlayPause", playPause); _registerGlobalShortcut(win.webContents, "MediaNextTrack", next); @@ -29,24 +32,54 @@ function registerShortcuts(win, options) { _registerLocalShortcut(win, "CommandOrControl+L", search); const { global, local } = options; - (global || []).forEach(({ shortcut, action }) => { - console.debug("Registering global shortcut", shortcut, ":", action); - if (!action || !songControls[action]) { - console.warn("Invalid action", action); - return; - } - _registerGlobalShortcut(win.webContents, shortcut, songControls[action]); - }); - (local || []).forEach(({ shortcut, action }) => { - console.debug("Registering local shortcut", shortcut, ":", action); - if (!action || !songControls[action]) { - console.warn("Invalid action", action); - return; + if (global) { + for (const action in global) { + if (!global[action]) { + return; //accelerator is empty + } + console.debug("Registering global shortcut", global[action], ":", action); + if (!songControls[action]) { + console.warn("Invalid action", action); + return; + } + _registerGlobalShortcut(win.webContents, global[action], songControls[action]); } + } - _registerLocalShortcut(win, shortcut, songControls[action]); - }); + if (local) { + for (const action in local) { + if (!local[action]) { + return; //accelerator is empty + } + console.debug("Registering local shortcut", local[action], ":", action); + if (!songControls[action]) { + console.warn("Invalid action", action); + return; + } + _registerLocalShortcut(win, local[action], songControls[action]); + } + } +} + +/** Update options to new format */ +function updateOptions(options) { + let updated = false; + for (const optionType of ["global", "local"]) { + if (Array.isArray(options[optionType])) { + const updatedOptions = {} + for (const obj of options[optionType]) { + if (obj.action && obj.shortcut) { + updatedOptions[obj.action] = obj.shortcut; + } + } + options[optionType] = updatedOptions; + updated = true; + } + } + if (updated) { + setOptions("shortcuts", options); + } } module.exports = registerShortcuts; diff --git a/plugins/shortcuts/menu.js b/plugins/shortcuts/menu.js index f7edabb6..2b5622c2 100644 --- a/plugins/shortcuts/menu.js +++ b/plugins/shortcuts/menu.js @@ -1,5 +1,6 @@ const { setOptions } = require("../../config/plugins"); const prompt = require("custom-electron-prompt"); + const path = require("path"); const is = require("electron-is"); @@ -23,74 +24,19 @@ module.exports = (win, options) => [ } ]; -//will not be needed if globalKeybinds will be an object -function getGlobalKeybinds(options) { - let playPause, next, previous; - if (options.global) { - for (const global of options.global) { - switch (global.action) { - case "playPause": - playPause = global.shortcut; - break; - case "previous": - previous = global.shortcut; - break; - case "next": - next = global.shortcut; - } - } - } - return { playPause, next, previous }; -} - -//will not be needed if globalKeybinds will be an object -function setGlobalKeybinds(options, newShortcuts) { - let didSet = {}; - for (const shortcut in newShortcuts) { - didSet[shortcut] = false; - } - if (!options.global) { - options.global = []; - } - for (let i in options.global) { - switch (options.global[i].action) { - case "playPause": - options.global[i].shortcut = newShortcuts.playPause; - didSet["playPause"] = true; - break; - case "previous": - options.global[i].shortcut = newShortcuts.previous; - didSet["previous"] = true; - break; - case "next": - options.global[i].shortcut = newShortcuts.next; - didSet["next"] = true; - break; - } - } - for (const action in didSet) { - if (!didSet[action]) { - options.global.push({ action: action, shortcut: newShortcuts[action] }); - } - } - options.global.forEach((obj) => console.log(obj)); - setOption(options); -} - -const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || "" } }; +const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || undefined } }; const iconPath = path.join(process.cwd(), "assets", "youtube-music-tray.png"); function promptKeybind(options, win) { - let globalKeybinds = getGlobalKeybinds(options); let promptOptions = { title: "Global Keybinds", icon: iconPath, label: "Choose Global Keybinds for Songs Control:", type: "keybind", keybindOptions: [ - kb("Previous", "previous", globalKeybinds.previous), - kb("Play / Pause", "playPause", globalKeybinds.playPause), - kb("Next", "next", globalKeybinds.next), + kb("Previous", "previous", options.global?.previous), + kb("Play / Pause", "playPause", options.global?.playPause), + kb("Next", "next", options.global?.next), ], customStylesheet: "dark", height: 250 @@ -106,11 +52,10 @@ function promptKeybind(options, win) { prompt(promptOptions, win) .then(output => { if (output) { - let toSave = {}; for (const keybindObj of output) { - toSave[keybindObj.value] = keybindObj.accelerator; + options.global[keybindObj.value] = keybindObj.accelerator; } - setGlobalKeybinds(options, toSave); + setOption(options); } //else = pressed cancel }) From 54cbe3faa473710a11283facd529f42d587d1848 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Fri, 30 Apr 2021 04:29:01 +0300 Subject: [PATCH 06/67] lint --- plugins/shortcuts/back.js | 22 +++++++++++++------- plugins/shortcuts/menu.js | 44 +++++++++++++++++++++------------------ 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/plugins/shortcuts/back.js b/plugins/shortcuts/back.js index a187ded8..f4f73e0b 100644 --- a/plugins/shortcuts/back.js +++ b/plugins/shortcuts/back.js @@ -36,13 +36,15 @@ function registerShortcuts(win, options) { if (global) { for (const action in global) { if (!global[action]) { - return; //accelerator is empty + continue; //accelerator is empty } + console.debug("Registering global shortcut", global[action], ":", action); if (!songControls[action]) { console.warn("Invalid action", action); - return; + continue; } + _registerGlobalShortcut(win.webContents, global[action], songControls[action]); } } @@ -50,13 +52,15 @@ function registerShortcuts(win, options) { if (local) { for (const action in local) { if (!local[action]) { - return; //accelerator is empty + continue; //accelerator is empty } + console.debug("Registering local shortcut", local[action], ":", action); if (!songControls[action]) { console.warn("Invalid action", action); - return; + continue; } + _registerLocalShortcut(win, local[action], songControls[action]); } } @@ -67,16 +71,18 @@ function updateOptions(options) { let updated = false; for (const optionType of ["global", "local"]) { if (Array.isArray(options[optionType])) { - const updatedOptions = {} - for (const obj of options[optionType]) { - if (obj.action && obj.shortcut) { - updatedOptions[obj.action] = obj.shortcut; + const updatedOptions = {}; + for (const optionObject of options[optionType]) { + if (optionObject.action && optionObject.shortcut) { + updatedOptions[optionObject.action] = optionObject.shortcut; } } + options[optionType] = updatedOptions; updated = true; } } + if (updated) { setOptions("shortcuts", options); } diff --git a/plugins/shortcuts/menu.js b/plugins/shortcuts/menu.js index 2b5622c2..fff28951 100644 --- a/plugins/shortcuts/menu.js +++ b/plugins/shortcuts/menu.js @@ -4,13 +4,6 @@ const prompt = require("custom-electron-prompt"); const path = require("path"); const is = require("electron-is"); -function setOption(options, key = null, newValue = null) { - if (key && newValue) { - options[key] = newValue; - } - setOptions("shortcuts", options) -} - module.exports = (win, options) => [ { label: "Set Global Song Controls", @@ -20,11 +13,19 @@ module.exports = (win, options) => [ label: "Override MediaKeys", type: "checkbox", checked: options.overrideMediaKeys, - click: (item) => setOption(options, "overrideMediaKeys", item.checked) + click: item => setOption(options, "overrideMediaKeys", item.checked) } ]; -const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || undefined } }; +function setOption(options, key = null, newValue = null) { + if (key && newValue) { + options[key] = newValue; + } + + setOptions("shortcuts", options); +} + +const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || undefined }; }; const iconPath = path.join(process.cwd(), "assets", "youtube-music-tray.png"); function promptKeybind(options, win) { @@ -36,11 +37,12 @@ function promptKeybind(options, win) { keybindOptions: [ kb("Previous", "previous", options.global?.previous), kb("Play / Pause", "playPause", options.global?.playPause), - kb("Next", "next", options.global?.next), + kb("Next", "next", options.global?.next) ], customStylesheet: "dark", height: 250 }; + if (!is.macOS()) { Object.assign(promptOptions, { frame: false, @@ -49,15 +51,17 @@ function promptKeybind(options, win) { height: 270 }); } + prompt(promptOptions, win) - .then(output => { - if (output) { - for (const keybindObj of output) { - options.global[keybindObj.value] = keybindObj.accelerator; + .then(output => { + if (output) { + for (const keybindObject of output) { + options.global[keybindObject.value] = keybindObject.accelerator; + } + + setOption(options); } - setOption(options); - } - //else = pressed cancel - }) - .catch(console.error) -} \ No newline at end of file + // else -> pressed cancel + }) + .catch(console.error); +} From d0d4ada7c22d6b8cb17157018957b2324274c4ca Mon Sep 17 00:00:00 2001 From: Araxeus Date: Fri, 30 Apr 2021 04:33:23 +0300 Subject: [PATCH 07/67] restore original menu lint --- menu.js | 165 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 83 insertions(+), 82 deletions(-) diff --git a/menu.js b/menu.js index a178a575..dcbc9db5 100644 --- a/menu.js +++ b/menu.js @@ -104,38 +104,30 @@ const mainMenuTemplate = (win, withRoles = true, isTray = false) => [ }, ...(is.windows() || is.linux() ? [ - { - label: "Hide menu", - type: "checkbox", - checked: config.get("options.hideMenu"), - click: (item) => { - config.set("options.hideMenu", item.checked); + { + label: "Hide menu", + type: "checkbox", + checked: config.get("options.hideMenu"), + click: (item) => { + config.set("options.hideMenu", item.checked); + }, }, - }, - ] + ] : []), ...(is.windows() || is.macOS() ? // Only works on Win/Mac - // https://www.electronjs.org/docs/api/app#appsetloginitemsettingssettings-macos-windows - [ - { - label: "Start at login", - type: "checkbox", - checked: config.get("options.startAtLogin"), - click: (item) => { - config.set("options.startAtLogin", item.checked); + // https://www.electronjs.org/docs/api/app#appsetloginitemsettingssettings-macos-windows + [ + { + label: "Start at login", + type: "checkbox", + checked: config.get("options.startAtLogin"), + click: (item) => { + config.set("options.startAtLogin", item.checked); + }, }, - }, - ] + ] : []), - { - label: "Proxy", - type: "checkbox", - checked: !!config.get("options.proxy"), - click: (item) => { - setProxy(item, win); - } - }, { label: "Tray", submenu: [ @@ -180,6 +172,15 @@ const mainMenuTemplate = (win, withRoles = true, isTray = false) => [ ], }, { type: "separator" }, + // Should be put in Advanced Options submenu + { + label: "Proxy", + type: "checkbox", + checked: !!config.get("options.proxy"), + click: (item) => { + setProxy(item, win); + } + }, { label: "Toggle DevTools", // Cannot use "toggleDevTools" role in MacOS @@ -203,56 +204,56 @@ const mainMenuTemplate = (win, withRoles = true, isTray = false) => [ }, ...(!isTray ? [ - { - label: "View", - submenu: withRoles - ? [ - { role: "reload" }, - { role: "forceReload" }, - { type: "separator" }, - { role: "zoomIn" }, - { role: "zoomOut" }, - { role: "resetZoom" }, - ] - : [ - { - label: "Reload", - click: () => { - win.webContents.reload(); - }, - }, - { - label: "Force Reload", - click: () => { - win.webContents.reloadIgnoringCache(); - }, - }, - { type: "separator" }, - { - label: "Zoom In", - click: () => { - win.webContents.setZoomLevel( - win.webContents.getZoomLevel() + 1 - ); - }, - }, - { - label: "Zoom Out", - click: () => { - win.webContents.setZoomLevel( - win.webContents.getZoomLevel() - 1 - ); - }, - }, - { - label: "Reset Zoom", - click: () => { - win.webContents.setZoomLevel(0); - }, - }, - ], - }, - ] + { + label: "View", + submenu: withRoles + ? [ + { role: "reload" }, + { role: "forceReload" }, + { type: "separator" }, + { role: "zoomIn" }, + { role: "zoomOut" }, + { role: "resetZoom" }, + ] + : [ + { + label: "Reload", + click: () => { + win.webContents.reload(); + }, + }, + { + label: "Force Reload", + click: () => { + win.webContents.reloadIgnoringCache(); + }, + }, + { type: "separator" }, + { + label: "Zoom In", + click: () => { + win.webContents.setZoomLevel( + win.webContents.getZoomLevel() + 1 + ); + }, + }, + { + label: "Zoom Out", + click: () => { + win.webContents.setZoomLevel( + win.webContents.getZoomLevel() - 1 + ); + }, + }, + { + label: "Reset Zoom", + click: () => { + win.webContents.setZoomLevel(0); + }, + }, + ], + }, + ] : []), { label: "Navigation", @@ -282,13 +283,13 @@ const mainMenuTemplate = (win, withRoles = true, isTray = false) => [ }, ...(!isTray ? [ - { - label: "Quit App", - click: () => { - app.quit(); + { + label: "Quit App", + click: () => { + app.quit(); + }, }, - }, - ] + ] : []), ], }, From ec981ac547334db5f970f8edc70140845a44b725 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Fri, 30 Apr 2021 05:09:49 +0300 Subject: [PATCH 08/67] refactor registerAllShortcuts --- plugins/shortcuts/back.js | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/plugins/shortcuts/back.js b/plugins/shortcuts/back.js index f4f73e0b..a3452351 100644 --- a/plugins/shortcuts/back.js +++ b/plugins/shortcuts/back.js @@ -32,35 +32,26 @@ function registerShortcuts(win, options) { _registerLocalShortcut(win, "CommandOrControl+L", search); const { global, local } = options; + const shortcutOptions = {global, local}; - if (global) { - for (const action in global) { - if (!global[action]) { - continue; //accelerator is empty - } - - console.debug("Registering global shortcut", global[action], ":", action); - if (!songControls[action]) { - console.warn("Invalid action", action); - continue; - } - - _registerGlobalShortcut(win.webContents, global[action], songControls[action]); - } + for (const optionType in shortcutOptions) { + registerAllShortcuts(shortcutOptions[optionType], optionType); } - if (local) { - for (const action in local) { - if (!local[action]) { + function registerAllShortcuts(container, type) { + for (const action in container) { + if (!container[action]) { continue; //accelerator is empty } - - console.debug("Registering local shortcut", local[action], ":", action); + + console.debug(`Registering ${type} shortcut`, container[action], ":", action); if (!songControls[action]) { console.warn("Invalid action", action); continue; } - + + type === "global" ? + _registerGlobalShortcut(win.webContents, container[action], songControls[action]) : _registerLocalShortcut(win, local[action], songControls[action]); } } From 79acf6c0ba2770888d25f1932f437b40ba9f7c02 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 5 May 2021 00:42:42 +0300 Subject: [PATCH 09/67] Volume Steps Prompt Precise-Volume Global Shortcuts Prompt --- menu.js | 17 +++--- plugins/precise-volume/front.js | 4 +- plugins/precise-volume/menu.js | 96 ++++++++++++++++++++++++++++++++- plugins/shortcuts/menu.js | 2 +- 4 files changed, 104 insertions(+), 15 deletions(-) diff --git a/menu.js b/menu.js index d2b778e7..776a52eb 100644 --- a/menu.js +++ b/menu.js @@ -141,18 +141,17 @@ const mainMenuTemplate = (win) => [ ], }, { type: "separator" }, - // Should be put in Advanced Options submenu - { - label: "Proxy", - type: "checkbox", - checked: !!config.get("options.proxy"), - click: (item) => { - setProxy(item, win); - } - }, { label: "Advanced options", submenu: [ + { + label: "Proxy", + type: "checkbox", + checked: !!config.get("options.proxy"), + click: (item) => { + setProxy(item, win); + } + }, { label: "Disable hardware acceleration", type: "checkbox", diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index a1b30fe4..5b66b31f 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -12,9 +12,7 @@ module.exports = (options) => { setupLocalArrowShortcuts(options); - if (options.globalShortcuts?.enabled) { - setupGlobalShortcuts(options); - } + setupGlobalShortcuts(options); firstRun(options); diff --git a/plugins/precise-volume/menu.js b/plugins/precise-volume/menu.js index d4ed37a7..ba03193e 100644 --- a/plugins/precise-volume/menu.js +++ b/plugins/precise-volume/menu.js @@ -1,13 +1,17 @@ const { enabled } = require("./back"); +const { app } = require("electron") const { setOptions } = require("../../config/plugins"); +const prompt = require("custom-electron-prompt"); +const path = require("path"); +const is = require("electron-is"); module.exports = (win, options) => [ { - label: "Arrowkeys controls", + label: "Local Arrowkeys Controls", type: "checkbox", checked: !!options.arrowsShortcut, click: (item) => { - // Dynamically change setting if plugin enabled + // Dynamically change setting if plugin is enabled if (enabled()) { win.webContents.send("setArrowsShortcut", item.checked); } else { // Fallback to usual method if disabled @@ -15,5 +19,93 @@ module.exports = (win, options) => [ setOptions("precise-volume", options); } } + }, + { + label: "Global Hotkeys", + type: "checkbox", + checked: !!options.globalShortcuts.volumeUp || !!options.globalShortcuts.volumeDown, + click: item => { + promptGlobalShortcuts(win, options, item); + } + }, + { + label: "Set Custom Volume Steps", + click: () => { + promptVolumeSteps(win, options); + } } ]; + +const iconPath = path.join(app.getAppPath(), "assets", "youtube-music-tray.png"); +const customTitlebarPath = path.join(app.getAppPath(), "plugins", "in-app-menu", "prompt-custom-titlebar.js"); +// helper function for globalShortcuts prompt +const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || undefined }; }; + +function useCustomTitlebar(options) { + if (!is.macOS()) { + Object.assign(options, { + customStylesheet: "dark", + icon: iconPath, + frame: false, + customScript: customTitlebarPath, + enableRemoteModule: true, + }); + } else { + Object.assign(options, { + customStylesheet: "dark", + icon: iconPath, + }) + } +} + +function promptVolumeSteps(win, options) { + let promptOptions = { + title: "Volume Steps", + label: "Choose Volume Increase/Decrease Steps", + value: options.steps || 1, + type: "counter", + counterOptions: { minimum: 0, maximum: 100, multiFire: true }, + } + + useCustomTitlebar(promptOptions); + + prompt(promptOptions, win).then(input => { + if (input || input === 0) { // 0 is somehow valid + options.steps = input; + setOptions("precise-volume", options); + } + }).catch(console.error) +} + +function promptGlobalShortcuts(win, options, item) { + let promptOptions = { + title: "Global Volume Keybinds", + label: "Choose Global Volume Keybinds:", + type: "keybind", + keybindOptions: [ + kb("Volume Up", "volumeUp", options.globalShortcuts?.volumeUp), + kb("Volume Down", "volumeDown", options.globalShortcuts?.volumeDown), + ], + height: 230 + }; + + useCustomTitlebar(promptOptions); + + prompt(promptOptions, win) + .then(output => { + if (output) { + for (const keybindObject of output) { + options.globalShortcuts[keybindObject.value] = keybindObject.accelerator; + } + + setOptions("precise-volume", options); + + item.checked = !!options.globalShortcuts.volumeUp || !!options.globalShortcuts.volumeDown; + } + else { + // Reset checkbox if prompt was canceled + item.checked = !item.checked; + } + }) + .catch(console.error); +} \ No newline at end of file diff --git a/plugins/shortcuts/menu.js b/plugins/shortcuts/menu.js index fff28951..0eec4572 100644 --- a/plugins/shortcuts/menu.js +++ b/plugins/shortcuts/menu.js @@ -18,7 +18,7 @@ module.exports = (win, options) => [ ]; function setOption(options, key = null, newValue = null) { - if (key && newValue) { + if (key && newValue !== null) { options[key] = newValue; } From 22c5ea50002686c3b72a4d6f4a8c76494408c242 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 5 May 2021 01:25:45 +0300 Subject: [PATCH 10/67] lint --- config/defaults.js | 5 +-- plugins/precise-volume/menu.js | 79 ++++++++++++++++------------------ plugins/shortcuts/back.js | 18 ++++---- plugins/shortcuts/menu.js | 7 +-- 4 files changed, 54 insertions(+), 55 deletions(-) diff --git a/config/defaults.js b/config/defaults.js index a15d6b70..b89a920a 100644 --- a/config/defaults.js +++ b/config/defaults.js @@ -60,9 +60,8 @@ const defaultConfig = { steps: 1, //percentage of volume to change arrowsShortcut: true, //enable ArrowUp + ArrowDown local shortcuts globalShortcuts: { - enabled: false, // enable global shortcuts - volumeUp: "Shift+PageUp", // Keybind default can be changed - volumeDown: "Shift+PageDown" + volumeUp: "", + volumeDown: "" }, savedVolume: undefined //plugin save volume between session here } diff --git a/plugins/precise-volume/menu.js b/plugins/precise-volume/menu.js index ba03193e..1919052f 100644 --- a/plugins/precise-volume/menu.js +++ b/plugins/precise-volume/menu.js @@ -1,5 +1,5 @@ const { enabled } = require("./back"); -const { app } = require("electron") +const { app } = require("electron"); const { setOptions } = require("../../config/plugins"); const prompt = require("custom-electron-prompt"); const path = require("path"); @@ -10,7 +10,7 @@ module.exports = (win, options) => [ label: "Local Arrowkeys Controls", type: "checkbox", checked: !!options.arrowsShortcut, - click: (item) => { + click: item => { // Dynamically change setting if plugin is enabled if (enabled()) { win.webContents.send("setArrowsShortcut", item.checked); @@ -24,88 +24,85 @@ module.exports = (win, options) => [ label: "Global Hotkeys", type: "checkbox", checked: !!options.globalShortcuts.volumeUp || !!options.globalShortcuts.volumeDown, - click: item => { - promptGlobalShortcuts(win, options, item); - } + click: item => promptGlobalShortcuts(win, options, item) }, { label: "Set Custom Volume Steps", - click: () => { - promptVolumeSteps(win, options); - } + click: () => promptVolumeSteps(win, options) } ]; const iconPath = path.join(app.getAppPath(), "assets", "youtube-music-tray.png"); const customTitlebarPath = path.join(app.getAppPath(), "plugins", "in-app-menu", "prompt-custom-titlebar.js"); -// helper function for globalShortcuts prompt +// Helper function for globalShortcuts prompt const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || undefined }; }; -function useCustomTitlebar(options) { - if (!is.macOS()) { +function setupPromptOptions(options) { + // TODO Custom titlebar needs testing on macOS + if (is.macOS()) { Object.assign(options, { customStylesheet: "dark", - icon: iconPath, - frame: false, - customScript: customTitlebarPath, - enableRemoteModule: true, + icon: iconPath }); } else { Object.assign(options, { customStylesheet: "dark", icon: iconPath, - }) + // The following are used for custom titlebar + frame: false, + customScript: customTitlebarPath, + enableRemoteModule: true + }); } } function promptVolumeSteps(win, options) { - let promptOptions = { + const promptOptions = { title: "Volume Steps", label: "Choose Volume Increase/Decrease Steps", value: options.steps || 1, type: "counter", - counterOptions: { minimum: 0, maximum: 100, multiFire: true }, - } + counterOptions: { minimum: 0, maximum: 100, multiFire: true } + }; - useCustomTitlebar(promptOptions); + setupPromptOptions(promptOptions); prompt(promptOptions, win).then(input => { if (input || input === 0) { // 0 is somehow valid options.steps = input; setOptions("precise-volume", options); } - }).catch(console.error) + }).catch(console.error); } function promptGlobalShortcuts(win, options, item) { - let promptOptions = { + const promptOptions = { title: "Global Volume Keybinds", label: "Choose Global Volume Keybinds:", type: "keybind", keybindOptions: [ - kb("Volume Up", "volumeUp", options.globalShortcuts?.volumeUp), - kb("Volume Down", "volumeDown", options.globalShortcuts?.volumeDown), + kb("Increase Volume", "volumeUp", options.globalShortcuts?.volumeUp), + kb("Decrease Volume", "volumeDown", options.globalShortcuts?.volumeDown) ], height: 230 }; - useCustomTitlebar(promptOptions); + setupPromptOptions(promptOptions); prompt(promptOptions, win) - .then(output => { - if (output) { - for (const keybindObject of output) { - options.globalShortcuts[keybindObject.value] = keybindObject.accelerator; + .then(output => { + if (output) { + for (const keybindObject of output) { + options.globalShortcuts[keybindObject.value] = keybindObject.accelerator; + } + + setOptions("precise-volume", options); + + item.checked = !!options.globalShortcuts.volumeUp || !!options.globalShortcuts.volumeDown; + } else { + // Reset checkbox if prompt was canceled + item.checked = !item.checked; } - - setOptions("precise-volume", options); - - item.checked = !!options.globalShortcuts.volumeUp || !!options.globalShortcuts.volumeDown; - } - else { - // Reset checkbox if prompt was canceled - item.checked = !item.checked; - } - }) - .catch(console.error); -} \ No newline at end of file + }) + .catch(console.error); +} diff --git a/plugins/shortcuts/back.js b/plugins/shortcuts/back.js index a3452351..688dc5a4 100644 --- a/plugins/shortcuts/back.js +++ b/plugins/shortcuts/back.js @@ -32,7 +32,7 @@ function registerShortcuts(win, options) { _registerLocalShortcut(win, "CommandOrControl+L", search); const { global, local } = options; - const shortcutOptions = {global, local}; + const shortcutOptions = { global, local }; for (const optionType in shortcutOptions) { registerAllShortcuts(shortcutOptions[optionType], optionType); @@ -41,23 +41,25 @@ function registerShortcuts(win, options) { function registerAllShortcuts(container, type) { for (const action in container) { if (!container[action]) { - continue; //accelerator is empty + continue; // Action accelerator is empty } - + console.debug(`Registering ${type} shortcut`, container[action], ":", action); if (!songControls[action]) { console.warn("Invalid action", action); continue; } - - type === "global" ? - _registerGlobalShortcut(win.webContents, container[action], songControls[action]) : - _registerLocalShortcut(win, local[action], songControls[action]); + + if (type === "global") { + _registerGlobalShortcut(win.webContents, container[action], songControls[action]); + } else { // type === "local" + _registerLocalShortcut(win, local[action], songControls[action]); + } } } } -/** Update options to new format */ +/** Update options to new format if they are still an array (old format) */ function updateOptions(options) { let updated = false; for (const optionType of ["global", "local"]) { diff --git a/plugins/shortcuts/menu.js b/plugins/shortcuts/menu.js index 0eec4572..12506a86 100644 --- a/plugins/shortcuts/menu.js +++ b/plugins/shortcuts/menu.js @@ -25,16 +25,17 @@ function setOption(options, key = null, newValue = null) { setOptions("shortcuts", options); } -const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || undefined }; }; const iconPath = path.join(process.cwd(), "assets", "youtube-music-tray.png"); +// Helper function for keybind prompt +const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ }; }; function promptKeybind(options, win) { - let promptOptions = { + const promptOptions = { title: "Global Keybinds", icon: iconPath, label: "Choose Global Keybinds for Songs Control:", type: "keybind", - keybindOptions: [ + keybindOptions: [ // If default=undefined then no default is used kb("Previous", "previous", options.global?.previous), kb("Play / Pause", "playPause", options.global?.playPause), kb("Next", "next", options.global?.next) From 34a4e6be3dec0923b483ad8a5eecf7bc22bafdef Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 5 May 2021 01:47:53 +0300 Subject: [PATCH 11/67] proxy url check --- menu.js | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/menu.js b/menu.js index 776a52eb..afe8b93d 100644 --- a/menu.js +++ b/menu.js @@ -318,6 +318,9 @@ function setProxy(item, win) { label: 'Enter Proxy Address: (leave empty to disable)', value: config.get("options.proxy") || example, type: 'input', + inputAttrs: { + type: 'url' + }, icon: iconPath, customStylesheet: "dark", }; diff --git a/package.json b/package.json index 2092f6f5..bb793dde 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "YoutubeNonStop": "git://github.com/lawfx/YoutubeNonStop.git#v0.9.0", "async-mutex": "^0.3.1", "browser-id3-writer": "^4.4.0", - "custom-electron-prompt": "^1.0.2", + "custom-electron-prompt": "^1.0.3", "custom-electron-titlebar": "^3.2.6", "discord-rpc": "^3.2.0", "electron-debug": "^3.2.0", From b97a86f6dcac140a5e64a0912e2f4ae72a8a5d86 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 5 May 2021 01:55:25 +0300 Subject: [PATCH 12/67] Update yarn.lock --- yarn.lock | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index c1857d13..845e34ea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2849,10 +2849,10 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" -custom-electron-prompt@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/custom-electron-prompt/-/custom-electron-prompt-1.0.1.tgz#6d11c6e5130a444a9425bd27864777b36f1fef11" - integrity sha512-ldEiZ1t3rBDOb0nfvVpxQOjWJvkkUO3B/sD9IIYr2C/VG9COkc6IJNO2E3rXMPdDDIwejXEQx3CTWp2N2d4moQ== +custom-electron-prompt@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/custom-electron-prompt/-/custom-electron-prompt-1.0.3.tgz#fc1f8313917d07d137fd80d060f9ca96fa953037" + integrity sha512-lEI/KH7qBn8sw7jkw4kAuE24rSfmjxSTdVKlLG2EKfUCvYKyDSLAOS1z8M6PEGAeAmHQxp4lA8kiA2BPFjpANA== dependencies: electron "^11.4.4" @@ -3381,15 +3381,6 @@ electron@^11.4.4: "@types/node" "^12.0.12" extract-zip "^1.0.3" -electron@^11.4.4: - version "11.4.4" - resolved "https://registry.yarnpkg.com/electron/-/electron-11.4.4.tgz#d6c046dedd9e22df5f6408841c3f8ae1a1d59414" - integrity sha512-m52nF85VADCmL9DpzJfgmkvc9fNiGZPYwptv/4fTYrYhAMiO+hmClGMXncCoSAzoULQjl+f+0b9CY4yd6nRFlQ== - dependencies: - "@electron/get" "^1.0.1" - "@types/node" "^12.0.12" - extract-zip "^1.0.3" - elliptic@^6.5.3: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" From db8d946178d058dd700b3a4c4a704808061eb639 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 5 May 2021 02:08:24 +0300 Subject: [PATCH 13/67] fix electron dependency --- package.json | 2 +- yarn.lock | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index bb793dde..73a52902 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "YoutubeNonStop": "git://github.com/lawfx/YoutubeNonStop.git#v0.9.0", "async-mutex": "^0.3.1", "browser-id3-writer": "^4.4.0", - "custom-electron-prompt": "^1.0.3", + "custom-electron-prompt": "^1.0.4", "custom-electron-titlebar": "^3.2.6", "discord-rpc": "^3.2.0", "electron-debug": "^3.2.0", diff --git a/yarn.lock b/yarn.lock index 845e34ea..ae0a453b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2849,12 +2849,10 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" -custom-electron-prompt@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/custom-electron-prompt/-/custom-electron-prompt-1.0.3.tgz#fc1f8313917d07d137fd80d060f9ca96fa953037" - integrity sha512-lEI/KH7qBn8sw7jkw4kAuE24rSfmjxSTdVKlLG2EKfUCvYKyDSLAOS1z8M6PEGAeAmHQxp4lA8kiA2BPFjpANA== - dependencies: - electron "^11.4.4" +custom-electron-prompt@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/custom-electron-prompt/-/custom-electron-prompt-1.0.4.tgz#b729cb10687b8fa9029e82d68652fd94e59b1918" + integrity sha512-Yj73jce2Sx7+ngnqGvth0aBuD6vx/QLrkziLJ5Iznh+n3qRrWnO1Qz+dJCdThCvobO5VUAbTXbHebtLuKj+7qw== custom-electron-titlebar@^3.2.6: version "3.2.6" From 98c00f7a60ccbf397e09a34f23a3ce75fa7d0875 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 5 May 2021 02:30:08 +0300 Subject: [PATCH 14/67] format proxy example --- menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menu.js b/menu.js index afe8b93d..15b99bf9 100644 --- a/menu.js +++ b/menu.js @@ -311,7 +311,7 @@ module.exports.setApplicationMenu = (win) => { }; const iconPath = path.join(__dirname, "assets", "youtube-music-tray.png"); -const example = `Example: "socks5://127.0.0.1:9999"`; +const example = "Example: 'socks5://127.0.0.1:9999'"; function setProxy(item, win) { let options = { title: 'Set Proxy', From 5cee331abe80a0a2c0212f123d5bced5922092a8 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 5 May 2021 02:53:05 +0300 Subject: [PATCH 15/67] update prompt version and lint --- menu.js | 8 +++--- package.json | 2 +- plugins/precise-volume/menu.js | 51 +++++++++++++++++----------------- yarn.lock | 8 +++--- 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/menu.js b/menu.js index 15b99bf9..bca09e7b 100644 --- a/menu.js +++ b/menu.js @@ -335,10 +335,10 @@ function setProxy(item, win) { }); } prompt(options, win) - .then(input => { - if (input !== null && input !== example) { - config.set("options.proxy", input); - item.checked = input !== ""; + .then(output => { + if (output !== null && output !== example) { + config.set("options.proxy", output); + item.checked = output !== ""; } else { //user pressed cancel item.checked = !item.checked; //reset checkbox } diff --git a/package.json b/package.json index 73a52902..931c3e8a 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "YoutubeNonStop": "git://github.com/lawfx/YoutubeNonStop.git#v0.9.0", "async-mutex": "^0.3.1", "browser-id3-writer": "^4.4.0", - "custom-electron-prompt": "^1.0.4", + "custom-electron-prompt": "^1.0.5", "custom-electron-titlebar": "^3.2.6", "discord-rpc": "^3.2.0", "electron-debug": "^3.2.0", diff --git a/plugins/precise-volume/menu.js b/plugins/precise-volume/menu.js index 1919052f..bfe73265 100644 --- a/plugins/precise-volume/menu.js +++ b/plugins/precise-volume/menu.js @@ -37,25 +37,6 @@ const customTitlebarPath = path.join(app.getAppPath(), "plugins", "in-app-menu", // Helper function for globalShortcuts prompt const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || undefined }; }; -function setupPromptOptions(options) { - // TODO Custom titlebar needs testing on macOS - if (is.macOS()) { - Object.assign(options, { - customStylesheet: "dark", - icon: iconPath - }); - } else { - Object.assign(options, { - customStylesheet: "dark", - icon: iconPath, - // The following are used for custom titlebar - frame: false, - customScript: customTitlebarPath, - enableRemoteModule: true - }); - } -} - function promptVolumeSteps(win, options) { const promptOptions = { title: "Volume Steps", @@ -67,12 +48,13 @@ function promptVolumeSteps(win, options) { setupPromptOptions(promptOptions); - prompt(promptOptions, win).then(input => { - if (input || input === 0) { // 0 is somehow valid - options.steps = input; - setOptions("precise-volume", options); - } - }).catch(console.error); + prompt(promptOptions, win) + .then(output => { + if (output || output === 0) { // 0 is somehow valid + options.steps = output; + setOptions("precise-volume", options); + } + }).catch(console.error); } function promptGlobalShortcuts(win, options, item) { @@ -106,3 +88,22 @@ function promptGlobalShortcuts(win, options, item) { }) .catch(console.error); } + +function setupPromptOptions(options) { + // TODO Custom titlebar needs testing on macOS + if (is.macOS()) { + Object.assign(options, { + customStylesheet: "dark", + icon: iconPath + }); + } else { + Object.assign(options, { + customStylesheet: "dark", + icon: iconPath, + // The following are used for custom titlebar + frame: false, + customScript: customTitlebarPath, + enableRemoteModule: true + }); + } +} diff --git a/yarn.lock b/yarn.lock index ae0a453b..e513ddc4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2849,10 +2849,10 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" -custom-electron-prompt@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/custom-electron-prompt/-/custom-electron-prompt-1.0.4.tgz#b729cb10687b8fa9029e82d68652fd94e59b1918" - integrity sha512-Yj73jce2Sx7+ngnqGvth0aBuD6vx/QLrkziLJ5Iznh+n3qRrWnO1Qz+dJCdThCvobO5VUAbTXbHebtLuKj+7qw== +custom-electron-prompt@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/custom-electron-prompt/-/custom-electron-prompt-1.0.5.tgz#2b72ac108f3038bab3757345f8faee3cd91b1f43" + integrity sha512-BEAlGVf7obLmAwSO/rgnWvLQxtYaPEXSu79XySx0qRuR7WEYdQgJdBpycQF+3ivjv8oRe5f4pjxaxu657fs+mg== custom-electron-titlebar@^3.2.6: version "3.2.6" From 834f8674a3dc1617f233e0af5dffd3c682da312b Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 5 May 2021 03:27:47 +0300 Subject: [PATCH 16/67] massive prompt speed boost with v1.1.0 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 931c3e8a..acddcb90 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "YoutubeNonStop": "git://github.com/lawfx/YoutubeNonStop.git#v0.9.0", "async-mutex": "^0.3.1", "browser-id3-writer": "^4.4.0", - "custom-electron-prompt": "^1.0.5", + "custom-electron-prompt": "^1.1.0", "custom-electron-titlebar": "^3.2.6", "discord-rpc": "^3.2.0", "electron-debug": "^3.2.0", diff --git a/yarn.lock b/yarn.lock index e513ddc4..8ba6b788 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2849,10 +2849,10 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" -custom-electron-prompt@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/custom-electron-prompt/-/custom-electron-prompt-1.0.5.tgz#2b72ac108f3038bab3757345f8faee3cd91b1f43" - integrity sha512-BEAlGVf7obLmAwSO/rgnWvLQxtYaPEXSu79XySx0qRuR7WEYdQgJdBpycQF+3ivjv8oRe5f4pjxaxu657fs+mg== +custom-electron-prompt@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/custom-electron-prompt/-/custom-electron-prompt-1.1.0.tgz#611b790047c91f6b532c7861355a0e1f9a81aef2" + integrity sha512-YZYmwZnMOdoWROUlJ+rEMHYsp4XJNNqLj6sZnx5aKBJ8cprEjKP4L5wfo6U+yyX/L9fxVOtvYD0Mp8ki5I9Kow== custom-electron-titlebar@^3.2.6: version "3.2.6" From 6b147b098a7f31695e1d6b8a6f73996f1fd6f49f Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 5 May 2021 03:48:07 +0300 Subject: [PATCH 17/67] fix prompt width --- menu.js | 5 ++--- plugins/precise-volume/menu.js | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/menu.js b/menu.js index bca09e7b..fcd18a7c 100644 --- a/menu.js +++ b/menu.js @@ -323,15 +323,14 @@ function setProxy(item, win) { }, icon: iconPath, customStylesheet: "dark", + width: 450, }; //TODO: custom bar on prompt need testing on macOS if (!is.macOS()) { Object.assign(options, { frame: false, customScript: path.join(__dirname, "plugins", "in-app-menu", "prompt-custom-titlebar.js"), - enableRemoteModule: true, - height: 200, - width: 450, + enableRemoteModule: true, }); } prompt(options, win) diff --git a/plugins/precise-volume/menu.js b/plugins/precise-volume/menu.js index bfe73265..c78c82df 100644 --- a/plugins/precise-volume/menu.js +++ b/plugins/precise-volume/menu.js @@ -43,7 +43,8 @@ function promptVolumeSteps(win, options) { label: "Choose Volume Increase/Decrease Steps", value: options.steps || 1, type: "counter", - counterOptions: { minimum: 0, maximum: 100, multiFire: true } + counterOptions: { minimum: 0, maximum: 100, multiFire: true }, + width: 380 }; setupPromptOptions(promptOptions); @@ -65,8 +66,7 @@ function promptGlobalShortcuts(win, options, item) { keybindOptions: [ kb("Increase Volume", "volumeUp", options.globalShortcuts?.volumeUp), kb("Decrease Volume", "volumeDown", options.globalShortcuts?.volumeDown) - ], - height: 230 + ] }; setupPromptOptions(promptOptions); From f910593fb648171956f62222eb47cba5f7a458a4 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Mon, 10 May 2021 00:40:02 +0300 Subject: [PATCH 18/67] use spread operator + async await --- menu.js | 25 ++++++-------- plugins/precise-volume/menu.js | 63 +++++++++++++++------------------- plugins/shortcuts/menu.js | 29 +++++++--------- 3 files changed, 52 insertions(+), 65 deletions(-) diff --git a/menu.js b/menu.js index fcd18a7c..44cb3716 100644 --- a/menu.js +++ b/menu.js @@ -312,7 +312,7 @@ module.exports.setApplicationMenu = (win) => { const iconPath = path.join(__dirname, "assets", "youtube-music-tray.png"); const example = "Example: 'socks5://127.0.0.1:9999'"; -function setProxy(item, win) { +async function setProxy(item, win) { let options = { title: 'Set Proxy', label: 'Enter Proxy Address: (leave empty to disable)', @@ -325,22 +325,19 @@ function setProxy(item, win) { customStylesheet: "dark", width: 450, }; - //TODO: custom bar on prompt need testing on macOS if (!is.macOS()) { - Object.assign(options, { + options = { + ...options, frame: false, customScript: path.join(__dirname, "plugins", "in-app-menu", "prompt-custom-titlebar.js"), enableRemoteModule: true, - }); + }; } - prompt(options, win) - .then(output => { - if (output !== null && output !== example) { - config.set("options.proxy", output); - item.checked = output !== ""; - } else { //user pressed cancel - item.checked = !item.checked; //reset checkbox - } - }) - .catch(console.error); + const output = await prompt(options, win); + if (output !== null && output !== example) { + config.set("options.proxy", output); + item.checked = output !== ""; + } else { //user pressed cancel + item.checked = !item.checked; //reset checkbox + } } diff --git a/plugins/precise-volume/menu.js b/plugins/precise-volume/menu.js index c78c82df..495315f5 100644 --- a/plugins/precise-volume/menu.js +++ b/plugins/precise-volume/menu.js @@ -37,29 +37,25 @@ const customTitlebarPath = path.join(app.getAppPath(), "plugins", "in-app-menu", // Helper function for globalShortcuts prompt const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || undefined }; }; -function promptVolumeSteps(win, options) { - const promptOptions = { +async function promptVolumeSteps(win, options) { + const promptOptions = setupPromptOptions({ title: "Volume Steps", label: "Choose Volume Increase/Decrease Steps", value: options.steps || 1, type: "counter", counterOptions: { minimum: 0, maximum: 100, multiFire: true }, width: 380 - }; + }); - setupPromptOptions(promptOptions); - - prompt(promptOptions, win) - .then(output => { - if (output || output === 0) { // 0 is somehow valid - options.steps = output; - setOptions("precise-volume", options); - } - }).catch(console.error); + const output = await prompt(promptOptions, win) + if (output || output === 0) { // 0 is somewhat valid + options.steps = output; + setOptions("precise-volume", options); + } } -function promptGlobalShortcuts(win, options, item) { - const promptOptions = { +async function promptGlobalShortcuts(win, options, item) { + const promptOptions = setupPromptOptions({ title: "Global Volume Keybinds", label: "Choose Global Volume Keybinds:", type: "keybind", @@ -67,43 +63,40 @@ function promptGlobalShortcuts(win, options, item) { kb("Increase Volume", "volumeUp", options.globalShortcuts?.volumeUp), kb("Decrease Volume", "volumeDown", options.globalShortcuts?.volumeDown) ] - }; + }); - setupPromptOptions(promptOptions); + const output = await prompt(promptOptions, win) + if (output) { + for (const keybindObject of output) { + options.globalShortcuts[keybindObject.value] = keybindObject.accelerator; + } - prompt(promptOptions, win) - .then(output => { - if (output) { - for (const keybindObject of output) { - options.globalShortcuts[keybindObject.value] = keybindObject.accelerator; - } + setOptions("precise-volume", options); - setOptions("precise-volume", options); - - item.checked = !!options.globalShortcuts.volumeUp || !!options.globalShortcuts.volumeDown; - } else { - // Reset checkbox if prompt was canceled - item.checked = !item.checked; - } - }) - .catch(console.error); + item.checked = !!options.globalShortcuts.volumeUp || !!options.globalShortcuts.volumeDown; + } else { + // Reset checkbox if prompt was canceled + item.checked = !item.checked; + } } function setupPromptOptions(options) { // TODO Custom titlebar needs testing on macOS if (is.macOS()) { - Object.assign(options, { + return { + ...options, customStylesheet: "dark", icon: iconPath - }); + }; } else { - Object.assign(options, { + return { + ...options, customStylesheet: "dark", icon: iconPath, // The following are used for custom titlebar frame: false, customScript: customTitlebarPath, enableRemoteModule: true - }); + }; } } diff --git a/plugins/shortcuts/menu.js b/plugins/shortcuts/menu.js index 12506a86..bf366182 100644 --- a/plugins/shortcuts/menu.js +++ b/plugins/shortcuts/menu.js @@ -29,8 +29,8 @@ const iconPath = path.join(process.cwd(), "assets", "youtube-music-tray.png"); // Helper function for keybind prompt const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ }; }; -function promptKeybind(options, win) { - const promptOptions = { +async function promptKeybind(options, win) { + let promptOptions = { title: "Global Keybinds", icon: iconPath, label: "Choose Global Keybinds for Songs Control:", @@ -45,24 +45,21 @@ function promptKeybind(options, win) { }; if (!is.macOS()) { - Object.assign(promptOptions, { + promptOptions = { + ...promptOptions, frame: false, customScript: path.join(process.cwd(), "plugins", "in-app-menu", "prompt-custom-titlebar.js"), enableRemoteModule: true, height: 270 - }); + }; } - prompt(promptOptions, win) - .then(output => { - if (output) { - for (const keybindObject of output) { - options.global[keybindObject.value] = keybindObject.accelerator; - } - - setOption(options); - } - // else -> pressed cancel - }) - .catch(console.error); + const output = await prompt(promptOptions, win); + if (output) { + for (const keybindObject of output) { + options.global[keybindObject.value] = keybindObject.accelerator; + } + setOption(options); + } + // else -> pressed cancel } From 36317c953af7050864cd559a8341b4f7a7b5407c Mon Sep 17 00:00:00 2001 From: Araxeus Date: Mon, 10 May 2021 01:43:50 +0300 Subject: [PATCH 19/67] globalize promptOptions --- menu.js | 30 +++++-------- plugins/precise-volume/menu.js | 44 +++++-------------- plugins/shortcuts/menu.js | 25 +++-------- .../prompt-custom-titlebar.js | 0 providers/prompt-options.js | 19 ++++++++ 5 files changed, 45 insertions(+), 73 deletions(-) rename {plugins/in-app-menu => providers}/prompt-custom-titlebar.js (100%) create mode 100644 providers/prompt-options.js diff --git a/menu.js b/menu.js index 44cb3716..cdcea4cd 100644 --- a/menu.js +++ b/menu.js @@ -6,7 +6,9 @@ const is = require("electron-is"); const { getAllPlugins } = require("./plugins/utils"); const config = require("./config"); + const prompt = require("custom-electron-prompt"); +const promptOptions = require("./providers/prompt-options"); const pluginEnabledMenu = (win, plugin, label = "", hasSubmenu = false) => ({ label: label || plugin, @@ -310,10 +312,9 @@ module.exports.setApplicationMenu = (win) => { Menu.setApplicationMenu(menu); }; -const iconPath = path.join(__dirname, "assets", "youtube-music-tray.png"); const example = "Example: 'socks5://127.0.0.1:9999'"; async function setProxy(item, win) { - let options = { + const output = await prompt({ title: 'Set Proxy', label: 'Enter Proxy Address: (leave empty to disable)', value: config.get("options.proxy") || example, @@ -321,23 +322,14 @@ async function setProxy(item, win) { inputAttrs: { type: 'url' }, - icon: iconPath, - customStylesheet: "dark", width: 450, - }; - if (!is.macOS()) { - options = { - ...options, - frame: false, - customScript: path.join(__dirname, "plugins", "in-app-menu", "prompt-custom-titlebar.js"), - enableRemoteModule: true, - }; + ...promptOptions() + }, win); + + if (output !== null && output !== example) { + config.set("options.proxy", output); + item.checked = output !== ""; + } else { //user pressed cancel + item.checked = !item.checked; //reset checkbox } - const output = await prompt(options, win); - if (output !== null && output !== example) { - config.set("options.proxy", output); - item.checked = output !== ""; - } else { //user pressed cancel - item.checked = !item.checked; //reset checkbox - } } diff --git a/plugins/precise-volume/menu.js b/plugins/precise-volume/menu.js index 495315f5..c605d75e 100644 --- a/plugins/precise-volume/menu.js +++ b/plugins/precise-volume/menu.js @@ -1,9 +1,8 @@ const { enabled } = require("./back"); -const { app } = require("electron"); const { setOptions } = require("../../config/plugins"); const prompt = require("custom-electron-prompt"); -const path = require("path"); -const is = require("electron-is"); +const promptOptions = require("../../providers/prompt-options"); + module.exports = (win, options) => [ { @@ -32,22 +31,20 @@ module.exports = (win, options) => [ } ]; -const iconPath = path.join(app.getAppPath(), "assets", "youtube-music-tray.png"); -const customTitlebarPath = path.join(app.getAppPath(), "plugins", "in-app-menu", "prompt-custom-titlebar.js"); // Helper function for globalShortcuts prompt const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || undefined }; }; async function promptVolumeSteps(win, options) { - const promptOptions = setupPromptOptions({ + const output = await prompt({ title: "Volume Steps", label: "Choose Volume Increase/Decrease Steps", value: options.steps || 1, type: "counter", counterOptions: { minimum: 0, maximum: 100, multiFire: true }, - width: 380 - }); + width: 380, + ...promptOptions() + }, win) - const output = await prompt(promptOptions, win) if (output || output === 0) { // 0 is somewhat valid options.steps = output; setOptions("precise-volume", options); @@ -55,17 +52,17 @@ async function promptVolumeSteps(win, options) { } async function promptGlobalShortcuts(win, options, item) { - const promptOptions = setupPromptOptions({ + const output = await prompt({ title: "Global Volume Keybinds", label: "Choose Global Volume Keybinds:", type: "keybind", keybindOptions: [ kb("Increase Volume", "volumeUp", options.globalShortcuts?.volumeUp), kb("Decrease Volume", "volumeDown", options.globalShortcuts?.volumeDown) - ] - }); + ], + ...promptOptions() + }, win) - const output = await prompt(promptOptions, win) if (output) { for (const keybindObject of output) { options.globalShortcuts[keybindObject.value] = keybindObject.accelerator; @@ -79,24 +76,3 @@ async function promptGlobalShortcuts(win, options, item) { item.checked = !item.checked; } } - -function setupPromptOptions(options) { - // TODO Custom titlebar needs testing on macOS - if (is.macOS()) { - return { - ...options, - customStylesheet: "dark", - icon: iconPath - }; - } else { - return { - ...options, - customStylesheet: "dark", - icon: iconPath, - // The following are used for custom titlebar - frame: false, - customScript: customTitlebarPath, - enableRemoteModule: true - }; - } -} diff --git a/plugins/shortcuts/menu.js b/plugins/shortcuts/menu.js index bf366182..cdb395f6 100644 --- a/plugins/shortcuts/menu.js +++ b/plugins/shortcuts/menu.js @@ -1,8 +1,6 @@ const { setOptions } = require("../../config/plugins"); const prompt = require("custom-electron-prompt"); - -const path = require("path"); -const is = require("electron-is"); +const promptOptions = require("../../providers/prompt-options"); module.exports = (win, options) => [ { @@ -25,14 +23,12 @@ function setOption(options, key = null, newValue = null) { setOptions("shortcuts", options); } -const iconPath = path.join(process.cwd(), "assets", "youtube-music-tray.png"); // Helper function for keybind prompt const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ }; }; async function promptKeybind(options, win) { - let promptOptions = { + const output = await prompt({ title: "Global Keybinds", - icon: iconPath, label: "Choose Global Keybinds for Songs Control:", type: "keybind", keybindOptions: [ // If default=undefined then no default is used @@ -40,21 +36,10 @@ async function promptKeybind(options, win) { kb("Play / Pause", "playPause", options.global?.playPause), kb("Next", "next", options.global?.next) ], - customStylesheet: "dark", - height: 250 - }; + height: 270, + ...promptOptions() + }, win); - if (!is.macOS()) { - promptOptions = { - ...promptOptions, - frame: false, - customScript: path.join(process.cwd(), "plugins", "in-app-menu", "prompt-custom-titlebar.js"), - enableRemoteModule: true, - height: 270 - }; - } - - const output = await prompt(promptOptions, win); if (output) { for (const keybindObject of output) { options.global[keybindObject.value] = keybindObject.accelerator; diff --git a/plugins/in-app-menu/prompt-custom-titlebar.js b/providers/prompt-custom-titlebar.js similarity index 100% rename from plugins/in-app-menu/prompt-custom-titlebar.js rename to providers/prompt-custom-titlebar.js diff --git a/providers/prompt-options.js b/providers/prompt-options.js new file mode 100644 index 00000000..1029a7b3 --- /dev/null +++ b/providers/prompt-options.js @@ -0,0 +1,19 @@ +const path = require("path"); +const is = require("electron-is"); + +const iconPath = path.resolve(__dirname, "../assets/youtube-music-tray.png"); +const customTitlebarPath = path.join(__dirname, "prompt-custom-titlebar.js"); + +const promptOptions = is.macOS() ? { + customStylesheet: "dark", + icon: iconPath +} : { + customStylesheet: "dark", + icon: iconPath, + // The following are used for custom titlebar + frame: false, + customScript: customTitlebarPath, + enableRemoteModule: true +} + +module.exports = () => promptOptions; \ No newline at end of file From 0eca30367f3db2789a3a1d5de68be34a483a26ef Mon Sep 17 00:00:00 2001 From: Araxeus Date: Mon, 10 May 2021 01:56:41 +0300 Subject: [PATCH 20/67] lint --- providers/prompt-custom-titlebar.js | 2 +- providers/prompt-options.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/providers/prompt-custom-titlebar.js b/providers/prompt-custom-titlebar.js index c36ce5f5..affa9206 100644 --- a/providers/prompt-custom-titlebar.js +++ b/providers/prompt-custom-titlebar.js @@ -1,7 +1,7 @@ const customTitlebar = require("custom-electron-titlebar"); module.exports = () => { - const bar = new customTitlebar.Titlebar({ + new customTitlebar.Titlebar({ backgroundColor: customTitlebar.Color.fromHex("#050505"), minimizable: false, maximizable: false, diff --git a/providers/prompt-options.js b/providers/prompt-options.js index 1029a7b3..79cbc36f 100644 --- a/providers/prompt-options.js +++ b/providers/prompt-options.js @@ -7,13 +7,13 @@ const customTitlebarPath = path.join(__dirname, "prompt-custom-titlebar.js"); const promptOptions = is.macOS() ? { customStylesheet: "dark", icon: iconPath -} : { +} : { customStylesheet: "dark", icon: iconPath, // The following are used for custom titlebar frame: false, customScript: customTitlebarPath, enableRemoteModule: true -} +}; -module.exports = () => promptOptions; \ No newline at end of file +module.exports = () => promptOptions; From 580caeffb93fa05baa3bd8d1db6b5beaf7752ea5 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Mon, 10 May 2021 16:53:57 +0300 Subject: [PATCH 21/67] destructure keybind output --- plugins/precise-volume/menu.js | 4 ++-- plugins/shortcuts/menu.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/precise-volume/menu.js b/plugins/precise-volume/menu.js index c605d75e..06ee84b9 100644 --- a/plugins/precise-volume/menu.js +++ b/plugins/precise-volume/menu.js @@ -64,8 +64,8 @@ async function promptGlobalShortcuts(win, options, item) { }, win) if (output) { - for (const keybindObject of output) { - options.globalShortcuts[keybindObject.value] = keybindObject.accelerator; + for (const { value, accelerator } of output) { + options.globalShortcuts[value] = accelerator; } setOptions("precise-volume", options); diff --git a/plugins/shortcuts/menu.js b/plugins/shortcuts/menu.js index cdb395f6..cef14665 100644 --- a/plugins/shortcuts/menu.js +++ b/plugins/shortcuts/menu.js @@ -41,8 +41,8 @@ async function promptKeybind(options, win) { }, win); if (output) { - for (const keybindObject of output) { - options.global[keybindObject.value] = keybindObject.accelerator; + for (const { value, accelerator } of output) { + options.global[value] = accelerator; } setOption(options); } From e43c01da6470d4ff0a2f844b8ac8bc219b2302a7 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Tue, 11 May 2021 00:20:00 +0300 Subject: [PATCH 22/67] lint --- providers/prompt-options.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/providers/prompt-options.js b/providers/prompt-options.js index 79cbc36f..16f02a99 100644 --- a/providers/prompt-options.js +++ b/providers/prompt-options.js @@ -1,7 +1,7 @@ const path = require("path"); const is = require("electron-is"); -const iconPath = path.resolve(__dirname, "../assets/youtube-music-tray.png"); +const iconPath = path.join(__dirname, "..", "assets", "youtube-music-tray.png"); const customTitlebarPath = path.join(__dirname, "prompt-custom-titlebar.js"); const promptOptions = is.macOS() ? { @@ -9,7 +9,6 @@ const promptOptions = is.macOS() ? { icon: iconPath } : { customStylesheet: "dark", - icon: iconPath, // The following are used for custom titlebar frame: false, customScript: customTitlebarPath, From 002081bcb91d1756684ed228cd8fa7241710ba70 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 12 May 2021 00:47:41 +0300 Subject: [PATCH 23/67] use store migration --- config/store.js | 22 ++++++++++++++++++++++ plugins/shortcuts/back.js | 25 ------------------------- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/config/store.js b/config/store.js index 9c0de1e4..c91174b7 100644 --- a/config/store.js +++ b/config/store.js @@ -3,6 +3,28 @@ const Store = require("electron-store"); const defaults = require("./defaults"); const migrations = { + /** Update shortcuts format from array to object */ + ">=1.12.0": (store) => { + const options = store.get("plugins.shortcuts") + let updated = false; + for (const optionType of ["global", "local"]) { + if (Array.isArray(options[optionType])) { + const updatedOptions = {}; + for (const optionObject of options[optionType]) { + if (optionObject.action && optionObject.shortcut) { + updatedOptions[optionObject.action] = optionObject.shortcut; + } + } + + options[optionType] = updatedOptions; + updated = true; + } + } + + if (updated) { + store.set("plugins.shortcuts", options); + } + }, ">=1.11.0": (store) => { if (store.get("options.resumeOnStart") === undefined) { store.set("options.resumeOnStart", true); diff --git a/plugins/shortcuts/back.js b/plugins/shortcuts/back.js index 688dc5a4..075aefe5 100644 --- a/plugins/shortcuts/back.js +++ b/plugins/shortcuts/back.js @@ -1,6 +1,5 @@ const { globalShortcut } = require("electron"); const electronLocalshortcut = require("electron-localshortcut"); -const { setOptions } = require("../../config/plugins"); const getSongControls = require("../../providers/song-controls"); @@ -20,8 +19,6 @@ function registerShortcuts(win, options) { const songControls = getSongControls(win); const { playPause, next, previous, search } = songControls; - updateOptions(options); - if (options.overrideMediaKeys) { _registerGlobalShortcut(win.webContents, "MediaPlayPause", playPause); _registerGlobalShortcut(win.webContents, "MediaNextTrack", next); @@ -59,26 +56,4 @@ function registerShortcuts(win, options) { } } -/** Update options to new format if they are still an array (old format) */ -function updateOptions(options) { - let updated = false; - for (const optionType of ["global", "local"]) { - if (Array.isArray(options[optionType])) { - const updatedOptions = {}; - for (const optionObject of options[optionType]) { - if (optionObject.action && optionObject.shortcut) { - updatedOptions[optionObject.action] = optionObject.shortcut; - } - } - - options[optionType] = updatedOptions; - updated = true; - } - } - - if (updated) { - setOptions("shortcuts", options); - } -} - module.exports = registerShortcuts; From 7bc35f4cee7d94fb7825d6c998c5fcbdc08461b6 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 12 May 2021 18:31:11 +0300 Subject: [PATCH 24/67] add volume hud --- plugins/precise-volume/back.js | 8 +----- plugins/precise-volume/front.js | 44 ++++++++++++++++++++++++++----- plugins/precise-volume/preload.js | 2 +- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/plugins/precise-volume/back.js b/plugins/precise-volume/back.js index 93ebea9f..a664041b 100644 --- a/plugins/precise-volume/back.js +++ b/plugins/precise-volume/back.js @@ -1,5 +1,3 @@ -const { isEnabled } = require("../../config/plugins"); - /* This is used to determine if plugin is actually active (not if its only enabled in options) @@ -9,12 +7,8 @@ let enabled = false; module.exports = (win) => { enabled = true; - // youtube-music register some of the target listeners after DOMContentLoaded - // did-finish-load is called after all elements finished loading, including said listeners - // Thats the reason the timing is controlled from main win.webContents.once("did-finish-load", () => { - win.webContents.send("restoreAddEventListener"); - win.webContents.send("setupVideoPlayerVolumeMousewheel", !isEnabled("hide-video-player")); + win.webContents.send("did-finish-load"); }); }; diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index 7195b5bf..546109c9 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -16,15 +16,45 @@ module.exports = (options) => { setupGlobalShortcuts(options); } - firstRun(options); - - // This way the ipc listener gets cleared either way - ipcRenderer.once("setupVideoPlayerVolumeMousewheel", (_event, toEnable) => { - if (toEnable) + ipcRenderer.once("did-finish-load", () => { + injectVolumeHud(); + // if hideVideo is disabled + if ($("#main-panel")?.computedStyleMap().get("display").value !== "none") { setupVideoPlayerOnwheel(options); + } }); + + firstRun(options); }; +function injectVolumeHud() { + const position = `top: 18px; right: 60px; z-index: 999; position: absolute;`; + const mainStyle = "font-size: xx-large; padding: 10px; transition: opacity 1.5s" + $(".center-content.ytmusic-nav-bar").insertAdjacentHTML('beforeend', ``) +} + +let hudFadeTimeout; + +function showVolumeHud(volume) { + let volumeHud = $('#volumeHud'); + if (!volumeHud) { + console.error("volumeHud Not Found !"); + return; + } + + volumeHud.textContent = volume + '%'; + volumeHud.style.opacity = 1; + + if (hudFadeTimeout) { + clearTimeout(hudFadeTimeout); + } + + hudFadeTimeout = setTimeout(() => { + volumeHud.style.opacity = 0; + hudFadeTimeout = null; + }, 2000); +} + /** Add onwheel event to video player */ function setupVideoPlayerOnwheel(options) { $("#main-panel").addEventListener("wheel", event => { @@ -102,8 +132,10 @@ function changeVolume(toIncrease, options) { slider.value = options.savedVolume; // Change tooltips to new value setTooltip(options.savedVolume); - // Show volume slider on volume change + // Show volume slider showVolumeSlider(slider); + // Show volume HUD + showVolumeHud(options.savedVolume); } let volumeHoverTimeoutID; diff --git a/plugins/precise-volume/preload.js b/plugins/precise-volume/preload.js index edc5f20c..6395c3a4 100644 --- a/plugins/precise-volume/preload.js +++ b/plugins/precise-volume/preload.js @@ -25,7 +25,7 @@ function overrideAddEventListener() { module.exports = () => { overrideAddEventListener(); // Restore original function after did-finish-load to avoid keeping Element.prototype altered - ipcRenderer.once("restoreAddEventListener", () => { // Called from main to make sure page is completly loaded + ipcRenderer.once("did-finish-load", () => { // Called from main to make sure page is completly loaded Element.prototype.addEventListener = Element.prototype._addEventListener; Element.prototype._addEventListener = undefined; ignored = undefined; From 8a07fccf8fdd139bf6ca68540b432b20195ec2fd Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 12 May 2021 18:58:29 +0300 Subject: [PATCH 25/67] setup on page reload --- plugins/precise-volume/back.js | 2 +- plugins/precise-volume/front.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/precise-volume/back.js b/plugins/precise-volume/back.js index a664041b..80aeea6a 100644 --- a/plugins/precise-volume/back.js +++ b/plugins/precise-volume/back.js @@ -7,7 +7,7 @@ let enabled = false; module.exports = (win) => { enabled = true; - win.webContents.once("did-finish-load", () => { + win.webContents.on("did-finish-load", () => { win.webContents.send("did-finish-load"); }); }; diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index 546109c9..1ca3a15d 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -16,7 +16,7 @@ module.exports = (options) => { setupGlobalShortcuts(options); } - ipcRenderer.once("did-finish-load", () => { + ipcRenderer.on("did-finish-load", () => { injectVolumeHud(); // if hideVideo is disabled if ($("#main-panel")?.computedStyleMap().get("display").value !== "none") { From 71ba6b8e558964dbcf4a1ece4a85de0614cffea8 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 12 May 2021 20:58:43 +0300 Subject: [PATCH 26/67] lint --- plugins/precise-volume/front.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index 1ca3a15d..61588947 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -28,19 +28,17 @@ module.exports = (options) => { }; function injectVolumeHud() { - const position = `top: 18px; right: 60px; z-index: 999; position: absolute;`; - const mainStyle = "font-size: xx-large; padding: 10px; transition: opacity 1.5s" - $(".center-content.ytmusic-nav-bar").insertAdjacentHTML('beforeend', ``) + const position = "top: 18px; right: 60px; z-index: 999; position: absolute;"; + const mainStyle = "font-size: xx-large; padding: 10px; transition: opacity 1.5s"; + $(".center-content.ytmusic-nav-bar").insertAdjacentHTML("beforeend", + ``) } let hudFadeTimeout; function showVolumeHud(volume) { - let volumeHud = $('#volumeHud'); - if (!volumeHud) { - console.error("volumeHud Not Found !"); - return; - } + let volumeHud = $("#volumeHud"); + if (!volumeHud) return; volumeHud.textContent = volume + '%'; volumeHud.style.opacity = 1; From ea672c242361a4f58aa0c94b9be43cf0623aaef1 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Thu, 13 May 2021 03:18:24 +0300 Subject: [PATCH 27/67] show volume hud in videoplayer if available --- plugins/precise-volume/front.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index 61588947..ddc1f3e5 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -17,9 +17,9 @@ module.exports = (options) => { } ipcRenderer.on("did-finish-load", () => { - injectVolumeHud(); - // if hideVideo is disabled - if ($("#main-panel")?.computedStyleMap().get("display").value !== "none") { + const noVid = $("#main-panel")?.computedStyleMap().get("display").value === "none"; + injectVolumeHud(noVid); + if (!noVid) { setupVideoPlayerOnwheel(options); } }); @@ -27,11 +27,20 @@ module.exports = (options) => { firstRun(options); }; -function injectVolumeHud() { - const position = "top: 18px; right: 60px; z-index: 999; position: absolute;"; - const mainStyle = "font-size: xx-large; padding: 10px; transition: opacity 1.5s"; - $(".center-content.ytmusic-nav-bar").insertAdjacentHTML("beforeend", - ``) +function injectVolumeHud(noVid) { + if (noVid) { + const position = "top: 18px; right: 60px; z-index: 999; position: absolute;"; + const mainStyle = "font-size: xx-large; padding: 10px; transition: opacity 1s"; + + $(".center-content.ytmusic-nav-bar").insertAdjacentHTML("beforeend", + ``) + } else { + const position = `top: 10px; left: 10px; z-index: 999; position: absolute;`; + const mainStyle = "font-size: xxx-large; padding: 10px; transition: opacity 0.6s; webkit-text-stroke: 1px black; font-weight: 600;"; + + $("#song-video").insertAdjacentHTML('afterend', + ``) + } } let hudFadeTimeout; From 355f61188af082b491785a4716b5658c17ea9f95 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Thu, 13 May 2021 07:08:17 +0300 Subject: [PATCH 28/67] use placeholder proxy example --- menu.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/menu.js b/menu.js index cdcea4cd..11234900 100644 --- a/menu.js +++ b/menu.js @@ -312,21 +312,21 @@ module.exports.setApplicationMenu = (win) => { Menu.setApplicationMenu(menu); }; -const example = "Example: 'socks5://127.0.0.1:9999'"; async function setProxy(item, win) { const output = await prompt({ title: 'Set Proxy', label: 'Enter Proxy Address: (leave empty to disable)', - value: config.get("options.proxy") || example, + value: config.get("options.proxy"), type: 'input', inputAttrs: { - type: 'url' + type: 'url', + placeholder: "Example: 'socks5://127.0.0.1:9999" }, width: 450, ...promptOptions() }, win); - if (output !== null && output !== example) { + if (output) { config.set("options.proxy", output); item.checked = output !== ""; } else { //user pressed cancel From b2c209837c5ee75fce697a5779fc20ed8b842cb0 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Fri, 14 May 2021 03:12:27 +0300 Subject: [PATCH 29/67] fix empty string input validation in setProxy --- menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menu.js b/menu.js index 11234900..4a8eeb1c 100644 --- a/menu.js +++ b/menu.js @@ -326,7 +326,7 @@ async function setProxy(item, win) { ...promptOptions() }, win); - if (output) { + if (typeof output === "string") { config.set("options.proxy", output); item.checked = output !== ""; } else { //user pressed cancel From 65178b259fbbd77b78272c98a2fdb1abf2887039 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Sun, 16 May 2021 21:32:40 +0300 Subject: [PATCH 30/67] fix video muting when volume < 3 --- plugins/precise-volume/front.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index ddc1f3e5..bffc5588 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -136,7 +136,7 @@ function changeVolume(toIncrease, options) { // Save the new volume saveVolume(toPercent(videoStream.volume), options); // Slider value automatically rounds to multiples of 5 - slider.value = options.savedVolume; + slider.value = Math.max(options.savedVolume, 5); // Change tooltips to new value setTooltip(options.savedVolume); // Show volume slider From 58557505ae3b07bb4907acdc77c6f0b308e286a4 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Sun, 16 May 2021 22:39:11 +0300 Subject: [PATCH 31/67] show mute icon when volume=0 --- plugins/precise-volume/front.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index bffc5588..360f5cbc 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -136,7 +136,9 @@ function changeVolume(toIncrease, options) { // Save the new volume saveVolume(toPercent(videoStream.volume), options); // Slider value automatically rounds to multiples of 5 - slider.value = Math.max(options.savedVolume, 5); + slider.value = options.savedVolume > 0 && options.savedVolume < 5 ? + 5 : options.savedVolume; + // Change tooltips to new value setTooltip(options.savedVolume); // Show volume slider From 6961cdee95f22243ee52af725dbe8871c668b252 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Sun, 16 May 2021 22:39:38 +0300 Subject: [PATCH 32/67] override youtube automatically changing the volume --- plugins/precise-volume/front.js | 55 +++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index 360f5cbc..daffcb31 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -86,17 +86,11 @@ function firstRun(options) { const slider = $("#volume-slider"); // Those elements load abit after DOMContentLoaded if (videoStream && slider) { - // Set saved volume IF it pass checks - if (options.savedVolume - && options.savedVolume >= 0 && options.savedVolume <= 100 - && Math.abs(slider.value - options.savedVolume) < 5 - // If plugin was disabled and volume changed then diff>4 - ) { - videoStream.volume = options.savedVolume / 100; - slider.value = options.savedVolume; + setupVolumeOverride(options); + if (typeof options.savedVolume === "number") { + // Set saved volume as tooltip + setTooltip(options.savedVolume); } - // Set current volume as tooltip - setTooltip(toPercent(videoStream.volume)); } else { setTimeout(firstRun, 500, options); // Try again in 500 milliseconds } @@ -126,7 +120,6 @@ function setupPlaybar(options) { function changeVolume(toIncrease, options) { // Need to change both the actual volume and the slider const videoStream = $(".video-stream"); - const slider = $("#volume-slider"); // Apply volume change if valid const steps = (options.steps || 1) / 100; videoStream.volume = toIncrease ? @@ -135,21 +128,49 @@ function changeVolume(toIncrease, options) { // Save the new volume saveVolume(toPercent(videoStream.volume), options); - // Slider value automatically rounds to multiples of 5 - slider.value = options.savedVolume > 0 && options.savedVolume < 5 ? - 5 : options.savedVolume; + + // change slider position (important) + updateVolumeSlider(options); // Change tooltips to new value setTooltip(options.savedVolume); // Show volume slider - showVolumeSlider(slider); + showVolumeSlider(); // Show volume HUD showVolumeHud(options.savedVolume); } +function setupVolumeOverride(options) { + const video = $('video'); + + video.addEventListener("canplay", () => { + if (typeof options.savedVolume === "number") { + const newVolume = options.savedVolume / 100; + + video.volume = newVolume; + updateVolumeSlider(options); + + const volumeOverrideInterval = setInterval(() => { + video.volume = newVolume; + }, 4); + setTimeout((interval) => { + updateVolumeSlider(options); + clearInterval(interval); + }, 500, volumeOverrideInterval); + } + }); +} + +function updateVolumeSlider(options) { + // Slider value automatically rounds to multiples of 5 + $("#volume-slider").value = options.savedVolume > 0 && options.savedVolume < 5 ? + 5 : options.savedVolume; +} + let volumeHoverTimeoutID; -function showVolumeSlider(slider) { +function showVolumeSlider() { + const slider = $("#volume-slider"); // This class display the volume slider if not in minimized mode slider.classList.add("on-hover"); // Reset timeout if previous one hasn't completed @@ -171,7 +192,7 @@ function setupSliderObserver(options) { for (const mutation of mutations) { // This checks that volume-slider was manually set if (mutation.oldValue !== mutation.target.value && - (!options.savedVolume || Math.abs(options.savedVolume - mutation.target.value) > 4)) { + (typeof options.savedVolume !== "number" || Math.abs(options.savedVolume - mutation.target.value) > 4)) { // Diff>4 means it was manually set setTooltip(mutation.target.value); saveVolume(mutation.target.value, options); From 28b70f64591aea97e299b6d5a4bc65e161882315 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Sun, 16 May 2021 22:59:05 +0300 Subject: [PATCH 33/67] added timeout when writing volume to config --- plugins/precise-volume/front.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index daffcb31..c8fb6a07 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -77,7 +77,18 @@ function toPercent(volume) { function saveVolume(volume, options) { options.savedVolume = volume; - setOptions("precise-volume", options); + writeOptions(options); +} + +//without this function it would rewrite config 20 time when volume change by 20 +let writeTimeout; +function writeOptions(options) { + if (writeTimeout) clearTimeout(writeTimeout); + + writeTimeout = setTimeout(() => { + setOptions("precise-volume", options); + writeTimeout = null; + }, 1500) } /** Restore saved volume and setup tooltip */ From 9c7a70e056d0f9f0de820027e3d8789907479c00 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Sun, 16 May 2021 23:50:59 +0300 Subject: [PATCH 34/67] use `.toFixed(2)` on volume decimals --- plugins/precise-volume/front.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index c8fb6a07..08231503 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -135,7 +135,7 @@ function changeVolume(toIncrease, options) { const steps = (options.steps || 1) / 100; videoStream.volume = toIncrease ? Math.min(videoStream.volume + steps, 1) : - Math.max(videoStream.volume - steps, 0); + Math.max(videoStream.volume - steps, 0).toFixed(2); // Save the new volume saveVolume(toPercent(videoStream.volume), options); @@ -156,7 +156,7 @@ function setupVolumeOverride(options) { video.addEventListener("canplay", () => { if (typeof options.savedVolume === "number") { - const newVolume = options.savedVolume / 100; + const newVolume = (options.savedVolume / 100).toFixed(2); video.volume = newVolume; updateVolumeSlider(options); From e5473cdfe4367253a3cdc3381df95d28d054ba22 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Mon, 17 May 2021 00:07:28 +0300 Subject: [PATCH 35/67] lint --- plugins/precise-volume/front.js | 36 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index 08231503..b0dd4502 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -31,13 +31,13 @@ function injectVolumeHud(noVid) { if (noVid) { const position = "top: 18px; right: 60px; z-index: 999; position: absolute;"; const mainStyle = "font-size: xx-large; padding: 10px; transition: opacity 1s"; - + $(".center-content.ytmusic-nav-bar").insertAdjacentHTML("beforeend", ``) } else { const position = `top: 10px; left: 10px; z-index: 999; position: absolute;`; const mainStyle = "font-size: xxx-large; padding: 10px; transition: opacity 0.6s; webkit-text-stroke: 1px black; font-weight: 600;"; - + $("#song-video").insertAdjacentHTML('afterend', ``) } @@ -46,20 +46,20 @@ function injectVolumeHud(noVid) { let hudFadeTimeout; function showVolumeHud(volume) { - let volumeHud = $("#volumeHud"); - if (!volumeHud) return; + let volumeHud = $("#volumeHud"); + if (!volumeHud) return; - volumeHud.textContent = volume + '%'; - volumeHud.style.opacity = 1; + volumeHud.textContent = volume + '%'; + volumeHud.style.opacity = 1; - if (hudFadeTimeout) { + if (hudFadeTimeout) { clearTimeout(hudFadeTimeout); } - hudFadeTimeout = setTimeout(() => { - volumeHud.style.opacity = 0; - hudFadeTimeout = null; - }, 2000); + hudFadeTimeout = setTimeout(() => { + volumeHud.style.opacity = 0; + hudFadeTimeout = null; + }, 2000); } /** Add onwheel event to video player */ @@ -83,12 +83,12 @@ function saveVolume(volume, options) { //without this function it would rewrite config 20 time when volume change by 20 let writeTimeout; function writeOptions(options) { - if (writeTimeout) clearTimeout(writeTimeout); + if (writeTimeout) clearTimeout(writeTimeout); - writeTimeout = setTimeout(() => { + writeTimeout = setTimeout(() => { setOptions("precise-volume", options); - writeTimeout = null; - }, 1500) + writeTimeout = null; + }, 1500) } /** Restore saved volume and setup tooltip */ @@ -133,9 +133,9 @@ function changeVolume(toIncrease, options) { const videoStream = $(".video-stream"); // Apply volume change if valid const steps = (options.steps || 1) / 100; - videoStream.volume = toIncrease ? + videoStream.volume = (toIncrease ? Math.min(videoStream.volume + steps, 1) : - Math.max(videoStream.volume - steps, 0).toFixed(2); + Math.max(videoStream.volume - steps, 0)).toFixed(2); // Save the new volume saveVolume(toPercent(videoStream.volume), options); @@ -152,7 +152,7 @@ function changeVolume(toIncrease, options) { } function setupVolumeOverride(options) { - const video = $('video'); + const video = $('video'); video.addEventListener("canplay", () => { if (typeof options.savedVolume === "number") { From 1e2085b99000d5648d5f8ee5bae97b203150bf13 Mon Sep 17 00:00:00 2001 From: Thymue Date: Mon, 17 May 2021 12:33:43 +0200 Subject: [PATCH 36/67] compressor plugin --- plugins/audio-compressor/front.js | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 plugins/audio-compressor/front.js diff --git a/plugins/audio-compressor/front.js b/plugins/audio-compressor/front.js new file mode 100644 index 00000000..67d7484c --- /dev/null +++ b/plugins/audio-compressor/front.js @@ -0,0 +1,32 @@ +const { + watchDOMElement +} = require("../../providers/dom-elements"); + +let videoElement; + +const applyCompressor = () => { + var audioContext = new AudioContext(); + + var compressor = audioContext.createDynamicsCompressor(); + compressor.threshold.value = -50; + compressor.ratio.value = 12; + compressor.knee.value = 40; + compressor.attack.value = 0; + compressor.release.value = 0.25; + + var source = audioContext.createMediaElementSource(videoElement); + + source.connect(compressor); + compressor.connect(audioContext.destination); +}; + +module.exports = () => { + watchDOMElement( + "video", + (document) => document.querySelector("video"), + (element) => { + videoElement = element; + applyCompressor(); + } + ); +}; From bae5155e1963062938769d19388d37686cb442a5 Mon Sep 17 00:00:00 2001 From: Thymue Date: Mon, 17 May 2021 13:42:27 +0200 Subject: [PATCH 37/67] use let and const instead of var --- plugins/audio-compressor/front.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/audio-compressor/front.js b/plugins/audio-compressor/front.js index 67d7484c..8372a0f4 100644 --- a/plugins/audio-compressor/front.js +++ b/plugins/audio-compressor/front.js @@ -5,16 +5,16 @@ const { let videoElement; const applyCompressor = () => { - var audioContext = new AudioContext(); + const audioContext = new AudioContext(); - var compressor = audioContext.createDynamicsCompressor(); + let compressor = audioContext.createDynamicsCompressor(); compressor.threshold.value = -50; compressor.ratio.value = 12; compressor.knee.value = 40; compressor.attack.value = 0; compressor.release.value = 0.25; - var source = audioContext.createMediaElementSource(videoElement); + const source = audioContext.createMediaElementSource(videoElement); source.connect(compressor); compressor.connect(audioContext.destination); From fd044072a1d2fa6598153cff5564c1119000fa45 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Tue, 18 May 2021 18:53:00 +0300 Subject: [PATCH 38/67] use front `load` event instead of `webcontents.did-finish-load` --- plugins/precise-volume/back.js | 12 ++---------- plugins/precise-volume/front.js | 3 ++- plugins/precise-volume/preload.js | 6 +++--- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/plugins/precise-volume/back.js b/plugins/precise-volume/back.js index 80aeea6a..f891ce32 100644 --- a/plugins/precise-volume/back.js +++ b/plugins/precise-volume/back.js @@ -4,14 +4,6 @@ This is used to determine if plugin is actually active */ let enabled = false; -module.exports = (win) => { - enabled = true; +module.exports = () => enabled = true; - win.webContents.on("did-finish-load", () => { - win.webContents.send("did-finish-load"); - }); -}; - -module.exports.enabled = () => { - return enabled; -}; +module.exports.enabled = () => enabled; diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index b0dd4502..ae8d264b 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -16,7 +16,7 @@ module.exports = (options) => { setupGlobalShortcuts(options); } - ipcRenderer.on("did-finish-load", () => { + window.addEventListener('load', () => { const noVid = $("#main-panel")?.computedStyleMap().get("display").value === "none"; injectVolumeHud(noVid); if (!noVid) { @@ -156,6 +156,7 @@ function setupVolumeOverride(options) { video.addEventListener("canplay", () => { if (typeof options.savedVolume === "number") { + console.log("canplay video called") const newVolume = (options.savedVolume / 100).toFixed(2); video.volume = newVolume; diff --git a/plugins/precise-volume/preload.js b/plugins/precise-volume/preload.js index 6395c3a4..6a0fd482 100644 --- a/plugins/precise-volume/preload.js +++ b/plugins/precise-volume/preload.js @@ -24,10 +24,10 @@ function overrideAddEventListener() { module.exports = () => { overrideAddEventListener(); - // Restore original function after did-finish-load to avoid keeping Element.prototype altered - ipcRenderer.once("did-finish-load", () => { // Called from main to make sure page is completly loaded + // Restore original function after finished loading to avoid keeping Element.prototype altered + window.addEventListener('load', () => { Element.prototype.addEventListener = Element.prototype._addEventListener; Element.prototype._addEventListener = undefined; ignored = undefined; - }); + }, { once: true }); }; From 9b887695858765b25cba71955d2f28b76f053349 Mon Sep 17 00:00:00 2001 From: Araxeus Date: Tue, 18 May 2021 19:02:56 +0300 Subject: [PATCH 39/67] remove leftover console.log --- plugins/precise-volume/front.js | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index ae8d264b..81f810cc 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -156,7 +156,6 @@ function setupVolumeOverride(options) { video.addEventListener("canplay", () => { if (typeof options.savedVolume === "number") { - console.log("canplay video called") const newVolume = (options.savedVolume / 100).toFixed(2); video.volume = newVolume; From 177ad2ce7c7009c218fc2b3f99be489ba7dba9df Mon Sep 17 00:00:00 2001 From: Araxeus Date: Tue, 18 May 2021 19:20:09 +0300 Subject: [PATCH 40/67] minify firstRun() --- plugins/precise-volume/front.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index 81f810cc..a55a889c 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -93,11 +93,10 @@ function writeOptions(options) { /** Restore saved volume and setup tooltip */ function firstRun(options) { - const videoStream = $(".video-stream"); - const slider = $("#volume-slider"); + const video = $("video"); // Those elements load abit after DOMContentLoaded - if (videoStream && slider) { - setupVolumeOverride(options); + if (video) { + setupVolumeOverride(video, options); if (typeof options.savedVolume === "number") { // Set saved volume as tooltip setTooltip(options.savedVolume); @@ -151,9 +150,7 @@ function changeVolume(toIncrease, options) { showVolumeHud(options.savedVolume); } -function setupVolumeOverride(options) { - const video = $('video'); - +function setupVolumeOverride(video, options) { video.addEventListener("canplay", () => { if (typeof options.savedVolume === "number") { const newVolume = (options.savedVolume / 100).toFixed(2); From e99c91ce6ef81fa3ba3d7bba81b5ce17c7e52cc3 Mon Sep 17 00:00:00 2001 From: Thymue Date: Wed, 19 May 2021 21:50:40 +0200 Subject: [PATCH 41/67] get rid of (hopefully) unnecessary watchDOMElement --- plugins/audio-compressor/front.js | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/plugins/audio-compressor/front.js b/plugins/audio-compressor/front.js index 8372a0f4..4f41a4d7 100644 --- a/plugins/audio-compressor/front.js +++ b/plugins/audio-compressor/front.js @@ -1,10 +1,12 @@ -const { - watchDOMElement -} = require("../../providers/dom-elements"); - -let videoElement; - const applyCompressor = () => { + const videoElement = document.querySelector("video"); + + // If video element is not loaded yet try again + if(videoElement === null) { + setTimeout(applyCompressor, 500); + return; + } + const audioContext = new AudioContext(); let compressor = audioContext.createDynamicsCompressor(); @@ -20,13 +22,4 @@ const applyCompressor = () => { compressor.connect(audioContext.destination); }; -module.exports = () => { - watchDOMElement( - "video", - (document) => document.querySelector("video"), - (element) => { - videoElement = element; - applyCompressor(); - } - ); -}; +module.exports = applyCompressor; \ No newline at end of file From 52a4608d764a3c81032179ca6e14e00161a20482 Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Tue, 20 Jul 2021 10:57:32 +0300 Subject: [PATCH 42/67] create options.global if needed --- plugins/shortcuts/menu.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/shortcuts/menu.js b/plugins/shortcuts/menu.js index cef14665..20f21233 100644 --- a/plugins/shortcuts/menu.js +++ b/plugins/shortcuts/menu.js @@ -41,6 +41,9 @@ async function promptKeybind(options, win) { }, win); if (output) { + if (!options.global) { + options.global = {}; + } for (const { value, accelerator } of output) { options.global[value] = accelerator; } From 88ee0fb9893438637a2c47420a788f24a040f42f Mon Sep 17 00:00:00 2001 From: Manish Date: Wed, 13 Oct 2021 12:26:38 +0530 Subject: [PATCH 43/67] fix: mpris was not registering itself before. Sorry I missed that somehow, because playerctl controls were working. That was because of chromium was also registering itself for mpris. --- plugins/shortcuts/back.js | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/plugins/shortcuts/back.js b/plugins/shortcuts/back.js index ba12ba42..cbbcc7ea 100644 --- a/plugins/shortcuts/back.js +++ b/plugins/shortcuts/back.js @@ -1,9 +1,11 @@ const { globalShortcut } = require("electron"); const is = require("electron-is"); const electronLocalshortcut = require("electron-localshortcut"); - const getSongControls = require("../../providers/song-controls"); const { setupMPRIS } = require("./mpris"); +const registerCallback = require("../../providers/song-info"); + +let player; function _registerGlobalShortcut(webContents, shortcut, action) { globalShortcut.register(shortcut, () => { @@ -26,18 +28,41 @@ function registerShortcuts(win, options) { _registerGlobalShortcut(win.webContents, "MediaPreviousTrack", previous); _registerLocalShortcut(win, "CommandOrControl+F", search); _registerLocalShortcut(win, "CommandOrControl+L", search); + registerCallback(songInfo => { + player.metadata = { + 'mpris:length': songInfo.songDuration * 60 * 1000 * 1000, // In microseconds + 'mpris:artUrl': songInfo.imageSrc, + 'xesam:title': songInfo.title, + 'xesam:artist': songInfo.artist + }; + } + ) if (is.linux()) { try { - const player = setupMPRIS(); - - player.on("raise", () => { + const MPRISPlayer = setupMPRIS(); + player = MPRISPlayer + MPRISPlayer.on("raise", () => { win.setSkipTaskbar(false); win.show(); }); - player.on("playpause", playPause); - player.on("next", next); - player.on("previous", previous); + MPRISPlayer.on("play", () => { + console.log('Event:', "play", arguments); + player.playbackStatus = 'Playing'; + playPause() + }); + MPRISPlayer.on("pause", () => { + console.log('Event:', "pause", arguments); + player.playbackStatus = 'Paused'; + playPause() + }); + MPRISPlayer.on("next", () => { + next() + }); + MPRISPlayer.on("previous", () => { + previous() + }); + } catch (e) { console.warn("Error in MPRIS", e); } From a76f12c01c1227d32fa8f24b81e9bcba4f43b0f8 Mon Sep 17 00:00:00 2001 From: Manish Date: Wed, 13 Oct 2021 12:27:13 +0530 Subject: [PATCH 44/67] feat: add play and pause seperate song controller. --- plugins/shortcuts/back.js | 15 +++++++++------ providers/song-controls-front.js | 18 ++++++++++++++++++ providers/song-controls.js | 2 ++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/plugins/shortcuts/back.js b/plugins/shortcuts/back.js index cbbcc7ea..dc711da1 100644 --- a/plugins/shortcuts/back.js +++ b/plugins/shortcuts/back.js @@ -21,7 +21,7 @@ function _registerLocalShortcut(win, shortcut, action) { function registerShortcuts(win, options) { const songControls = getSongControls(win); - const { playPause, next, previous, search } = songControls; + const { play, pause, playPause, next, previous, search } = songControls; _registerGlobalShortcut(win.webContents, "MediaPlayPause", playPause); _registerGlobalShortcut(win.webContents, "MediaNextTrack", next); @@ -41,20 +41,21 @@ function registerShortcuts(win, options) { if (is.linux()) { try { const MPRISPlayer = setupMPRIS(); - player = MPRISPlayer + MPRISPlayer.on("raise", () => { win.setSkipTaskbar(false); win.show(); }); + MPRISPlayer.on("playPause", () => { + console.log("Playpause"); + }) MPRISPlayer.on("play", () => { - console.log('Event:', "play", arguments); player.playbackStatus = 'Playing'; - playPause() + play() }); MPRISPlayer.on("pause", () => { - console.log('Event:', "pause", arguments); player.playbackStatus = 'Paused'; - playPause() + pause() }); MPRISPlayer.on("next", () => { next() @@ -63,6 +64,8 @@ function registerShortcuts(win, options) { previous() }); + player = MPRISPlayer + } catch (e) { console.warn("Error in MPRIS", e); } diff --git a/providers/song-controls-front.js b/providers/song-controls-front.js index 1860e761..9283a0b8 100644 --- a/providers/song-controls-front.js +++ b/providers/song-controls-front.js @@ -15,4 +15,22 @@ module.exports = () => { videoStream.pause(); } }); + + ipcRenderer.on("play", () => { + if (!videoStream) { + videoStream = document.querySelector(".video-stream"); + } + + if (videoStream.paused) videoStream.play(); + }); + + ipcRenderer.on("pause", () => { + if (!videoStream) { + videoStream = document.querySelector(".video-stream"); + } + + videoStream.yns_pause ? + videoStream.yns_pause() : + videoStream.pause(); + }); }; diff --git a/providers/song-controls.js b/providers/song-controls.js index 5d3ad953..27be8822 100644 --- a/providers/song-controls.js +++ b/providers/song-controls.js @@ -13,6 +13,8 @@ module.exports = (win) => { previous: () => pressKey(win, "k"), next: () => pressKey(win, "j"), playPause: () => win.webContents.send("playPause"), + play: () => win.webContents.send("play"), + pause: () => win.webContents.send("pause"), like: () => pressKey(win, "_"), dislike: () => pressKey(win, "+"), go10sBack: () => pressKey(win, "h"), From 81fb5118aab95b81e5d7c8265ab7c63069a3df3e Mon Sep 17 00:00:00 2001 From: Manish Date: Thu, 14 Oct 2021 10:16:36 +0530 Subject: [PATCH 45/67] fix: don't create play pause method unneccessarily --- plugins/shortcuts/back.js | 31 +++++++++++++++++-------------- providers/song-controls-front.js | 18 ------------------ 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/plugins/shortcuts/back.js b/plugins/shortcuts/back.js index dc711da1..d3fb2dc7 100644 --- a/plugins/shortcuts/back.js +++ b/plugins/shortcuts/back.js @@ -21,7 +21,7 @@ function _registerLocalShortcut(win, shortcut, action) { function registerShortcuts(win, options) { const songControls = getSongControls(win); - const { play, pause, playPause, next, previous, search } = songControls; + const { playPause, next, previous, search } = songControls; _registerGlobalShortcut(win.webContents, "MediaPlayPause", playPause); _registerGlobalShortcut(win.webContents, "MediaNextTrack", next); @@ -29,12 +29,14 @@ function registerShortcuts(win, options) { _registerLocalShortcut(win, "CommandOrControl+F", search); _registerLocalShortcut(win, "CommandOrControl+L", search); registerCallback(songInfo => { - player.metadata = { - 'mpris:length': songInfo.songDuration * 60 * 1000 * 1000, // In microseconds - 'mpris:artUrl': songInfo.imageSrc, - 'xesam:title': songInfo.title, - 'xesam:artist': songInfo.artist - }; + if (player) { + player.metadata = { + 'mpris:length': songInfo.songDuration * 60 * 1000 * 1000, // In microseconds + 'mpris:artUrl': songInfo.imageSrc, + 'xesam:title': songInfo.title, + 'xesam:artist': songInfo.artist + }; + } } ) @@ -46,16 +48,17 @@ function registerShortcuts(win, options) { win.setSkipTaskbar(false); win.show(); }); - MPRISPlayer.on("playPause", () => { - console.log("Playpause"); - }) MPRISPlayer.on("play", () => { - player.playbackStatus = 'Playing'; - play() + if (MPRISPlayer.playbackStatus !== 'Playing') { + MPRISPlayer.playbackStatus = 'Playing'; + playPause() + } }); MPRISPlayer.on("pause", () => { - player.playbackStatus = 'Paused'; - pause() + if (MPRISPlayer.playbackStatus === 'Playing') { + MPRISPlayer.playbackStatus = 'Paused'; + playPause() + } }); MPRISPlayer.on("next", () => { next() diff --git a/providers/song-controls-front.js b/providers/song-controls-front.js index 9283a0b8..1860e761 100644 --- a/providers/song-controls-front.js +++ b/providers/song-controls-front.js @@ -15,22 +15,4 @@ module.exports = () => { videoStream.pause(); } }); - - ipcRenderer.on("play", () => { - if (!videoStream) { - videoStream = document.querySelector(".video-stream"); - } - - if (videoStream.paused) videoStream.play(); - }); - - ipcRenderer.on("pause", () => { - if (!videoStream) { - videoStream = document.querySelector(".video-stream"); - } - - videoStream.yns_pause ? - videoStream.yns_pause() : - videoStream.pause(); - }); }; From 361606427a2509893c8bf457cdcce5da49ebf6a9 Mon Sep 17 00:00:00 2001 From: Manish Date: Thu, 14 Oct 2021 10:18:05 +0530 Subject: [PATCH 46/67] fix: remove unused play pause functions --- providers/song-controls.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/providers/song-controls.js b/providers/song-controls.js index 27be8822..5d3ad953 100644 --- a/providers/song-controls.js +++ b/providers/song-controls.js @@ -13,8 +13,6 @@ module.exports = (win) => { previous: () => pressKey(win, "k"), next: () => pressKey(win, "j"), playPause: () => win.webContents.send("playPause"), - play: () => win.webContents.send("play"), - pause: () => win.webContents.send("pause"), like: () => pressKey(win, "_"), dislike: () => pressKey(win, "+"), go10sBack: () => pressKey(win, "h"), From f7a1de05c82e2e9d88a2ecfef4e7369b19e12045 Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Fri, 15 Oct 2021 05:41:47 +0300 Subject: [PATCH 47/67] defensive coding --- plugins/precise-volume/front.js | 50 ++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index a55a889c..3abbbb17 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -8,8 +8,6 @@ module.exports = (options) => { setupPlaybar(options); - setupSliderObserver(options); - setupLocalArrowShortcuts(options); if (options.globalShortcuts?.enabled) { @@ -109,6 +107,10 @@ function firstRun(options) { /** Add onwheel event to play bar and also track if play bar is hovered*/ function setupPlaybar(options) { const playerbar = $("ytmusic-player-bar"); + if (!playerbar) { + setTimeout(setupPlaybar(options), 200); + return; + } playerbar.addEventListener("wheel", event => { event.preventDefault(); @@ -124,6 +126,29 @@ function setupPlaybar(options) { playerbar.addEventListener("mouseleave", () => { playerbar.classList.remove("on-hover"); }); + + setupSliderObserver(options); +} + +/** Save volume + Update the volume tooltip when volume-slider is manually changed */ +function setupSliderObserver(options) { + const sliderObserver = new MutationObserver(mutations => { + for (const mutation of mutations) { + // This checks that volume-slider was manually set + if (mutation.oldValue !== mutation.target.value && + (typeof options.savedVolume !== "number" || Math.abs(options.savedVolume - mutation.target.value) > 4)) { + // Diff>4 means it was manually set + setTooltip(mutation.target.value); + saveVolume(mutation.target.value, options); + } + } + }); + + // Observing only changes in 'value' of volume-slider + sliderObserver.observe($("#volume-slider"), { + attributeFilter: ["value"], + attributeOldValue: true + }); } /** if (toIncrease = false) then volume decrease */ @@ -194,27 +219,6 @@ function showVolumeSlider() { }, 3000); } -/** Save volume + Update the volume tooltip when volume-slider is manually changed */ -function setupSliderObserver(options) { - const sliderObserver = new MutationObserver(mutations => { - for (const mutation of mutations) { - // This checks that volume-slider was manually set - if (mutation.oldValue !== mutation.target.value && - (typeof options.savedVolume !== "number" || Math.abs(options.savedVolume - mutation.target.value) > 4)) { - // Diff>4 means it was manually set - setTooltip(mutation.target.value); - saveVolume(mutation.target.value, options); - } - } - }); - - // Observing only changes in 'value' of volume-slider - sliderObserver.observe($("#volume-slider"), { - attributeFilter: ["value"], - attributeOldValue: true - }); -} - // Set new volume as tooltip for volume slider and icon + expanding slider (appears when window size is small) const tooltipTargets = [ "#volume-slider", From dda18a72afaf07c5971833cab79fedf335061385 Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Fri, 15 Oct 2021 14:38:09 +0300 Subject: [PATCH 48/67] new auto confirm when paused --- package.json | 4 +--- plugins/auto-confirm-when-paused/front.js | 12 ------------ preload.js | 10 ++++++---- providers/song-controls-front.js | 18 ------------------ providers/song-controls.js | 2 +- readme.md | 2 +- yarn.lock | 4 ---- 7 files changed, 9 insertions(+), 43 deletions(-) delete mode 100644 plugins/auto-confirm-when-paused/front.js delete mode 100644 providers/song-controls-front.js diff --git a/package.json b/package.json index 6920b186..a428d1de 100644 --- a/package.json +++ b/package.json @@ -52,9 +52,8 @@ "build:mac": "yarn run clean && electron-builder --mac", "build:win": "yarn run clean && electron-builder --win", "lint": "xo", - "plugins": "yarn run plugin:adblocker && yarn run plugin:autoconfirm", + "plugins": "yarn run plugin:adblocker", "plugin:adblocker": "rimraf plugins/adblocker/ad-blocker-engine.bin && node plugins/adblocker/blocker.js", - "plugin:autoconfirm": "yarn run generate:package YoutubeNonStop", "release:linux": "yarn run clean && electron-builder --linux -p always -c.snap.publish=github", "release:mac": "yarn run clean && electron-builder --mac -p always", "release:win": "yarn run clean && electron-builder --win -p always" @@ -67,7 +66,6 @@ "@cliqz/adblocker-electron": "^1.22.5", "@ffmpeg/core": "^0.10.0", "@ffmpeg/ffmpeg": "^0.10.0", - "YoutubeNonStop": "git://github.com/lawfx/YoutubeNonStop.git#v0.9.0", "async-mutex": "^0.3.1", "browser-id3-writer": "^4.4.0", "chokidar": "^3.5.2", diff --git a/plugins/auto-confirm-when-paused/front.js b/plugins/auto-confirm-when-paused/front.js deleted file mode 100644 index 0ead302e..00000000 --- a/plugins/auto-confirm-when-paused/front.js +++ /dev/null @@ -1,12 +0,0 @@ -// Define global chrome object to be compliant with the extension code -global.chrome = { - runtime: { - getManifest: () => ({ - version: 1 - }) - } -}; - -module.exports = () => { - require("YoutubeNonStop/autoconfirm.js"); -}; diff --git a/preload.js b/preload.js index 5a09c845..3451be18 100644 --- a/preload.js +++ b/preload.js @@ -5,7 +5,6 @@ const { remote } = require("electron"); const config = require("./config"); const { fileExists } = require("./plugins/utils"); const setupFrontLogger = require("./providers/front-logger"); -const setupSongControl = require("./providers/song-controls-front"); const setupSongInfo = require("./providers/song-info-front"); const plugins = config.plugins.getEnabled(); @@ -41,13 +40,16 @@ document.addEventListener("DOMContentLoaded", () => { // inject song-info provider setupSongInfo(); - // inject song-control provider - setupSongControl(); - // inject front logger setupFrontLogger(); // Add action for reloading global.reload = () => remote.getCurrentWindow().webContents.loadURL(config.get("url")); + + // Block "You still there?" popup by setting last active time to date.now every 15min + const activityScript = document.createElement('script'); + activityScript.textContent = `setInterval(() => window._lact = Date.now(), 900000);`; + (document.head || document.documentElement).appendChild(activityScript); + activityScript.remove(); }); diff --git a/providers/song-controls-front.js b/providers/song-controls-front.js deleted file mode 100644 index 1860e761..00000000 --- a/providers/song-controls-front.js +++ /dev/null @@ -1,18 +0,0 @@ -const { ipcRenderer } = require("electron"); - -let videoStream = document.querySelector(".video-stream"); -module.exports = () => { - ipcRenderer.on("playPause", () => { - if (!videoStream) { - videoStream = document.querySelector(".video-stream"); - } - - if (videoStream.paused) { - videoStream.play(); - } else { - videoStream.yns_pause ? - videoStream.yns_pause() : - videoStream.pause(); - } - }); -}; diff --git a/providers/song-controls.js b/providers/song-controls.js index 5d3ad953..7f43df11 100644 --- a/providers/song-controls.js +++ b/providers/song-controls.js @@ -12,7 +12,7 @@ module.exports = (win) => { // Playback previous: () => pressKey(win, "k"), next: () => pressKey(win, "j"), - playPause: () => win.webContents.send("playPause"), + playPause: () => pressKey(win, "space"), like: () => pressKey(win, "_"), dislike: () => pressKey(win, "+"), go10sBack: () => pressKey(win, "h"), diff --git a/readme.md b/readme.md index c47170c1..46ef0e9e 100644 --- a/readme.md +++ b/readme.md @@ -35,7 +35,6 @@ Install the `youtube-music-bin` package from the AUR. For AUR installation instr ## Available plugins: - **Ad Blocker**: block all ads and tracking out of the box -- **Auto confirm when paused**: when the ["Continue Watching?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png) modal appears, automatically click "Yes" - **Disable autoplay**: makes every song start in "paused" mode - [**Discord**](https://discord.com/): show your friends what you listen to with [Rich Presence](https://user-images.githubusercontent.com/28219076/104362104-a7a0b980-5513-11eb-9744-bb89eabe0016.png) - **Downloader**: downloads MP3 [directly from the interface](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl) @@ -51,6 +50,7 @@ Install the `youtube-music-bin` package from the AUR. For AUR installation instr - [**SponsorBlock**](https://github.com/ajayyy/SponsorBlock): skips non-music parts - **Taskbar media control**: control app from your [Windows taskbar](https://user-images.githubusercontent.com/78568641/111916130-24a35e80-8a82-11eb-80c8-5021c1aa27f4.png) - **Touchbar**: custom TouchBar layout for macOS +- **Auto confirm when paused** (Always Enabled): disable the ["Continue Watching?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png) popup that pause music after a certain time ## Dev diff --git a/yarn.lock b/yarn.lock index 743fcc50..c64f6d20 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1523,10 +1523,6 @@ dependencies: "@wdio/logger" "6.10.10" -"YoutubeNonStop@git://github.com/lawfx/YoutubeNonStop.git#v0.9.0": - version "0.0.0" - resolved "git://github.com/lawfx/YoutubeNonStop.git#7b6b97b31bb3fd2078179660db0fd3fcc7062259" - abab@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" From ce4580605df07ae25eb4535508be2dd4415c55e5 Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Fri, 15 Oct 2021 15:40:34 +0300 Subject: [PATCH 49/67] remove upgrade button + makes img unselectable --- menu.js | 8 ++++++++ preload.js | 5 +++++ youtube-music.css | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/menu.js b/menu.js index 72b2cc66..b179e188 100644 --- a/menu.js +++ b/menu.js @@ -76,6 +76,14 @@ const mainMenuTemplate = (win) => { config.set("options.resumeOnStart", item.checked); }, }, + { + label: "Remove upgrade button", + type: "checkbox", + checked: config.get("options.removeUpgradeButton"), + click: (item) => { + config.set("options.removeUpgradeButton", item.checked); + }, + }, ...(is.windows() || is.linux() ? [ { diff --git a/preload.js b/preload.js index 5a09c845..aa213071 100644 --- a/preload.js +++ b/preload.js @@ -38,6 +38,11 @@ document.addEventListener("DOMContentLoaded", () => { }); }); + // Remove upgrade button + if (config.get("options.removeUpgradeButton")) { + document.querySelector('[tab-id*="SPunlimited"]').style.display = "none"; + } + // inject song-info provider setupSongInfo(); diff --git a/youtube-music.css b/youtube-music.css index fe5eb326..67a74dc0 100644 --- a/youtube-music.css +++ b/youtube-music.css @@ -28,3 +28,9 @@ ytmusic-search-box.ytmusic-nav-bar { ytmusic-mealbar-promo-renderer { display: none !important; } + +/* Disable Image Selection */ +img { + -webkit-user-select: none; + user-select: none; +} From 79d0c7b666f64091a49cff11c9688085c89c4222 Mon Sep 17 00:00:00 2001 From: Manish Date: Sun, 17 Oct 2021 10:54:05 +0530 Subject: [PATCH 50/67] fix: typo --- plugins/shortcuts/back.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/shortcuts/back.js b/plugins/shortcuts/back.js index d3fb2dc7..9bb01d07 100644 --- a/plugins/shortcuts/back.js +++ b/plugins/shortcuts/back.js @@ -55,7 +55,7 @@ function registerShortcuts(win, options) { } }); MPRISPlayer.on("pause", () => { - if (MPRISPlayer.playbackStatus === 'Playing') { + if (MPRISPlayer.playbackStatus !== 'Paused') { MPRISPlayer.playbackStatus = 'Paused'; playPause() } From 663507b3f80074898a43bbab764529bfc9d432dc Mon Sep 17 00:00:00 2001 From: Manish Date: Sun, 17 Oct 2021 11:06:26 +0530 Subject: [PATCH 51/67] fix: player status when play at start --- plugins/shortcuts/back.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/shortcuts/back.js b/plugins/shortcuts/back.js index 9bb01d07..0184ffb3 100644 --- a/plugins/shortcuts/back.js +++ b/plugins/shortcuts/back.js @@ -36,6 +36,9 @@ function registerShortcuts(win, options) { 'xesam:title': songInfo.title, 'xesam:artist': songInfo.artist }; + if (!songInfo.isPaused) { + player.playbackStatus = "Playing" + } } } ) From 4d4dacbc711fe9b784681dee63bc128da5683a98 Mon Sep 17 00:00:00 2001 From: Constantin Piber Date: Tue, 19 Oct 2021 18:40:27 +0200 Subject: [PATCH 52/67] discord: clean up export (follow-up #380) --- plugins/discord/back.js | 5 +---- plugins/discord/menu.js | 6 +++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/plugins/discord/back.js b/plugins/discord/back.js index 3c3ab5fd..9dc6f9fe 100644 --- a/plugins/discord/back.js +++ b/plugins/discord/back.js @@ -145,7 +145,4 @@ module.exports.clear = () => { }; module.exports.connect = connect; module.exports.registerRefresh = (cb) => refreshCallbacks.push(cb); -/** - * @type {Info} - */ -module.exports.info = Object.defineProperties({}, Object.keys(info).reduce((o, k) => ({ ...o, [k]: { enumerable: true, get: () => info[k] } }), {})); +module.exports.isConnected = () => info.rpc !== null; diff --git a/plugins/discord/menu.js b/plugins/discord/menu.js index 9750dabe..49a087d6 100644 --- a/plugins/discord/menu.js +++ b/plugins/discord/menu.js @@ -1,6 +1,6 @@ const { setOptions } = require("../../config/plugins"); const { edit } = require("../../config"); -const { clear, info, connect, registerRefresh } = require("./back"); +const { clear, connect, registerRefresh, isConnected } = require("./back"); let hasRegisterred = false; @@ -12,8 +12,8 @@ module.exports = (win, options, refreshMenu) => { return [ { - label: info.rpc !== null ? "Connected" : "Reconnect", - enabled: info.rpc === null, + label: isConnected() ? "Connected" : "Reconnect", + enabled: !isConnected(), click: connect, }, { From 831b1ea8e12afde9bf31b2259efcc0eaeea30b45 Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Sat, 23 Oct 2021 15:21:49 +0300 Subject: [PATCH 53/67] access window._lact directly --- preload.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/preload.js b/preload.js index 3451be18..6f890e6a 100644 --- a/preload.js +++ b/preload.js @@ -47,9 +47,6 @@ document.addEventListener("DOMContentLoaded", () => { global.reload = () => remote.getCurrentWindow().webContents.loadURL(config.get("url")); - // Block "You still there?" popup by setting last active time to date.now every 15min - const activityScript = document.createElement('script'); - activityScript.textContent = `setInterval(() => window._lact = Date.now(), 900000);`; - (document.head || document.documentElement).appendChild(activityScript); - activityScript.remove(); + // Blocks the "Are You Still There?" popup by setting the last active time to Date.now every 15min + setInterval(() => window._lact = Date.now(), 900000); }); From c897bedd9019c79458d997384f542bda9ee93424 Mon Sep 17 00:00:00 2001 From: cdaydreamer <61342411+cdaydreamer@users.noreply.github.com> Date: Sat, 23 Oct 2021 15:38:46 +0300 Subject: [PATCH 54/67] New plugin: Blur navigation bar --- plugins/blur-nav-bar/back.js | 6 ++++++ plugins/blur-nav-bar/style.css | 8 ++++++++ readme.md | 1 + 3 files changed, 15 insertions(+) create mode 100644 plugins/blur-nav-bar/back.js create mode 100644 plugins/blur-nav-bar/style.css diff --git a/plugins/blur-nav-bar/back.js b/plugins/blur-nav-bar/back.js new file mode 100644 index 00000000..1c95289f --- /dev/null +++ b/plugins/blur-nav-bar/back.js @@ -0,0 +1,6 @@ +const path = require("path"); +const { injectCSS } = require("../utils"); + +module.exports = win => { + injectCSS(win.webContents, path.join(__dirname, "style.css")); +}; diff --git a/plugins/blur-nav-bar/style.css b/plugins/blur-nav-bar/style.css new file mode 100644 index 00000000..e64b7526 --- /dev/null +++ b/plugins/blur-nav-bar/style.css @@ -0,0 +1,8 @@ +#nav-bar-background { + background: rgba(0, 0, 0, 0.3) !important; + backdrop-filter: blur(18px) !important; +} + +#nav-bar-divider { + display: none !important; +} diff --git a/readme.md b/readme.md index c47170c1..4a704638 100644 --- a/readme.md +++ b/readme.md @@ -36,6 +36,7 @@ Install the `youtube-music-bin` package from the AUR. For AUR installation instr ## Available plugins: - **Ad Blocker**: block all ads and tracking out of the box - **Auto confirm when paused**: when the ["Continue Watching?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png) modal appears, automatically click "Yes" +- **Blur navigation bar**: makes navigation bar transparent and blurry - **Disable autoplay**: makes every song start in "paused" mode - [**Discord**](https://discord.com/): show your friends what you listen to with [Rich Presence](https://user-images.githubusercontent.com/28219076/104362104-a7a0b980-5513-11eb-9744-bb89eabe0016.png) - **Downloader**: downloads MP3 [directly from the interface](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl) From 51364b63e7b7cb9cc2b33266bba9b2852b769dfe Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Sat, 23 Oct 2021 16:13:06 +0300 Subject: [PATCH 55/67] get songInfo from youtube API --- providers/song-info-front.js | 42 ++++++++++++++++++++---------------- providers/song-info.js | 39 ++++++++++++--------------------- 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/providers/song-info-front.js b/providers/song-info-front.js index fccc54a8..25cea261 100644 --- a/providers/song-info-front.js +++ b/providers/song-info-front.js @@ -9,23 +9,27 @@ ipcRenderer.on("update-song-info", async (_, extractedSongInfo) => { global.songInfo.image = await getImage(global.songInfo.imageSrc); }); -const injectListener = () => { - const oldXHR = window.XMLHttpRequest; - function newXHR() { - const realXHR = new oldXHR(); - realXHR.addEventListener( - "readystatechange", - () => { - if (realXHR.readyState === 4 && realXHR.status === 200 - && realXHR.responseURL.includes("/player")) { - // if the request contains the song info, send the response to ipcMain - ipcRenderer.send("song-info-request", realXHR.responseText); - } - }, - false - ); - return realXHR; - } - window.XMLHttpRequest = newXHR; +function setup() { + if (document.querySelector('#movie_player')) { + injectListener(); + return; + } + + const observer = new MutationObserver(() => { + if (document.querySelector('#movie_player')) { + observer.disconnect(); + injectListener(); + } + }) + + observer.observe(document.documentElement, { childList: true, subtree: true }); +} + +function injectListener() { + document.querySelector('video').addEventListener('loadedmetadata', () => { + const data = document.querySelector('#movie_player').getPlayerResponse(); + ipcRenderer.send("song-info-request", JSON.stringify(data)); + }); }; -module.exports = injectListener; + +module.exports = setup; diff --git a/providers/song-info.js b/providers/song-info.js index 6e5a119c..d386e23a 100644 --- a/providers/song-info.js +++ b/providers/song-info.js @@ -2,15 +2,11 @@ const { ipcMain, nativeImage } = require("electron"); const fetch = require("node-fetch"); -// This selects the progress bar, used for current progress -const progressSelector = "#progress-bar"; - - // Grab the progress using the selector const getProgress = async (win) => { // Get current value of the progressbar element return win.webContents.executeJavaScript( - 'document.querySelector("' + progressSelector + '").value' + 'document.querySelector("#progress-bar").value' ); }; @@ -29,16 +25,10 @@ const getImage = async (src) => { // To find the paused status, we check if the title contains `-` const getPausedStatus = async (win) => { const title = await win.webContents.executeJavaScript("document.title"); + console.log('doc title = ',title) return !title.includes("-"); }; -const getArtist = async (win) => { - return win.webContents.executeJavaScript(` - document.querySelector(".subtitle.ytmusic-player-bar .yt-formatted-string") - ?.textContent - `); -} - // Fill songInfo with empty values /** * @typedef {songInfo} SongInfo @@ -59,14 +49,13 @@ const songInfo = { const handleData = async (responseText, win) => { let data = JSON.parse(responseText); songInfo.title = cleanupName(data?.videoDetails?.title); - songInfo.artist = - (await getArtist(win)) || cleanupName(data?.videoDetails?.author); + songInfo.artist =cleanupName(data?.videoDetails?.author); songInfo.views = data?.videoDetails?.viewCount; songInfo.imageSrc = data?.videoDetails?.thumbnail?.thumbnails?.pop()?.url; songInfo.songDuration = data?.videoDetails?.lengthSeconds; songInfo.image = await getImage(songInfo.imageSrc); songInfo.uploadDate = data?.microformat?.microformatDataRenderer?.uploadDate; - songInfo.url = data?.microformat?.microformatDataRenderer?.urlCanonical; + songInfo.url = data?.microformat?.microformatDataRenderer?.urlCanonical?.split("&")[0]; win.webContents.send("update-song-info", JSON.stringify(songInfo)); }; @@ -111,19 +100,19 @@ const registerProvider = (win) => { }; const suffixesToRemove = [ - " - Topic", - "VEVO", - " (Performance Video)", - " (Official Music Video)", - " (Official Video)", - " (Clip officiel)", + " - topic", + "vevo", + " (performance video)", + " (official music video)", + " (official video)", + " (clip officiel)", ]; + function cleanupName(artist) { - if (!artist) { - return artist; - } + if (!artist) return artist; + const lowerCaseArtist = artist.toLowerCase(); for (const suffix of suffixesToRemove) { - if (artist.endsWith(suffix)) { + if (lowerCaseArtist.endsWith(suffix)) { return artist.slice(0, -suffix.length); } } From 2224786478ce99b00473a52780aebc073e8fd463 Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Sat, 23 Oct 2021 16:19:45 +0300 Subject: [PATCH 56/67] lint --- providers/song-info-front.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/providers/song-info-front.js b/providers/song-info-front.js index 25cea261..ccf0b764 100644 --- a/providers/song-info-front.js +++ b/providers/song-info-front.js @@ -4,30 +4,33 @@ const { getImage } = require("./song-info"); global.songInfo = {}; +let api = document.querySelector('#movie_player'); + ipcRenderer.on("update-song-info", async (_, extractedSongInfo) => { global.songInfo = JSON.parse(extractedSongInfo); global.songInfo.image = await getImage(global.songInfo.imageSrc); }); function setup() { - if (document.querySelector('#movie_player')) { - injectListener(); - return; - } + if (api) { + injectListener(); + return; + } - const observer = new MutationObserver(() => { - if (document.querySelector('#movie_player')) { - observer.disconnect(); - injectListener(); - } - }) + const observer = new MutationObserver(() => { + api = document.querySelector('#movie_player'); + if (api) { + observer.disconnect(); + injectListener(); + } + }) - observer.observe(document.documentElement, { childList: true, subtree: true }); + observer.observe(document.documentElement, { childList: true, subtree: true }); } function injectListener() { document.querySelector('video').addEventListener('loadedmetadata', () => { - const data = document.querySelector('#movie_player').getPlayerResponse(); + const data = api.getPlayerResponse(); ipcRenderer.send("song-info-request", JSON.stringify(data)); }); }; From 978aca1f9aac3148909d20f69d0e52ea11d6cb08 Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Sat, 23 Oct 2021 16:21:42 +0300 Subject: [PATCH 57/67] use loadeddata instead of loadedmetadata send event closer to actual initial start time of video --- providers/song-info-front.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/song-info-front.js b/providers/song-info-front.js index ccf0b764..674faeb7 100644 --- a/providers/song-info-front.js +++ b/providers/song-info-front.js @@ -29,7 +29,7 @@ function setup() { } function injectListener() { - document.querySelector('video').addEventListener('loadedmetadata', () => { + document.querySelector('video').addEventListener('loadeddata', () => { const data = api.getPlayerResponse(); ipcRenderer.send("song-info-request", JSON.stringify(data)); }); From 2d518abc1931ee06213cc59b78aa03fd1a3dc3fc Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Sat, 23 Oct 2021 16:26:45 +0300 Subject: [PATCH 58/67] remove leftover console.log --- providers/song-info.js | 1 - 1 file changed, 1 deletion(-) diff --git a/providers/song-info.js b/providers/song-info.js index d386e23a..f88d4103 100644 --- a/providers/song-info.js +++ b/providers/song-info.js @@ -25,7 +25,6 @@ const getImage = async (src) => { // To find the paused status, we check if the title contains `-` const getPausedStatus = async (win) => { const title = await win.webContents.executeJavaScript("document.title"); - console.log('doc title = ',title) return !title.includes("-"); }; From bb2e1bd61604975a264cdee00d82dcd099728eca Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Sat, 23 Oct 2021 16:57:44 +0300 Subject: [PATCH 59/67] use youtube native api to change volume --- plugins/precise-volume/front.js | 94 ++++++++++++++------------------- 1 file changed, 39 insertions(+), 55 deletions(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index 3abbbb17..8f323fd1 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -3,8 +3,36 @@ const { ipcRenderer, remote } = require("electron"); const { setOptions } = require("../../config/plugins"); function $(selector) { return document.querySelector(selector); } +let api = $('#movie_player'); module.exports = (options) => { + if (api) { + firstRun(options); + return; + } + + const observer = new MutationObserver(() => { + api = $('#movie_player'); + if (api) { + observer.disconnect(); + firstRun(options); + } + }) + + observer.observe(document.documentElement, { childList: true, subtree: true }); +}; + + +/** Restore saved volume and setup tooltip */ +function firstRun(options) { + if (typeof options.savedVolume === "number") { + // Set saved volume as tooltip + setTooltip(options.savedVolume); + + if (api.getVolume() !== options.savedVolume) { + api.setVolume(options.savedVolume); + } + } setupPlaybar(options); @@ -14,16 +42,12 @@ module.exports = (options) => { setupGlobalShortcuts(options); } - window.addEventListener('load', () => { - const noVid = $("#main-panel")?.computedStyleMap().get("display").value === "none"; - injectVolumeHud(noVid); - if (!noVid) { - setupVideoPlayerOnwheel(options); - } - }); - - firstRun(options); -}; + const noVid = $("#main-panel")?.computedStyleMap().get("display").value === "none"; + injectVolumeHud(noVid); + if (!noVid) { + setupVideoPlayerOnwheel(options); + } +} function injectVolumeHud(noVid) { if (noVid) { @@ -89,28 +113,9 @@ function writeOptions(options) { }, 1500) } -/** Restore saved volume and setup tooltip */ -function firstRun(options) { - const video = $("video"); - // Those elements load abit after DOMContentLoaded - if (video) { - setupVolumeOverride(video, options); - if (typeof options.savedVolume === "number") { - // Set saved volume as tooltip - setTooltip(options.savedVolume); - } - } else { - setTimeout(firstRun, 500, options); // Try again in 500 milliseconds - } -} - /** Add onwheel event to play bar and also track if play bar is hovered*/ function setupPlaybar(options) { const playerbar = $("ytmusic-player-bar"); - if (!playerbar) { - setTimeout(setupPlaybar(options), 200); - return; - } playerbar.addEventListener("wheel", event => { event.preventDefault(); @@ -153,16 +158,14 @@ function setupSliderObserver(options) { /** if (toIncrease = false) then volume decrease */ function changeVolume(toIncrease, options) { - // Need to change both the actual volume and the slider - const videoStream = $(".video-stream"); // Apply volume change if valid - const steps = (options.steps || 1) / 100; - videoStream.volume = (toIncrease ? - Math.min(videoStream.volume + steps, 1) : - Math.max(videoStream.volume - steps, 0)).toFixed(2); + const steps = (options.steps || 1); + api.setVolume(toIncrease ? + Math.min(api.getVolume() + steps, 100) : + Math.max(api.getVolume() - steps, 0)); // Save the new volume - saveVolume(toPercent(videoStream.volume), options); + saveVolume(api.getVolume(), options); // change slider position (important) updateVolumeSlider(options); @@ -175,25 +178,6 @@ function changeVolume(toIncrease, options) { showVolumeHud(options.savedVolume); } -function setupVolumeOverride(video, options) { - video.addEventListener("canplay", () => { - if (typeof options.savedVolume === "number") { - const newVolume = (options.savedVolume / 100).toFixed(2); - - video.volume = newVolume; - updateVolumeSlider(options); - - const volumeOverrideInterval = setInterval(() => { - video.volume = newVolume; - }, 4); - setTimeout((interval) => { - updateVolumeSlider(options); - clearInterval(interval); - }, 500, volumeOverrideInterval); - } - }); -} - function updateVolumeSlider(options) { // Slider value automatically rounds to multiples of 5 $("#volume-slider").value = options.savedVolume > 0 && options.savedVolume < 5 ? From 9b1a5b8d26f93c58cf78b95487ce3d0cf80be01f Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Sat, 23 Oct 2021 17:18:58 +0300 Subject: [PATCH 60/67] clarify var names in cleanupName() --- providers/song-info.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/providers/song-info.js b/providers/song-info.js index f88d4103..3f4ad435 100644 --- a/providers/song-info.js +++ b/providers/song-info.js @@ -107,15 +107,15 @@ const suffixesToRemove = [ " (clip officiel)", ]; -function cleanupName(artist) { - if (!artist) return artist; - const lowerCaseArtist = artist.toLowerCase(); +function cleanupName(name) { + if (!name) return name; + const lowCaseName = name.toLowerCase(); for (const suffix of suffixesToRemove) { - if (lowerCaseArtist.endsWith(suffix)) { - return artist.slice(0, -suffix.length); + if (lowCaseName.endsWith(suffix)) { + return name.slice(0, -suffix.length); } } - return artist; + return name; } module.exports = registerCallback; From 79a95f133bde84f3fb26e7012ea598933608a36f Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Sat, 23 Oct 2021 18:22:17 +0300 Subject: [PATCH 61/67] use apiLoad event --- preload.js | 27 +++++++++++++++++++++++++++ providers/song-info-front.js | 31 ++++++------------------------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/preload.js b/preload.js index 5a09c845..67ae8f7c 100644 --- a/preload.js +++ b/preload.js @@ -10,6 +10,8 @@ const setupSongInfo = require("./providers/song-info-front"); const plugins = config.plugins.getEnabled(); +let api; + plugins.forEach(([plugin, options]) => { const preloadPath = path.join(__dirname, "plugins", plugin, "preload.js"); fileExists(preloadPath, () => { @@ -38,6 +40,9 @@ document.addEventListener("DOMContentLoaded", () => { }); }); + // wait for complete load of youtube api + listenForApiLoad(); + // inject song-info provider setupSongInfo(); @@ -51,3 +56,25 @@ document.addEventListener("DOMContentLoaded", () => { global.reload = () => remote.getCurrentWindow().webContents.loadURL(config.get("url")); }); + +function listenForApiLoad() { + api = document.querySelector('#movie_player'); + if (api) { + onApiLoaded(); + return; + } + + const observer = new MutationObserver(() => { + api = document.querySelector('#movie_player'); + if (api) { + observer.disconnect(); + onApiLoaded(); + } + }) + + observer.observe(document.documentElement, { childList: true, subtree: true }); +} + +function onApiLoaded() { + document.dispatchEvent(new CustomEvent('apiLoaded', { detail: api })); +} diff --git a/providers/song-info-front.js b/providers/song-info-front.js index 674faeb7..80c2e990 100644 --- a/providers/song-info-front.js +++ b/providers/song-info-front.js @@ -4,35 +4,16 @@ const { getImage } = require("./song-info"); global.songInfo = {}; -let api = document.querySelector('#movie_player'); - ipcRenderer.on("update-song-info", async (_, extractedSongInfo) => { global.songInfo = JSON.parse(extractedSongInfo); global.songInfo.image = await getImage(global.songInfo.imageSrc); }); -function setup() { - if (api) { - injectListener(); - return; - } - - const observer = new MutationObserver(() => { - api = document.querySelector('#movie_player'); - if (api) { - observer.disconnect(); - injectListener(); - } +module.exports = () => { + document.addEventListener('apiLoaded', e => { + document.querySelector('video').addEventListener('loadeddata', () => { + const data = e.detail.getPlayerResponse(); + ipcRenderer.send("song-info-request", JSON.stringify(data)); + }); }) - - observer.observe(document.documentElement, { childList: true, subtree: true }); -} - -function injectListener() { - document.querySelector('video').addEventListener('loadeddata', () => { - const data = api.getPlayerResponse(); - ipcRenderer.send("song-info-request", JSON.stringify(data)); - }); }; - -module.exports = setup; From df75e480a68e1d830fa45fcc93776e49ef8c139e Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Sat, 23 Oct 2021 18:27:35 +0300 Subject: [PATCH 62/67] use apiLoad event --- plugins/precise-volume/front.js | 21 +++------------------ preload.js | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index 8f323fd1..790a0c72 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -3,26 +3,15 @@ const { ipcRenderer, remote } = require("electron"); const { setOptions } = require("../../config/plugins"); function $(selector) { return document.querySelector(selector); } -let api = $('#movie_player'); +let api; module.exports = (options) => { - if (api) { + document.addEventListener('apiLoaded', e => { + api = e.detail; firstRun(options); - return; - } - - const observer = new MutationObserver(() => { - api = $('#movie_player'); - if (api) { - observer.disconnect(); - firstRun(options); - } }) - - observer.observe(document.documentElement, { childList: true, subtree: true }); }; - /** Restore saved volume and setup tooltip */ function firstRun(options) { if (typeof options.savedVolume === "number") { @@ -93,10 +82,6 @@ function setupVideoPlayerOnwheel(options) { }); } -function toPercent(volume) { - return Math.round(Number.parseFloat(volume) * 100); -} - function saveVolume(volume, options) { options.savedVolume = volume; writeOptions(options); diff --git a/preload.js b/preload.js index 5a09c845..67ae8f7c 100644 --- a/preload.js +++ b/preload.js @@ -10,6 +10,8 @@ const setupSongInfo = require("./providers/song-info-front"); const plugins = config.plugins.getEnabled(); +let api; + plugins.forEach(([plugin, options]) => { const preloadPath = path.join(__dirname, "plugins", plugin, "preload.js"); fileExists(preloadPath, () => { @@ -38,6 +40,9 @@ document.addEventListener("DOMContentLoaded", () => { }); }); + // wait for complete load of youtube api + listenForApiLoad(); + // inject song-info provider setupSongInfo(); @@ -51,3 +56,25 @@ document.addEventListener("DOMContentLoaded", () => { global.reload = () => remote.getCurrentWindow().webContents.loadURL(config.get("url")); }); + +function listenForApiLoad() { + api = document.querySelector('#movie_player'); + if (api) { + onApiLoaded(); + return; + } + + const observer = new MutationObserver(() => { + api = document.querySelector('#movie_player'); + if (api) { + observer.disconnect(); + onApiLoaded(); + } + }) + + observer.observe(document.documentElement, { childList: true, subtree: true }); +} + +function onApiLoaded() { + document.dispatchEvent(new CustomEvent('apiLoaded', { detail: api })); +} From 38449f003affcdcd131b0ccaacebf420e1edbb76 Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Sat, 23 Oct 2021 18:28:38 +0300 Subject: [PATCH 63/67] use apiLoad event --- preload.js | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/preload.js b/preload.js index aa213071..65e55300 100644 --- a/preload.js +++ b/preload.js @@ -10,6 +10,8 @@ const setupSongInfo = require("./providers/song-info-front"); const plugins = config.plugins.getEnabled(); +let api; + plugins.forEach(([plugin, options]) => { const preloadPath = path.join(__dirname, "plugins", plugin, "preload.js"); fileExists(preloadPath, () => { @@ -38,10 +40,8 @@ document.addEventListener("DOMContentLoaded", () => { }); }); - // Remove upgrade button - if (config.get("options.removeUpgradeButton")) { - document.querySelector('[tab-id*="SPunlimited"]').style.display = "none"; - } + // wait for complete load of youtube api + listenForApiLoad(); // inject song-info provider setupSongInfo(); @@ -56,3 +56,30 @@ document.addEventListener("DOMContentLoaded", () => { global.reload = () => remote.getCurrentWindow().webContents.loadURL(config.get("url")); }); + +function listenForApiLoad() { + api = document.querySelector('#movie_player'); + if (api) { + onApiLoaded(); + return; + } + + const observer = new MutationObserver(() => { + api = document.querySelector('#movie_player'); + if (api) { + observer.disconnect(); + onApiLoaded(); + } + }) + + observer.observe(document.documentElement, { childList: true, subtree: true }); +} + +function onApiLoaded() { + document.dispatchEvent(new CustomEvent('apiLoaded', { detail: api })); + + // Remove upgrade button + if (config.get("options.removeUpgradeButton")) { + document.querySelector('ytmusic-pivot-bar-item-renderer[tab-id="SPunlimited"]').style.display = "none"; + } +} From 02f4aabead52f4279bcfa93343868ce99cab27d0 Mon Sep 17 00:00:00 2001 From: TC Date: Sun, 24 Oct 2021 14:01:00 +0200 Subject: [PATCH 64/67] Fix condition on query selector --- preload.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/preload.js b/preload.js index d100e954..6c7c1b16 100644 --- a/preload.js +++ b/preload.js @@ -79,6 +79,9 @@ function onApiLoaded() { // Remove upgrade button if (config.get("options.removeUpgradeButton")) { - document.querySelector('ytmusic-pivot-bar-item-renderer[tab-id="SPunlimited"]')?.style.display = "none"; + const upgradeButtton = document.querySelector('ytmusic-pivot-bar-item-renderer[tab-id="SPunlimited"]') + if (upgradeButtton) { + upgradeButtton.style.display = "none"; + } } } From f9a4bffa55761f28bbc4b2b6fd202cd65324ab77 Mon Sep 17 00:00:00 2001 From: TC Date: Sun, 24 Oct 2021 14:01:29 +0200 Subject: [PATCH 65/67] Fix styling of store migrations --- config/store.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/store.js b/config/store.js index d6451cee..8cfa8203 100644 --- a/config/store.js +++ b/config/store.js @@ -8,8 +8,8 @@ const migrations = { store.set("plugins.discord.listenAlong", true); } }, - ">=1.12.0": (store) => { - const options = store.get("plugins.shortcuts") + ">=1.12.0": (store) => { + const options = store.get("plugins.shortcuts"); let updated = false; for (const optionType of ["global", "local"]) { if (Array.isArray(options[optionType])) { From 18f87c7b0d4a2c9be306d2e6597e3ec9094f1b76 Mon Sep 17 00:00:00 2001 From: TC Date: Sun, 24 Oct 2021 14:02:01 +0200 Subject: [PATCH 66/67] Add migration for precise-volume plugin (`globalShortcuts` key) --- config/store.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/store.js b/config/store.js index 8cfa8203..3653de1b 100644 --- a/config/store.js +++ b/config/store.js @@ -3,6 +3,13 @@ const Store = require("electron-store"); const defaults = require("./defaults"); const migrations = { + ">=1.14.0": (store) => { + if ( + typeof store.get("plugins.precise-volume.globalShortcuts") !== "object" + ) { + store.set("plugins.precise-volume.globalShortcuts", {}); + } + }, ">=1.13.0": (store) => { if (store.get("plugins.discord.listenAlong") === undefined) { store.set("plugins.discord.listenAlong", true); From fc1211f7a1e133871cc400361659e3ee3ea8e653 Mon Sep 17 00:00:00 2001 From: TC Date: Sun, 24 Oct 2021 14:02:13 +0200 Subject: [PATCH 67/67] Bump version to 1.14.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3c2af2eb..aa4e39e5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "youtube-music", "productName": "YouTube Music", - "version": "1.13.0", + "version": "1.14.0", "description": "YouTube Music Desktop App - including custom plugins", "license": "MIT", "repository": "th-ch/youtube-music",