From e4eed2e51979378e62dab902e425218cae5108dc Mon Sep 17 00:00:00 2001 From: Araxeus Date: Wed, 28 Apr 2021 02:41:44 +0300 Subject: [PATCH 01/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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/65] 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 183bad43f662ffc294be57548720eb09c9fa0cbb Mon Sep 17 00:00:00 2001 From: Constantin Piber Date: Sun, 15 Aug 2021 12:20:37 +0200 Subject: [PATCH 43/65] Fix discord clearActivity, menu The callback sends multiple events, in particular two pause when going to the next song, so the timeout wasn't properly cleared. Add menu buttons for the two options --- plugins/discord/back.js | 13 +++++++++---- plugins/discord/menu.js | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 plugins/discord/menu.js diff --git a/plugins/discord/back.js b/plugins/discord/back.js index c6faadd7..2f75c430 100644 --- a/plugins/discord/back.js +++ b/plugins/discord/back.js @@ -16,6 +16,10 @@ module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { win.once("ready-to-show", () => { rpc.once("ready", () => { // Register the callback + // + // We get multiple events + // Next song: PAUSE(n), PAUSE(n+1), PLAY(n+1) + // Skip time: PAUSE(N), PLAY(N) registerCallback((songInfo) => { if (songInfo.title.length === 0 && songInfo.artist.length === 0) { return; @@ -31,16 +35,17 @@ module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { ].join(' || '), }; + // stop the clear activity timout + clearTimeout(clearActivity); + if (songInfo.isPaused) { // Add an idle icon to show that the song is paused activityInfo.smallImageKey = "idle"; activityInfo.smallImageText = "idle/paused"; // Set start the timer so the activity gets cleared after a while if enabled if (activityTimoutEnabled) - clearActivity = setTimeout(()=>rpc.clearActivity(), activityTimoutTime||10000); + clearActivity = setTimeout(() => rpc.clearActivity().catch(console.error), activityTimoutTime || 10000); } else { - // stop the clear activity timout - clearTimeout(clearActivity); // Add the start and end time of the song const songStartTime = Date.now() - songInfo.elapsedSeconds * 1000; activityInfo.startTimestamp = songStartTime; @@ -48,7 +53,7 @@ module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { songStartTime + songInfo.songDuration * 1000; } - rpc.setActivity(activityInfo); + rpc.setActivity(activityInfo).catch(console.error); }); }); diff --git a/plugins/discord/menu.js b/plugins/discord/menu.js new file mode 100644 index 00000000..d0af48e8 --- /dev/null +++ b/plugins/discord/menu.js @@ -0,0 +1,21 @@ +const { setOptions } = require("../../config/plugins"); +const { edit } = require("../../config"); + +module.exports = (win, options) => [ + { + label: "Clear activity after timeout", + type: "checkbox", + checked: options.activityTimoutEnabled, + click: (item) => { + options.activityTimoutEnabled = item.checked; + setOptions('discord', options); + }, + }, + { + label: "Set timeout time in config", + click: () => { + // open config.json + edit(); + }, + }, +]; From 39014572180798772c0a9a464c2bf43fb7d417ce Mon Sep 17 00:00:00 2001 From: Constantin Piber Date: Tue, 17 Aug 2021 10:09:11 +0200 Subject: [PATCH 44/65] Discord add menu button for clearing activity --- plugins/discord/back.js | 2 ++ plugins/discord/menu.js | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/plugins/discord/back.js b/plugins/discord/back.js index 2f75c430..57d9902a 100644 --- a/plugins/discord/back.js +++ b/plugins/discord/back.js @@ -61,3 +61,5 @@ module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { rpc.login({ clientId }).catch(console.error); }); }; + +module.exports.clear = () => rpc.clearActivity(); diff --git a/plugins/discord/menu.js b/plugins/discord/menu.js index d0af48e8..96e25e8c 100644 --- a/plugins/discord/menu.js +++ b/plugins/discord/menu.js @@ -1,7 +1,14 @@ const { setOptions } = require("../../config/plugins"); const { edit } = require("../../config"); +const { clear } = require("./back"); module.exports = (win, options) => [ + { + label: "Clear activity", + click: () => { + clear(); + }, + }, { label: "Clear activity after timeout", type: "checkbox", From 36bc9c62b0e964dd8cbc1ad964ae570c0fe7566a Mon Sep 17 00:00:00 2001 From: Constantin Piber Date: Wed, 18 Aug 2021 21:39:40 +0200 Subject: [PATCH 45/65] Discord timeout 0 clear activity directly --- plugins/discord/back.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/discord/back.js b/plugins/discord/back.js index 57d9902a..c0808e4e 100644 --- a/plugins/discord/back.js +++ b/plugins/discord/back.js @@ -38,6 +38,12 @@ module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { // stop the clear activity timout clearTimeout(clearActivity); + // clear directly if timeout is 0 + if (songInfo.isPaused && activityTimoutEnabled && activityTimoutTime === 0) { + rpc.clearActivity().catch(console.error); + return; + } + if (songInfo.isPaused) { // Add an idle icon to show that the song is paused activityInfo.smallImageKey = "idle"; From b5fd6b4969a318b3738583e7f33eb2c0cf295237 Mon Sep 17 00:00:00 2001 From: Constantin Piber Date: Fri, 27 Aug 2021 16:32:55 +0200 Subject: [PATCH 46/65] Discord add reconnecting functionality Clear rpc on disconnect Add menu button to reconnect --- plugins/discord/back.js | 183 +++++++++++++++++++++++++++------------- plugins/discord/menu.js | 52 +++++++----- providers/song-info.js | 11 +++ 3 files changed, 168 insertions(+), 78 deletions(-) diff --git a/plugins/discord/back.js b/plugins/discord/back.js index c0808e4e..7ba1ea1a 100644 --- a/plugins/discord/back.js +++ b/plugins/discord/back.js @@ -1,71 +1,140 @@ const Discord = require("discord-rpc"); +const { dev } = require("electron-is") const registerCallback = require("../../providers/song-info"); -const rpc = new Discord.Client({ - transport: "ipc", -}); - // Application ID registered by @semvis123 const clientId = "790655993809338398"; -let clearActivity; +/** + * @typedef {Object} Info + * @property {import('discord-rpc').Client} rpc + * @property {boolean} ready + * @property {import('../../providers/song-info').SongInfo} lastSongInfo + */ +/** + * @type {Info} + */ +const info = { + rpc: null, + ready: false, + lastSongInfo: null, +}; +/** + * @type {(() => void)[]} + */ +const refreshCallbacks = []; +const resetInfo = () => { + info.rpc = null; + info.ready = false; + clearTimeout(clearActivity); + if (dev()) console.log("discord disconnected"); + refreshCallbacks.forEach(cb => cb()); +}; -module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { - // If the page is ready, register the callback - win.once("ready-to-show", () => { - rpc.once("ready", () => { - // Register the callback - // - // We get multiple events - // Next song: PAUSE(n), PAUSE(n+1), PLAY(n+1) - // Skip time: PAUSE(N), PLAY(N) - registerCallback((songInfo) => { - if (songInfo.title.length === 0 && songInfo.artist.length === 0) { - return; - } - // Song information changed, so lets update the rich presence - const activityInfo = { - details: songInfo.title, - state: songInfo.artist, - largeImageKey: "logo", - largeImageText: [ - songInfo.uploadDate, - songInfo.views.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " views" - ].join(' || '), - }; +const connect = () => { + if (info.rpc) { + if (dev()) + console.log('Attempted to connect with active RPC object'); + return; + } - // stop the clear activity timout - clearTimeout(clearActivity); + info.rpc = new Discord.Client({ + transport: "ipc", + }); + info.ready = false; - // clear directly if timeout is 0 - if (songInfo.isPaused && activityTimoutEnabled && activityTimoutTime === 0) { - rpc.clearActivity().catch(console.error); - return; - } + info.rpc.once("connected", () => { + if (dev()) console.log("discord connected"); + refreshCallbacks.forEach(cb => cb()); + }); + info.rpc.once("ready", () => { + info.ready = true; + if (info.lastSongInfo) updateActivity(info.lastSongInfo) + }); + info.rpc.once("disconnected", resetInfo); - if (songInfo.isPaused) { - // Add an idle icon to show that the song is paused - activityInfo.smallImageKey = "idle"; - activityInfo.smallImageText = "idle/paused"; - // Set start the timer so the activity gets cleared after a while if enabled - if (activityTimoutEnabled) - clearActivity = setTimeout(() => rpc.clearActivity().catch(console.error), activityTimoutTime || 10000); - } else { - // Add the start and end time of the song - const songStartTime = Date.now() - songInfo.elapsedSeconds * 1000; - activityInfo.startTimestamp = songStartTime; - activityInfo.endTimestamp = - songStartTime + songInfo.songDuration * 1000; - } - - rpc.setActivity(activityInfo).catch(console.error); - }); - }); - - // Startup the rpc client - rpc.login({ clientId }).catch(console.error); + // Startup the rpc client + info.rpc.login({ clientId }).catch(err => { + resetInfo(); + if (dev()) console.error(err); }); }; -module.exports.clear = () => rpc.clearActivity(); +let clearActivity; +/** + * @type {import('../../providers/song-info').songInfoCallback} + */ +let updateActivity; + +module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { + // We get multiple events + // Next song: PAUSE(n), PAUSE(n+1), PLAY(n+1) + // Skip time: PAUSE(N), PLAY(N) + updateActivity = songInfo => { + if (songInfo.title.length === 0 && songInfo.artist.length === 0) { + return; + } + info.lastSongInfo = songInfo; + + // stop the clear activity timout + clearTimeout(clearActivity); + + // stop early if discord connection is not ready + // do this after clearTimeout to avoid unexpected clears + if (!info.rpc || !info.ready) { + return; + } + + // clear directly if timeout is 0 + if (songInfo.isPaused && activityTimoutEnabled && activityTimoutTime === 0) { + info.rpc.clearActivity().catch(console.error); + return; + } + + // Song information changed, so lets update the rich presence + const activityInfo = { + details: songInfo.title, + state: songInfo.artist, + largeImageKey: "logo", + largeImageText: [ + songInfo.uploadDate, + songInfo.views.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " views" + ].join(' || '), + }; + + if (songInfo.isPaused) { + // Add an idle icon to show that the song is paused + activityInfo.smallImageKey = "idle"; + activityInfo.smallImageText = "idle/paused"; + // Set start the timer so the activity gets cleared after a while if enabled + if (activityTimoutEnabled) + clearActivity = setTimeout(() => info.rpc.clearActivity().catch(console.error), activityTimoutTime || 10000); + } else { + // Add the start and end time of the song + const songStartTime = Date.now() - songInfo.elapsedSeconds * 1000; + activityInfo.startTimestamp = songStartTime; + activityInfo.endTimestamp = + songStartTime + songInfo.songDuration * 1000; + } + + info.rpc.setActivity(activityInfo).catch(console.error); + }; + + // If the page is ready, register the callback + win.once("ready-to-show", () => { + registerCallback(updateActivity); + connect(); + }); +}; + +module.exports.clear = () => { + if (info.rpc) info.rpc.clearActivity(); + clearTimeout(clearActivity); +}; +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] } }), {})); diff --git a/plugins/discord/menu.js b/plugins/discord/menu.js index 96e25e8c..3e8d97e9 100644 --- a/plugins/discord/menu.js +++ b/plugins/discord/menu.js @@ -1,28 +1,38 @@ const { setOptions } = require("../../config/plugins"); const { edit } = require("../../config"); -const { clear } = require("./back"); +const { clear, info, connect, registerRefresh } = require("./back"); -module.exports = (win, options) => [ - { - label: "Clear activity", - click: () => { - clear(); +let hasRegisterred = false; + +module.exports = (win, options, refreshMenu) => { + if (!hasRegisterred) { + registerRefresh(refreshMenu); + hasRegisterred = true; + } + + return [ + { + label: info.rpc !== null ? "Connected" : "Reconnect", + enabled: info.rpc === null, + click: connect, }, - }, - { - label: "Clear activity after timeout", - type: "checkbox", - checked: options.activityTimoutEnabled, - click: (item) => { - options.activityTimoutEnabled = item.checked; - setOptions('discord', options); + { + label: "Clear activity", + click: clear, }, - }, - { - label: "Set timeout time in config", - click: () => { + { + label: "Clear activity after timeout", + type: "checkbox", + checked: options.activityTimoutEnabled, + click: (item) => { + options.activityTimoutEnabled = item.checked; + setOptions('discord', options); + }, + }, + { + label: "Set timeout time in config", // open config.json - edit(); + click: edit, }, - }, -]; + ]; +}; diff --git a/providers/song-info.js b/providers/song-info.js index 08eaf944..11b2abeb 100644 --- a/providers/song-info.js +++ b/providers/song-info.js @@ -40,6 +40,9 @@ const getArtist = async (win) => { } // Fill songInfo with empty values +/** + * @typedef {songInfo} SongInfo + */ const songInfo = { title: "", artist: "", @@ -71,6 +74,14 @@ const handleData = async (responseText, win) => { const callbacks = []; // This function will allow plugins to register callback that will be triggered when data changes +/** + * @callback songInfoCallback + * @param {songInfo} songInfo + * @returns {void} + */ +/** + * @param {songInfoCallback} callback + */ const registerCallback = (callback) => { callbacks.push(callback); }; From ef66612cc87e749f702a96248099d7178cad8ae7 Mon Sep 17 00:00:00 2001 From: Constantin Piber Date: Fri, 27 Aug 2021 17:07:23 +0200 Subject: [PATCH 47/65] Discord show error dialog on reconnect error --- plugins/discord/back.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/discord/back.js b/plugins/discord/back.js index 6a8dd007..8f0cc614 100644 --- a/plugins/discord/back.js +++ b/plugins/discord/back.js @@ -1,5 +1,6 @@ const Discord = require("discord-rpc"); -const { dev } = require("electron-is") +const { dev } = require("electron-is"); +const { dialog } = require("electron"); const registerCallback = require("../../providers/song-info"); @@ -32,7 +33,8 @@ const resetInfo = () => { refreshCallbacks.forEach(cb => cb()); }; -const connect = () => { +let window; +const connect = (showErr = false) => { if (info.rpc) { if (dev()) console.log('Attempted to connect with active RPC object'); @@ -58,6 +60,7 @@ const connect = () => { info.rpc.login({ clientId }).catch(err => { resetInfo(); if (dev()) console.error(err); + if (showErr) dialog.showMessageBox(window, { title: 'Connection failed', message: err.message || String(err), type: 'error' }); }); }; @@ -68,6 +71,7 @@ let clearActivity; let updateActivity; module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { + window = win; // We get multiple events // Next song: PAUSE(n), PAUSE(n+1), PLAY(n+1) // Skip time: PAUSE(N), PLAY(N) From ea2d33c3cfbaa952dac9b21ce8dfbaf72f0e14f2 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Tue, 21 Sep 2021 03:24:11 +0000 Subject: [PATCH 48/65] fix: upgrade async-mutex from 0.3.1 to 0.3.2 Snyk has created this PR to upgrade async-mutex from 0.3.1 to 0.3.2. See this package in npm: See this project in Snyk: https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr --- package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 6920b186..0151ddc7 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "@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", + "async-mutex": "^0.3.2", "browser-id3-writer": "^4.4.0", "chokidar": "^3.5.2", "custom-electron-titlebar": "^3.2.7", diff --git a/yarn.lock b/yarn.lock index 743fcc50..0bed6c60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1913,12 +1913,12 @@ async-exit-hook@^2.0.1: resolved "https://registry.yarnpkg.com/async-exit-hook/-/async-exit-hook-2.0.1.tgz#8bd8b024b0ec9b1c01cccb9af9db29bd717dfaf3" integrity sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw== -async-mutex@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.3.1.tgz#7033af665f1c7cebed8b878267a43ba9e77c5f67" - integrity sha512-vRfQwcqBnJTLzVQo72Sf7KIUbcSUP5hNchx6udI1U6LuPQpfePgdjJzlCe76yFZ8pxlLjn9lwcl/Ya0TSOv0Tw== +async-mutex@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.3.2.tgz#1485eda5bda1b0ec7c8df1ac2e815757ad1831df" + integrity sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA== dependencies: - tslib "^2.1.0" + tslib "^2.3.1" async@0.9.x: version "0.9.2" @@ -8943,10 +8943,10 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== +tslib@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== tsutils@^3.21.0: version "3.21.0" From f2039e29e7aabd6fe1f69fbb7c054ee539f07327 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Sep 2021 21:12:33 +0000 Subject: [PATCH 49/65] build(deps): bump tmpl from 1.0.4 to 1.0.5 Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5. - [Release notes](https://github.com/daaku/nodejs-tmpl/releases) - [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5) --- updated-dependencies: - dependency-name: tmpl dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 743fcc50..1025e2bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8826,9 +8826,9 @@ tmp@^0.2.0: rimraf "^3.0.0" tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== to-absolute-glob@^2.0.2: version "2.0.2" From 157ae05f80a25612a2861fe9c9e6a101f22bbbd8 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Mon, 27 Sep 2021 19:13:33 +0000 Subject: [PATCH 50/65] fix: upgrade node-fetch from 2.6.1 to 2.6.2 Snyk has created this PR to upgrade node-fetch from 2.6.1 to 2.6.2. See this package in npm: See this project in Snyk: https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr --- package.json | 2 +- yarn.lock | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 6920b186..7fcc987f 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "filenamify": "^4.3.0", "md5": "^2.3.0", "mpris-service": "^2.1.2", - "node-fetch": "^2.6.1", + "node-fetch": "^2.6.2", "node-notifier": "^9.0.1", "ytdl-core": "^4.9.1", "ytpl": "^2.2.3" diff --git a/yarn.lock b/yarn.lock index 743fcc50..b194c7e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6784,6 +6784,13 @@ node-fetch@^2.6.1: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +node-fetch@^2.6.2: + version "2.6.5" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd" + integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ== + dependencies: + whatwg-url "^5.0.0" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -8909,6 +8916,11 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + trim-newlines@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" @@ -9308,6 +9320,11 @@ webdriverio@^6.9.1: serialize-error "^8.0.0" webdriver "6.12.1" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + webidl-conversions@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" @@ -9330,6 +9347,14 @@ whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + whatwg-url@^8.0.0: version "8.4.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.4.0.tgz#50fb9615b05469591d2b2bd6dfaed2942ed72837" From 587818b91ed0730bb75c421f27405a3e1038c4e4 Mon Sep 17 00:00:00 2001 From: Constantin Piber Date: Tue, 5 Oct 2021 10:10:36 +0200 Subject: [PATCH 51/65] Add type, clear on close --- plugins/discord/back.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/discord/back.js b/plugins/discord/back.js index 8f0cc614..478af101 100644 --- a/plugins/discord/back.js +++ b/plugins/discord/back.js @@ -97,7 +97,10 @@ module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { } // Song information changed, so lets update the rich presence + // @see https://discord.com/developers/docs/topics/gateway#activity-object + // not all options are transfered through https://github.com/discordjs/RPC/blob/6f83d8d812c87cb7ae22064acd132600407d7d05/src/client.js#L518-530 const activityInfo = { + type: 2, // Listening, addressed in https://github.com/discordjs/RPC/pull/149 details: songInfo.title, state: songInfo.artist, largeImageKey: "logo", @@ -133,6 +136,7 @@ module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { registerCallback(updateActivity); connect(); }); + win.on("close", () => module.exports.clear()); }; module.exports.clear = () => { From b9dbd8bd4def9e9f43f25946228ed495f3365417 Mon Sep 17 00:00:00 2001 From: Constantin Piber Date: Mon, 11 Oct 2021 15:02:24 +0200 Subject: [PATCH 52/65] Allow disable listen along (#426) --- config/defaults.js | 3 ++- config/store.js | 5 +++++ plugins/discord/back.js | 10 +++++----- plugins/discord/menu.js | 9 +++++++++ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/config/defaults.js b/config/defaults.js index f0533241..552a4995 100644 --- a/config/defaults.js +++ b/config/defaults.js @@ -45,7 +45,8 @@ const defaultConfig = { discord: { enabled: false, activityTimoutEnabled: true, // if enabled, the discord rich presence gets cleared when music paused after the time specified below - activityTimoutTime: 10 * 60 * 1000 // 10 minutes + activityTimoutTime: 10 * 60 * 1000, // 10 minutes + listenAlong: true, // add a "listen along" button to rich presence }, notifications: { enabled: false, diff --git a/config/store.js b/config/store.js index 9c0de1e4..f66c1f9a 100644 --- a/config/store.js +++ b/config/store.js @@ -3,6 +3,11 @@ const Store = require("electron-store"); const defaults = require("./defaults"); const migrations = { + ">=1.13.0": (store) => { + if (store.get("plugins.discord.listenAlong") === undefined) { + store.set("plugins.discord.listenAlong", true); + } + }, ">=1.11.0": (store) => { if (store.get("options.resumeOnStart") === undefined) { store.set("options.resumeOnStart", true); diff --git a/plugins/discord/back.js b/plugins/discord/back.js index 478af101..3c3ab5fd 100644 --- a/plugins/discord/back.js +++ b/plugins/discord/back.js @@ -70,7 +70,7 @@ let clearActivity; */ let updateActivity; -module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { +module.exports = (win, {activityTimoutEnabled, activityTimoutTime, listenAlong}) => { window = win; // We get multiple events // Next song: PAUSE(n), PAUSE(n+1), PLAY(n+1) @@ -106,11 +106,11 @@ module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { largeImageKey: "logo", largeImageText: [ songInfo.uploadDate, - songInfo.views.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " views" + songInfo.views.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " views", ].join(' || '), - buttons: [ + buttons: listenAlong ? [ { label: "Listen Along", url: songInfo.url }, - ], + ] : undefined, }; if (songInfo.isPaused) { @@ -119,7 +119,7 @@ module.exports = (win, {activityTimoutEnabled, activityTimoutTime}) => { activityInfo.smallImageText = "idle/paused"; // Set start the timer so the activity gets cleared after a while if enabled if (activityTimoutEnabled) - clearActivity = setTimeout(() => info.rpc.clearActivity().catch(console.error), activityTimoutTime || 10000); + clearActivity = setTimeout(() => info.rpc.clearActivity().catch(console.error), activityTimoutTime ?? 10000); } else { // Add the start and end time of the song const songStartTime = Date.now() - songInfo.elapsedSeconds * 1000; diff --git a/plugins/discord/menu.js b/plugins/discord/menu.js index 3e8d97e9..9750dabe 100644 --- a/plugins/discord/menu.js +++ b/plugins/discord/menu.js @@ -29,6 +29,15 @@ module.exports = (win, options, refreshMenu) => { setOptions('discord', options); }, }, + { + label: "Listen Along", + type: "checkbox", + checked: options.listenAlong, + click: (item) => { + options.listenAlong = item.checked; + setOptions('discord', options); + }, + }, { label: "Set timeout time in config", // open config.json From 1908921ae639846e5ba001e7534bc506784e0824 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Mon, 11 Oct 2021 21:23:58 +0000 Subject: [PATCH 53/65] fix: upgrade @cliqz/adblocker-electron from 1.22.5 to 1.22.6 Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.22.5 to 1.22.6. See this package in npm: See this project in Snyk: https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr --- package.json | 2 +- yarn.lock | 62 ++++++++++++++++++++++++++-------------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 6920b186..b0b6a118 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "npm": "Please use yarn and not npm" }, "dependencies": { - "@cliqz/adblocker-electron": "^1.22.5", + "@cliqz/adblocker-electron": "^1.22.6", "@ffmpeg/core": "^0.10.0", "@ffmpeg/ffmpeg": "^0.10.0", "YoutubeNonStop": "git://github.com/lawfx/YoutubeNonStop.git#v0.9.0", diff --git a/yarn.lock b/yarn.lock index 743fcc50..fa7d74db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -439,45 +439,45 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@cliqz/adblocker-content@^1.22.5": - version "1.22.5" - resolved "https://registry.yarnpkg.com/@cliqz/adblocker-content/-/adblocker-content-1.22.5.tgz#84a82a630b3824623fff203ffaa9f4831f902eaa" - integrity sha512-79UAWMLZ5Na3FJey/RkYbUcPsmRbfkWq7LzUVffRR+yL8B24P6ptd+T7/qBFAULbJ0unp1DBtJ/i1P1QOPktXw== +"@cliqz/adblocker-content@^1.22.7": + version "1.22.7" + resolved "https://registry.yarnpkg.com/@cliqz/adblocker-content/-/adblocker-content-1.22.7.tgz#02bfa1775d8be1efa82e9d5802cc17cfa9dc0712" + integrity sha512-pAGxQ7sKCk7r0g/d7vyxY1MhkLfxfwMzd4WPL9234HmU/blCGCg1QL8wkjLTNYJERXZ+xoJ2dqMOisR/nE0ypA== dependencies: - "@cliqz/adblocker-extended-selectors" "^1.22.5" + "@cliqz/adblocker-extended-selectors" "^1.22.7" -"@cliqz/adblocker-electron-preload@^1.22.5": - version "1.22.5" - resolved "https://registry.yarnpkg.com/@cliqz/adblocker-electron-preload/-/adblocker-electron-preload-1.22.5.tgz#3a9067279bdab0fd5e6d147b5a36c15c2273c83d" - integrity sha512-O0Baz5SXT4cSGkwcmPiTFWmeLGFYy/vQxRsh2C8sJzkmCj8593rHOVgvVUL4M9o1wKTh+RycmWpoi6dWu75mZw== +"@cliqz/adblocker-electron-preload@^1.22.7": + version "1.22.7" + resolved "https://registry.yarnpkg.com/@cliqz/adblocker-electron-preload/-/adblocker-electron-preload-1.22.7.tgz#1de6c4c3e66d566149cf60785b85d6f3fdb9a9ea" + integrity sha512-1eUQvmmDd5Wi0ka48SRggd80ZBilnA7uRePni/cVGfH5LSecCs5WoIpEhuoc1G333DXeBv9W0sRc1wVlKBsszg== dependencies: - "@cliqz/adblocker-content" "^1.22.5" + "@cliqz/adblocker-content" "^1.22.7" -"@cliqz/adblocker-electron@^1.22.5": - version "1.22.5" - resolved "https://registry.yarnpkg.com/@cliqz/adblocker-electron/-/adblocker-electron-1.22.5.tgz#3b45851d47c1835bb7f6476f4e29ae43606c90cf" - integrity sha512-yAfbPszTT5ZDIA4PfPwoImdUJLhAMXZg9G2wfpZP3uadMZHS6E1wJaufjMelDDo/UL5xjH/Mi4ZCRmGZPhZ7Wg== +"@cliqz/adblocker-electron@^1.22.6": + version "1.22.7" + resolved "https://registry.yarnpkg.com/@cliqz/adblocker-electron/-/adblocker-electron-1.22.7.tgz#bd29cf47835bc5c0c4d146333de3944096d23b4d" + integrity sha512-/O5Dskkr7R/8RKOby04VZ7HbnU/OD6Kk+raLxyP858FOYccHOnBjkAcUcUzun2x0UXmHX9Cus8SJ3h8GbrG7ZA== dependencies: - "@cliqz/adblocker" "^1.22.5" - "@cliqz/adblocker-electron-preload" "^1.22.5" + "@cliqz/adblocker" "^1.22.7" + "@cliqz/adblocker-electron-preload" "^1.22.7" tldts-experimental "^5.6.21" -"@cliqz/adblocker-extended-selectors@^1.22.5": - version "1.22.5" - resolved "https://registry.yarnpkg.com/@cliqz/adblocker-extended-selectors/-/adblocker-extended-selectors-1.22.5.tgz#228fdec6a58e313225a0be4266529f495432db0e" - integrity sha512-5HTrNq1TaTXpTOddBo7z7GMEE7r44J6HusMVaDmbMpoA115YoQJyMfD82OYgoddj4Zdvp63/pjP+MBlE0WZyJg== +"@cliqz/adblocker-extended-selectors@^1.22.7": + version "1.22.7" + resolved "https://registry.yarnpkg.com/@cliqz/adblocker-extended-selectors/-/adblocker-extended-selectors-1.22.7.tgz#ca0f219d773af5e8013287e5ddd8b00761359d87" + integrity sha512-eHZWYJsgPZPaiLyQtZF7phDFoEqAzk54eno0P+Daal+QwiNixobsk3V4Uh1AVGFcmFEG/Z2CbC/vdWSHpSlImw== -"@cliqz/adblocker@^1.22.5": - version "1.22.5" - resolved "https://registry.yarnpkg.com/@cliqz/adblocker/-/adblocker-1.22.5.tgz#26e675078db9d9854f295a87e969db0c95a15764" - integrity sha512-hQSyedelwG2+D6RDorJkarIUd9mln5IyxnRKO4ADGXvdQhZ5G/E90bTyJ2apDBdnvaUwXpmhhXs2cK12HhN14g== +"@cliqz/adblocker@^1.22.7": + version "1.22.7" + resolved "https://registry.yarnpkg.com/@cliqz/adblocker/-/adblocker-1.22.7.tgz#e2ee745c663ad6862e627de240973bdb4f1dc100" + integrity sha512-DxHlLJmV1q05F1I6BORqvBaOc43Vqts8c+vZdsjYdfiwfrPtuVRFYVTwZeMlZHBhmWx4HyxnfFakzJ8hw/B09A== dependencies: - "@cliqz/adblocker-content" "^1.22.5" - "@cliqz/adblocker-extended-selectors" "^1.22.5" + "@cliqz/adblocker-content" "^1.22.7" + "@cliqz/adblocker-extended-selectors" "^1.22.7" "@remusao/guess-url-type" "^1.1.2" "@remusao/small" "^1.1.2" "@remusao/smaz" "^1.7.1" - "@types/chrome" "^0.0.154" + "@types/chrome" "^0.0.157" "@types/firefox-webext-browser" "^82.0.0" tldts-experimental "^5.6.21" @@ -1208,10 +1208,10 @@ "@types/node" "*" "@types/responselike" "*" -"@types/chrome@^0.0.154": - version "0.0.154" - resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.154.tgz#7992e97364f4447e961028ad07ac843d0b052c2d" - integrity sha512-6QmP744MeMUZUIUHED4d4L2la5dIF1e6bcrkGF4yGQTyO94ER+r++Ss165wkzA5cAGUYt8kToDa6L9xtNqVMxg== +"@types/chrome@^0.0.157": + version "0.0.157" + resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.157.tgz#5a50bd378f4f632383c6ebbc34c88fb87d501f58" + integrity sha512-q5SSmA9nKaDzFi8QkJW9kW8MYwWg9O7PKPUdBxsz+3rPcIF1Kxw0Bexpd70Uq1mU6PN4DBp4qKMXQDybUeiI9w== dependencies: "@types/filesystem" "*" "@types/har-format" "*" From 3ec49bca742f7cdecec946b7f4ab4725f793071a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Oct 2021 22:10:41 +0000 Subject: [PATCH 54/65] build(deps-dev): bump electron from 12.0.8 to 12.1.0 Bumps [electron](https://github.com/electron/electron) from 12.0.8 to 12.1.0. - [Release notes](https://github.com/electron/electron/releases) - [Changelog](https://github.com/electron/electron/blob/main/docs/breaking-changes.md) - [Commits](https://github.com/electron/electron/compare/v12.0.8...v12.1.0) --- updated-dependencies: - dependency-name: electron dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 6920b186..63e0977b 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "ytpl": "^2.2.3" }, "devDependencies": { - "electron": "^12.0.8", + "electron": "^12.1.0", "electron-builder": "^22.10.5", "electron-devtools-installer": "^3.1.1", "electron-icon-maker": "0.0.5", diff --git a/yarn.lock b/yarn.lock index 743fcc50..225e289b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1316,12 +1316,7 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== -"@types/node@*": - version "14.14.25" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.25.tgz#15967a7b577ff81383f9b888aa6705d43fbbae93" - integrity sha512-EPpXLOVqDvisVxtlbvzfyqSsFeQxltFbluZNRndIb8tr9KiBnYNLzrc1N3pyKUCww2RNrfHDViqDWWE1LCJQtQ== - -"@types/node@^14.6.2": +"@types/node@*", "@types/node@^14.6.2": version "14.14.44" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.44.tgz#df7503e6002847b834371c004b372529f3f85215" integrity sha512-+gaugz6Oce6ZInfI/tK4Pq5wIIkJMEJUu92RB3Eu93mtj4wjjjz9EB5mLp5s1pSsLXdC/CPut/xF20ZzAQJbTA== @@ -3511,10 +3506,10 @@ electron-updater@^4.4.6: lodash.isequal "^4.5.0" semver "^7.3.5" -electron@^12.0.8: - version "12.0.8" - resolved "https://registry.yarnpkg.com/electron/-/electron-12.0.8.tgz#e52583b2b4f1eaa6fbb0e3666b9907f99f1f24c7" - integrity sha512-bN2wYNnnma7ugBsiwysO1LI6oTTV1lDHOXuWip+OGjDUiz0IiJmZ+r0gAIMMeypVohZh7AA1ftnKad7tJ8sH4A== +electron@^12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/electron/-/electron-12.1.0.tgz#615a7f9dbb2fc79cc72361fba9f39d005c697bca" + integrity sha512-joQlYI/nTIrTUldO3GENZ2j225eKar9nTQBSEwSUSWN4h65QGDmXNQ7dbWPmLlkUQWtHhz8lXhFk30OLG9ZjLw== dependencies: "@electron/get" "^1.0.1" "@types/node" "^14.6.2" From 88ee0fb9893438637a2c47420a788f24a040f42f Mon Sep 17 00:00:00 2001 From: Manish Date: Wed, 13 Oct 2021 12:26:38 +0530 Subject: [PATCH 55/65] 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 56/65] 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 57/65] 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 58/65] 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 59/65] 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 60/65] 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 79d0c7b666f64091a49cff11c9688085c89c4222 Mon Sep 17 00:00:00 2001 From: Manish Date: Sun, 17 Oct 2021 10:54:05 +0530 Subject: [PATCH 61/65] 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 62/65] 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 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 63/65] 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 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 64/65] 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 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 65/65] 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 })); +}