Stop Tracking Mods

Stop tracking multiple mods at once on Nexus Mods.

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name               Stop Tracking Mods
// @namespace          https://github.com/ewigl/nexusmods-stop-tracking-mods
// @version            1.0.3
// @description        Stop tracking multiple mods at once on Nexus Mods.
// @author             Licht
// @license            MIT
// @homepage           https://github.com/ewigl/nexusmods-stop-tracking-mods
// @icon               https://www.nexusmods.com/favicon.ico
// @match              https://www.nexusmods.com/mods/trackingcentre*
// @match              https://www.nexusmods.com/*/mods/trackingcentre*
// @grant              GM_addStyle
// ==/UserScript==

; (function () {
    'use strict';

    // "UPDATED" label
    GM_addStyle(`
        .tracking-highlight {
            left: 31px;
        }
        #batch-untrack-btn:hover {
            opacity: 0.9;
        }
    `)

    function initBatchUntrack() {
        const trackingTable = document.querySelector('.mod-table.mod-tracking-table');
        if (!trackingTable) return;

        const hasMods = trackingTable.querySelector('tbody tr .tracking-mod') !== null;

        let untrackControls = document.getElementById('batch-untrack-controls');

        if (!untrackControls) {
            untrackControls = document.createElement('div');
            untrackControls.id = 'batch-untrack-controls';
            untrackControls.style.display = hasMods ? 'flex' : 'none';
            untrackControls.style.justifyContent = 'flex-start';
            untrackControls.style.alignItems = 'center';
            untrackControls.style.margin = "8px 0"
            untrackControls.innerHTML = `
                <input
                    type="checkbox" 
                    id="select-all-untrack"
                    style="transform: scale(1.3); margin: 0 12px 0 6px; cursor: pointer;"
                >
                <button
                    id="batch-untrack-btn"
                    style="
                        width: 100px;
                        height: 60px;
                        padding: 4px;
                        font-size: 14px;
                        font-weight: bold;
                        background-color: #da3e3e;
                        color: white;
                        border-radius: 4px;
                        border: none;
                        cursor: pointer;
                        box-shadow: 0 2px 4px rgba(0,0,0,0.2);
                    "
                >
                    Stop Tracking
                </button>
            `;

            trackingTable.parentNode.insertBefore(untrackControls, trackingTable.nextSibling);

            document.getElementById('select-all-untrack').addEventListener('change', (e) => {
                const rowCbs = document.querySelectorAll('.batch-untrack-cb');
                rowCbs.forEach(cb => {
                    cb.checked = e.target.checked;
                });
            });

            document.getElementById('batch-untrack-btn').addEventListener('click', (e) => {
                e.preventDefault();
                const checkedCbs = document.querySelectorAll('.batch-untrack-cb:checked');

                if (checkedCbs.length === 0) {
                    alert('Please select at least 1 mod.');
                    return;
                }

                if (!confirm(`Are you sure you want to stop tracking these ${checkedCbs.length} mods(s)?`)) {
                    return;
                }

                // Click "Stop tracking"
                checkedCbs.forEach(cb => {
                    const tr = cb.closest('tr');
                    const untrackBtn = tr.querySelector('.toggle-track-mod');
                    if (untrackBtn) {
                        untrackBtn.click();
                        const wrapper = cb.closest('.batch-untrack-wrapper');
                        if (wrapper) wrapper.style.display = 'none';
                    }
                });

                document.getElementById('select-all-untrack').checked = false;
            });
        } else {
            untrackControls.style.display = hasMods ? 'flex' : 'none';
        }

        if (!hasMods) return;

        const tbodyTrs = trackingTable.querySelectorAll('tbody tr');
        tbodyTrs.forEach(tr => {
            const modNameTd = tr.querySelector('.tracking-mod');
            if (modNameTd && !modNameTd.querySelector('.batch-untrack-cb')) {
                modNameTd.insertAdjacentHTML('afterbegin', `
                    <div class="batch-untrack-wrapper" style="display: inline-block; vertical-align: middle; margin: 0 12px 0 6px;">
                        <input type="checkbox" class="batch-untrack-cb" style="transform: scale(1.3); cursor: pointer; margin: 0;">
                    </div>
                `);
            }
        });
    }

    let observerTimeout = null;

    const observer = new MutationObserver((_mutations) => {
        clearTimeout(observerTimeout);

        observerTimeout = setTimeout(() => {
            const table = document.querySelector('.mod-table.mod-tracking-table');

            if (table) {
                const isControlsMissing = !document.getElementById('batch-untrack-controls');

                const hasModRows = table.querySelector('.tracking-mod') !== null;
                const isCheckboxMissing = hasModRows && !table.querySelector('.batch-untrack-cb');

                if (isControlsMissing || isCheckboxMissing) {
                    initBatchUntrack();
                }
            }
        }, 100);
    });

    const targetContainer = document.querySelector('.tabcontent') || document.querySelector('.wrapper') || document.body;

    observer.observe(targetContainer, {
        childList: true,
        subtree: true
    });

    window.addEventListener('load', initBatchUntrack);

})();