Closed kwaschny closed 2 years ago
Hey, last time I did not realize I do not need to muck around with constructing the GraphQL request, it is possible to just find the overflow menu button relative to the category image, click it to make the overflow menu mount and in it find and click the "Not Interested" button. It is much simpler, check it out:
// Find all poster images on the https://www.twitch.tv/directory page
[...document.querySelectorAll('.tw-image[src*="ttv-boxart"]')]
// Extract ID, name, the `img` element and the "Not Interested" `button` element
.map(img => ({
// Convert the ID to a number for comparisons
id: +img.src.match(/\d+/)[0],
// Extract the name from the `alt` tag (least likely to change format)
name: img.alt.slice(0, -' cover image'.length),
// Keep the `img` element reference to be able to hover over it and debug
img,
// Find the overflow menu button (it is the only button in the query)
button: img.closest('a').parentNode.querySelector('button'),
}))
// Check all the results to drop unexpected data rather than cause damange
.filter(category => category.id && category.name && category.img && category.button)
// Drop categories I do not wish to remove:
// Just Chatting: 509658, Music: 26936, Art: 509660, Chess: 743,
// Retro Gaming: 27284, Makers & Crafting: 509673,
// Software and Game Development: 1469308723, Science & Technology: 509670
.filter(category => ![509658, 26936, 509660, 743, 27284, 509673, 1469308723, 509670].includes(category.id))
// Limit to a handful for a test - change or re-run the script at your leisure
.slice(0, 5)
// Open the overflow menu and click the "Not Interested" button for each item
.forEach(category => {
// Open the overflow menu to make the "Not Interested" button mount in DOM
category.button.click();
// Find the "Not Interested" `button` through the shared parent of the elements
const button = category.img.closest('a').parentNode.querySelector('button[data-a-target="rec-feedback-card-not-interested"]');
if (!button) {
console.log(category.id, category.name, 'Overflow button click did not reveal the "Not Interested" button');
return;
}
button.click();
console.log(category.id, category.name, '"Not Interested" button clicked');
});
Hey, thanks for bringing this up. Always nice to see other people trying to find (better) ways to block/hide unwanted content.
the extension blocks the browser tab for several seconds at a time whenever a new page of the infinite scroll functionality is fetched.
FYI: That's Twitch's infinite scroll behavior. The more pages you load (i.e. the bigger the DOM becomes), the slower everything loads. Mass blocking may trigger multiple of these infinite scrolls, making JS block the UI for a noticeable time. The poor performance is on Twitch's side and can also be observed without using any extension. UTTV just happens to highlight this (and used to cause clientside bot checks with large blacklists due to the unnatural small intervals between fetching more pages).
Now regarding "Not Interested": If we start telling Twitch about blocks, we also need to tell Twitch about unblocks. That requires a change how the blacklist entries are stored, since we need to remember Twitch's IDs then. I also checked if this applies to channels and it does! Unfortunately we need channels IDs of the currently logged in user and the channel to add/remove from the "Not Interested" list. So at some point we need to actual query (and cache) data from the Twitch API, which requires OAuth.
Changing the storage entries and adjusting the fragmentation algorithm is only worth touching (remember: backward compatibility) if we can actually store categories AND channels IMO. And even then, I don't plan on going the "login to allow this extension to change something in your name" route, especially because the "Not Interested" list is not part of the official API (at least not yet?). The param is prefixed with v0
, that figures. 😄 Relying on the ID in an external resource such as the category image is nice and all, but it's "risky" considering that the whole change is based on the assumption that this won't change anytime soon.
And as you already stated: maintaining the "Not Interested" list currently has no impact on the actual directory views. It is really just useful for recommended content.
tl;dr: I don't want to start communicating with Twitch in the name of the user as long as it doesn't grant "life-changing benefits".
Hey Alex, thanks for the response. I see your point and I agree. My request here is pretty niche and it looks like it would be a big change for a sake of questionable benefit especially because mass-marking-stuff-as-not-interested is super easy with the above snippet so if anyone else interested in this comes along, they can just open the DevTools and use the snippet themselves - it is not as comfortable but not a big deal either. Thanks again!
Hey, last time I did not realize I do not need to muck around with constructing the GraphQL request, it is possible to just find the overflow menu button relative to the category image, click it to make the overflow menu mount and in it find and click the "Not Interested" button. It is much simpler, check it out:
// Find all poster images on the https://www.twitch.tv/directory page [...document.querySelectorAll('.tw-image[src*="ttv-boxart"]')] // Extract ID, name, the `img` element and the "Not Interested" `button` element .map(img => ({ // Convert the ID to a number for comparisons id: +img.src.match(/\d+/)[0], // Extract the name from the `alt` tag (least likely to change format) name: img.alt.slice(0, -' cover image'.length), // Keep the `img` element reference to be able to hover over it and debug img, // Find the overflow menu button (it is the only button in the query) button: img.closest('a').parentNode.querySelector('button'), })) // Check all the results to drop unexpected data rather than cause damange .filter(category => category.id && category.name && category.img && category.button) // Drop categories I do not wish to remove: // Just Chatting: 509658, Music: 26936, Art: 509660, Chess: 743, // Retro Gaming: 27284, Makers & Crafting: 509673, // Software and Game Development: 1469308723, Science & Technology: 509670 .filter(category => ![509658, 26936, 509660, 743, 27284, 509673, 1469308723, 509670].includes(category.id)) // Limit to a handful for a test - change or re-run the script at your leisure .slice(0, 5) // Open the overflow menu and click the "Not Interested" button for each item .forEach(category => { // Open the overflow menu to make the "Not Interested" button mount in DOM category.button.click(); // Find the "Not Interested" `button` through the shared parent of the elements const button = category.img.closest('a').parentNode.querySelector('button[data-a-target="rec-feedback-card-not-interested"]'); if (!button) { console.log(category.id, category.name, 'Overflow button click did not reveal the "Not Interested" button'); return; } button.click(); console.log(category.id, category.name, '"Not Interested" button clicked'); });
I'd like to use this, but I have no clue how to 'insert' this code into the extension, nor how to make it react to the user choices rather than fixed categories. Would you kindly point me to in the right direction for that?
@Idontneedaname This code is supposed to be run using the web browser developer tools. If you are not a developer, you might still be able to use it, but it is not going to be user-friendly and will require some effort.
Note that this script works as a whitelist, you tell it what categories to keep, not what categories to bulk remove! If you need the latter, I can't help you unfortunately.
The steps to do it would be to:
img
element with class="tw-image"
on it and a src
with a URL as wellttv-boxart
bit followed by a slash and a number.filter(category => ![509658, 26936, 509660, 743, 27284, 509673, 1469308723, 509670].includes(category.id))
[
and ]
with your numbers, separating them with spacesThat should be it. It will do 5 categories at first as a test. Visually check the behavior to make sure it is good.
If it looks good, press the up arrow in the Console to recall the script text again, remove this line: .slice(0, 5)
and run it again. You might need to manually scroll, let Twitch load more categories and keep re-running the script. The script can't scroll on its own.
This is all assuming Twitch hasn't changed the structure of their page. I've not used this for a while, so if they did, I'd need to fix the script first and I am not sure I'll get to that if it is needed.
Hi, thanks for the reply! Alas, I couldn't get it to work. I'll just keep blocking the trash manually, it's a somewhat relaxing thing to do anyway.
Originally posted by @TomasHubelbauer in https://github.com/kwaschny/unwanted-twitch/issues/55#issuecomment-974865100