// ==UserScript== // @name VoidVerified // @namespace http://tampermonkey.net/ // @version 0.3.4 // @description Display a verified sign next to user's name in AniList. // @author voidnyan // @match https://anilist.co/* // @grant none // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; const version = "0.3.4"; const evaluationIntervalInSeconds = 1; const localStorageColors = "void-verified-colors"; const verified = { copyColorFromProfile: false, username: { enabled: true, enabledForReplies: true, enabledForProfileName: true, color: "white", sign: "✔", }, highlight: { enabled: true, enabledForReplies: true, enabledForSmallCards: false, color: undefined, size: "5px", } }; const shouldIntervalBeUsed = verified.username.enabledForProfileName || verified.highlight.enabled; let verifiedUsers = [ { username: "voidnyan", sign: "💻", }, ] .map(u => typeof u === "string" ? {username: u} : u); const colorsInLocalStorage = JSON.parse(localStorage.getItem(localStorageColors)); if (colorsInLocalStorage !== null) { verifiedUsers = verifiedUsers.map(u => colorsInLocalStorage !== null && u.color ? u : { ...u, color: colorsInLocalStorage.find(c => c.username === u.username)?.color }); } let usernameStyles = ""; let highlightStyles = ""; createStyles(); function createStyles(){ usernameStyles = ""; highlightStyles = ""; for (const user of verifiedUsers){ if (verified.username.enabled) { createUsernameCSS(user); } if (verified.highlight.enabled) { createHighlightCSS(user, `div.wrap:has( div.header > a.name[href*="${user.username}"] )`); createHighlightCSS(user, `div.wrap:has( div.details > a.name[href*="${user.username}"] )`); } if (verified.highlight.enabledForReplies) { createHighlightCSS(user, `div.reply:has( a.name[href*="${user.username}"] )`); } } if (verified.highlight.enabled && !verified.highlight.enabledForSmallCards) { disableHighlightOnSmallCards(); } } function createUsernameCSS(user) { usernameStyles += ` a.name[href*="${user.username}"]::after { content: "${user.sign ?? verified.username.sign}"; color: ${user.color ?? verified.username.color ?? "rgb(var(--color-blue))"} } `; }; function createHighlightCSS(user, selector){ highlightStyles += ` ${selector} { margin-right: -${verified.highlight.size}; border-right: ${verified.highlight.size} solid ${user.color ?? verified.highlight.color ?? "rgb(var(--color-blue))"}; border-radius: 5px; } `; } function disableHighlightOnSmallCards(){ highlightStyles += ` div.wrap:has(div.small) { margin-right: 0px !important; border-right: 0px solid black !important; } `; } const usernameLink = createStyleLink(usernameStyles, "username"); const highlightLink = createStyleLink(highlightStyles, "highlight"); const profileLink = createStyleLink("", "profile"); function refreshHomePage(){ if (!verified.highlight.enabled) { return; } const oldHighlightLink = document.getElementById("void-verified-highlight-styles"); const newHighlightLink = createStyleLink(highlightStyles, "highlight"); oldHighlightLink.remove(); } function verifyProfile(){ if (!verified.username.enabledForProfileName) { return; } const usernameHeader = document.querySelector("h1.name"); const username = usernameHeader.innerHTML.trim(); const user = verifiedUsers.find(u => u.username === username); if (!user){ profileLink.href = 'data:text/css;charset=UTF-8,' + encodeURIComponent(""); return; } copyUserColor(user, usernameHeader); const profileStyle = ` h1.name::after { content: "${user.sign ?? verified.username.sign}" } `; profileLink.href = 'data:text/css;charset=UTF-8,' + encodeURIComponent(profileStyle); } function copyUserColor(user, header) { if (user.copyColorFromProfile === false || !user.copyColorFromProfile && !verified.copyColorFromProfile) { return; } const color = getComputedStyle(header).getPropertyValue('--color-blue'); user.color = `rgb(${color})`; verifiedUsers = verifiedUsers.map(u => u.username !== user.username ? u : user); createStyles(); const oldHighlightLink = document.getElementById("void-verified-highlight-styles"); const newHighlightLink = createStyleLink(highlightStyles, "highlight"); oldHighlightLink.remove(); const oldUsernameLink = document.getElementById("void-verified-username-styles"); const newUsernameLink = createStyleLink(highlightStyles, "username"); oldUsernameLink.remove(); addOrUpdateColorToLocalStorage(user); } function addOrUpdateColorToLocalStorage(user) { let localColors = JSON.parse(localStorage.getItem(localStorageColors)); if (localColors === null) { localStorage.setItem(localStorageColors, JSON.stringify([{username: user.username, color: user.color}])); return; } let localStorageUser = localColors.find(u => u.username === user.username); if (localStorageUser){ localStorageUser.color = user.color; localColors = localColors.map(u => u.username === localStorageUser.username ? localStorageUser : u); } else { localColors.push({username: user.username, color: user.color}); } localStorage.setItem(localStorageColors, JSON.stringify(localColors)); } function createStyleLink(styles, id){ const link = document.createElement('link'); link.setAttribute('id', `void-verified-${id}-styles`); link.setAttribute('rel', 'stylesheet'); link.setAttribute('type', 'text/css'); link.setAttribute('href', 'data:text/css;charset=UTF-8,' + encodeURIComponent(styles)); document.head?.append(link); return link; } let currentPath = ""; function hasPathChanged(path){ if (path === currentPath){ return false; } currentPath = path; return true; } function handleIntervalScripts(){ const path = window.location.pathname; if (path === "/home") { refreshHomePage(); return; } if (!hasPathChanged(path)){ return; } if (path.startsWith("/user/")){ verifyProfile(); } } if (shouldIntervalBeUsed) { setInterval(handleIntervalScripts, evaluationIntervalInSeconds * 1000); } console.log(`VoidVerified ${version} loaded.`); })();