Greasy Fork 支持简体中文。

GC Quickstock Helper (Form over Function)

Adds a button to items that have not been tagged on Quick Stock that allows you to save your Deposit, Stock, Discard preference. To remove a preference, use the "Remove Item" button in the Tampermonkey menu (in your browser extensions). The button will load again for that item on next refresh. Recommend turning off auto-update to protect your GM Storage. Copy your GM Storage text to notepad before updating, then paste back in after update.

// ==UserScript==
// @name         GC Quickstock Helper (Form over Function)
// @namespace    https://greasyfork.org/users/1295622
// @version      1.5
// @description  Adds a button to items that have not been tagged on Quick Stock that allows you to save your Deposit, Stock, Discard preference. To remove a preference, use the "Remove Item" button in the Tampermonkey menu (in your browser extensions). The button will load again for that item on next refresh. Recommend turning off auto-update to protect your GM Storage. Copy your GM Storage text to notepad before updating, then paste back in after update. 
// @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("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 = '10px';
        button.style.height = '5px';
        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 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 });

})();