GC Quickstock with Manual Tagging/ GM Storage

Selects Deposit, Discard, or Stock based on your chosen preference. Adds button next to item name with drop down to choose. Saves to GM storage for persistence. Now includes menu option to remove item.

当前为 2024-07-26 提交的版本,查看 最新版本

// ==UserScript==
// @name         GC Quickstock with Manual Tagging/ GM Storage
// @namespace    https://greasyfork.org/users/1295622
// @version      1.1
// @description  Selects Deposit, Discard, or Stock based on your chosen preference. Adds button next to item name with drop down to choose. Saves to GM storage for persistence. Now includes menu option to remove item.
// @author       spiderpool1855 (based on Dij's auto discard script)
// @match        https://www.grundos.cafe/quickstock/
// @match        https://grundos.cafe/quickstock/
// @grant        GM.getValue
// @grant        GM.setValue
// @grant        GM.deleteValue
// @grant        GM.registerMenuCommand
// @grant        GM.addStyle
// @grant        GM.xmlHttpRequest
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    async function setVariableValue(variableName, promptMessage, action) {
        let currentValue = JSON.parse(await GM.getValue(variableName, '[]'));
        let userInput = prompt(promptMessage);

        if (userInput !== null) {
            switch (action) {
                case 'add':
                    if (!currentValue.includes(userInput)) {
                        currentValue.push(userInput);
                    }
                    break;
                case 'remove':
                    currentValue = currentValue.filter(item => item !== userInput);
                    break;
            }
            GM.setValue(variableName, JSON.stringify(currentValue));
        }
    }

    async function removeFromAll(promptMessage) {
        let userInput = prompt(promptMessage);

        if (userInput !== null) {
            let discard = JSON.parse(await GM.getValue('defaultDiscard', '[]'));
            let stock = JSON.parse(await GM.getValue('defaultStock', '[]'));
            let deposit = JSON.parse(await GM.getValue('defaultDeposit', '[]'));

            discard = discard.filter(item => item !== userInput);
            stock = stock.filter(item => item !== userInput);
            deposit = deposit.filter(item => item !== userInput);

            GM.setValue('defaultDiscard', JSON.stringify(discard));
            GM.setValue('defaultStock', JSON.stringify(stock));
            GM.setValue('defaultDeposit', JSON.stringify(deposit));
        }
    }

    // GM.registerMenuCommand("Add to Discard", function() {
    //    setVariableValue('defaultDiscard', 'Add item to Discard:', 'add');
    //});

    //GM.registerMenuCommand("Add to Stock", function() {
    //    setVariableValue('defaultStock', 'Add item to Stock:', 'add');
    //});

    //GM.registerMenuCommand("Add to Deposit", function() {
    //    setVariableValue('defaultDeposit', 'Add item to Deposit:', 'add');
    //});

    GM.registerMenuCommand("Remove item", function() {
        removeFromAll('Remove item: ');
    });
})();


(async function() {
    'use strict';

    // Load arrays from GM storage or start new
    const defaultDiscard = JSON.parse(await GM.getValue('defaultDiscard', '[]'));
    const defaultStock = JSON.parse(await GM.getValue('defaultStock', '[]'));
    const defaultDeposit = JSON.parse(await GM.getValue('defaultDeposit', '[]'));

    // save arrays to GM storage
    async function saveArrays() {
        await GM.setValue('defaultDiscard', JSON.stringify(defaultDiscard));
        await GM.setValue('defaultStock', JSON.stringify(defaultStock));
        await GM.setValue('defaultDeposit', JSON.stringify(defaultDeposit));
    }

    // create a button with dropdown
    function addTaggingButton(itemElement, itemName) {
        const button = document.createElement('button');
        button.type = "button";
        button.style.width = '20px';
        button.style.height = '10px';
        button.style.marginLeft = '10px';
        button.style.cursor = 'pointer';
        //button.style.border = 'none'; // Optional: remove border

        // Create dropdown menu
        const select = document.createElement('select');
        const options = ['Add to List', 'Deposit', 'Stock', 'Discard'];
        options.forEach(option => {
            const opt = document.createElement('option');
            opt.value = option;
            opt.textContent = option;
            select.appendChild(opt);
        });
        select.style.display = 'none';
        select.style.position = 'absolute';
        select.style.zIndex = '1000'; // Ensure dropdown appears on top

        // Show dropdown on button click
        button.addEventListener('click', (event) => {
            event.stopPropagation();
            select.style.display = (select.style.display === 'none') ? 'inline' : 'none';
            // Position the dropdown directly below the button
            select.style.top = `${button.offsetTop + button.offsetHeight}px`;
            select.style.left = `${button.offsetLeft}px`;
        });

        // Update arrays on selection
        select.addEventListener('change', async () => {
            const value = select.value;
            switch (value) {
                case 'Deposit':
                    if (!defaultDeposit.includes(itemName)) {
                        defaultDeposit.push(itemName);
                    }
                    if (defaultStock.includes(itemName)) {
                        defaultStock.splice(defaultStock.indexOf(itemName), 1);
                    }
                    if (defaultDiscard.includes(itemName)) {
                        defaultDiscard.splice(defaultDiscard.indexOf(itemName), 1);
                    }
                    break;
                case 'Stock':
                    if (!defaultStock.includes(itemName)) {
                        defaultStock.push(itemName);
                    }
                    if (defaultDeposit.includes(itemName)) {
                        defaultDeposit.splice(defaultDeposit.indexOf(itemName), 1);
                    }
                    if (defaultDiscard.includes(itemName)) {
                        defaultDiscard.splice(defaultDiscard.indexOf(itemName), 1);
                    }
                    break;
                case 'Discard':
                    if (!defaultDiscard.includes(itemName)) {
                        defaultDiscard.push(itemName);
                    }
                    if (defaultDeposit.includes(itemName)) {
                        defaultDeposit.splice(defaultDeposit.indexOf(itemName), 1);
                    }
                    if (defaultStock.includes(itemName)) {
                        defaultStock.splice(defaultStock.indexOf(itemName), 1);
                    }
                    break;
            }
            // Save arrays after modification
            await saveArrays();
            // Hide dropdown and remove button after selection
            select.style.display = 'none';
            button.remove();
            updateItems();
        });

        itemElement.appendChild(button);
        itemElement.appendChild(select);
    }

    // fill out quickstock form with chosen selections
    function updateItems() {
        const quickstock = document.querySelector("main .market_grid");
        if (!quickstock) return;

        const gridLength = quickstock.querySelectorAll(".header").length;
        const quickstockNames = quickstock.querySelectorAll(".data.justify-right");
        const quickstockDeposit = quickstock.querySelectorAll(`.data:nth-child(${gridLength}n+3)`);
        const quickstockStock = quickstock.querySelectorAll(`.data:nth-child(${gridLength}n+2)`);
        const quickstockDiscard = quickstock.querySelectorAll(`.data:nth-child(${gridLength}n+5)`);

        quickstockNames.forEach((itemName, index) => {
            const name = itemName.innerText;
            if (defaultDiscard.includes(name)) {
                quickstockDiscard[index].children[0].checked = true;
            } else if (defaultStock.includes(name)) {
                quickstockStock[index].children[0].checked = true;
            } else if (defaultDeposit.includes(name)) {
                quickstockDeposit[index].children[0].checked = true;
            }

            // Add tagging button only if the item is not in any of the arrays
            if (!defaultDiscard.includes(name) && !defaultStock.includes(name) && !defaultDeposit.includes(name)) {
                if (!quickstockNames[index].querySelector('button')) {
                    addTaggingButton(quickstockNames[index], name);
                }
            }
        });
    }

    // Allows to page to see the array change after initial dropdown selection so it will fill quickstock without a refresh
    const observer = new MutationObserver(() => {
        updateItems();
        // Disconnect the observer after the initial update
        observer.disconnect();
    });

    // Initial update and start observing
    updateItems();
    observer.observe(document.body, { childList: true, subtree: true });

})();