From 5718d09d74b84c90aa7c6e5dbe72a95d023ef6ed Mon Sep 17 00:00:00 2001 From: uwaa Date: Fri, 10 Jan 2025 08:23:07 +0000 Subject: [PATCH] refactor --- rot.js | 305 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 187 insertions(+), 118 deletions(-) diff --git a/rot.js b/rot.js index d61ca5b..99ea30e 100644 --- a/rot.js +++ b/rot.js @@ -24,34 +24,33 @@ })(); function getPromiseFromEvent(item, event) { - return new Promise((resolve) => { - const listener = () => { - item.removeEventListener(event, listener); - resolve(); - } - item.addEventListener(event, listener); - }) + return new Promise((resolve) => { + const listener = () => { + item.removeEventListener(event, listener); + resolve(); + } + item.addEventListener(event, listener); + }); } // MIT Licensed // Author: jwilson8767 function waitUntil(selector) { - return new Promise((resolve, reject) => { - const el = document.querySelector(selector); - if (el) {resolve(el);} - new MutationObserver((mutationRecords, observer) => { - // Query for elements matching the specified selector - Array.from(document.querySelectorAll(selector)).forEach((element) => { - resolve(element); - //Once we have resolved we don't need the observer anymore. - observer.disconnect(); - }); - }) - .observe(document.documentElement, { - childList: true, - subtree: true - }); - }); + return new Promise((resolve, reject) => { + const el = document.querySelector(selector); + if (el) resolve(el); + new MutationObserver((mutationRecords, observer) => { + // Query for elements matching the specified selector + Array.from(document.querySelectorAll(selector)).forEach((element) => { + resolve(element); + //Once we have resolved we don't need the observer anymore. + observer.disconnect(); + }); + }).observe(document.documentElement, { + childList: true, + subtree: true + }); + }); } @@ -60,121 +59,191 @@ function sex(sex) { } function rand(list) { - return list == undefined ? undefined : list[list.length*Math.random()|0] + return list ? list[list.length * Math.random() | 0] : null; } -function audioplay(obj) { - obj.play().catch( - ()=>{ - getPromiseFromEvent(window,'click').then( - ()=>{audio.play()} - ) - } - ) +// Rot music player +const audio = document.createElement("audio"); +audio.loop = true; +audio.id = "user-music"; +audio.style = "display:none;"; +localStorage.audiovolume = (audio.volume = localStorage.audiovolume ? localStorage.audiovolume / 100 : 0.5) * 100; + +function setMusic(url) { + if (audio.src == url) + return; + + if (!audio.paused || audio.src != "") { + console.log("Stopping music"); + audio.pause(); + // This line will cause a lot of errors. + // Setting src to "" will cause any pending .play()s to fail. + audio.src = ""; + } + + if (url) { + console.log("Setting music: " + url); + audio.src = url; + } } -function volumeChange (number) { - localStorage.audiovolume = audio.volume = Math.round(audio.volume * 100 + (number%101))/100 - document.getElementById("user-audio-percentage").innerHTML = Math.floor(audio.volume * 100) + "%" +function playMusic() { + //Starts playing the music if it isn't muted and isn't already playing + if (audio.src && audio.src != "" && audio.paused && !audio.muted) + audio.play().catch(() => getPromiseFromEvent(window, 'click').then(audio.play)); } +function setImage(url) { + if (!url) + url = '/static/background.jpg'; + + console.log("Setting background: " + url); + document.getElementById("app-loaded").style.setProperty("--body-background-image", "url(" + url + ")"); +} + +//Audio control events function volumeSet(number) { - localStorage.audiovolume = audio.volume = Math.round((number%101))/100 - document.getElementById("user-audio-percentage").innerHTML = Math.floor(audio.volume * 100) + "%" + localStorage.audiovolume = Math.round((audio.volume = number) * 100); + updateVolumeLabel(); +} +function volumeAdd(number) { + volumeSet(Math.min(1, Math.max(0, audio.volume + number))); +} +function updateVolumeLabel() { + document.getElementById("user-audio-percentage").innerHTML = Math.round(audio.volume * 100) + "%"; } -// Add rot music. -audio = document.createElement("audio") -audio.loop = true -audio.id = "user-music" -audio.style = "display:none;" -localStorage.audiovolume = audio.volume = localStorage.audiovolume ? localStorage.audiovolume : 0.5 -// Rot player! - -waitUntil("#music-controls").then ( (controls) => { - document.getElementById("user-audio-percentage").innerHTML = Math.floor(localStorage.audiovolume * 100) + "%" - controls.querySelector("#music-up").onclick = () => volumeChange(5) - controls.querySelector("#music-down").onclick = () => volumeChange(-5) - +//Initialize audio controls +waitUntil("#music-controls").then((controls) => { + updateVolumeLabel(); + controls.querySelector("#music-up").onclick = () => volumeAdd(0.05); + controls.querySelector("#music-down").onclick = () => volumeAdd(-0.05); }) -waitUntil("#music-slider").then ( (slider) => { - document.getElementById("user-audio-percentage").innerHTML = (slider.value = Math.floor(localStorage.audiovolume * 100)) + "%" - slider.oninput = () => volumeSet(slider.value) +waitUntil("#music-slider").then((slider) => { + updateVolumeLabel(); + slider.oninput = () => volumeSet(slider.value / 100); }) -waitUntil("#music-mute").then ( (box) => { - audio.muted = box.checked = localStorage.audiomuted === "true" +waitUntil("#music-mute").then((box) => { + audio.muted = box.checked = localStorage.audiomuted === "true"; box.addEventListener('click', () => { - localStorage.audiomuted = audio.muted = box.checked + localStorage.audiomuted = audio.muted = box.checked; + playMusic(); }) }); -let prev; -let choice; +//Theme application +function applySpecialTheme() { + let pageMusic = document.querySelector('meta[name="pageMusic"]')?.content || document.getElementById("pageMusic")?.getAttribute("href"); + setMusic(pageMusic); + playMusic(); + + let pageImage = document.querySelector('meta[name="pageImage"]')?.content || document.getElementById("pageImage")?.getAttribute("href"); + setImage(pageImage); +} -console.log("rot custom js loaded") +function applyUserTheme() { + setMusic(null); + setTimeout(() => { + let posts = []; + let pinnedPosts = document.getElementsByClassName("pin"); + if (pinnedPosts.length != 0) { + posts = [...pinnedPosts] + posts = posts.filter( // I hate this. It keeps getting worse. + (x) => x.nextElementSibling + .querySelector(".StatusBody") + .querySelector(".text") + .innerHTML + .toLowerCase() + .replace( /(<([^>]+)>)/ig, '') + .search(/profile theming post/ig) != -1 + ) + } + + if (posts.length != 0) { + //Configured by post + let statusBody = posts[0].nextElementSibling.querySelector(".StatusBody") + + let musicContainer = statusBody.querySelector(".audio-container") + if (musicContainer) + setMusic(rand(musicContainer.children).src); + else + setMusic(null); + + let imageContainer = statusBody.querySelector(".image-container") + if (imageContainer) + setImage(rand(imageContainer.getElementsByTagName("img")).src); + else + setImage(null); + } else { + let fields = [...document.getElementsByClassName("user-profile-field-name")] + if (fields.length != 0) { + //Configured by fields + let musicFields = fields.filter((x) => x.title.toLowerCase().replace(/\s+/g, '') == "music") + if (musicFields.length > 0) + setMusic(rand(musicFields).nextElementSibling.title); + else + setMusic(null); + + let imageFields = fields.filter((x) => x.title.toLowerCase().replace(/\s+/g, '') == "image") + if (imageFields.length > 0) + setImage(rand(imageFields).nextElementSibling.title); + else + setImage(null); + } + } + playMusic(); + }, 1000); +} + +//Switch-based monkey patching router bullshit addEventListener('locationchange',(event) => { - f = window.location.toString().split("/").reverse(); - prev = choice - choice = f[0].split('?')[0].split('#')[0] - switch (choice) { - case "about": - //audio.src = document.getElementById("pageMusic").getAttribute("href") - //console.log("audio sources set to " + audio.src) - audio.src = "https://rape.pet/music/ItsFunny.mp3"; - audioplay(audio) - break; - default: - if (prev == choice) return; - audio.pause() - // This line will cause a lot of errors. - // Setting src to "" will cause any pending .play()s ot fail. - audio.src = "" - setTimeout( () => { - posts = [] - if (document.getElementsByClassName("pin").length != 0) { - posts = [...document.getElementsByClassName("pin")] - posts = posts.filter( // I hate this. It keeps getting worse. - (x) => x.nextElementSibling.querySelector(".StatusBody").querySelector(".text").innerHTML.toLowerCase().replace( /(<([^>]+)>)/ig, '').search(/profile theming post/ig) != -1 - ) - } - if (posts.length != 0) { - base = posts[0].nextElementSibling.querySelector(".StatusBody") - music = base.querySelector(".audio-container") - image = base.querySelector(".image-container") - if (music) { - audio.src = rand(music.children).src - audio.id = "user-music" - audioplay(audio) - } - if (image) { - image = "url(" + rand(image.getElementsByTagName("img")).src + ")" - document.getElementById("app-loaded").style.setProperty("--body-background-image",image) - } - } else if (document.getElementsByClassName("user-profile-field").length != 0) { - // Music setup. - fields = document.getElementsByClassName("user-profile-field-name") - music = [...fields].filter( (x)=>x.title.toLowerCase().replace(/\s+/g, '')=="music" ) - if (music.length !=0) { - music = rand(music).nextElementSibling.title - audio.src = music - audio.id = "user-music" - audioplay(audio) - } - // Image setup. Unneeded. Pleroma sets it for you. - //if (default_bg == undefined) { - // default_bg = document.getElementById("app-loaded").style.getPropertyValue("--body-background-image") - //} - image = [...fields].filter( (x)=>x.title.toLowerCase().replace(/\s+/g, '')=="image" ) - if (image.length != 0) { - image = image.at(0).nextElementSibling.title - image = "url(" + image + ")" - document.getElementById("app-loaded").style.setProperty("--body-background-image",image) - } + let pathSpl = window.location.pathname.split("/"); + switch (pathSpl.length) { + case 1: + applySpecialTheme(); //Root + break; + + case 2: + switch (pathSpl[1]) { + case "about": + case "announcements": + case "lists": + case "bookmarks": + applySpecialTheme(); + break; + + default: + applyUserTheme(); + break; } + break; + + case 3: + switch (pathSpl[1]) { + case "main": + applySpecialTheme(); //Main timelines + break; + + case "users": + applyUserTheme(); + break; + + case "notice": + //Continue playing + break; - }, 1000); - break; + default: + applySpecialTheme(); + break; + } + break; + + default: + applySpecialTheme(); + break; } }); + +console.log("rot.js loaded"); \ No newline at end of file