Custom highlighting for selected "Followed Channels" in twitch.tv sidebar.
当前为
// ==UserScript==
// @name Twitch Followed Channels Color Customizer
// @namespace http://tampermonkey.net/
// @version 2025-05-11T18-13
// @description Custom highlighting for selected "Followed Channels" in twitch.tv sidebar.
// @author Technosoap
// @license MIT
// @match https://www.twitch.tv/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=twitch.tv
// @grant none
// ==/UserScript==
//
// INSTRUCTIONS FOR USERS: modify the `userConfigJson` below to add or remove
// the channels you want to highlight. For example add the line:
//
// "MyFavouriteStreamer": "lime",
//
// to highlight MyFavouriteStreamer with a lime-green color.
//
// If you want to add more colors, be sure to add another `GM_addStyle` line
// too.
(function() {
'use strict';
const addStyle = function(cssText) {
let head = document.getElementsByTagName('head')[0];
if (head) {
let style = document.createElement('style');
style.setAttribute('type', 'text/css');
style.textContent = cssText;
head.appendChild(style);
return style;
}
return null;
};
addStyle('p.twitch-followed-channels-color-customizer-userscript-highlight-gray { color: gray !important; }');
addStyle('p.twitch-followed-channels-color-customizer-userscript-highlight-lime { color: lime !important; }');
// The long term plan is that this JSON would be stored in local storage and
// modified by some sort of configuration interface. For now, we hard-code
// it.
//
// TODO validate that colors here have a corresponding
// twitch-followed-channels-color-customizer-userscript-highlight-* class.
//
// TODO the config is using human-friendly twitch channel handles (e.g.
// "OldTimeyComputerShow"). Handles can change, so ideally we would be using
// something immutable like the channel ID, but AFAICT that requires an API
// call. Not worth the faff right now.
const userConfigJson = `{"highlights": {
"OldTimeyComputerShow": "gray",
"PirateSoftware": "lime"}}`;
// Revive with Object.create(null), to avoid issues of a namespace collision
// between Object's prototype and twitch users (imagine a twitch streamer
// called toString...).
//
// ref:
// https://esdiscuss.org/topic/proposal-add-an-option-to-omit-prototype-of-objects-created-by-json-parse#content-1
// via https://stackoverflow.com/a/48260948
const userConfig = JSON.parse(userConfigJson, function(key, value) {
if (value && typeof value === 'object' && !Array.isArray(value)) {
return Object.assign(Object.create(null), value);
}
return value;
});
const findFollowedChannelsDiv = function() {
const followedChannelsDiv = document.querySelector(`div[aria-label="Followed Channels"]`);
if (followedChannelsDiv) {
let observerTimer = 0;
const observer = new ResizeObserver((entries) => {
// debouncing
clearTimeout(observerTimer);
observerTimer = setTimeout(changeColor, 100, followedChannelsDiv);
}).observe(followedChannelsDiv);
clearInterval(findFollowedChannelsDivInterval);
}
}
const findFollowedChannelsDivInterval = setInterval(findFollowedChannelsDiv, 1000);
const changeColor = function(followedChannelsDiv) {
for (const titleElem of followedChannelsDiv.getElementsByClassName("side-nav-card__title")) {
const handle = titleElem.firstElementChild.title;
const highlightColor = userConfig.highlights[handle];
if (highlightColor) {
titleElem.firstElementChild.classList.toggle(`twitch-followed-channels-color-customizer-userscript-highlight-${highlightColor}`, true);
}
}
};
})();