diff --git a/index.js b/index.js index 8b687673..fabf3312 100644 --- a/index.js +++ b/index.js @@ -99,7 +99,7 @@ function createMainWindow() { } : undefined), }, - frame: !is.macOS(), + frame: !is.macOS() && !config.plugins.isEnabled("styled-bars"), titleBarStyle: is.macOS() ? "hiddenInset" : "default", autoHideMenuBar: config.get("options.hideMenu"), }); diff --git a/menu.js b/menu.js index 91bb073d..3f5744b4 100644 --- a/menu.js +++ b/menu.js @@ -219,6 +219,14 @@ const mainMenuTemplate = (win) => [ } }, }, + { + label: 'Restart App', + click: () => {app.relaunch(); app.quit();} + } , + { + label: 'Quit App', + click: () => {app.quit();} + } ], }, ]; diff --git a/package.json b/package.json index 8769c834..ce144c38 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-titlebar": "^3.2.6", "discord-rpc": "^3.2.0", "downloads-folder": "^3.0.1", "electron-debug": "^3.2.0", diff --git a/plugins/styled-bars/back.js b/plugins/styled-bars/back.js new file mode 100644 index 00000000..37fd6c8b --- /dev/null +++ b/plugins/styled-bars/back.js @@ -0,0 +1,111 @@ +const { injectCSS } = require('../utils'); +const { Menu } = require('electron'); +const path = require('path'); +const electronLocalshortcut = require("electron-localshortcut"); +const config = require('../../config'); +var { mainMenuTemplate } = require("../../menu"); + +//override menu template for custom menu +const originTemplate = mainMenuTemplate; +mainMenuTemplate = function (winHook) { + //get template + let template = originTemplate(winHook); + //fix checkbox and roles + fixMenu(template); + //return as normal + return template; +} +//win hook for fixing menu +let win; + +//check that menu doesn't get created twice +let done = false; + +module.exports = winImport => { + win = winImport; + // css for custom scrollbar + disable drag area(was causing bugs) + injectCSS(win.webContents, path.join(__dirname, 'style.css')); + win.on('ready-to-show', () => { + // (apparently ready-to-show is called twice) + if (done) { + return + } + done = true; + let template = mainMenuTemplate(win); + let menu = Menu.buildFromTemplate(template); + Menu.setApplicationMenu(menu); + + //register keyboard shortcut && hide menu if hideMenu is enabled + if (config.get('options.hideMenu')) { + switchMenuVisibility(); + electronLocalshortcut.register(win, 'Esc', () => { + switchMenuVisibility(); + }); + } + }); +}; + +let visible = true; +function switchMenuVisibility() { + visible=!visible; + win.webContents.send('updateMenu',visible) +} + +//go over each item in menu +function fixMenu(template) { + for (let index in template) { + let item = template[index]; + //apply function on submenu + if (item.submenu != null) { + fixMenu(item.submenu); + } + //change onClick of checkbox+radio + else if (item.type === 'checkbox' || item.type === 'radio') { + let ogOnclick = item.click; + item.click = (itemClicked) => { + ogOnclick(itemClicked); + checkCheckbox(itemClicked); + }; + } + //customize roles + else if (item.role != null) { + fixRoles(item) + } + } +} + +//custom menu doesn't support roles, so they get injected manually +function fixRoles(MenuItem) { + switch (MenuItem.role) { + case 'reload': + MenuItem.label = 'Reload'; + MenuItem.click = () => { win.webContents.reload(); } + break; + case 'forceReload': + MenuItem.label = 'Force Reload'; + MenuItem.click = () => { win.webContents.reloadIgnoringCache(); } + break; + case 'zoomIn': + MenuItem.label = 'Zoom In'; + MenuItem.click = () => { win.webContents.setZoomLevel(win.webContents.getZoomLevel() + 1); } + break; + case 'zoomOut': + MenuItem.label = 'Zoom Out'; + MenuItem.click = () => { win.webContents.setZoomLevel(win.webContents.getZoomLevel() - 1); } + break; + case 'resetZoom': + MenuItem.label = 'Reset Zoom'; + MenuItem.click = () => { win.webContents.setZoomLevel(0); } + break; + default: + console.log(`Error fixing MenuRoles: "${MenuItem.role}" was not expected`); + } + delete MenuItem.role; +} + +function checkCheckbox(item) { + //check item + item.checked = !item.checked; + //update menu (closes it) + win.webContents.send('updateMenu', true); +} diff --git a/plugins/styled-bars/front.js b/plugins/styled-bars/front.js new file mode 100644 index 00000000..d5274364 --- /dev/null +++ b/plugins/styled-bars/front.js @@ -0,0 +1,23 @@ +const customTitlebar = require('custom-electron-titlebar'); +const {remote, ipcRenderer} = require('electron'); + +module.exports = () => { + const myBar = new customTitlebar.Titlebar({ + backgroundColor: customTitlebar.Color.fromHex('#050505'), + itemBackgroundColor: customTitlebar.Color.fromHex('#121212') + }); + myBar.updateTitle(' '); + document.title = 'Youtube Music'; + + ipcRenderer.on('updateMenu', function (event, menu) { + if (menu) { + myBar.updateMenu(remote.Menu.getApplicationMenu()); + } else { + try { + myBar.updateMenu(null); + } catch (e) { + //will always throw type error - null isn't menu, but it works + } + } + }); +}; \ No newline at end of file diff --git a/plugins/styled-bars/style.css b/plugins/styled-bars/style.css new file mode 100644 index 00000000..f0d0c88b --- /dev/null +++ b/plugins/styled-bars/style.css @@ -0,0 +1,61 @@ +/* increase font size for menu and menuItems */ +.titlebar, .menubar-menu-container .action-label{ + font-size: 14px !important; +} + +/* allow submenu's to show correctly */ +.menubar-menu-container{ + overflow-y: visible !important; +} +/* fixes scrollbar positioning relative to nav bar */ +#nav-bar-background.ytmusic-app-layout { + right: 15px !important; +} +/* remove window dragging for nav bar (conflict with titlebar drag) */ +ytmusic-nav-bar, +.tab-titleiron-icon, +ytmusic-pivot-bar-item-renderer { + -webkit-app-region : unset; +} + +/* Move navBar downwards and make it opaque */ +ytmusic-app-layout { + --ytmusic-nav-bar-height: 120px; +} + +ytmusic-search-box.ytmusic-nav-bar { + margin-top: 29px; +} + +.center-content.ytmusic-nav-bar { + background: #030303; +} +yt-page-navigation-progress, +#progress.yt-page-navigation-progress, +ytmusic-item-section-renderer[has-item-section-tabbed-header-renderer_] #header.ytmusic-item-section-renderer, +ytmusic-header-renderer.ytmusic-search-page { + top: 90px !important; +} +/* Custom scrollbar */ +::-webkit-scrollbar { + width: 12px; + background-color: #030303; + -webkit-border-radius: 100px; +} +/* hover effect for both scrollbar area, and scrollbar 'thumb' */ +::-webkit-scrollbar:hover { + background-color: rgba(15, 15, 15, 0.699); +} + +/* The scrollbar 'thumb' ...that marque oval shape in a scrollbar */ +::-webkit-scrollbar-thumb:vertical { + background-clip: padding-box; + border: 2px solid rgba(0, 0, 0, 0); + + background: rgb(49, 0, 0); + -webkit-border-radius: 100px; +} +::-webkit-scrollbar-thumb:vertical:active { + background: rgb(56, 0, 0); /* Some darker color when you click it */ + -webkit-border-radius: 100px; +} \ No newline at end of file diff --git a/tray.js b/tray.js index 75af7494..e8eb22d3 100644 --- a/tray.js +++ b/tray.js @@ -32,7 +32,7 @@ module.exports.setUpTray = (app, win) => { } }); - const trayMenu = Menu.buildFromTemplate([ + let template = [ { label: "Play/Pause", click: () => { @@ -64,6 +64,20 @@ module.exports.setUpTray = (app, win) => { app.quit(); }, }, - ]); + ]; + + // delete quit button from navigation submenu + let navigation = getIndex(template,'Navigation'); + let quit = getIndex(template[navigation].submenu,'Quit App'); + delete template[navigation].submenu[quit]; + + // delete View submenu (all buttons are useless in tray) + delete template[getIndex(template, 'View')]; + + const trayMenu = Menu.buildFromTemplate(template); tray.setContextMenu(trayMenu); }; + +function getIndex(arr,label) { + return arr.findIndex(item => item.label === label) +} diff --git a/yarn.lock b/yarn.lock index 045dacdd..c969527e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2636,6 +2636,11 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" +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" + integrity sha512-P3ZGEr0eouUHqhdBBXllpuy2bFhfSmp+32HQBPcwzujjIsUhQxQj/nCpJiFa4SUGAEp1ifu/icuZdDKNNX72Tw== + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"