SteamDatabase / BrowserExtension

💻 SteamDB's extension for Steam websites
https://steamdb.info/extension/
BSD 3-Clause "New" or "Revised" License
762 stars 55 forks source link

Hide ignored games everywhere on SteamDB #89

Closed avf closed 2 years ago

avf commented 3 years ago

Hi,

I think it would be really great if you could hide games that you've marked as 'ignored' on Steam everywhere on the SteamDB website. For example, I use the instant search feature a lot to find new games that I might be interested in, and I keep running into games I've already played on other platforms.

I'd be interested in contributing this feature. If the community is interested, maybe someone can point me in the right direction where to start :-)

AnitaJonker commented 3 years ago

I second this idea. Hiding games/apps/DLC based on tags would be wonderful.

avf commented 3 years ago

So I dug into the code a bit and found the place where the list of owned and ignored games has finished downloading, which executes this callback:

https://github.com/SteamDatabase/BrowserExtension/blob/a177db27d7d73dea6411f7d504cf8073a8e1ded4/scripts/steamdb/global.js#L55-L61

If I understand correctly, the call to window.postMessage then sends a message to the SteamDB website, including the data. SteamDB then updates the DOM to highlight owned games, for example. So from what I can tell, the clean way to do this would require updating the code for the SteamDB website to also remove the ignored games, since it already has that data.

I've quickly hacked together a proof-of-concept in my local copy of the extension, though it only works for the Instant Search page (which is what I care about). Could be pretty easily modified for other pages too though:

// elsewhere, as a global var
var myObserver;

    const OnDataLoaded = function( data )
    {

        const ignoredItemIds = [];
        for (var key in data.rgIgnoredApps) {
            ignoredItemIds.push(key);
        }

        if (!myObserver) {
            const callback = () => {
                var allInstantSearchItems = document.querySelectorAll(".ais-Hits-item");
                for (var instantSearchItem of allInstantSearchItems) {
                    const aTag = instantSearchItem.children[0];
                    const url = aTag.getAttribute("href");
                    const splitUrl = url.split("/");
                    const itemID = splitUrl[splitUrl.length - 2];
                    if (ignoredItemIds.includes(itemID)) {
                        console.log("removed: ", url, itemID);
                        instantSearchItem.remove();
                        // instantSearchItem.style.outline = '#f00 solid 2px';
                    }
                }   
            };

            myObserver = new MutationObserver(callback);
            const config = { attributes: true, childList: true, subtree: true };
            myObserver.observe(document, config);   
        }

        window.postMessage( {
            type: 'steamdb:extension-loaded',
            data: data,
        }, GetHomepage() );
    };

It's pretty hacky since I'm using a MutationObserver to listen for DOM changes - otherwise the DOM might not be fully loaded when I try to filter out the elements.

If someone has suggestions for improvements or a cleaner way to do this, please let me know. I guess a more optimal way can't be done solely through the extension and would require changing the code of SteamDB itself.

xPaw commented 2 years ago

Instant search has checkboxes to hide ignored games now.

You can use adblocker or something similar to just hide .app.ignored elements too. I don't quite want to add an option for this because there are a lot of different pages on SteamDB where hiding apps wouldn't make much sense.