Sunajo / Gwent Old Decks Filtering

// ==UserScript==
// @name         Gwent Old Decks Filtering
// @namespace    https://openuserjs.org/users/Sunajo
// @version      0.2
// @description  Blocks deck requests in Gwent Deck Library to filter out old decks as decks are a "fresh commodity" and showing old decks in lists isn't really useful.
// @author       Sunajo
// @match        https://www.playgwent.com/en/decks*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=playgwent.com
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';
    console.log("Running Block Gwent Deck Requests To Not Show Old Decks!");
    const { fetch: originalFetch } = window,
          HIDE_OLD_DECKS = "hideOldDecks",
          tableHeaderElem = document.querySelectorAll("#root > div > div")[0];
    let active = localStorage.getItem(HIDE_OLD_DECKS);

    if (tableHeaderElem) {
        console.log("Header found! Adding hide old decks checkbox.");
        const hideOldDecksDiv = document.createElement("div"),
              hideOldDecksCheckbox = document.createElement("div"),
              hideOldDecksLabel = document.createElement("div");

        // set up checkbox
        hideOldDecksCheckbox.style.cssText = `
            cursor: pointer;
            background-color: transparent;
            border: 1px solid rgb(226, 167, 62);
            padding-left: 2px;
            padding-top: 10px;
            margin: 2px;
            margin-right: 4px;
            border-radius: 0px;
            width: 20px;
            height: 20px;
            color: rgb(226, 167, 62);
            float: left;
            line-height: 0;
            font-size: 20px;
            `;

        if (active) {
            hideOldDecksCheckbox.innerText = '\u2713';
        } else {
            hideOldDecksCheckbox.innerText = "";
        }

        hideOldDecksCheckbox.onclick = function() {
            console.log("Checkbox clicked");
            if (!active) {
                console.log("Activating blocking of deck requests!");
                localStorage.setItem(HIDE_OLD_DECKS, true);
            } else {
                console.log("Deactivating blocking of deck requests!");
                localStorage.removeItem(HIDE_OLD_DECKS);
            }
            location.reload();
        };

        // set up checkbox label
        hideOldDecksLabel.innerText = "Hide old decks";
        hideOldDecksLabel.style.cssText=`
            width: auto;
            float: left;
            `;

        //set up checkbox div container
        hideOldDecksDiv.style.cssText = `
            position: absolute;
            right: 0px;
            color: rgb(226, 167, 62);
            margin-bottom: 0px;
            margin-left: auto;
            margin-right: 6px;
            margin-top: 6px;
            font-family: HalisGR-Book, sans-serif;
            font-size: 18px;
            z-index: 0;
            `;
        hideOldDecksDiv.append(hideOldDecksCheckbox);
        hideOldDecksDiv.append(hideOldDecksLabel);

        // hide checkbox div if in a deck guide or deck list
        if (location.href.split("decks/")[1]) {
            console.log("In deck guide. Hide checkbox!");
            hideOldDecksDiv.style.display = "none";
            hideOldDecksDiv.style.zIndex = -5;
        }

        // add the checkbox dev to the page
        tableHeaderElem.append(hideOldDecksDiv);

        // add observer to keep track of if we are in a guide where checkbox should hide
        const observer = new MutationObserver(function(mutations_list) {
            if (location.href.indexOf("guide") !== -1) {
                console.log("In deck guide. Hide checkbox!");
                hideOldDecksDiv.style.display = "none";
                hideOldDecksDiv.style.zIndex = -5;
            } else {
                console.log("In Deck Library! Show checkbox.");
                hideOldDecksDiv.style.display = "block";
                setTimeout(function() {hideOldDecksDiv.style.zIndex = 0;}, 1700);
            }
        });
        observer.observe(document.querySelector("#root > div > section"), { subtree: false, childList: true });

        // add function to show/hide checkbox on screen size change
        function toggleCheckboxDependingOnScreenSize(x) {
            if (location.href.split("decks/")[1]) {
                return;
            }
            if (x.matches && hideOldDecksDiv.style.display !== "none") { // If media query matches
                console.log("Hiding checkbox because of screen size change!");
                hideOldDecksDiv.style.display = "none";
                hideOldDecksDiv.style.zIndex = -5; //for visual reasons where create deck button clashes with checkbox
            } else if (hideOldDecksDiv.style.display !== "block") {
                console.log("Showing checkbox because of screen size change!");
                hideOldDecksDiv.style.display = "block";
                // create deck button clashes with checkbox, and without delay for z-index sometimes it looks bad
                // needs to be at z-index 0 to be clickable, otherwise this would not be needed
                setTimeout(function() {hideOldDecksDiv.style.zIndex = 0;}, 1700);
            }
        };

        const x = window.matchMedia("(max-width: 760px)");
        toggleCheckboxDependingOnScreenSize(x);
        x.addListener(toggleCheckboxDependingOnScreenSize);

    } else {
        console.log("Header not found. Can't add checkbox! Deactivating blocking of deck requests!");
        active = false;
    }

    // if the blocking is active, modify fetch to block deck requests but allow other requests
    if (active && window.fetch) {
        window.fetch = async (...args) => {
            let [resource, config ] = args;
            // block deck calls, but if going back to decks from a deck guide, the 0, 500 and 1000 limit deck list calls need to be allowed because otherwise list will be empty
            if (resource && resource.indexOf("decks/api") !== -1 && resource.indexOf("/limit/") !== -1 && resource.indexOf("/0/limit/") === -1 && resource.indexOf("/500/limit/") === -1 && resource.indexOf("/1000/limit/") === -1) {
                console.log("Deck API call found! Blocking!", resource);
                return Promise.reject(new Response());
            // any other call will be allowed through and use original fetch function
            } else {
                console.log("Other call. Letting through!", resource);
                const response = await originalFetch(resource, config);
                return response;
            }
        };
    } else {
        console.log("Blocking not activated!");
    }

})();