Skip to content

Commit

Permalink
added YT Swap
Browse files Browse the repository at this point in the history
  • Loading branch information
k3rielit committed Jun 11, 2023
1 parent 0133129 commit a2d2680
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 33 deletions.
21 changes: 12 additions & 9 deletions youtube/README.md
Original file line number Diff line number Diff line change
@@ -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)
24 changes: 0 additions & 24 deletions youtube/normalize-links.user.js

This file was deleted.

98 changes: 98 additions & 0 deletions youtube/swap.user.js
Original file line number Diff line number Diff line change
@@ -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: `<link rel="stylesheet" href="https://maxst.icons8.com/vue-static/landings/line-awesome/line-awesome/1.3.0/css/line-awesome.min.css">`,
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: `<a id="ytsw-home" class="k-btn" href="/"><i class="las la-house-damage"></i></a>`,
buttonSwapToShorts: `<a id="ytsw-swap" class="k-btn" href="#"><i class="las la-compress"></i></a>`,
buttonSwapToWatch: `<a id="ytsw-swap" class="k-btn" href="#"><i class="las la-expand"></i></a>`,
buttonInfo: `<a id="ytsw-info" class="k-btn"><i class="las la-chart-bar"></i></a>`,
buttonQRCode: `<a id="ytsw-qr" class="k-btn"><i class="las la-qrcode"></i></a>`,
};

// 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));
}
}
});
}
})();

0 comments on commit a2d2680

Please sign in to comment.