diff --git a/CHANGELOG.md b/CHANGELOG.md index 40d89818..530ff670 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,11 @@ # Changelog -## v3.1.8-beta +## v3.1.8 - The button's tooltip may now show additional information on the shuffle status. +- The extension will now show that a shuffle is still running when navigating within a channel. +- Fixed a bug where an active shuffle would continue in the background when navigating to a different channel. - Fixed a bug where clicking the shuffle button while the shuffle was running would start a second shuffle at the same time. - Fixed a bug where the shuffle button would sometimes not be added to the page if it was opened directly from a new tab. - Fixed a bug where the playlist created by the extension would sometimes not be renamed correctly. diff --git a/package-lock.json b/package-lock.json index 64703b08..b72a4aea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "random-youtube-video", - "version": "3.1.7", + "version": "3.1.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "random-youtube-video", - "version": "3.1.7", + "version": "3.1.8", "dependencies": { "@babel/runtime": "^7.18.6", "firebase": "^9.22.0" diff --git a/package.json b/package.json index 59c9fe5d..fc2573b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "random-youtube-video", - "version": "3.1.7", + "version": "3.1.8", "description": "Customize, shuffle and play random videos from any YouTube channel.", "scripts": { "dev": "concurrently \"npm run dev:chromium\" \"npm run dev:firefox\"", diff --git a/src/content.js b/src/content.js index e9a6d02d..5e6087d8 100644 --- a/src/content.js +++ b/src/content.js @@ -31,7 +31,6 @@ document.addEventListener("yt-navigate-finish", startDOMObserver); async function startDOMObserver(event) { // Sometimes, YouTube changes contents of the event or the page structure. Whenever we encounter an identifying change, we update this variable to track it through the process let eventVersion = "default"; - resetShuffleButtonText(); let pageType = getPageTypeFromURL(window.location.href); @@ -55,11 +54,76 @@ async function startDOMObserver(event) { } } + // If no valid channelId was provided in the event, we won't be able to add the button if (!channelId?.startsWith("UC")) { - // If no valid channelId was provided in the event, we won't be able to add the button + if (isShuffling) { + window.location.reload(); + } + return; + } + + // The user navigated within the channel page (using tabs such as Videos, Shorts, Community, etc.), so if we already have a button, we re-use it + // We check if it's the same channel, because otherwise we need to reload the page in case a shuffle is running + if (channelId == configSync.currentChannelId && + (pageType == "channel" && shuffleButton?.id == "youtube-random-video-large-shuffle-button-channel" || + pageType == "video" && shuffleButton?.id == "youtube-random-video-large-shuffle-button-video") + ) { + // If the extension context was invalidated, the shuffle button handler won't work any more, so we need to reload to reset the context + try { + // If we are still connected to the background worker, we can send a message to test the connection + await chrome.runtime.sendMessage({ command: "connectionTest" }); + } catch (error) { + // If the extension's background worker was reloaded, we need to reload the page to re-connect to the background worker + if (error.message === 'Extension context invalidated.') { + window.location.reload(); + } + } + + const observer = new MutationObserver(function (mutations, me) { + let channelPageRequiredElementLoadComplete, videoPageRequiredElementLoadComplete; + if (pageType === "channel") { + switch (eventVersion) { + case "default": + channelPageRequiredElementLoadComplete = document.getElementById("channel-header")?.querySelector("#inner-header-container")?.children?.namedItem("buttons"); + break; + case "20240521": + channelPageRequiredElementLoadComplete = document.getElementById("page-header")?.getElementsByTagName("yt-flexible-actions-view-model")[0]; + break; + } + } else if (pageType === "video") { + videoPageRequiredElementLoadComplete = document.getElementById("above-the-fold")?.children?.namedItem("top-row")?.children?.namedItem("owner"); + } + + if (pageType === "channel" && channelPageRequiredElementLoadComplete) { + me.disconnect(); + switch (eventVersion) { + case "default": + document.getElementById("channel-header")?.querySelector("#inner-header-container")?.children?.namedItem("buttons")?.appendChild(shuffleButton); + break; + case "20240521": + document.getElementById("page-header")?.getElementsByTagName("yt-flexible-actions-view-model")[0]?.appendChild(shuffleButton); + break; + } + } else if (pageType === "video" && videoPageRequiredElementLoadComplete) { + me.disconnect(); + document.getElementById("above-the-fold")?.children?.namedItem("top-row")?.children?.namedItem("owner")?.appendChild(shuffleButton); + } + return; + }); + + observer.observe(document, { + childList: true, + subtree: true + }); return; } + // The user navigated while a shuffle was running + // As we can't represent the shuffle still running, we need to reload the page to reset the extension context + if (isShuffling) { + window.location.reload(); + } + // Wait until the required DOM element we add the button to is loaded const observer = new MutationObserver(function (mutations, me) { let channelPageRequiredElementLoadComplete, videoPageRequiredElementLoadComplete, shortsPageRequiredElementLoadComplete; diff --git a/static/manifest.json b/static/manifest.json index 23d7b25f..63532435 100644 --- a/static/manifest.json +++ b/static/manifest.json @@ -1,8 +1,8 @@ { "name": "Random YouTube Video", "description": "Customize, shuffle and play random videos from any YouTube channel.", - "version": "3.1.7", - "version_name": "3.1.8-beta", + "version": "3.1.8", + "version_name": "3.1.8", "manifest_version": 3, "content_scripts": [ {