UI Tweaks By web crawler 223 installs Rating 0.0 (0) approved

Neopets - Inventory Plus

Improves the Inventory page by allowing multiple actions to be performed without a page refresh and saves selected options for items.
https://www.scriptneo.com/script/neopets-inventory-plus

Version selector


SHA256
2a3005f657df9df42923daf4661c4b43b70e3abf938b49b1f35c87faa971a9eb
No scan flags on this version.

Source code

// ==UserScript==
// @name         Neopets - Inventory Plus
// @version      1.2
// @description  Improves the Inventory page by allowing multiple actions to be performed without a page refresh and saves selected options for items.
// @author       Metamagic
// @match        *://*.neopets.com/inventory.phtml*
// @match        *://neopets.com/inventory.phtml*
// @icon         https://i.imgur.com/RnuqLRm.png
// @grant        GM_getValue
// @grant        GM_setValue
// @downloadURL  https://www.scriptneo.com/scripts/download.php?id=14
// @updateURL    https://www.scriptneo.com/scripts/download.php?id=14
// ==/UserScript==

//================
// script settings
//================

(function($) {

    //lets you bypass the refresh by clicking outside the box
    const DISABLE_REFRESH = true
    //updates inventory contents when actions are performed
    const UPDATE_ON_ACTION = true
    //remembers the last selected option for each item
    const REMEMBER_SELECTION = true
    //defaults to unstacked view. for fans of the old neopets layout. ^^
    const UNSTACK_VIEW_DEFAULT = false


    //============
    // main script
    //============


    $("#container__2020 > div.page-title__2020 > div.inv-title-container > h1")[0].innerHTML += "+"
    if(DISABLE_REFRESH) $("#refreshshade__2020")[0].remove()
    if(UNSTACK_VIEW_DEFAULT) setStackView("unstack")


    //watches for item description popup
    const descObs = new MutationObserver((mutations) => {
        if(REMEMBER_SELECTION) {
            let selection = $("#iteminfo_select_action").find("option:selected")[0]
            if(selection) {
                if(selection.innerHTML == "Choose an Action") setRememberedSelection()
            }
            rememberSelections()
        }
    })
    descObs.observe(document.getElementById("invDesc"), {childList: true, subtree: true})


    //NOTE: script may not be compatible with certain selection-based capsules (eg essentials) - i don't have the nc to test this unfort
    //watches for item results popup
    let prevDisplay = 'none'
    const resultObs = new MutationObserver((mutations) => {
        //if not loading
        if($("#invResult div.inv-loading-static").length == 0) {
            //special case for gift box menu
            if($("#invResult div.giftgram-img").length > 0 && $("#invResult").css('display') == 'block') {
                //gift sent, refresh page
                console.log($("#invResult > div.popup-body__2020 > p")?.[0])
                if($("#invResult > div.popup-body__2020 > p")?.[0]?.innerHTML?.includes("Your gift has been delivered to")) {
                    if(UPDATE_ON_ACTION) refreshInventory()
                    if(DISABLE_REFRESH) disableRefresh()
                }
                else if(DISABLE_REFRESH) disableRefresh(false)
                prevDisplay = 'block'
            }
            //now showing results
            else if($("#invResult").css('display') == 'block' && prevDisplay == 'none') {
                if(UPDATE_ON_ACTION) refreshInventory()
                if(DISABLE_REFRESH) disableRefresh()
                prevDisplay = 'block'
            }
            //no longer showing results
            else if($("#invResult").css('display') == 'none' && prevDisplay == 'block') {
                prevDisplay = 'none'
            }
        }
        //adds unclickable shade if loading
        else {
            document.getElementById("invpopupshade__2020").setAttribute("style", "display: block;")
        }
    })
    resultObs.observe(document.getElementById("invResult"), {attributes:true})

    let reload = false
    reloadImages()

    //================
    // functionalities
    //================

    function disableRefresh(addButton = true) {
        document.getElementById("invpopupshade__2020").setAttribute("style", "display: none;")
        document.getElementById("navpopupshade__2020").setAttribute("style", "display: block;")
        //updates the button to not refresh
        $("#invResult > div.popup-header__2020 > a")[0].removeAttribute("href")
        $("#invResult > div.popup-header__2020 > a > div")[0].setAttribute("onclick", "togglePopup__2020()")
        //adds refresh button
        if(addButton) {
            let a = getRefreshButton()
            $("#invResult > div.popup-body__2020")[0].appendChild(a)
        }
    }

    function getRefreshButton() {
        let a = document.createElement("a")
        a.href = "/inventory.phtml"
        let button = document.createElement("div")
        button.classList.add("button-default__2020", "button-yellow__2020", "btn-single__2020")
        button.innerHTML = "Refresh Page"
        a.appendChild(button)
        return a
    }

    function rememberSelections() {
        $("#iteminfo_select_action > select").change(() => {
            let option = $("#iteminfo_select_action").find("option:selected").val()
            let itemname = document.getElementById("invItemName").innerHTML
            let list = GM_getValue("invselect", {})
            list[itemname] = option
            GM_setValue("invselect", list)
            console.log(`[Inv+] Selection remembered for item '${itemname}'`)
        })
    }

    function setRememberedSelection() {
        console.log("[Inv+] Attempting to set")
        let itemname = document.getElementById("invItemName").innerHTML
        let memory = GM_getValue("invselect", {})[itemname]
        if(memory != undefined) {
            $("#iteminfo_select_action > select")[0].value = memory
            $("#iteminfo_select_action > div.invitem-submit")[0].classList.remove("disabledButton")
            console.log(`[Inv+] Selection set for item '${itemname}'`)
        }
    }

    //you have to do this because neopets code put a lowercase instead of an uppercase in their code. incredible.
    function reloadImages() {
        let invObs = new MutationObserver((mutations) => {
            if(reload && $(`#invDisplay > div.inv-display:not([style="display: none;"])`).length && $('.lazy').length) {
                reload = false
                $('.lazy').Lazy({
                    threshold: 50,
                    visibleOnly: true,
                })
                console.log("[Inv+] Item images force-loaded.")
            }
        })
        invObs.observe($("#invDisplay")[0], {childList:true, subtree:true})
    }

    function refreshInventory() {
        // Temporary Loading Image
        $('#invDisplay' + 1).html("<br><br><br><div class='inv-loading-static'></div><p>Loading...</p>");

        $.get("https://www.neopets.com/inventory.phtml", ()=>{
            console.log("[Inv+] Refreshed inventory contents.")
            $("#tabs > div.inv-tabs-container > ul.invTabs > li.inv-tab-label.invTab-selected")[0].click() //refreshes the inventory tab
            reload = true
        })
    }

    function setStackView(type) {
        //if it's stacked and we want unstack
        if(type == "unstack" && $("#invStack > div.stack-icon-container.invfilter-active").length > 0) {
            document.getElementById("invStack").click()
        }
        //if it's unstacked and we want stacked
        else if(type == "stack" && $("#invStack > div.unstack-icon-container.invfilter-active").length > 0) {
            document.getElementById("invStack").click()
        }
        //simply toggles it
        else document.getElementById("invStack").click()
    }
})(jQuery)