mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-14 03:41:46 +00:00
Merge branch 'master' into update-custom-electron-titlebar
This commit is contained in:
@ -1,11 +1,17 @@
|
|||||||
const defaultConfig = require("./defaults");
|
const defaultConfig = require("./defaults");
|
||||||
const plugins = require("./plugins");
|
const plugins = require("./plugins");
|
||||||
const store = require("./store");
|
const store = require("./store");
|
||||||
|
const { restart } = require("../providers/app-controls");
|
||||||
|
|
||||||
const set = (key, value) => {
|
const set = (key, value) => {
|
||||||
store.set(key, value);
|
store.set(key, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function setMenuOption(key, value) {
|
||||||
|
set(key, value);
|
||||||
|
if (store.get("options.restartOnConfigChanges")) restart();
|
||||||
|
}
|
||||||
|
|
||||||
const get = (key) => {
|
const get = (key) => {
|
||||||
return store.get(key);
|
return store.get(key);
|
||||||
};
|
};
|
||||||
@ -14,6 +20,7 @@ module.exports = {
|
|||||||
defaultConfig,
|
defaultConfig,
|
||||||
get,
|
get,
|
||||||
set,
|
set,
|
||||||
|
setMenuOption,
|
||||||
edit: () => store.openInEditor(),
|
edit: () => store.openInEditor(),
|
||||||
watch: (cb) => {
|
watch: (cb) => {
|
||||||
store.onDidChange("options", cb);
|
store.onDidChange("options", cb);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
const store = require("./store");
|
const store = require("./store");
|
||||||
|
const { restart } = require("../providers/app-controls");
|
||||||
|
|
||||||
function getEnabled() {
|
function getEnabled() {
|
||||||
const plugins = store.get("plugins");
|
const plugins = store.get("plugins");
|
||||||
@ -24,16 +25,21 @@ function setOptions(plugin, options) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setMenuOptions(plugin, options) {
|
||||||
|
setOptions(plugin, options);
|
||||||
|
if (store.get("options.restartOnConfigChanges")) restart();
|
||||||
|
}
|
||||||
|
|
||||||
function getOptions(plugin) {
|
function getOptions(plugin) {
|
||||||
return store.get("plugins")[plugin];
|
return store.get("plugins")[plugin];
|
||||||
}
|
}
|
||||||
|
|
||||||
function enable(plugin) {
|
function enable(plugin) {
|
||||||
setOptions(plugin, { enabled: true });
|
setMenuOptions(plugin, { enabled: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
function disable(plugin) {
|
function disable(plugin) {
|
||||||
setOptions(plugin, { enabled: false });
|
setMenuOptions(plugin, { enabled: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@ -42,5 +48,6 @@ module.exports = {
|
|||||||
enable,
|
enable,
|
||||||
disable,
|
disable,
|
||||||
setOptions,
|
setOptions,
|
||||||
|
setMenuOptions,
|
||||||
getOptions,
|
getOptions,
|
||||||
};
|
};
|
||||||
|
|||||||
96
index.js
96
index.js
@ -26,6 +26,22 @@ unhandled({
|
|||||||
process.env.NODE_OPTIONS = "";
|
process.env.NODE_OPTIONS = "";
|
||||||
|
|
||||||
const app = electron.app;
|
const app = electron.app;
|
||||||
|
// Prevent window being garbage collected
|
||||||
|
let mainWindow;
|
||||||
|
autoUpdater.autoDownload = false;
|
||||||
|
|
||||||
|
if(config.get("options.singleInstanceLock")){
|
||||||
|
const gotTheLock = app.requestSingleInstanceLock();
|
||||||
|
if (!gotTheLock) app.quit();
|
||||||
|
|
||||||
|
app.on('second-instance', () => {
|
||||||
|
if (!mainWindow) return;
|
||||||
|
if (mainWindow.isMinimized()) mainWindow.restore();
|
||||||
|
if (!mainWindow.isVisible()) mainWindow.show();
|
||||||
|
mainWindow.focus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
app.commandLine.appendSwitch(
|
app.commandLine.appendSwitch(
|
||||||
"js-flags",
|
"js-flags",
|
||||||
// WebAssembly flags
|
// WebAssembly flags
|
||||||
@ -54,10 +70,6 @@ require("electron-debug")({
|
|||||||
showDevTools: false //disable automatic devTools on new window
|
showDevTools: false //disable automatic devTools on new window
|
||||||
});
|
});
|
||||||
|
|
||||||
// Prevent window being garbage collected
|
|
||||||
let mainWindow;
|
|
||||||
autoUpdater.autoDownload = false;
|
|
||||||
|
|
||||||
let icon = "assets/youtube-music.png";
|
let icon = "assets/youtube-music.png";
|
||||||
if (process.platform == "win32") {
|
if (process.platform == "win32") {
|
||||||
icon = "assets/generated/icon.ico";
|
icon = "assets/generated/icon.ico";
|
||||||
@ -160,22 +172,39 @@ function createMainWindow() {
|
|||||||
win.on("closed", onClosed);
|
win.on("closed", onClosed);
|
||||||
|
|
||||||
win.on("move", () => {
|
win.on("move", () => {
|
||||||
|
if (win.isMaximized()) return;
|
||||||
let position = win.getPosition();
|
let position = win.getPosition();
|
||||||
config.set("window-position", { x: position[0], y: position[1] });
|
lateSave("window-position", { x: position[0], y: position[1] });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let winWasMaximized;
|
||||||
|
|
||||||
win.on("resize", () => {
|
win.on("resize", () => {
|
||||||
const windowSize = win.getSize();
|
const windowSize = win.getSize();
|
||||||
|
|
||||||
config.set("window-maximized", win.isMaximized());
|
const isMaximized = win.isMaximized();
|
||||||
if (!win.isMaximized()) {
|
if (winWasMaximized !== isMaximized) {
|
||||||
config.set("window-size", {
|
winWasMaximized = isMaximized;
|
||||||
|
config.set("window-maximized", isMaximized);
|
||||||
|
}
|
||||||
|
if (!isMaximized) {
|
||||||
|
lateSave("window-size", {
|
||||||
width: windowSize[0],
|
width: windowSize[0],
|
||||||
height: windowSize[1],
|
height: windowSize[1],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let savedTimeouts = {};
|
||||||
|
function lateSave(key, value) {
|
||||||
|
if (savedTimeouts[key]) clearTimeout(savedTimeouts[key]);
|
||||||
|
|
||||||
|
savedTimeouts[key] = setTimeout(() => {
|
||||||
|
config.set(key, value);
|
||||||
|
savedTimeouts[key] = undefined;
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
win.webContents.on("render-process-gone", (event, webContents, details) => {
|
win.webContents.on("render-process-gone", (event, webContents, details) => {
|
||||||
showUnresponsiveDialog(win, details);
|
showUnresponsiveDialog(win, details);
|
||||||
});
|
});
|
||||||
@ -192,30 +221,31 @@ function createMainWindow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.once("browser-window-created", (event, win) => {
|
app.once("browser-window-created", (event, win) => {
|
||||||
// User agents are from https://developers.whatismybrowser.com/useragents/explore/
|
if (config.get("options.overrideUserAgent")) {
|
||||||
const originalUserAgent = win.webContents.userAgent;
|
// User agents are from https://developers.whatismybrowser.com/useragents/explore/
|
||||||
const userAgents = {
|
const originalUserAgent = win.webContents.userAgent;
|
||||||
mac: "Mozilla/5.0 (Macintosh; Intel Mac OS X 12.1; rv:95.0) Gecko/20100101 Firefox/95.0",
|
const userAgents = {
|
||||||
windows: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0",
|
mac: "Mozilla/5.0 (Macintosh; Intel Mac OS X 12.1; rv:95.0) Gecko/20100101 Firefox/95.0",
|
||||||
linux: "Mozilla/5.0 (Linux x86_64; rv:95.0) Gecko/20100101 Firefox/95.0",
|
windows: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0",
|
||||||
}
|
linux: "Mozilla/5.0 (Linux x86_64; rv:95.0) Gecko/20100101 Firefox/95.0",
|
||||||
|
|
||||||
const updatedUserAgent =
|
|
||||||
is.macOS() ? userAgents.mac :
|
|
||||||
is.windows() ? userAgents.windows :
|
|
||||||
userAgents.linux;
|
|
||||||
|
|
||||||
win.webContents.userAgent = updatedUserAgent;
|
|
||||||
app.userAgentFallback = updatedUserAgent;
|
|
||||||
|
|
||||||
win.webContents.session.webRequest.onBeforeSendHeaders((details, cb) => {
|
|
||||||
// this will only happen if login failed, and "retry" was pressed
|
|
||||||
if (win.webContents.getURL().startsWith("https://accounts.google.com") && details.url.startsWith("https://accounts.google.com")){
|
|
||||||
details.requestHeaders["User-Agent"] = originalUserAgent;
|
|
||||||
}
|
}
|
||||||
cb({ requestHeaders: details.requestHeaders });
|
|
||||||
});
|
|
||||||
|
|
||||||
|
const updatedUserAgent =
|
||||||
|
is.macOS() ? userAgents.mac :
|
||||||
|
is.windows() ? userAgents.windows :
|
||||||
|
userAgents.linux;
|
||||||
|
|
||||||
|
win.webContents.userAgent = updatedUserAgent;
|
||||||
|
app.userAgentFallback = updatedUserAgent;
|
||||||
|
|
||||||
|
win.webContents.session.webRequest.onBeforeSendHeaders((details, cb) => {
|
||||||
|
// this will only happen if login failed, and "retry" was pressed
|
||||||
|
if (win.webContents.getURL().startsWith("https://accounts.google.com") && details.url.startsWith("https://accounts.google.com")) {
|
||||||
|
details.requestHeaders["User-Agent"] = originalUserAgent;
|
||||||
|
}
|
||||||
|
cb({ requestHeaders: details.requestHeaders });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setupSongInfo(win);
|
setupSongInfo(win);
|
||||||
loadPlugins(win);
|
loadPlugins(win);
|
||||||
@ -325,12 +355,6 @@ app.on("ready", () => {
|
|||||||
|
|
||||||
mainWindow = createMainWindow();
|
mainWindow = createMainWindow();
|
||||||
setApplicationMenu(mainWindow);
|
setApplicationMenu(mainWindow);
|
||||||
if (config.get("options.restartOnConfigChanges")) {
|
|
||||||
config.watch(() => {
|
|
||||||
app.relaunch();
|
|
||||||
app.exit();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
setUpTray(app, mainWindow);
|
setUpTray(app, mainWindow);
|
||||||
|
|
||||||
// Autostart at login
|
// Autostart at login
|
||||||
|
|||||||
69
menu.js
69
menu.js
@ -68,7 +68,7 @@ const mainMenuTemplate = (win) => {
|
|||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
checked: config.get("options.autoUpdates"),
|
checked: config.get("options.autoUpdates"),
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
config.set("options.autoUpdates", item.checked);
|
config.setMenuOption("options.autoUpdates", item.checked);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -76,7 +76,7 @@ const mainMenuTemplate = (win) => {
|
|||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
checked: config.get("options.resumeOnStart"),
|
checked: config.get("options.resumeOnStart"),
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
config.set("options.resumeOnStart", item.checked);
|
config.setMenuOption("options.resumeOnStart", item.checked);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -84,7 +84,20 @@ const mainMenuTemplate = (win) => {
|
|||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
checked: config.get("options.removeUpgradeButton"),
|
checked: config.get("options.removeUpgradeButton"),
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
config.set("options.removeUpgradeButton", item.checked);
|
config.setMenuOption("options.removeUpgradeButton", item.checked);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Single instance lock",
|
||||||
|
type: "checkbox",
|
||||||
|
checked: config.get("options.singleInstanceLock"),
|
||||||
|
click: (item) => {
|
||||||
|
config.set("options.singleInstanceLock", item.checked);
|
||||||
|
if (item.checked && !app.hasSingleInstanceLock()) {
|
||||||
|
app.requestSingleInstanceLock();
|
||||||
|
} else if (!item.checked && app.hasSingleInstanceLock()) {
|
||||||
|
app.releaseSingleInstanceLock();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
...(is.windows() || is.linux()
|
...(is.windows() || is.linux()
|
||||||
@ -94,7 +107,7 @@ const mainMenuTemplate = (win) => {
|
|||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
checked: config.get("options.hideMenu"),
|
checked: config.get("options.hideMenu"),
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
config.set("options.hideMenu", item.checked);
|
config.setMenuOption("options.hideMenu", item.checked);
|
||||||
if (item.checked && !config.get("options.hideMenuWarned")) {
|
if (item.checked && !config.get("options.hideMenuWarned")) {
|
||||||
dialog.showMessageBox(win, {
|
dialog.showMessageBox(win, {
|
||||||
type: 'info', title: 'Hide Menu Enabled',
|
type: 'info', title: 'Hide Menu Enabled',
|
||||||
@ -114,7 +127,7 @@ const mainMenuTemplate = (win) => {
|
|||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
checked: config.get("options.startAtLogin"),
|
checked: config.get("options.startAtLogin"),
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
config.set("options.startAtLogin", item.checked);
|
config.setMenuOption("options.startAtLogin", item.checked);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -127,8 +140,8 @@ const mainMenuTemplate = (win) => {
|
|||||||
type: "radio",
|
type: "radio",
|
||||||
checked: !config.get("options.tray"),
|
checked: !config.get("options.tray"),
|
||||||
click: () => {
|
click: () => {
|
||||||
config.set("options.tray", false);
|
config.setMenuOption("options.tray", false);
|
||||||
config.set("options.appVisible", true);
|
config.setMenuOption("options.appVisible", true);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -137,8 +150,8 @@ const mainMenuTemplate = (win) => {
|
|||||||
checked:
|
checked:
|
||||||
config.get("options.tray") && config.get("options.appVisible"),
|
config.get("options.tray") && config.get("options.appVisible"),
|
||||||
click: () => {
|
click: () => {
|
||||||
config.set("options.tray", true);
|
config.setMenuOption("options.tray", true);
|
||||||
config.set("options.appVisible", true);
|
config.setMenuOption("options.appVisible", true);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -147,8 +160,8 @@ const mainMenuTemplate = (win) => {
|
|||||||
checked:
|
checked:
|
||||||
config.get("options.tray") && !config.get("options.appVisible"),
|
config.get("options.tray") && !config.get("options.appVisible"),
|
||||||
click: () => {
|
click: () => {
|
||||||
config.set("options.tray", true);
|
config.setMenuOption("options.tray", true);
|
||||||
config.set("options.appVisible", false);
|
config.setMenuOption("options.appVisible", false);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ type: "separator" },
|
{ type: "separator" },
|
||||||
@ -157,7 +170,7 @@ const mainMenuTemplate = (win) => {
|
|||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
checked: config.get("options.trayClickPlayPause"),
|
checked: config.get("options.trayClickPlayPause"),
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
config.set("options.trayClickPlayPause", item.checked);
|
config.setMenuOption("options.trayClickPlayPause", item.checked);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -166,20 +179,28 @@ const mainMenuTemplate = (win) => {
|
|||||||
{
|
{
|
||||||
label: "Advanced options",
|
label: "Advanced options",
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: "Proxy",
|
label: "Proxy",
|
||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
checked: !!config.get("options.proxy"),
|
checked: !!config.get("options.proxy"),
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
setProxy(item, win);
|
setProxy(item, win);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "Override useragent",
|
||||||
|
type: "checkbox",
|
||||||
|
checked: config.get("options.overrideUserAgent"),
|
||||||
|
click: (item) => {
|
||||||
|
config.setMenuOption("options.overrideUserAgent", item.checked);
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "Disable hardware acceleration",
|
label: "Disable hardware acceleration",
|
||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
checked: config.get("options.disableHardwareAcceleration"),
|
checked: config.get("options.disableHardwareAcceleration"),
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
config.set("options.disableHardwareAcceleration", item.checked);
|
config.setMenuOption("options.disableHardwareAcceleration", item.checked);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -187,7 +208,7 @@ const mainMenuTemplate = (win) => {
|
|||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
checked: config.get("options.restartOnConfigChanges"),
|
checked: config.get("options.restartOnConfigChanges"),
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
config.set("options.restartOnConfigChanges", item.checked);
|
config.setMenuOption("options.restartOnConfigChanges", item.checked);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -195,7 +216,7 @@ const mainMenuTemplate = (win) => {
|
|||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
checked: config.get("options.autoResetAppCache"),
|
checked: config.get("options.autoResetAppCache"),
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
config.set("options.autoResetAppCache", item.checked);
|
config.setMenuOption("options.autoResetAppCache", item.checked);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ type: "separator" },
|
{ type: "separator" },
|
||||||
@ -316,7 +337,7 @@ async function setProxy(item, win) {
|
|||||||
}, win);
|
}, win);
|
||||||
|
|
||||||
if (typeof output === "string") {
|
if (typeof output === "string") {
|
||||||
config.set("options.proxy", output);
|
config.setMenuOption("options.proxy", output);
|
||||||
item.checked = output !== "";
|
item.checked = output !== "";
|
||||||
} else { //user pressed cancel
|
} else { //user pressed cancel
|
||||||
item.checked = !item.checked; //reset checkbox
|
item.checked = !item.checked; //reset checkbox
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "youtube-music",
|
"name": "youtube-music",
|
||||||
"productName": "YouTube Music",
|
"productName": "YouTube Music",
|
||||||
"version": "1.15.0",
|
"version": "1.15.1",
|
||||||
"description": "YouTube Music Desktop App - including custom plugins",
|
"description": "YouTube Music Desktop App - including custom plugins",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": "th-ch/youtube-music",
|
"repository": "th-ch/youtube-music",
|
||||||
@ -89,7 +89,7 @@
|
|||||||
"async-mutex": "^0.3.2",
|
"async-mutex": "^0.3.2",
|
||||||
"browser-id3-writer": "^4.4.0",
|
"browser-id3-writer": "^4.4.0",
|
||||||
"chokidar": "^3.5.3",
|
"chokidar": "^3.5.3",
|
||||||
"custom-electron-prompt": "^1.4.0",
|
"custom-electron-prompt": "^1.4.1",
|
||||||
"custom-electron-titlebar": "^4.1.0",
|
"custom-electron-titlebar": "^4.1.0",
|
||||||
"discord-rpc": "^4.0.1",
|
"discord-rpc": "^4.0.1",
|
||||||
"electron-better-web-request": "^1.0.1",
|
"electron-better-web-request": "^1.0.1",
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
const { setOptions } = require("../../config/plugins");
|
const prompt = require("custom-electron-prompt");
|
||||||
const { edit } = require("../../config");
|
|
||||||
|
const { setMenuOptions } = require("../../config/plugins");
|
||||||
|
const promptOptions = require("../../providers/prompt-options");
|
||||||
const { clear, connect, registerRefresh, isConnected } = require("./back");
|
const { clear, connect, registerRefresh, isConnected } = require("./back");
|
||||||
|
|
||||||
let hasRegisterred = false;
|
let hasRegisterred = false;
|
||||||
@ -26,7 +28,7 @@ module.exports = (win, options, refreshMenu) => {
|
|||||||
checked: options.activityTimoutEnabled,
|
checked: options.activityTimoutEnabled,
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
options.activityTimoutEnabled = item.checked;
|
options.activityTimoutEnabled = item.checked;
|
||||||
setOptions('discord', options);
|
setMenuOptions('discord', options);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -35,13 +37,29 @@ module.exports = (win, options, refreshMenu) => {
|
|||||||
checked: options.listenAlong,
|
checked: options.listenAlong,
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
options.listenAlong = item.checked;
|
options.listenAlong = item.checked;
|
||||||
setOptions('discord', options);
|
setMenuOptions('discord', options);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Set timeout time in config",
|
label: "Set inactivity timeout",
|
||||||
// open config.json
|
click: () => setInactivityTimeout(win, options),
|
||||||
click: edit,
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function setInactivityTimeout(win, options) {
|
||||||
|
let output = await prompt({
|
||||||
|
title: 'Set Inactivity Timeout',
|
||||||
|
label: 'Enter inactivity timeout in seconds:',
|
||||||
|
value: Math.round((options.activityTimoutTime ?? 0) / 1e3),
|
||||||
|
type: "counter",
|
||||||
|
counterOptions: { minimum: 0, multiFire: true },
|
||||||
|
width: 450,
|
||||||
|
...promptOptions()
|
||||||
|
}, win)
|
||||||
|
|
||||||
|
if (output) {
|
||||||
|
options.activityTimoutTime = Math.round(output * 1e3);
|
||||||
|
setMenuOptions("discord", options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ const ytpl = require("ytpl");
|
|||||||
const chokidar = require('chokidar');
|
const chokidar = require('chokidar');
|
||||||
const filenamify = require('filenamify');
|
const filenamify = require('filenamify');
|
||||||
|
|
||||||
const { setOptions } = require("../../config/plugins");
|
const { setMenuOptions } = require("../../config/plugins");
|
||||||
const { sendError } = require("./back");
|
const { sendError } = require("./back");
|
||||||
const { defaultMenuDownloadLabel, getFolder, presets, setBadge } = require("./utils");
|
const { defaultMenuDownloadLabel, getFolder, presets, setBadge } = require("./utils");
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ module.exports = (win, options) => {
|
|||||||
});
|
});
|
||||||
if (result) {
|
if (result) {
|
||||||
options.downloadFolder = result[0];
|
options.downloadFolder = result[0];
|
||||||
setOptions("downloader", options);
|
setMenuOptions("downloader", options);
|
||||||
} // else = user pressed cancel
|
} // else = user pressed cancel
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -60,7 +60,7 @@ module.exports = (win, options) => {
|
|||||||
type: "radio",
|
type: "radio",
|
||||||
click: () => {
|
click: () => {
|
||||||
options.preset = preset;
|
options.preset = preset;
|
||||||
setOptions("downloader", options);
|
setMenuOptions("downloader", options);
|
||||||
},
|
},
|
||||||
checked: options.preset === preset || presets[preset] === undefined,
|
checked: options.preset === preset || presets[preset] === undefined,
|
||||||
})),
|
})),
|
||||||
|
|||||||
@ -3,20 +3,34 @@ const is = require("electron-is");
|
|||||||
|
|
||||||
module.exports = () => {
|
module.exports = () => {
|
||||||
ipcRenderer.on("update-song-info", (_, extractedSongInfo) => {
|
ipcRenderer.on("update-song-info", (_, extractedSongInfo) => {
|
||||||
const lyricsTab = document.querySelector('tp-yt-paper-tab[tabindex="-1"]');
|
const tabList = document.querySelectorAll("tp-yt-paper-tab");
|
||||||
|
const tabs = {
|
||||||
|
upNext: tabList[0],
|
||||||
|
lyrics: tabList[1],
|
||||||
|
discover: tabList[2],
|
||||||
|
}
|
||||||
|
|
||||||
// Check if disabled
|
// Check if disabled
|
||||||
if (!lyricsTab || !lyricsTab.hasAttribute("disabled")) {
|
if (!tabs.lyrics?.hasAttribute("disabled")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let hasLyrics = true;
|
||||||
|
|
||||||
const html = ipcRenderer.sendSync(
|
const html = ipcRenderer.sendSync(
|
||||||
"search-genius-lyrics",
|
"search-genius-lyrics",
|
||||||
extractedSongInfo
|
extractedSongInfo
|
||||||
);
|
);
|
||||||
if (!html) {
|
if (!html) {
|
||||||
|
// Delete previous lyrics if tab is open and couldn't get new lyrics
|
||||||
|
checkLyricsContainer(() => {
|
||||||
|
hasLyrics = false;
|
||||||
|
setTabsOnclick(undefined);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
} else if (is.dev()) {
|
}
|
||||||
|
|
||||||
|
if (is.dev()) {
|
||||||
console.log("Fetched lyrics from Genius");
|
console.log("Fetched lyrics from Genius");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,27 +49,16 @@ module.exports = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lyricsTab.removeAttribute("disabled");
|
enableLyricsTab();
|
||||||
lyricsTab.removeAttribute("aria-disabled");
|
|
||||||
document.querySelector("tp-yt-paper-tab").onclick = () => {
|
|
||||||
lyricsTab.removeAttribute("disabled");
|
|
||||||
lyricsTab.removeAttribute("aria-disabled");
|
|
||||||
};
|
|
||||||
|
|
||||||
lyricsTab.onclick = () => {
|
setTabsOnclick(enableLyricsTab);
|
||||||
|
|
||||||
|
checkLyricsContainer();
|
||||||
|
|
||||||
|
tabs.lyrics.onclick = () => {
|
||||||
const tabContainer = document.querySelector("ytmusic-tab-renderer");
|
const tabContainer = document.querySelector("ytmusic-tab-renderer");
|
||||||
const observer = new MutationObserver((_, observer) => {
|
const observer = new MutationObserver((_, observer) => {
|
||||||
const lyricsContainer = document.querySelector(
|
checkLyricsContainer(() => observer.disconnect());
|
||||||
'[page-type="MUSIC_PAGE_TYPE_TRACK_LYRICS"] > ytmusic-message-renderer'
|
|
||||||
);
|
|
||||||
if (lyricsContainer) {
|
|
||||||
lyricsContainer.innerHTML = `<div id="contents" class="style-scope ytmusic-section-list-renderer genius-lyrics">
|
|
||||||
${lyrics}
|
|
||||||
|
|
||||||
<yt-formatted-string class="footer style-scope ytmusic-description-shelf-renderer">Source : Genius</yt-formatted-string>
|
|
||||||
</div>`;
|
|
||||||
observer.disconnect();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
observer.observe(tabContainer, {
|
observer.observe(tabContainer, {
|
||||||
attributes: true,
|
attributes: true,
|
||||||
@ -63,5 +66,41 @@ module.exports = () => {
|
|||||||
subtree: true,
|
subtree: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function checkLyricsContainer(callback = () => {}) {
|
||||||
|
const lyricsContainer = document.querySelector(
|
||||||
|
'[page-type="MUSIC_PAGE_TYPE_TRACK_LYRICS"] > ytmusic-message-renderer'
|
||||||
|
);
|
||||||
|
if (lyricsContainer) {
|
||||||
|
callback();
|
||||||
|
setLyrics(lyricsContainer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLyrics(lyricsContainer) {
|
||||||
|
lyricsContainer.innerHTML =
|
||||||
|
`<div id="contents" class="style-scope ytmusic-section-list-renderer description ytmusic-description-shelf-renderer genius-lyrics">
|
||||||
|
${hasLyrics ? lyrics : 'Could not retrieve lyrics from genius'}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<yt-formatted-string class="footer style-scope ytmusic-description-shelf-renderer" style="align-self: baseline"></yt-formatted-string>`;
|
||||||
|
if (hasLyrics) {
|
||||||
|
lyricsContainer.querySelector('.footer').textContent = 'Source: Genius';
|
||||||
|
enableLyricsTab();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTabsOnclick(callback) {
|
||||||
|
for (const tab of [tabs.upNext, tabs.discover]) {
|
||||||
|
if (tab) {
|
||||||
|
tab.onclick = callback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableLyricsTab() {
|
||||||
|
tabs.lyrics.removeAttribute("disabled");
|
||||||
|
tabs.lyrics.removeAttribute("aria-disabled");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,8 +6,7 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#contents.genius-lyrics {
|
.description {
|
||||||
font-size: 1vw;
|
font-size: 1.1vw !important;
|
||||||
opacity: 0.9;
|
text-align: center !important;
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const { setOptions } = require("../../config/plugins");
|
const { setMenuOptions } = require("../../config/plugins");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const { app } = require("electron");
|
const { app } = require("electron");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
@ -15,7 +15,7 @@ module.exports.icons = {
|
|||||||
|
|
||||||
module.exports.setOption = (options, option, value) => {
|
module.exports.setOption = (options, option, value) => {
|
||||||
options[option] = value;
|
options[option] = value;
|
||||||
setOptions("notifications", options)
|
setMenuOptions("notifications", options)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.urgencyLevels = [
|
module.exports.urgencyLevels = [
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
const { ipcRenderer } = require("electron");
|
const { ipcRenderer } = require("electron");
|
||||||
const { globalShortcut } = require('@electron/remote');
|
const { globalShortcut } = require('@electron/remote');
|
||||||
|
|
||||||
const { setOptions, isEnabled } = require("../../config/plugins");
|
const { setOptions, setMenuOptions, isEnabled } = require("../../config/plugins");
|
||||||
|
|
||||||
function $(selector) { return document.querySelector(selector); }
|
function $(selector) { return document.querySelector(selector); }
|
||||||
let api;
|
let api;
|
||||||
@ -48,7 +48,7 @@ function firstRun(options) {
|
|||||||
for (option in newOptions) {
|
for (option in newOptions) {
|
||||||
options[option] = newOptions[option];
|
options[option] = newOptions[option];
|
||||||
}
|
}
|
||||||
setOptions("precise-volume", options);
|
setMenuOptions("precise-volume", options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
const { enabled } = require("./back");
|
const { enabled } = require("./back");
|
||||||
const { setOptions } = require("../../config/plugins");
|
const { setMenuOptions } = require("../../config/plugins");
|
||||||
const prompt = require("custom-electron-prompt");
|
const prompt = require("custom-electron-prompt");
|
||||||
const promptOptions = require("../../providers/prompt-options");
|
const promptOptions = require("../../providers/prompt-options");
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ function changeOptions(changedOptions, options, win) {
|
|||||||
if (enabled()) {
|
if (enabled()) {
|
||||||
win.webContents.send("setOptions", changedOptions);
|
win.webContents.send("setOptions", changedOptions);
|
||||||
} else { // Fallback to usual method if disabled
|
} else { // Fallback to usual method if disabled
|
||||||
setOptions("precise-volume", options);
|
setMenuOptions("precise-volume", options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const { setOptions } = require("../../config/plugins");
|
const { setMenuOptions } = require("../../config/plugins");
|
||||||
const prompt = require("custom-electron-prompt");
|
const prompt = require("custom-electron-prompt");
|
||||||
const promptOptions = require("../../providers/prompt-options");
|
const promptOptions = require("../../providers/prompt-options");
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ function setOption(options, key = null, newValue = null) {
|
|||||||
options[key] = newValue;
|
options[key] = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
setOptions("shortcuts", options);
|
setMenuOptions("shortcuts", options);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function for keybind prompt
|
// Helper function for keybind prompt
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const { setOptions } = require("../../config/plugins");
|
const { setMenuOptions } = require("../../config/plugins");
|
||||||
|
|
||||||
module.exports = (win, options) => [
|
module.exports = (win, options) => [
|
||||||
{
|
{
|
||||||
@ -7,7 +7,7 @@ module.exports = (win, options) => [
|
|||||||
checked: options.forceHide,
|
checked: options.forceHide,
|
||||||
click: item => {
|
click: item => {
|
||||||
options.forceHide = item.checked;
|
options.forceHide = item.checked;
|
||||||
setOptions("video-toggle", options);
|
setMenuOptions("video-toggle", options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
6
providers/app-controls.js
Normal file
6
providers/app-controls.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
const app = require("electron").app || require('@electron/remote').app;
|
||||||
|
|
||||||
|
module.exports.restart = () => {
|
||||||
|
app.relaunch();
|
||||||
|
app.exit();
|
||||||
|
};
|
||||||
@ -6,7 +6,8 @@ const config = require("../config");
|
|||||||
|
|
||||||
global.songInfo = {};
|
global.songInfo = {};
|
||||||
|
|
||||||
function $(selector) { return document.querySelector(selector); }
|
const $ = s => document.querySelector(s);
|
||||||
|
const $$ = s => Array.from(document.querySelectorAll(s));
|
||||||
|
|
||||||
ipcRenderer.on("update-song-info", async (_, extractedSongInfo) => {
|
ipcRenderer.on("update-song-info", async (_, extractedSongInfo) => {
|
||||||
global.songInfo = JSON.parse(extractedSongInfo);
|
global.songInfo = JSON.parse(extractedSongInfo);
|
||||||
@ -43,7 +44,11 @@ module.exports = () => {
|
|||||||
|
|
||||||
function sendSongInfo() {
|
function sendSongInfo() {
|
||||||
const data = apiEvent.detail.getPlayerResponse();
|
const data = apiEvent.detail.getPlayerResponse();
|
||||||
data.videoDetails.album = $('ytmusic-player-page')?.__data?.playerPageWatchMetadata?.albumName?.runs[0].text
|
|
||||||
|
data.videoDetails.album = $$(
|
||||||
|
".byline.ytmusic-player-bar > .yt-simple-endpoint"
|
||||||
|
).find(e => e.href?.includes("browse"))?.textContent;
|
||||||
|
|
||||||
data.videoDetails.elapsedSeconds = Math.floor(video.currentTime);
|
data.videoDetails.elapsedSeconds = Math.floor(video.currentTime);
|
||||||
data.videoDetails.isPaused = false;
|
data.videoDetails.isPaused = false;
|
||||||
ipcRenderer.send("video-src-changed", JSON.stringify(data));
|
ipcRenderer.send("video-src-changed", JSON.stringify(data));
|
||||||
|
|||||||
@ -112,13 +112,12 @@ const suffixesToRemove = [
|
|||||||
" - topic",
|
" - topic",
|
||||||
"vevo",
|
"vevo",
|
||||||
" (performance video)",
|
" (performance video)",
|
||||||
" (official music video)",
|
|
||||||
" (official video)",
|
|
||||||
" (clip officiel)",
|
" (clip officiel)",
|
||||||
];
|
];
|
||||||
|
|
||||||
function cleanupName(name) {
|
function cleanupName(name) {
|
||||||
if (!name) return name;
|
if (!name) return name;
|
||||||
|
name = name.replace(/\((?:official)?[ ]?(?:music)?[ ]?(?:lyric[s]?)?[ ]?(?:video)?\)$/i, '')
|
||||||
const lowCaseName = name.toLowerCase();
|
const lowCaseName = name.toLowerCase();
|
||||||
for (const suffix of suffixesToRemove) {
|
for (const suffix of suffixesToRemove) {
|
||||||
if (lowCaseName.endsWith(suffix)) {
|
if (lowCaseName.endsWith(suffix)) {
|
||||||
|
|||||||
@ -2725,10 +2725,10 @@ cssstyle@^2.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
cssom "~0.3.6"
|
cssom "~0.3.6"
|
||||||
|
|
||||||
custom-electron-prompt@^1.4.0:
|
custom-electron-prompt@^1.4.1:
|
||||||
version "1.4.0"
|
version "1.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/custom-electron-prompt/-/custom-electron-prompt-1.4.0.tgz#04d261372807b87ec07ed12e990306d5debd5667"
|
resolved "https://registry.yarnpkg.com/custom-electron-prompt/-/custom-electron-prompt-1.4.1.tgz#79adc3d5cd9a372e5dfe43b21de70f0fe7d1c2f7"
|
||||||
integrity sha512-tqDa3yDILVI3xxwNRW1m2fyQgdMYtFcnl1d3uMx8Tt6sQ9zG+Y4n/ie4VbttQaq7dJvFCu9K3JX65K8hfaSf1g==
|
integrity sha512-bR6JhEusBxKnooXfFFlIIUhDbF23eaDhaYwvqcw3ZTcdEzzJew63+ilwhIwD7flRAO+sCroaLwP495VBexHg/A==
|
||||||
|
|
||||||
custom-electron-titlebar@^3.2.10:
|
custom-electron-titlebar@^3.2.10:
|
||||||
version "3.2.10"
|
version "3.2.10"
|
||||||
|
|||||||
Reference in New Issue
Block a user