Files
reddit-tweaks-ffe/content/tweaks/badges.js

170 lines
5.7 KiB
JavaScript
Raw Normal View History

(function () {
"use strict";
let contentObserver = null;
let darkModeObserver = null;
let currentSettings = null;
function applyColorsToContainer(container, settings, subredditName) {
const prefix = window.RedditTweaks.getColorPrefix(settings);
if (window.RedditTweaks.isDarkMode(settings)) {
container.classList.add("rt-dark");
} else {
container.classList.remove("rt-dark");
}
const entry = subredditName && settings.subredditColors[subredditName];
const overrides = entry && entry[prefix];
container.style.setProperty("--rt-sub-bg", overrides?.bg || settings[prefix + ".subredditBgColor"]);
container.style.setProperty("--rt-sub-border", overrides?.border || settings[prefix + ".subredditBorderColor"]);
container.style.setProperty("--rt-sub-text", overrides?.text || settings[prefix + ".subredditTextColor"]);
container.style.setProperty("--rt-com-bg", settings[prefix + ".commentsBgColor"]);
container.style.setProperty("--rt-com-border", settings[prefix + ".commentsBorderColor"]);
container.style.setProperty("--rt-com-text", settings[prefix + ".commentsTextColor"]);
}
function normalizeCommentText(text) {
const trimmed = text.trim();
if (trimmed === "comment") return "0 comments";
return trimmed;
}
function processPost(post, settings) {
if (post.hasAttribute("data-rt-processed")) return;
const entry = post.querySelector(".entry");
if (!entry) return;
const container = document.createElement("div");
container.className = "reddit-tweaks-badges";
let subredditName = null;
const subLink = post.querySelector(".tagline .subreddit");
if (subLink) {
const badge = document.createElement("a");
badge.className = "rt-badge rt-badge--subreddit";
badge.href = subLink.href;
badge.textContent = subLink.textContent.trim();
subredditName = subLink.textContent.trim().replace(/^r\//, "");
container.setAttribute("data-rt-subreddit", subredditName);
container.appendChild(badge);
const gear = document.createElement("span");
gear.className = "rt-badge-gear";
gear.textContent = "\u2699";
gear.addEventListener("click", function (e) {
e.preventDefault();
e.stopPropagation();
if (window.RedditTweaks.colorPopover) {
window.RedditTweaks.colorPopover.open(badge, subredditName, currentSettings);
}
});
badge.appendChild(gear);
const prevNode = subLink.previousSibling;
if (prevNode && prevNode.nodeType === Node.TEXT_NODE && /\bto\s*$/.test(prevNode.textContent)) {
prevNode.textContent = prevNode.textContent.replace(/\s*to\s*$/, " ");
}
}
const commentsLink = post.querySelector(".flat-list .comments");
if (commentsLink) {
const badge = document.createElement("a");
badge.className = "rt-badge rt-badge--comments";
badge.href = commentsLink.href;
badge.textContent = normalizeCommentText(commentsLink.textContent);
container.appendChild(badge);
}
if (container.children.length === 0) return;
applyColorsToContainer(container, settings, subredditName);
entry.insertBefore(container, entry.firstChild);
post.setAttribute("data-rt-processed", "true");
}
function processPosts(settings) {
const posts = document.querySelectorAll("div.thing.link:not([data-rt-processed])");
posts.forEach(function (post) {
processPost(post, settings);
});
}
function getObserverTarget() {
return (
document.getElementById("siteTable") ||
document.querySelector('.content[role="main"]') ||
document.body
);
}
function startContentObserver(settings) {
if (contentObserver) contentObserver.disconnect();
const target = getObserverTarget();
contentObserver = new MutationObserver(function (mutations) {
let hasNewPosts = false;
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.nodeType === Node.ELEMENT_NODE) {
if (node.matches && node.matches("div.thing.link")) {
hasNewPosts = true;
} else if (node.querySelector && node.querySelector("div.thing.link")) {
hasNewPosts = true;
}
}
}
}
if (hasNewPosts) processPosts(currentSettings);
});
contentObserver.observe(target, { childList: true, subtree: true });
}
function startDarkModeObserver() {
if (darkModeObserver) darkModeObserver.disconnect();
darkModeObserver = new MutationObserver(function () {
if (currentSettings && currentSettings.darkMode === "auto") {
updateColors(currentSettings);
}
});
darkModeObserver.observe(document.body, {
attributes: true,
attributeFilter: ["class"],
});
}
function updateColors(settings) {
currentSettings = settings;
const containers = document.querySelectorAll(".reddit-tweaks-badges");
containers.forEach(function (container) {
const subredditName = container.getAttribute("data-rt-subreddit");
applyColorsToContainer(container, settings, subredditName);
});
if (window.RedditTweaks.colorPopover && window.RedditTweaks.colorPopover.refreshTheme) {
window.RedditTweaks.colorPopover.refreshTheme(settings);
}
}
function apply(settings) {
currentSettings = settings;
processPosts(settings);
startContentObserver(settings);
startDarkModeObserver();
}
window.RedditTweaks = window.RedditTweaks || {};
window.RedditTweaks.badgeTweak = {
apply: apply,
updateColors: updateColors,
isDarkMode: window.RedditTweaks.isDarkMode,
getColorPrefix: window.RedditTweaks.getColorPrefix,
};
})();