91 lines
3 KiB
JavaScript
91 lines
3 KiB
JavaScript
// ==UserScript==
|
|
// @name winterify cohost
|
|
// @namespace datagirl.xyz
|
|
// @match https://cohost.org/*
|
|
// @grant none
|
|
// @version 1.6.1
|
|
// @author snow flurry
|
|
// @description 11/14/2022, 1:16:16 PM
|
|
// ==/UserScript==
|
|
|
|
// Changelog:
|
|
// 1.5:
|
|
// - Use a MutationObserver instead of Interval (less brute forcing)
|
|
// - Removed foreground snow effect
|
|
|
|
|
|
(() => {
|
|
// if you want snowfall mode to run by default, set this to true.
|
|
const defaultOn = true;
|
|
|
|
const divId = 'userscript-snowfall';
|
|
|
|
function makeWinter() {
|
|
let activateBtn = document.createElement("button");
|
|
activateBtn.innerHTML = "❄️";
|
|
activateBtn.id = "userscript-winterify-activate";
|
|
activateBtn.style.padding = "0.5em 0.75em";
|
|
|
|
// only create the snowfall if it doesn't already exist
|
|
// (so we don't mess up the DOM more than we already are)
|
|
let snowfall = document.getElementById(divId);
|
|
if (snowfall == null) {
|
|
let snowfall = document.createElement("div");
|
|
snowfall.id = divId;
|
|
|
|
snowfall.style.position = "fixed";
|
|
snowfall.style.top = snowfall.style.bottom = snowfall.style.left = snowfall.style.right = "0";
|
|
snowfall.style.pointerEvents = "none";
|
|
|
|
const setBg = (snowfall, isDark) => {
|
|
// this darkens the background, but the 20% opacity (hopefully!) doesn't darken it too much.
|
|
darkMode = isDark ? "" : "#000";
|
|
snowfall.style.background = `url('https://staging.cohostcdn.org/attachment/cc9ae945-a270-4059-8992-70f74128c332/snowfall_anim.gif') ${darkMode}`;
|
|
};
|
|
|
|
snowfall.style.opacity = "0.2";
|
|
snowfall.style.zIndex = "-1";
|
|
snowfall.style.display = defaultOn ? "block" : "none";
|
|
setBg(snowfall);
|
|
|
|
// try to respond to light and dark modes
|
|
if (window.matchMedia) {
|
|
const darkMatch = window.matchMedia('(prefers-color-scheme: dark)');
|
|
setBg(snowfall, darkMatch.matches);
|
|
darkMatch.addEventListener('change', (ev) => {
|
|
setBg(snowfall, ev.matches);
|
|
});
|
|
|
|
// and append it to the body
|
|
document.body.append(snowfall);
|
|
} else {
|
|
// assume dark, I guess?
|
|
setBg(snowfall, true);
|
|
}
|
|
|
|
activateBtn.addEventListener("click", function(ev) {
|
|
let snowfall = document.getElementById(divId);
|
|
ev.target.innerHTML = "❄️";
|
|
snowfall.style.display = (snowfall.style.display == "none") ? "block" : "none";
|
|
});
|
|
|
|
let nav = document.querySelector("nav");
|
|
if (nav != null) {
|
|
nav.prepend(activateBtn);
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: this feels like a bad idea, but I wasn't able to find a better way
|
|
// to handle this by messing with __reactContainer$[bytes]. If you know of a
|
|
// better way, send an ask on cohost (@flurry) pls!
|
|
const app = document.getElementById("app");
|
|
const observer = new MutationObserver(() => {
|
|
if (document.getElementById(divId) == null) {
|
|
makeWinter();
|
|
}
|
|
});
|
|
observer.observe(app, { subtree: true, childList: true });
|
|
})();
|
|
|