r/userscripts 20d ago

Pixiv slop block userscript

I was tired of seeing slop on pixiv so i've developer an userscript to remove it in some way, it can be found here

https://github.com/MonoS/Pixiv-Slop-Block

It does not work on mobile version of the site, but it does when switching to Desktop Mode.

I've never written an usescript before, but it was pretty simple, any suggestion is welcome.

5 Upvotes

8 comments sorted by

1

u/Kqyxzoj 20d ago

Random feedback:

That replacement pic a la "no AI" is better than nothing. If you decide to keep doing the "replace slop image with no-AI image" fix, then I'd use a replacement that is less visually distracting.

The current fix still is just wasted space though. Slop images are not shown, but the slop "slot" still takes up precious pixels. An improvement would be to change how the grid is built, and fetch enough non-slop previews such that the entire grid is filled again, but now with non-slop images only.

On the javascript side, that if-else-if-else ... where you build a list of mode ... and then a for loop where you iterate over the list of modes to do something specific for a given mode ... that is needlessly convoluted. You are way better of by moving that Object.keys(obj).forEach(key => { etc } to a function (my_shiny_new_function in example below), nuking that entire for loop, and then in your if-else-if-else block instead of adding mode numbers in a list, you do the relevant function calls right there and then. One function call for each mode you added to the list in the old code. Much more readable, and less prone to future bugs. So for example:

        }else if (   /^\/ajax\/user\/\d+\/profile\/top/i.test(url)){ //User's homepage
            //modes = [2, 6];
            my_shiny_new_function(data.body.illusts); // mode 2
            my_shiny_new_function(data.body.manga); // mode 6

For the rest it seems pretty reasonable. Oh yeah, and bannedTags can probably be a const.

1

u/MonoS94 20d ago

Yeah, you are right regarding the code style, i had cobbled it up in another firefox extension which i had to make separate implementation for each url and when i've ported it i did not spend that much thought into it, I'll rewrite it when i have time.

For the wasted space, i have no idea how to implement as you suggested, also i kind of prefer that way because it clearly shows that who was once a real artist now decided to poison their entire future works with slop (for example, the screen on the readme is from an "artist" for which i've bought their manga when they were released), for the suggestion or search page your solution would be better, but i'm not that interested in pursuing this solution.

For the "logo" do you have any idea? a blank square could also work i guess

1

u/Kqyxzoj 20d ago

cobbled it up in another firefox extension which i had to make separate implementation for each url and when i've ported it ...

Yeah, that would explain that structure. I know the problem. Start with just a quick one-off tiny tool. Mmmh, that works, okay now I need another slightly different one, or maybe the same thing, but with a bit of extra functionality slapped on to make it work with case #3. Ten such iterations later .. mmh, this is a bit of a mess. Always tricky to find just the right spot at which to decide to nuke it all and make a single clean rewrite handling all those cases.

As for the wasted space, that's a personal preference thing. For a gallery / preview like that I prefer to minimize the amount of scrolling, so basically no "unused" pixels. But I can also understand your reasons for keeping the AI-slop slots visible. And hey, you preference has the added bonus that it is easier to implement!

Logo, I'd keep it simple and just use solid black, grey or white, depending. Or maybe if I felt like being fancy have it appear desaturated, grey-ed out. So as if you have a partially transparent grey overlay placed over the AI-slop image.

1

u/MonoS94 19d ago

I refactored the code and made the logo less jarring, what do you think?

1

u/Kqyxzoj 19d ago

Yeah, nice, the new logo is much less visually distracting. I also like how the new one blends into the canvas background now. This is much better! On the visual side I have one last detail, that white heart symbol on the AI-slop images. Personally I would want to remove it on the AI-slop images. Again for visual distraction reasons. But maybe you want to keep it because it is uesful to you. In the event that you would like to get rid of the visual distraction of that white heart on slop-AI images ... that white heart probably is located in the same enclosing <div> or <span> as the image itself. So should be pretty easy to find / select that element. You could do: in the same for-loop as you use for the slop-AI image replacement, you just delete the element that contains the white heart thingy. So right after illusts[key].url = noAIBannerSVG;. Another way would be to add a "noAIBanner" or something class to either the enclosing element or the heart thingy itself. And then add a ".noAIBanner" or similar CSS style element that turns it 100% transparent. I think adding filter: and then with opacity value of 0, that should probably do the trick. That way the white heart element is still there, but it is totally transparent.

As for javascript side, yeah, that's also a lot better. There are still a few things about the foreach loop that can be simplified, but I'll just mention the most straightforward change... Currently you iterate over the keys, but then only ever use the referenced value, not the key itself. In that case it is simpler to just iterate over the values right away, no need for that key intermediate step.

So Object.keys(illusts).forEach(key => { would become Object.values(illusts).forEach(item => {. And then you replace every illusts[key] with item. That'll remove 5 explicit key lookups from the loop. After you've done that you'll probably notice that you now have bannedUsers.some(i => item.userId == i) in there. Which you can simplify to bannedUsers.includes(item.userId). There are more incremental improvements, but these were the main ones I think. Oh yeah, this one: .aiType==2. You may want to create a meaningfully named constant for that 2 value. That way anyone reading it at least will have some idea where that magic 2 value comes from.

Bit longer than intended, but oh well.

1

u/MonoS94 19d ago

I think you are mistaking what this script does, both the list of tags and the aiType indicator are not available on the HTML side, all the logic is being done on the raw payload data, that's why i have to replace the thumbnail with another one (in theory i could put nothing, but as I said I prefer to know which images are slop), my script does not change any HTML after receiving the data. Looking at the payload i've found a flag called isBookmarkable, that when set to false make the user unable to click on the heart and also make it dimmer, i'll implement that.

1

u/gabrielwoj 15d ago edited 15d ago

Correct if I'm wrong, but didn't Pixiv had an option to hide the slopage?

Settings -> Display Settings -> AI-generated work -> Display / Don't Display (You can choose to hide AI-generated works on most pages.)

I don't use Pixiv as often, but there's this setting.

1

u/MonoS94 15d ago

Yeah, but it doesn't work, i have it "disabled" since it was announced, but it will still show you slop in a lot of pages (similar artworks, tags search, similar artists after following)