diff --git a/index.js b/index.js index 90096ecf..50e31d10 100644 --- a/index.js +++ b/index.js @@ -197,13 +197,6 @@ app.once("browser-window-created", (event, win) => { event.preventDefault(); }); - win.webContents.on("did-navigate-in-page", () => { - const url = win.webContents.getURL(); - if (url.startsWith("https://music.youtube.com")) { - config.set("url", url); - } - }); - win.webContents.on("will-navigate", (_, url) => { if (url.startsWith("https://accounts.google.com")) { // Force user-agent "Firefox Windows" for Google OAuth to work @@ -348,6 +341,14 @@ app.on("ready", () => { }); } + if (config.get("options.hideMenu") && !config.get("options.hideMenuWarned")) { + electron.dialog.showMessageBox(mainWindow, { + type: 'info', title: 'Hide Menu Enabled', + message: "Menu is hidden, use 'Alt' to show it (or 'Escape' if using in-app-menu)" + }); + config.set("options.hideMenuWarned", true); + } + // Optimized for Mac OS X if (is.macOS() && !config.get("options.appVisible")) { app.dock.hide(); diff --git a/menu.js b/menu.js index afea532d..0a62249b 100644 --- a/menu.js +++ b/menu.js @@ -1,7 +1,7 @@ const { existsSync } = require("fs"); const path = require("path"); -const { app, Menu } = require("electron"); +const { app, Menu, dialog } = require("electron"); const is = require("electron-is"); const { getAllPlugins } = require("./plugins/utils"); @@ -95,6 +95,12 @@ const mainMenuTemplate = (win) => { checked: config.get("options.hideMenu"), click: (item) => { config.set("options.hideMenu", item.checked); + if (item.checked && !config.get("options.hideMenuWarned")) { + dialog.showMessageBox(win, { + type: 'info', title: 'Hide Menu Enabled', + message: "Menu will be hidden on next launch, use 'Alt' to show it (or 'Escape' if using in-app-menu)" + }); + } }, }, ] diff --git a/package.json b/package.json index 62e33218..0a43726a 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "ytpl": "^2.2.3" }, "devDependencies": { - "electron": "^12.1.0", + "electron": "^12.2.2", "electron-builder": "^22.10.5", "electron-devtools-installer": "^3.1.1", "electron-icon-maker": "0.0.5", diff --git a/plugins/audio-compressor/front.js b/plugins/audio-compressor/front.js index 4f41a4d7..9c3631cd 100644 --- a/plugins/audio-compressor/front.js +++ b/plugins/audio-compressor/front.js @@ -1,14 +1,6 @@ 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(); compressor.threshold.value = -50; compressor.ratio.value = 12; @@ -16,10 +8,12 @@ const applyCompressor = () => { compressor.attack.value = 0; compressor.release.value = 0.25; - const source = audioContext.createMediaElementSource(videoElement); + const source = audioContext.createMediaElementSource(document.querySelector("video")); source.connect(compressor); compressor.connect(audioContext.destination); }; -module.exports = applyCompressor; \ No newline at end of file +module.exports = () => document.addEventListener('apiLoaded', () => { + applyCompressor(); +}) diff --git a/plugins/blur-nav-bar/style.css b/plugins/blur-nav-bar/style.css index e64b7526..d1722b79 100644 --- a/plugins/blur-nav-bar/style.css +++ b/plugins/blur-nav-bar/style.css @@ -1,4 +1,4 @@ -#nav-bar-background { +#nav-bar-background, #header.ytmusic-item-section-renderer { background: rgba(0, 0, 0, 0.3) !important; backdrop-filter: blur(18px) !important; } diff --git a/plugins/disable-autoplay/front.js b/plugins/disable-autoplay/front.js index eb1b72db..532405de 100644 --- a/plugins/disable-autoplay/front.js +++ b/plugins/disable-autoplay/front.js @@ -1,10 +1,7 @@ -const { ontimeupdate } = require("../../providers/video-element"); - module.exports = () => { - ontimeupdate((videoElement) => { - if (videoElement.currentTime === 0 && videoElement.duration !== NaN) { - // auto-confirm-when-paused plugin can interfere here if not disabled! - videoElement.pause(); - } - }); + document.addEventListener('apiLoaded', () => { + document.querySelector('video').addEventListener('loadeddata', e => { + e.target.pause(); + }) + }, { once: true, passive: true }) }; diff --git a/plugins/in-app-menu/front.js b/plugins/in-app-menu/front.js index 49e56b2b..c731b1a0 100644 --- a/plugins/in-app-menu/front.js +++ b/plugins/in-app-menu/front.js @@ -1,6 +1,7 @@ const { remote, ipcRenderer } = require("electron"); const customTitlebar = require("custom-electron-titlebar"); +function $(selector) { return document.querySelector(selector); } module.exports = () => { const bar = new customTitlebar.Titlebar({ @@ -13,4 +14,19 @@ module.exports = () => { ipcRenderer.on("updateMenu", function (_event, showMenu) { bar.updateMenu(showMenu ? remote.Menu.getApplicationMenu() : null); }); + + // Increases the right margin of Navbar background when the scrollbar is visible to avoid blocking it (z-index doesn't affect it) + document.addEventListener('apiLoaded', () => { + setNavbarMargin() + const playPageObserver = new MutationObserver(() => { + setNavbarMargin(); + }); + playPageObserver.observe($('ytmusic-app-layout'), { attributeFilter: ['player-page-open_', 'playerPageOpen_'] }) + }) }; + +function setNavbarMargin() { + $('ytmusic-app-layout').playerPageOpen_ ? + $('#nav-bar-background').style.right = '0px' : + $('#nav-bar-background').style.right = '12px'; +} diff --git a/plugins/in-app-menu/style.css b/plugins/in-app-menu/style.css index d1efb3d0..090a94ef 100644 --- a/plugins/in-app-menu/style.css +++ b/plugins/in-app-menu/style.css @@ -4,9 +4,10 @@ font-size: 14px !important; } -/* fixes scrollbar positioning relative to nav bar */ -#nav-bar-background.ytmusic-app-layout { - right: 15px !important; +/* fixes nav-bar-background opacity bug and allows clicking scrollbar through it */ +#nav-bar-background { + opacity: 1 !important; + pointer-events: none; } /* remove window dragging for nav bar (conflict with titlebar drag) */ @@ -16,14 +17,9 @@ ytmusic-pivot-bar-item-renderer { -webkit-app-region: unset !important; } -/* navbar background black */ -.center-content.ytmusic-nav-bar { - background: #030303; -} - -/* move up item selectrion renderer by 15 px */ -ytmusic-item-section-renderer[has-item-section-tabbed-header-renderer_] #header.ytmusic-item-section-renderer { - top: 75 !important; +/* move up item selection renderer by 13 px */ +ytmusic-item-section-renderer.stuck #header.ytmusic-item-section-renderer { + top: calc(var(--ytmusic-nav-bar-height) - 13px) !important; } /* fix weird positioning in search screen*/ @@ -32,8 +28,8 @@ ytmusic-header-renderer.ytmusic-search-page { } /* Move navBar downwards */ -ytmusic-app-layout > [slot="nav-bar"], -#nav-bar-background.ytmusic-app-layout { +ytmusic-nav-bar[slot="nav-bar"], +#nav-bar-background { top: 17px !important; } diff --git a/plugins/lyrics-genius/front.js b/plugins/lyrics-genius/front.js index e1354d26..48227e1d 100644 --- a/plugins/lyrics-genius/front.js +++ b/plugins/lyrics-genius/front.js @@ -1,4 +1,5 @@ const { ipcRenderer } = require("electron"); +const is = require("electron-is"); module.exports = () => { ipcRenderer.on("update-song-info", (_, extractedSongInfo) => { @@ -15,6 +16,8 @@ module.exports = () => { ); if (!html) { return; + } else if (is.dev()) { + console.log("Fetched lyrics from Genius"); } const wrapper = document.createElement("div"); @@ -41,7 +44,6 @@ module.exports = () => { lyricsTab.onclick = () => { const tabContainer = document.querySelector("ytmusic-tab-renderer"); - console.log("tabContainer", tabContainer); const observer = new MutationObserver((_, observer) => { const lyricsContainer = document.querySelector( '[page-type="MUSIC_PAGE_TYPE_TRACK_LYRICS"] > ytmusic-message-renderer' diff --git a/plugins/precise-volume/front.js b/plugins/precise-volume/front.js index 84241fb8..4bb606cd 100644 --- a/plugins/precise-volume/front.js +++ b/plugins/precise-volume/front.js @@ -9,7 +9,7 @@ module.exports = (options) => { document.addEventListener('apiLoaded', e => { api = e.detail; firstRun(options); - }) + }, { once: true, passive: true }) }; /** Restore saved volume and setup tooltip */ diff --git a/plugins/quality-changer/front.js b/plugins/quality-changer/front.js index d167776c..9972c97f 100644 --- a/plugins/quality-changer/front.js +++ b/plugins/quality-changer/front.js @@ -9,7 +9,7 @@ const qualitySettingsButton = ElementFromFile( module.exports = () => { - document.addEventListener('apiLoaded', setup); + document.addEventListener('apiLoaded', setup, { once: true, passive: true }); } function setup(event) { diff --git a/plugins/sponsorblock/back.js b/plugins/sponsorblock/back.js index 3c7eb5b4..0f16f102 100644 --- a/plugins/sponsorblock/back.js +++ b/plugins/sponsorblock/back.js @@ -1,4 +1,5 @@ const fetch = require("node-fetch"); +const is = require("electron-is"); const defaultConfig = require("../../config/defaults"); const registerCallback = require("../../providers/song-info"); @@ -24,6 +25,7 @@ module.exports = (win, options) => { }); }; + const fetchSegments = async (apiURL, categories) => { const sponsorBlockURL = `${apiURL}/api/skipSegments?videoID=${videoID}&categories=${JSON.stringify( categories @@ -45,7 +47,10 @@ const fetchSegments = async (apiURL, categories) => { ); return sortedSegments; - } catch { + } catch (e) { + if (is.dev()) { + console.log('error on sponsorblock request:', e); + } return []; } }; diff --git a/plugins/sponsorblock/front.js b/plugins/sponsorblock/front.js index 4f248bfa..45d739b2 100644 --- a/plugins/sponsorblock/front.js +++ b/plugins/sponsorblock/front.js @@ -2,8 +2,6 @@ const { ipcRenderer } = require("electron"); const is = require("electron-is"); -const { ontimeupdate } = require("../../providers/video-element"); - let currentSegments = []; module.exports = () => { @@ -11,17 +9,19 @@ module.exports = () => { currentSegments = segments; }); - ontimeupdate((videoElement) => { - currentSegments.forEach((segment) => { - if ( - videoElement.currentTime >= segment[0] && - videoElement.currentTime <= segment[1] - ) { - videoElement.currentTime = segment[1]; - if (is.dev()) { - console.log("SponsorBlock: skipping segment", segment); + document.addEventListener('apiLoaded', () => { + document.querySelector('video').addEventListener('timeupdate', e => { + currentSegments.forEach((segment) => { + if ( + e.target.currentTime >= segment[0] && + e.target.currentTime < segment[1] + ) { + e.target.currentTime = segment[1]; + if (is.dev()) { + console.log("SponsorBlock: skipping segment", segment); + } } - } - }); - }); + }); + }) + }, { once: true, passive: true }) }; diff --git a/providers/song-info-front.js b/providers/song-info-front.js index 80c2e990..31748cd3 100644 --- a/providers/song-info-front.js +++ b/providers/song-info-front.js @@ -15,5 +15,5 @@ module.exports = () => { const data = e.detail.getPlayerResponse(); ipcRenderer.send("song-info-request", JSON.stringify(data)); }); - }) + }, { once: true, passive: true }) }; diff --git a/providers/song-info.js b/providers/song-info.js index 3f4ad435..37cd55fa 100644 --- a/providers/song-info.js +++ b/providers/song-info.js @@ -2,6 +2,8 @@ const { ipcMain, nativeImage } = require("electron"); const fetch = require("node-fetch"); +const config = require("../config"); + // Grab the progress using the selector const getProgress = async (win) => { // Get current value of the progressbar element @@ -56,6 +58,9 @@ const handleData = async (responseText, win) => { songInfo.uploadDate = data?.microformat?.microformatDataRenderer?.uploadDate; songInfo.url = data?.microformat?.microformatDataRenderer?.urlCanonical?.split("&")[0]; + // used for options.resumeOnStart + config.set("url", data?.microformat?.microformatDataRenderer?.urlCanonical); + win.webContents.send("update-song-info", JSON.stringify(songInfo)); }; diff --git a/providers/video-element.js b/providers/video-element.js deleted file mode 100644 index 7be61c89..00000000 --- a/providers/video-element.js +++ /dev/null @@ -1,22 +0,0 @@ -let videoElement = null; - -module.exports.ontimeupdate = (cb) => { - const observer = new MutationObserver((mutations, observer) => { - if (!videoElement) { - videoElement = document.querySelector("video"); - if (videoElement) { - observer.disconnect(); - videoElement.ontimeupdate = () => cb(videoElement); - } - } - }); - - if (!videoElement) { - observer.observe(document, { - childList: true, - subtree: true, - }); - } else { - videoElement.ontimeupdate = () => cb(videoElement); - } -}; diff --git a/readme.md b/readme.md index 49f4c0e6..2467d83b 100644 --- a/readme.md +++ b/readme.md @@ -42,10 +42,11 @@ Install the `youtube-music-bin` package from the AUR. For AUR installation instr - **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) - **Hide video player**: no video in the interface when playing music - **In-app menu**: [gives bars a fancy, dark look](https://user-images.githubusercontent.com/78568641/112215894-923dbf00-8c29-11eb-95c3-3ce15db27eca.png) + > (see [this post](https://github.com/th-ch/youtube-music/issues/410#issuecomment-952060709) if you have problem accessing the menu after enabling this plugin and hide-menu option) - [**Last.fm**](https://www.last.fm/): scrobbles support - **Navigation**: next/back navigation arrows directly integrated in the interface, like in your favorite browser - **No Google Login**: remove Google login buttons and links from the interface -- **Notifications**: display a [notification](https://user-images.githubusercontent.com/78568641/114102651-63ce0e00-98d0-11eb-9dfe-c5a02bb54f9c.png) when a song starts playing +- **Notifications**: display a notification when a song starts playing ([interactive notifications](https://user-images.githubusercontent.com/78568641/114102651-63ce0e00-98d0-11eb-9dfe-c5a02bb54f9c.png) are available on windows) - **Playback speed**: listen fast, listen slow! [Adds a slider that controls song speed](https://user-images.githubusercontent.com/61631665/129976003-e55db5ba-bf42-448c-a059-26a009775e68.png) - **Precise volume**: customizable volume steps for more comfort, allows controlling the volume precisely using mousewheel - **Quality changer**: change video quality @@ -55,6 +56,8 @@ Install the `youtube-music-bin` package from the AUR. For AUR installation instr - **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 +> If using `Hide Menu` option - you can show the menu with the `alt` key (or `escape` if using the in-app-menu plugin) + ## Dev ```sh diff --git a/yarn.lock b/yarn.lock index 2a52e14e..33cca1d9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3412,10 +3412,10 @@ electron-updater@^4.4.6: lodash.isequal "^4.5.0" semver "^7.3.5" -electron@^12.1.0: - version "12.1.0" - resolved "https://registry.yarnpkg.com/electron/-/electron-12.1.0.tgz#615a7f9dbb2fc79cc72361fba9f39d005c697bca" - integrity sha512-joQlYI/nTIrTUldO3GENZ2j225eKar9nTQBSEwSUSWN4h65QGDmXNQ7dbWPmLlkUQWtHhz8lXhFk30OLG9ZjLw== +electron@^12.2.2: + version "12.2.2" + resolved "https://registry.yarnpkg.com/electron/-/electron-12.2.2.tgz#9627594d6b5bb589f00355989d316b6542539e54" + integrity sha512-Oma/nIfvgql9JjAxdB9gQk//qxpJaI6PgMocYMiW4kFyLi+8jS6oGn33QG3FESS//cw09KRnWmA9iutuFAuXtw== dependencies: "@electron/get" "^1.0.1" "@types/node" "^14.6.2"