Open Kryptortio opened 1 month ago
I never bothered to use the internal React props. I'd rather not rely on implementation details, especially with Twitch frontend devs going back and forth. And while using the rendered elements is not exactly a better solution either, it has been working surprisingly well.
Thanks for pointing out the option, but I'm not going to refactor and maintain the data retrieval code for it.
I'll keep the issue open, so people can see there is a solution available.
It's certainly possible that Twitch will break it. I'll just add it as a userscript then so it's easier to use if someone wants to do that.
To use you install an add-on like Tampermonkey and then install the script (create new and paste it). Then you can edit it and change the tags as needed (tagToBan1, tagToBan2
). You can also change removeFullyOnMatch
if you prefer completely hiding matches instead of just making them fade out.
// ==UserScript==
// @name Twitch tag blacklist
// @namespace https://www.twitch.tv/tag-blacklist
// @version 0.1
// @description Twitch tag blacklist
// @author You
// @match https://www.twitch.tv/directory/*
// ==/UserScript==
(function() {
// Blacklist for tags edit this manually:
let tagBlackList = [
/* ↓ Add tags to blacklist here ↓ */
'tagToBan1',
'tagToBan2',
/* ↑ Add tags to blacklist here ↑ */
];
let removeFullyOnMatch = false; // Change to true to completely hide matches for blacklist
tagBlackList = new Set( tagBlackList.map(value => value.toLowerCase()));
function checkChannels() {
let channels = document.querySelectorAll('.tw-tower > div:not(#directory-rectangle)');
// Find react property name
let reactVar = Object.keys(channels[0]).filter(
function(el, ind, arr){ return el.startsWith('__reactFiber$') }
)[0];
// Loop all channels
channels.forEach((node) => {
if(node[reactVar].child == null) return;
let tags = node[reactVar].child.memoizedProps.item.tags;
let blackListMatch = false;
// Loop tags for this channel
tags.forEach((tagEl) => {
if(tagBlackList.has(tagEl.name.toLowerCase())) blackListMatch = true;
});
// Did it have a tag from the blacklist?
if(blackListMatch) {
if(removeFullyOnMatch) {
node.parentNode.removeChild(node);
} else {
node.style.opacity = "0.5";
node.style.filter = "grayscale(1)";
}
} else {
node.style.opacity = "unset";
node.style.filter = "unset";
}
});
}
setInterval( () => {
checkChannels();
},1000);
})();
I realize this is listed as not possible in the FAQ but I'll provide a POC snippet that shows how it can be done.
The snippet above looks at the React component properties to get all the tags and prints a list. This should be possible to integrate in the add-on instead of just looping over the visible tags. Also the technique could solve other similar issues. For example to get the sidebar channel titles you can modify the above snippet slightly like this:
If needed you can install the react developer tools to be able to inspect nodes so you can see what properties they contain. Or in Firefox you can inspect as normal, right click on an element and select "Show DOM properties" then you can expand the element pasted in the console and view the "__reactFiber$xxxxxxxx" property there.