Mass Bazaar and Trade adder for Torn.com

Toggle all selected items on Torn.com and set maximum quantity and price (excluding equipped items, supports lazy loading, remembers inputs)

// ==UserScript==
// @name         Mass Bazaar and Trade adder for Torn.com
// @namespace    http://tampermonkey.net/
// @version      7.7
// @description  Toggle all selected items on Torn.com and set maximum quantity and price (excluding equipped items, supports lazy loading, remembers inputs)
// @author       Fists [2830940]
// @match        https://www.torn.com/bazaar.php*
// @match        https://www.torn.com/trade.php*
// @match        https://www.torn.com/factions.php*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    function toggleItems() {
        const button = document.getElementById('toggleButton');
        button.style.transform = 'translate(-4px, 4px)';
        button.style.backgroundColor = '#7B1FA2';
        setTimeout(() => {
            button.style.transform = '';
            button.style.backgroundColor = '#AB47BC';
        }, 200);

        const itemNameInput = document.getElementById('itemNameInput');
        const itemPriceInput = document.getElementById('itemPriceInput');
        const itemName = itemNameInput.value.trim().toLowerCase();
        const itemPrice = parseFloat(itemPriceInput.value.trim());

        if (!itemName) return;

        // Save to localStorage
        localStorage.setItem('massAdder_itemName', itemName);
        localStorage.setItem('massAdder_itemPrice', itemPriceInput.value.trim());

        // Select all currently loaded items
        const items = document.querySelectorAll('.clearfix[data-group="child"], .item___jLJcf');
        let matchingItems = [];

        items.forEach(item => {
            // 🚫 Skip equipped or disabled items
            if (item.classList.contains('disabled') || item.classList.contains('bg-red')) return;
            const usedText = item.querySelector('.used');
            if (usedText && usedText.textContent.trim().toLowerCase() === 'equipped') return;

            const itemNameElement = item.querySelector('.name-wrap .t-overflow, .desc___VJSNQ span b');
            const itemNameText = itemNameElement ? itemNameElement.textContent.trim().toLowerCase() : '';
            if (itemNameText.includes(itemName)) matchingItems.push(item);
        });

        if (matchingItems.length === 0) return;

        // Check if ALL matching items are already selected
        const allSelected = matchingItems.every(item => {
            const checkbox = item.querySelector('.amount-main-wrap .amount .checkbox-css');
            const qtyInput = item.querySelector('.amount input[type="text"]');
            return (checkbox && checkbox.checked) || (qtyInput && qtyInput.value && qtyInput.value !== '0');
        });

        const shouldSelect = !allSelected;

        matchingItems.forEach(item => {
            const itemPriceElement = item.querySelector('.input-money');
            const itemQuantityElement = item.querySelector('.amount input[type="text"]');
            const checkbox = item.querySelector('.amount-main-wrap .amount .checkbox-css');

            if (shouldSelect) {
                // ✅ Select and set price
                if (checkbox && !checkbox.checked) {
                    checkbox.checked = true;
                    checkbox.dispatchEvent(new Event('click', { bubbles: true }));
                } else if (itemQuantityElement && (!itemQuantityElement.value || itemQuantityElement.value === '0')) {
                    itemQuantityElement.value = '999999999';
                    itemQuantityElement.dispatchEvent(new Event('input', { bubbles: true }));
                }

                const currentPrice = parseFloat(itemPriceElement?.value.trim());
                if (!isNaN(itemPrice) && itemPriceInput.value.trim() !== '' && currentPrice !== itemPrice) {
                    itemPriceElement.value = itemPrice;
                    itemPriceElement.dispatchEvent(new Event('input', { bubbles: true }));
                }
            } else {
                // ❌ Deselect / clear
                if (checkbox && checkbox.checked) {
                    checkbox.checked = false;
                    checkbox.dispatchEvent(new Event('click', { bubbles: true }));
                } else if (itemQuantityElement && itemQuantityElement.value) {
                    itemQuantityElement.value = '';
                    itemQuantityElement.dispatchEvent(new Event('input', { bubbles: true }));
                }

                if (itemPriceElement && itemPriceElement.value) {
                    itemPriceElement.value = '';
                    itemPriceElement.dispatchEvent(new Event('input', { bubbles: true }));
                }
            }
        });
    }

    function createInputs() {
        const button = document.createElement('button');
        button.textContent = 'Toggle Selected Items';
        button.id = 'toggleButton';
        button.addEventListener('click', toggleItems);
        Object.assign(button.style, {
            position: 'fixed',
            top: '10px',
            right: '15px',
            zIndex: '99999',
            backgroundColor: '#AB47BC',
            color: 'white',
            padding: '10px 20px',
            transition: 'transform 0.2s ease, background-color 0.2s ease'
        });
        document.body.appendChild(button);

        const itemNameInput = document.createElement('input');
        Object.assign(itemNameInput, {
            type: 'text',
            placeholder: 'Enter item name',
            id: 'itemNameInput'
        });
        Object.assign(itemNameInput.style, {
            position: 'fixed',
            top: 'calc(10px + 50px)',
            right: '15px',
            zIndex: '99999',
            height: '36px',
            width: '200px',
            fontSize: '13px'
        });
        document.body.appendChild(itemNameInput);

        const itemPriceInput = document.createElement('input');
        Object.assign(itemPriceInput, {
            type: 'number',
            placeholder: 'Enter item price',
            id: 'itemPriceInput'
        });
        Object.assign(itemPriceInput.style, {
            position: 'fixed',
            top: 'calc(56px + 50px)',
            right: '15px',
            zIndex: '99999',
            height: '36px',
            width: '200px',
            fontSize: '13px'
        });
        document.body.appendChild(itemPriceInput);

        // Restore saved inputs
        const savedName = localStorage.getItem('massAdder_itemName');
        const savedPrice = localStorage.getItem('massAdder_itemPrice');
        if (savedName) itemNameInput.value = savedName;
        if (savedPrice) itemPriceInput.value = savedPrice;

        const creditText = document.createElement('div');
        creditText.textContent = 'Made by Fists [2830940] and ChatGPT';
        Object.assign(creditText.style, {
            position: 'fixed',
            top: 'calc(92px + 50px)',
            right: '15px',
            zIndex: '99999',
            textAlign: 'center',
            fontSize: '10px',
            color: 'white'
        });
        document.body.appendChild(creditText);

        const backgroundBox = document.createElement('div');
        Object.assign(backgroundBox.style, {
            position: 'fixed',
            top: 'calc(-3px)',
            right: 'calc(-3px)',
            width: '220px',
            height: '170px',
            backgroundColor: 'rgba(0, 0, 0, 0.5)',
            zIndex: '99998'
        });
        backgroundBox.addEventListener('click', e => e.stopPropagation());
        document.body.appendChild(backgroundBox);
    }

    setTimeout(createInputs, 2000);
})();