Grok Delete File Uploads

Add a button to delete all uploaded files on grok.com/files

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         Grok Delete File Uploads
// @namespace    nisc
// @version      2025.06.08-A
// @description  Add a button to delete all uploaded files on grok.com/files
// @homepageURL  https://github.com/nisc/grok-userscripts/
// @author       nisc
// @match        https://grok.com/files
// @icon         https://grok.com/images/favicon-light.png
// @run-at       document-end
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    /**
     * Configuration object containing all constants used in the script
     * - Button appearance and behavior settings
     * - DOM selectors for finding elements
     * - Timing delays for various operations
     */
    const CONFIG = {
        BUTTON_ID: 'delete-all-btn',
        BUTTON_TEXT: 'Delete all files',
        BUTTON_STYLES: {
            backgroundColor: 'white',
            color: 'black',
            padding: '8px 12px',
            border: 'none',
            borderRadius: '8px',
            cursor: 'pointer',
            marginBottom: '30px'
        },
        CONTAINER_SELECTOR: '.max-w-\\[50rem\\]',
        DELETE_BUTTON_SELECTOR: 'button[aria-label="Delete"]',
        CONFIRM_BUTTON_SELECTOR: 'button[aria-label="Confirm"]',
        DELAYS: {
            DELETE_BUTTON: 200,    // Time to wait after clicking delete button
            CONFIRM_BUTTON: 200,   // Time to wait after clicking confirm button
            MODAL_RENDER: 500      // Time to wait for all modals to render
        }
    };

    /**
     * Utility function to create a promise that resolves after specified milliseconds
     * Used to add necessary delays between operations
     */
    const sleep = ms => new Promise(res => setTimeout(res, ms));

    /**
     * Main deletion function that:
     * 1. Clicks all delete buttons sequentially
     * 2. Waits for confirmation modals to render
     * 3. Clicks all confirm buttons sequentially
     *
     * Delays are added between operations to ensure UI can keep up
     */
    async function deleteAll() {
        // First phase: Click all delete buttons
        const deleteButtons = Array.from(document.querySelectorAll(CONFIG.DELETE_BUTTON_SELECTOR));
        if (deleteButtons.length === 0) {
            return;
        }

        for (const btn of deleteButtons) {
            btn.click();
            await sleep(CONFIG.DELAYS.DELETE_BUTTON);
        }

        // Wait for all confirmation modals to render
        await sleep(CONFIG.DELAYS.MODAL_RENDER);

        // Second phase: Confirm all deletions
        const confirmButtons = Array.from(document.querySelectorAll(CONFIG.CONFIRM_BUTTON_SELECTOR));
        if (confirmButtons.length === 0) {
            return;
        }

        for (const conf of confirmButtons) {
            conf.click();
            await sleep(CONFIG.DELAYS.CONFIRM_BUTTON);
        }
    }

    /**
     * Creates and adds the "Delete all files" button to the page
     * Only adds the button if it doesn't already exist
     */
    function addButton() {
        const container = document.querySelector(CONFIG.CONTAINER_SELECTOR);
        if (container && !document.getElementById(CONFIG.BUTTON_ID)) {
            const btn = document.createElement('button');
            btn.id = CONFIG.BUTTON_ID;
            btn.textContent = CONFIG.BUTTON_TEXT;
            Object.assign(btn.style, CONFIG.BUTTON_STYLES);
            btn.addEventListener('click', deleteAll);
            container.insertBefore(btn, container.firstChild);
        }
    }

    // Watch for DOM changes and try to add button when possible
    // This ensures the button is added even if the container loads dynamically
    new MutationObserver(addButton).observe(document.body, { childList: true, subtree: true });

    // Initial attempt to add the button
    addButton();
})();