From 4fffb16f8b04678ddb0461edbac64905919b02d6 Mon Sep 17 00:00:00 2001 From: Noel Aeby Date: Sun, 19 May 2024 20:50:44 +0200 Subject: [PATCH 1/2] add ui controls for instance and disabling temporarily --- js/background.js | 68 ++++++++++++++++++++++++++++++++++++------------ manifest.json | 10 +++++-- popup/ui.css | 12 +++++++++ popup/ui.html | 21 +++++++++++++++ popup/ui.js | 55 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+), 18 deletions(-) create mode 100644 popup/ui.css create mode 100644 popup/ui.html create mode 100644 popup/ui.js diff --git a/js/background.js b/js/background.js index a0aea7d..f07d36b 100644 --- a/js/background.js +++ b/js/background.js @@ -2,27 +2,63 @@ window.browser = window.browser || window.chrome; const INVIDIOUS_INSTANCES = []; +// Those are the default settings and also required as reading from local storage before deciding on whether to reject the request appears to be too slow +var activeInstance = "piped.video"; +var redirectDisabled = false; + +// Reading settings from local storage on startup +browser.storage.local.get().then(localStorage => { + if(localStorage.disabled) redirectDisabled = true; + if(typeof localStorage.instance != "undefined") activeInstance = localStorage.instance; +}); + +// Instance decoding from api docs and put in local storage for ui to retrieve when loading +fetch("https://raw.githubusercontent.com/wiki/TeamPiped/Piped-Frontend/Instances.md") +.then(resp => resp.text()) +.then(body => { + var instances = []; + let lines = body.split("\n"); + lines.map(line => { + let split = line.split("|"); + if(split.length == 5) { + instances.push(split[0]); + } + }); + browser.storage.local.set({instances: instances.slice(2)}); +}); + +// Fetching invidious instances and redirecting fetch("https://api.invidious.io/instances.json") .then((resp) => resp.json()) .then((array) => array.forEach((json) => INVIDIOUS_INSTANCES.push(json[0]))); - -browser.webRequest.onBeforeRequest.addListener( - (details) => { - const url = new URL(details.url); - if (url.hostname.endsWith("youtu.be") && url.pathname.length > 1) { - return { redirectUrl: "https://piped.kavin.rocks/watch?v=" + url.pathname.substr(1) }; - } - if ( - url.hostname.endsWith("youtube.com") || - url.hostname.endsWith("youtube-nocookie.com") || - INVIDIOUS_INSTANCES.includes(url.hostname) - ) { - url.hostname = "piped.kavin.rocks"; - return { redirectUrl: url.href }; - } + browser.webRequest.onBeforeRequest.addListener( + (details) => { + if(!redirectDisabled) { + const url = new URL(details.url); + if (url.hostname.endsWith("youtu.be") && url.pathname.length > 1) { + return { redirectUrl: "https://" + activeInstance + "/watch?v=" + url.pathname.substr(1) }; + } + if ( + url.hostname.endsWith("youtube.com") || + url.hostname.endsWith("youtube-nocookie.com") || + INVIDIOUS_INSTANCES.includes(url.hostname) + ) { + url.hostname = activeInstance; + return { redirectUrl: url.href }; + } + } }, { urls: [""], }, ["blocking"], -); + ); + +// Realtime communication needed to stay in sync with user preferences +browser.runtime.onMessage.addListener(function(request, sender, sendResponse) { + if(request.action == "instanceChanged") { + activeInstance = request.value; + } else if(request.action == "statusChanged") { + redirectDisabled = request.value; + } +}); \ No newline at end of file diff --git a/manifest.json b/manifest.json index ed51707..1bd7c37 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "name": "Piped Redirects", - "version": "1.2", + "version": "2.0", "description": "Redirects YouTube links to Piped", "permissions": [ "webRequest", @@ -8,7 +8,8 @@ "*://youtu.be/*", "*://*.youtube.com/*", "*://*.youtube-nocookie.com/*", - "" + "", + "storage" ], "icons": { "48": "img/logo-48.png", @@ -20,5 +21,10 @@ "js/background.js" ] }, + "browser_action": { + "default_icon": "img/logo.svg", + "default_title": "Piped Redirects", + "default_popup": "popup/ui.html" + }, "manifest_version": 2 } diff --git a/popup/ui.css b/popup/ui.css new file mode 100644 index 0000000..49d7b4b --- /dev/null +++ b/popup/ui.css @@ -0,0 +1,12 @@ +body { + background-color: rgba(0, 0, 0, 0.8); + text-align: center; + color: white; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji, ui-sans-serif, system-ui; +} +a { + color: white; +} +* { + margin: 5px; +} \ No newline at end of file diff --git a/popup/ui.html b/popup/ui.html new file mode 100644 index 0000000..4356348 --- /dev/null +++ b/popup/ui.html @@ -0,0 +1,21 @@ + + + + + + + +
+ Enable/Disable piped redirects +
+
+
Select instance
+ +
+ About Instances +
+ + + \ No newline at end of file diff --git a/popup/ui.js b/popup/ui.js new file mode 100644 index 0000000..4ae1aef --- /dev/null +++ b/popup/ui.js @@ -0,0 +1,55 @@ +window.browser = window.browser || window.chrome; + +const instanceSelector = document.getElementById("PIPED_INSTANCES"); +const statusBtn = document.getElementById("STATUS_BTN"); + +var isDisabled = false; + +function updateStatus(disabled) { + if(!disabled) { + statusBtn.style.opacity = "1"; + } else { + statusBtn.style.opacity = "0.4"; + } +} + +// Read settings from local storage +browser.storage.local.get().then(localStorage => { + // Set instances + localStorage.instances.forEach(instance => { + let instanceOption = document.createElement("option"); + instanceOption.innerText = instance.trim(); + instanceOption.value = "piped." + instance.replace("(Official)", "").trim(); + console.log(instance.replace("(Official)").trim()); + instanceSelector.appendChild(instanceOption); + }); + + // check if redirections are disabled + if(localStorage.disabled) { + updateStatus(true); + isDisabled = true; + } + // select correct instance according to settings + if(typeof localStorage.instance != "undefined") { + instanceSelector.value = localStorage.instance; + } else instanceSelector.value = "piped.video"; +}); + +statusBtn.addEventListener("click", () => { + isDisabled = !isDisabled; + updateStatus(isDisabled); + browser.runtime.sendMessage({ + action: "statusChanged", + value: isDisabled + }); + browser.storage.local.set({disabled: isDisabled}); +}); + +instanceSelector.addEventListener("change", () => { + browser.runtime.sendMessage({ + action: "instanceChanged", + value: instanceSelector.value + }); + //console.log(instanceSelector.value); + browser.storage.local.set({instance: instanceSelector.value}); +}); \ No newline at end of file From 265720bb875a1c63e5c56b900d5518f3649f0ac3 Mon Sep 17 00:00:00 2001 From: Noel Aeby Date: Mon, 20 May 2024 14:36:33 +0200 Subject: [PATCH 2/2] filter unwanted duplicate --- js/background.js | 2 +- popup/ui.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/js/background.js b/js/background.js index f07d36b..6ce5f34 100644 --- a/js/background.js +++ b/js/background.js @@ -20,7 +20,7 @@ fetch("https://raw.githubusercontent.com/wiki/TeamPiped/Piped-Frontend/Instances let lines = body.split("\n"); lines.map(line => { let split = line.split("|"); - if(split.length == 5) { + if(split.length == 5 && split[0].indexOf(" libre") == -1) { instances.push(split[0]); } }); diff --git a/popup/ui.js b/popup/ui.js index 4ae1aef..9e12ef3 100644 --- a/popup/ui.js +++ b/popup/ui.js @@ -20,7 +20,6 @@ browser.storage.local.get().then(localStorage => { let instanceOption = document.createElement("option"); instanceOption.innerText = instance.trim(); instanceOption.value = "piped." + instance.replace("(Official)", "").trim(); - console.log(instance.replace("(Official)").trim()); instanceSelector.appendChild(instanceOption); }); @@ -50,6 +49,5 @@ instanceSelector.addEventListener("change", () => { action: "instanceChanged", value: instanceSelector.value }); - //console.log(instanceSelector.value); browser.storage.local.set({instance: instanceSelector.value}); }); \ No newline at end of file