From a2d2680393bc5cf2d80d2cd7e00c3ceb74f75d71 Mon Sep 17 00:00:00 2001 From: szialajoscosplay <70654182+k3rielit@users.noreply.github.com> Date: Sun, 11 Jun 2023 16:01:39 +0200 Subject: [PATCH] added YT Swap --- youtube/README.md | 21 ++++--- youtube/normalize-links.user.js | 24 -------- youtube/swap.user.js | 98 +++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 33 deletions(-) delete mode 100644 youtube/normalize-links.user.js create mode 100644 youtube/swap.user.js diff --git a/youtube/README.md b/youtube/README.md index f589b09..a4841aa 100644 --- a/youtube/README.md +++ b/youtube/README.md @@ -1,11 +1,14 @@ -## NORMALIZE LINKS -Just replaces ```youtube.com/redirect``` links with the real one. Mostly pointless though. -## HOW TO USE -1. Install the Tampermonkey extension. ([Link](https://www.tampermonkey.net)) -2. [Install](https://github.com/k3rielit/scripts/raw/main/youtube/normalize-links.user.js) -## UPDATES -If it breaks, I'll try fixing it +# Swap + +Replaces the top left logo with something more useful: -(If youtube changes their use of class names, it will break. Which didn't happen to ```yt-formatted-string``` for a long time, but whatever...) +- [x] Switch between Shorts and Watch UI +- [x] Smaller home button +- [ ] [Return YouTube Dislike](https://returnyoutubedislike.com/docs) raw data popup +- [ ] Display a [QR code](https://davidshimjs.github.io/qrcodejs/) for the video +- [ ] Replace redirect links with real ones -Last tested: 2021.12.07. +## Install + +1. Install the Tampermonkey extension. ([Link](https://www.tampermonkey.net)) +2. [Install](https://github.com/k3rielit/scripts/raw/main/youtube/swap.user.js) diff --git a/youtube/normalize-links.user.js b/youtube/normalize-links.user.js deleted file mode 100644 index 6a64653..0000000 --- a/youtube/normalize-links.user.js +++ /dev/null @@ -1,24 +0,0 @@ -// ==UserScript== -// @name YT Normalize Links -// @namespace yt_normalize_links -// @version 1.0 -// @description replaces external links with the actual url instead of youtube's own redirect page -// @author k3rielit -// @match *://*.youtube.com/watch?* -// @icon https://www.google.com/s2/favicons?domain=youtube.com -// @grant none -// ==/UserScript== - -(function() { - 'use strict'; - const callback = () => { - let redirects = [...document.getElementsByClassName('yt-formatted-string')].filter(f => f.href && f.href.startsWith('https://www.youtube.com/redirect')); - redirects.forEach(a => { - let decode = decodeURIComponent(a.href.split('q=')[1]); - a.href = decode; - a.innerText = decode.length > 100 ? decode.substring(0,100)+'...' : decode; - }); - }; - const observer = new MutationObserver(callback); - observer.observe(document.documentElement || document.body, { attributes: true, childList: true, subtree: true }); -})(); \ No newline at end of file diff --git a/youtube/swap.user.js b/youtube/swap.user.js new file mode 100644 index 0000000..70b66ad --- /dev/null +++ b/youtube/swap.user.js @@ -0,0 +1,98 @@ +// ==UserScript== +// @name YT Swap +// @namespace k3rielit.ytswap +// @version 1.0 +// @description Swaps between Shorts and Watch UI for the current video. +// @author github.com/k3rielit +// @match *://*.youtube.com/* +// @match *://*.youtu.be/* +// @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com +// @grant none +// ==/UserScript== + +console.log('[YTSwap] Loaded'); + +// Components +const components = { + lineawesome: ``, + flexmincss: `.container,.row>*{width:100%}.row{display:flex;flex-wrap:wrap}.row>*{flex-shrink:0;max-width:100%}.col{flex:1 0 0%}.col-auto{flex:0 0 auto;width:auto}`, + buttoncss: `.k-btn{cursor:pointer;border:0;display:inline;border-radius:30px;padding:8px 10px;font-size:20px;max-height:40px;max-width:40px;font-family:Roboto,Arial,sans-serif;font-weight:700;color:var(--yt-spec-text-primary);margin-left:10px}.k-btn:hover{background-color:rgba(255,255,255,.1)}`, + buttonHome: ``, + buttonSwapToShorts: ``, + buttonSwapToWatch: ``, + buttonInfo: ``, + buttonQRCode: ``, +}; + +// Functions +// https://stackoverflow.com/questions/5525071/how-to-wait-until-an-element-exists +function waitForElement(selector) { + return new Promise(resolve => { + if (document.querySelector(selector)) { + return resolve(document.querySelector(selector)); + } + console.log('[waitForElement] Waiting for: '+selector); + const observer = new MutationObserver((mutationList, observer) => { + if (document.querySelector(selector)) { + console.log(document.querySelector(selector)); + resolve(document.querySelector(selector)); + observer.disconnect(); + } + }); + observer.observe(document.body, { + attributes: true, childList: true, subtree: true + }); + }); +} + +function stringToElement(str) { + let template = document.createElement('template'); + template.innerHTML = str.trim(); + return template.content.firstChild; +} + +function injectCSS(css) { + let style = document.createElement('style'); + style.innerHTML = css; + document.head.appendChild(style); +} + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +// Main +(async function() { + await waitForElement('div#buttons.style-scope.ytd-masthead yt-icon'); + const topRightButtonContainer = await waitForElement('div#buttons.style-scope.ytd-masthead'); + const topLeftLogo = await waitForElement('div#start.style-scope.ytd-masthead > #logo'); + document.head.appendChild(stringToElement(components.lineawesome)); + injectCSS(components.flexmincss); + injectCSS(components.buttoncss); + let lastHref = window.location.href; + // YT rerenders UI on route change + while(true) { + await sleep(111).then(() => { + if(lastHref != window.location.href || !document.getElementById('ytsw-home')) { + topLeftLogo.innerText = ''; + // waitForElement('#voice-search-button').then((elem) => elem.remove()); + // Determine what components to render + topLeftLogo.appendChild(stringToElement(components.buttonHome)); + const currentUI = window.location.pathname.split('/')[1]; + if(currentUI == 'shorts' || currentUI == 'watch') { + const videoId = window.location.href.includes('?v=') ? window.location.href.split('?v=')[1].substring(0,11) : window.location.pathname.split('/')[2]; + switch(currentUI) { + case 'shorts': + topLeftLogo.appendChild(stringToElement(components.buttonSwapToWatch.replace(`href="#"`,`href="https://www.youtube.com/watch?v=${videoId}"`))); + break; + case 'watch': + topLeftLogo.appendChild(stringToElement(components.buttonSwapToShorts.replace(`href="#"`,`href="https://www.youtube.com/shorts/${videoId}"`))); + break; + } + topLeftLogo.appendChild(stringToElement(components.buttonInfo)); + topLeftLogo.appendChild(stringToElement(components.buttonQRCode)); + } + } + }); + } +})(); \ No newline at end of file