Envato Elements Quick Downloader

Automatically selects your configured Envato Elements project and triggers “Add & Download” in the modal. Defaults to “My Project”—be sure to configure!

当前为 2025-05-08 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Envato Elements Quick Downloader
// @namespace    Finickyspider://envato/auto
// @version      1.5
// @description  Automatically selects your configured Envato Elements project and triggers “Add & Download” in the modal. Defaults to “My Project”—be sure to configure!
// @author       FinickySpider
// @match        https://elements.envato.com/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @license      GNU GPLv3 
// ==/UserScript==

(function() {
    'use strict';

    // === SETTINGS STORAGE KEYS & DEFAULTS ===
    const KEY_PROJECT = 'envato_targetProject';
    const KEY_ENABLED = 'envato_autoEnabled';
    let targetProject = GM_getValue(KEY_PROJECT, 'My Project');
    let autoDownloadEnabled = GM_getValue(KEY_ENABLED, true);
    // =========================================

    // --- Settings Panel via Tampermonkey Menu ---
    GM_registerMenuCommand("⚙️ Open Settings Panel", showSettingsPanel);

    const handledModals = new WeakSet();

    // Observe for new modals
    const observer = new MutationObserver((mutations) => {
        if (!autoDownloadEnabled) return;
        for (const m of mutations) {
            for (const node of m.addedNodes) {
                if (!(node instanceof HTMLElement)) continue;
                const modal = node.matches('[data-testid="add-to-project-modal"]')
                    ? node
                    : node.querySelector?.('[data-testid="add-to-project-modal"]');
                if (modal && !handledModals.has(modal)) {
                    handledModals.add(modal);
                    initModal(modal);
                }
            }
        }
    });
    observer.observe(document.body, { childList: true, subtree: true });

    function initModal(modal) {
        const selector = `input[type="radio"][value="${targetProject}"]`;
        const radio = modal.querySelector(selector);
        if (radio) {
            selectProject(radio, modal);
        } else {
            const radioObserver = new MutationObserver((ms, obs2) => {
                const r = modal.querySelector(selector);
                if (r) {
                    obs2.disconnect();
                    selectProject(r, modal);
                }
            });
            radioObserver.observe(modal, { childList: true, subtree: true });
        }
    }

    function selectProject(radio, modal) {
        console.log('👾 Selecting project:', targetProject);
        radio.click();
        waitForDownloadButton(modal);
    }

    function waitForDownloadButton(modal) {
        const btn = modal.querySelector('[data-testid="add-download-button"]');
        if (btn) {
            triggerWhenEnabled(btn);
        } else {
            const btnObserver = new MutationObserver((ms, obs3) => {
                const b = modal.querySelector('[data-testid="add-download-button"]');
                if (b) {
                    obs3.disconnect();
                    triggerWhenEnabled(b);
                }
            });
            btnObserver.observe(modal, { childList: true, subtree: true });
        }
    }

    function triggerWhenEnabled(button) {
        const interval = setInterval(() => {
            if (!button.disabled) {
                console.log('💻 Download button enabled, clicking...');
                button.click();
                clearInterval(interval);
            }
        }, 200);
    }

    function showSettingsPanel() {
        if (document.querySelector('#tm-settings-panel')) return;

        const panel = document.createElement('div');
        panel.id = 'tm-settings-panel';
        Object.assign(panel.style, {
            position: 'fixed',
            top: '100px',
            right: '20px',
            zIndex: '2147483647',
            padding: '20px',
            background: '#111',
            color: '#eee',
            border: '2px solid #444',
            borderRadius: '8px',
            minWidth: '260px'
        });
        panel.innerHTML = `
            <h3 style="margin-top:0">⚙️ Envato Elements Settings</h3>
            <label>
              Project Name (exact match):<br>
              <input type="text" id="projectName" style="width:100%; margin-top:4px;">
            </label><br><br>
            <label>
              <input type="checkbox" id="autoEnabled">
              Enable auto-add & download
            </label><br><br>
            <button id="saveSettings" style="margin-top:8px">Save</button>
            <button id="closeSettings" style="float:right">Close</button>
        `;
        document.body.appendChild(panel);

        // Populate current values
        panel.querySelector('#projectName').value = targetProject;
        panel.querySelector('#autoEnabled').checked = autoDownloadEnabled;

        panel.querySelector('#closeSettings').addEventListener('click', () => panel.remove());
        panel.querySelector('#saveSettings').addEventListener('click', () => {
            const newProject = panel.querySelector('#projectName').value.trim();
            const newEnabled = panel.querySelector('#autoEnabled').checked;
            if (newProject) {
                targetProject = newProject;
                GM_setValue(KEY_PROJECT, targetProject);
            }
            autoDownloadEnabled = newEnabled;
            GM_setValue(KEY_ENABLED, autoDownloadEnabled);
            panel.remove();
            if (autoDownloadEnabled) {
                document.querySelectorAll('[data-testid="add-to-project-modal"]').forEach(modal => {
                    if (!handledModals.has(modal)) {
                        handledModals.add(modal);
                        initModal(modal);
                    }
                });
            }
        });
    }

    // --- Hotkey: Ctrl+Alt+P to open settings panel ---
    document.addEventListener('keydown', (e) => {
        if (e.ctrlKey && e.altKey && e.key.toLowerCase() === 'p') {
            showSettingsPanel();
            e.preventDefault();
        }
    });

})();