Last active
July 19, 2024 14:17
-
-
Save uhwot/fdccd80db1df46b4569ac1b8cb91523b to your computer and use it in GitHub Desktop.
Userscript which shows format info on Tidal, tested on Violentmonkey
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Tidal Formats | |
// @namespace io.github.uhwot.tidalformats | |
// @match https://listen.tidal.com/* | |
// @match https://listen.stage.tidal.com/* | |
// @grant none | |
// @version 1.0.7 | |
// @author uh wot | |
// @icon https://tidal.com/favicon-192x192.png | |
// @description Shows format info on Tidal | |
// @run-at document-start | |
// @homepageURL https://gist.github.com/uhwot/fdccd80db1df46b4569ac1b8cb91523b | |
// @downloadURL https://gist.github.com/uhwot/fdccd80db1df46b4569ac1b8cb91523b/raw/tidal_formats.user.js | |
// ==/UserScript== | |
const TAGS = { | |
LOSSLESS: { bgcolor: '21feec1a', color: '3fe' }, | |
MQA: { bgcolor: 'ffbe7d1a', color: 'ffbe7d' }, | |
HIRES_LOSSLESS: { bgcolor: 'ffd4321a', color: 'ffd432', text: 'HIRES' }, | |
SONY_360RA: { text: '360' }, | |
DOLBY_ATMOS: { text: 'ATMOS' }, | |
} | |
function waitForElem(selector) { | |
return new Promise(resolve => { | |
let elem = document.body.querySelector(selector) | |
if (elem) { | |
resolve(elem); | |
} | |
const observer = new MutationObserver(mutations => { | |
elem = document.body.querySelector(selector) | |
if (elem) { | |
resolve(elem); | |
observer.disconnect(); | |
} | |
}); | |
observer.observe(document.body, { | |
childList: true, | |
subtree: true, | |
}); | |
}); | |
} | |
function setAlbumBadges(json) { | |
const mediaTags = json.rows[0].modules[0].album.mediaMetadata.tags | |
if (mediaTags.length > 0) { | |
waitForElem('div[class=css-14iiv3l]').then((badgeContainer) => { | |
if (badgeContainer.children.length > 1) { | |
badgeContainer.removeChild(badgeContainer.children[1]) | |
} | |
for (tag of mediaTags) { | |
const div = document.createElement('div') | |
const badge = document.createElement('span') | |
badge.setAttribute('class', '_wave-badge_1oxl7_1 _wave-badge-text_1oxl7_32 _wave-text-badge-bold_p36zi_92 _wave-badge-color-default_1oxl7_7') | |
badge.textContent = tag | |
let tagData = TAGS[tag] | |
if (tagData) { | |
if (tagData.text) { | |
badge.textContent = tagData.text | |
} | |
let style = [] | |
if (tagData.bgcolor) { | |
style.push(`background-color: #${tagData.bgcolor}`) | |
} | |
if (tagData.color) { | |
style.push(`color: #${tagData.color}`) | |
} | |
if (style) { | |
badge.setAttribute('style', style.join(';')) | |
} | |
} | |
div.appendChild(badge) | |
badgeContainer.appendChild(div) | |
} | |
}) | |
} | |
} | |
window.fetch = (function (fetch) { | |
return async function (url, init) { | |
let resp = await fetch(url, init) | |
if (!resp.ok) { | |
return resp | |
} | |
try { | |
url = new URL(url) | |
} catch { | |
return resp | |
} | |
if (url.hostname === location.hostname) { | |
if (url.pathname === '/v1/pages/album') { | |
const json = await resp.json() | |
setAlbumBadges(json) | |
resp = new Response(JSON.stringify(json), resp) | |
} | |
} | |
return resp | |
} | |
})(window.fetch); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
very epic