Merge pull request #249 from Araxeus/update-in-app-menu

Update and simplify in-app-menu
This commit is contained in:
th-ch
2021-06-25 23:03:05 +02:00
committed by GitHub
6 changed files with 221 additions and 314 deletions

445
menu.js
View File

@ -7,12 +7,13 @@ const is = require("electron-is");
const { getAllPlugins } = require("./plugins/utils"); const { getAllPlugins } = require("./plugins/utils");
const config = require("./config"); const config = require("./config");
const pluginEnabledMenu = (win, plugin, label = "", hasSubmenu = false) => ({ // true only if in-app-menu was loaded on launch
const inAppMenuActive = config.plugins.isEnabled("in-app-menu");
const pluginEnabledMenu = (plugin, label = "", hasSubmenu = false, refreshMenu = undefined) => ({
label: label || plugin, label: label || plugin,
type: "checkbox", type: "checkbox",
checked: config.plugins.isEnabled(plugin), checked: config.plugins.isEnabled(plugin),
//Submenu check used in in-app-menu
hasSubmenu: hasSubmenu || undefined,
click: (item) => { click: (item) => {
if (item.checked) { if (item.checked) {
config.plugins.enable(plugin); config.plugins.enable(plugin);
@ -20,252 +21,226 @@ const pluginEnabledMenu = (win, plugin, label = "", hasSubmenu = false) => ({
config.plugins.disable(plugin); config.plugins.disable(plugin);
} }
if (hasSubmenu) { if (hasSubmenu) {
this.setApplicationMenu(win); refreshMenu();
} }
}, },
}); });
const mainMenuTemplate = (win) => [ const mainMenuTemplate = (win) => {
{ const refreshMenu = () => {
label: "Plugins", this.setApplicationMenu(win);
submenu: [ if (inAppMenuActive) {
...getAllPlugins().map((plugin) => { win.webContents.send("updateMenu", true);
const pluginPath = path.join(__dirname, "plugins", plugin, "menu.js") }
if (existsSync(pluginPath)) { }
if (!config.plugins.isEnabled(plugin)) { return [
return pluginEnabledMenu(win, plugin, "", true); {
label: "Plugins",
submenu: [
...getAllPlugins().map((plugin) => {
const pluginPath = path.join(__dirname, "plugins", plugin, "menu.js")
if (existsSync(pluginPath)) {
if (!config.plugins.isEnabled(plugin)) {
return pluginEnabledMenu(plugin, "", true, refreshMenu);
}
const getPluginMenu = require(pluginPath);
return {
label: plugin,
submenu: [
pluginEnabledMenu(plugin, "Enabled", true, refreshMenu),
...getPluginMenu(win, config.plugins.getOptions(plugin), refreshMenu),
],
};
} }
const getPluginMenu = require(pluginPath);
return {
label: plugin,
submenu: [
pluginEnabledMenu(win, plugin, "Enabled", true),
...getPluginMenu(win, config.plugins.getOptions(plugin), () =>
module.exports.setApplicationMenu(win)
),
],
};
}
return pluginEnabledMenu(win, plugin); return pluginEnabledMenu(plugin);
}), }),
], ],
}, },
{ {
label: "Options", label: "Options",
submenu: [ submenu: [
{ {
label: "Auto-update", label: "Auto-update",
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.set("options.autoUpdates", item.checked);
},
},
{
label: "Resume last song when app starts",
type: "checkbox",
checked: config.get("options.resumeOnStart"),
click: (item) => {
config.set("options.resumeOnStart", item.checked);
},
},
...(is.windows() || is.linux()
? [
{
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);
},
},
]
: []),
{
label: "Tray",
submenu: [
{
label: "Disabled",
type: "radio",
checked: !config.get("options.tray"),
click: () => {
config.set("options.tray", false);
config.set("options.appVisible", true);
},
},
{
label: "Enabled + app visible",
type: "radio",
checked:
config.get("options.tray") && config.get("options.appVisible"),
click: () => {
config.set("options.tray", true);
config.set("options.appVisible", true);
},
},
{
label: "Enabled + app hidden",
type: "radio",
checked:
config.get("options.tray") && !config.get("options.appVisible"),
click: () => {
config.set("options.tray", true);
config.set("options.appVisible", false);
},
},
{ type: "separator" },
{
label: "Play/Pause on click",
type: "checkbox",
checked: config.get("options.trayClickPlayPause"),
click: (item) => {
config.set("options.trayClickPlayPause", item.checked);
},
},
],
},
{ type: "separator" },
{
label: "Advanced options",
submenu: [
{
label: "Disable hardware acceleration",
type: "checkbox",
checked: config.get("options.disableHardwareAcceleration"),
click: (item) => {
config.set("options.disableHardwareAcceleration", item.checked);
},
},
{
label: "Restart on config changes",
type: "checkbox",
checked: config.get("options.restartOnConfigChanges"),
click: (item) => {
config.set("options.restartOnConfigChanges", item.checked);
},
},
{
label: "Reset App cache when app starts",
type: "checkbox",
checked: config.get("options.autoResetAppCache"),
click: (item) => {
config.set("options.autoResetAppCache", item.checked);
},
},
{ type: "separator" },
{
label: "Toggle DevTools",
// Cannot use "toggleDevTools" role in MacOS
click: () => {
const { webContents } = win;
if (webContents.isDevToolsOpened()) {
webContents.closeDevTools();
} else {
const devToolsOptions = {};
webContents.openDevTools(devToolsOptions);
}
},
},
{
label: "Edit config.json",
click: () => {
config.edit();
},
},
]
},
],
},
{
label: "View",
submenu: [
{
label: "Reload",
click: () => {
win.webContents.reload();
}, },
}, {
{ label: "Resume last song when app starts",
label: "Force Reload", type: "checkbox",
click: () => { checked: config.get("options.resumeOnStart"),
win.webContents.reloadIgnoringCache(); click: (item) => {
config.set("options.resumeOnStart", item.checked);
},
}, },
}, ...(is.windows() || is.linux()
{ type: "separator" }, ? [
{ {
label: "Zoom In", label: "Hide menu",
click: () => { type: "checkbox",
win.webContents.setZoomLevel( checked: config.get("options.hideMenu"),
win.webContents.getZoomLevel() + 1 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);
},
},
]
: []),
{
label: "Tray",
submenu: [
{
label: "Disabled",
type: "radio",
checked: !config.get("options.tray"),
click: () => {
config.set("options.tray", false);
config.set("options.appVisible", true);
},
},
{
label: "Enabled + app visible",
type: "radio",
checked:
config.get("options.tray") && config.get("options.appVisible"),
click: () => {
config.set("options.tray", true);
config.set("options.appVisible", true);
},
},
{
label: "Enabled + app hidden",
type: "radio",
checked:
config.get("options.tray") && !config.get("options.appVisible"),
click: () => {
config.set("options.tray", true);
config.set("options.appVisible", false);
},
},
{ type: "separator" },
{
label: "Play/Pause on click",
type: "checkbox",
checked: config.get("options.trayClickPlayPause"),
click: (item) => {
config.set("options.trayClickPlayPause", item.checked);
},
},
],
}, },
}, { type: "separator" },
{ {
label: "Zoom Out", label: "Advanced options",
click: () => { submenu: [
win.webContents.setZoomLevel( {
win.webContents.getZoomLevel() - 1 label: "Disable hardware acceleration",
); type: "checkbox",
checked: config.get("options.disableHardwareAcceleration"),
click: (item) => {
config.set("options.disableHardwareAcceleration", item.checked);
},
},
{
label: "Restart on config changes",
type: "checkbox",
checked: config.get("options.restartOnConfigChanges"),
click: (item) => {
config.set("options.restartOnConfigChanges", item.checked);
},
},
{
label: "Reset App cache when app starts",
type: "checkbox",
checked: config.get("options.autoResetAppCache"),
click: (item) => {
config.set("options.autoResetAppCache", item.checked);
},
},
{ type: "separator" },
is.macOS() ?
{
label: "Toggle DevTools",
// Cannot use "toggleDevTools" role in MacOS
click: () => {
const { webContents } = win;
if (webContents.isDevToolsOpened()) {
webContents.closeDevTools();
} else {
const devToolsOptions = {};
webContents.openDevTools(devToolsOptions);
}
},
} :
{ role: "toggleDevTools" },
{
label: "Edit config.json",
click: () => {
config.edit();
},
},
]
}, },
}, ],
{ },
label: "Reset Zoom", {
click: () => { label: "View",
win.webContents.setZoomLevel(0); submenu: [
{ role: "reload" },
{ role: "forceReload" },
{ type: "separator" },
{ role: "zoomIn" },
{ role: "zoomOut" },
{ role: "resetZoom" },
],
},
{
label: "Navigation",
submenu: [
{
label: "Go back",
click: () => {
if (win.webContents.canGoBack()) {
win.webContents.goBack();
}
},
}, },
}, {
], label: "Go forward",
}, click: () => {
{ if (win.webContents.canGoForward()) {
label: "Navigation", win.webContents.goForward();
submenu: [ }
{ },
label: "Go back",
click: () => {
if (win.webContents.canGoBack()) {
win.webContents.goBack();
}
}, },
}, {
{ label: "Restart App",
label: "Go forward", click: () => {
click: () => { app.relaunch();
if (win.webContents.canGoForward()) { app.quit();
win.webContents.goForward(); },
}
}, },
}, { role: "quit" },
{ ],
label: "Restart App", },
click: () => { ];
app.relaunch(); }
app.quit();
},
},
{
label: "Quit App",
click: () => {
app.quit();
},
},
],
},
];
module.exports.mainMenuTemplate = mainMenuTemplate; module.exports.mainMenuTemplate = mainMenuTemplate;
module.exports.setApplicationMenu = (win) => { module.exports.setApplicationMenu = (win) => {

View File

@ -69,8 +69,8 @@
"YoutubeNonStop": "git://github.com/lawfx/YoutubeNonStop.git#v0.9.0", "YoutubeNonStop": "git://github.com/lawfx/YoutubeNonStop.git#v0.9.0",
"async-mutex": "^0.3.1", "async-mutex": "^0.3.1",
"browser-id3-writer": "^4.4.0", "browser-id3-writer": "^4.4.0",
"chokidar": "^3.5.1",
"custom-electron-titlebar": "^3.2.7", "custom-electron-titlebar": "^3.2.7",
"chokidar": "^3.5.1",
"discord-rpc": "^3.2.0", "discord-rpc": "^3.2.0",
"electron-debug": "^3.2.0", "electron-debug": "^3.2.0",
"electron-is": "^3.0.0", "electron-is": "^3.0.0",

View File

@ -1,83 +1,33 @@
const path = require("path"); const path = require("path");
const { Menu } = require("electron");
const electronLocalshortcut = require("electron-localshortcut"); const electronLocalshortcut = require("electron-localshortcut");
const config = require("../../config"); const config = require("../../config");
const { setApplicationMenu } = require("../../menu");
const { injectCSS } = require("../utils"); const { injectCSS } = require("../utils");
//tracks menu visibility //tracks menu visibility
let visible = true; let visible = true;
// win hook for fixing menu
let win;
const originalBuildMenu = Menu.buildFromTemplate;
// This function natively gets called on all submenu so no more reason to use recursion
Menu.buildFromTemplate = (template) => {
// Fix checkboxes and radio buttons
updateTemplate(template);
// return as normal
return originalBuildMenu(template);
};
module.exports = (winImport) => {
win = winImport;
module.exports = (win) => {
// css for custom scrollbar + disable drag area(was causing bugs) // css for custom scrollbar + disable drag area(was causing bugs)
injectCSS(win.webContents, path.join(__dirname, "style.css")); injectCSS(win.webContents, path.join(__dirname, "style.css"));
win.once("ready-to-show", () => { win.once("ready-to-show", () => {
setApplicationMenu(win);
//register keyboard shortcut && hide menu if hideMenu is enabled //register keyboard shortcut && hide menu if hideMenu is enabled
if (config.get("options.hideMenu")) { if (config.get("options.hideMenu")) {
electronLocalshortcut.register(win, "Esc", () => { electronLocalshortcut.register(win, "Esc", () => {
switchMenuVisibility(); setMenuVisibility(!visible);
}); });
} }
}); });
//set menu visibility on load
win.webContents.once("did-finish-load", () => { win.webContents.once("did-finish-load", () => {
// fix bug with menu not applying on start when no internet connection available // fix bug with menu not applying on start when no internet connection available
setMenuVisibility(!config.get("options.hideMenu")); setMenuVisibility(!config.get("options.hideMenu"));
}); });
function setMenuVisibility(value) {
visible = value;
win.webContents.send("updateMenu", visible);
}
}; };
function switchMenuVisibility() {
setMenuVisibility(!visible);
}
function setMenuVisibility(value) {
visible = value;
win.webContents.send("updateMenu", visible);
}
function updateCheckboxesAndRadioButtons(item, isRadio, hasSubmenu) {
if (!isRadio) {
//fix checkbox
item.checked = !item.checked;
}
//update menu if radio / hasSubmenu
if (isRadio || hasSubmenu) {
win.webContents.send("updateMenu", true);
}
}
// Update checkboxes/radio buttons
function updateTemplate(template) {
for (let item of template) {
// Change onClick of checkbox+radio
if ((item.type === "checkbox" || item.type === "radio") && !item.fixed) {
const originalOnclick = item.click;
item.click = (itemClicked) => {
originalOnclick(itemClicked);
updateCheckboxesAndRadioButtons(itemClicked, item.type === "radio", item.hasSubmenu);
};
item.fixed = true;
}
}
}

View File

@ -10,15 +10,7 @@ module.exports = () => {
bar.updateTitle(" "); bar.updateTitle(" ");
document.title = "Youtube Music"; document.title = "Youtube Music";
ipcRenderer.on("updateMenu", function (event, menu) { ipcRenderer.on("updateMenu", function (_event, showMenu) {
if (menu) { bar.updateMenu(showMenu ? remote.Menu.getApplicationMenu() : null);
bar.updateMenu(remote.Menu.getApplicationMenu());
} else {
try {
bar.updateMenu(null);
} catch (e) {
//will always throw type error - null isn't menu, but it works
}
}
}); });
}; };

View File

@ -4,11 +4,6 @@
font-size: 14px !important; font-size: 14px !important;
} }
/* allow submenu's to show correctly */
.menubar-menu-container {
overflow-y: visible !important;
}
/* fixes scrollbar positioning relative to nav bar */ /* fixes scrollbar positioning relative to nav bar */
#nav-bar-background.ytmusic-app-layout { #nav-bar-background.ytmusic-app-layout {
right: 15px !important; right: 15px !important;

View File

@ -63,12 +63,7 @@ module.exports.setUpTray = (app, win) => {
app.quit(); app.quit();
}, },
}, },
{ { role: "quit" }
label: "Quit",
click: () => {
app.quit();
},
},
]; ];
const trayMenu = Menu.buildFromTemplate(template); const trayMenu = Menu.buildFromTemplate(template);