1900-文件按钮增强

对文件按钮进行增强

// ==UserScript==
// @name         1900-文件按钮增强
// @namespace    https://tampermonkey.net/
// @version      1.6
// @description  对文件按钮进行增强
// @author       陛下
// @match        https://mypikpak.com/drive/*
// @license      MIT
// @grant        GM_setClipboard
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    // ✅ 弹出提示
    function toastNotify(msg) {
        const toast = document.createElement('div');
        toast.innerText = msg;
        Object.assign(toast.style, {
            position: 'fixed',
            bottom: '30px',
            right: '30px',
            background: 'rgba(0,0,0,0.75)',
            color: '#fff',
            padding: '8px 14px',
            borderRadius: '6px',
            fontSize: '13px',
            boxShadow: '0 2px 6px rgba(0,0,0,0.3)',
            zIndex: 9999,
        });
        document.body.appendChild(toast);
        setTimeout(() => toast.remove(), 2000);
    }

    // ✅ 创建图标按钮
    function createIconButton(emoji, title, onClick) {
        const btn = document.createElement('button');
        btn.innerText = emoji;
        btn.title = title;
        Object.assign(btn.style, {
            marginLeft: '6px',
            border: '1px solid #ccc',
            background: '#f1f1f1',
            borderRadius: '4px',
            fontSize: '12px',
            padding: '1px 6px',
            cursor: 'pointer',
            color: '#333',
        });
        btn.addEventListener('mouseover', () => btn.style.background = '#e1ecf4');
        btn.addEventListener('mouseout', () => btn.style.background = '#f1f1f1');
        btn.addEventListener('click', onClick);
        return btn;
    }

    function findNameSpanAndInsertPoint(li) {
        // 依次尝试所有可能的结构(顺序按常见程度)
        const span =
              li.querySelector('div.grid-file-info > div.name > span') ||
              li.querySelector('div.info > div.file-info > div.name > span') || // 更明确版本
              li.querySelector('div.info > div.file-info > div > span');

        return span || null;
    }

    function removeExtension(filename) {
        return filename.replace(/\.[^/.]+$/, '');
    }

    function enhanceFileRow(li) {
        if (li.dataset._enhanced) return;
        li.dataset._enhanced = 'true';

        const id = li.id;
        const nameSpan = findNameSpanAndInsertPoint(li);

        const fullName = nameSpan?.innerText?.trim() || '';
        const name = removeExtension(fullName);

        if (!nameSpan || !id || !name) return;

        const btnId = createIconButton('🆔', '复制 ID', () => {
            GM_setClipboard(id);
            toastNotify(`已复制 ID: ${id}`);
        });

        const btnMissav = createIconButton('🔍', 'MissAV 搜索', () => {
            window.open(`https://missav.ws/${encodeURIComponent(name)}`, '_blank');
        });

        const btnCili = createIconButton('🧲', '磁力搜索', () => {
            window.open(`https://cili.re/search?q=${encodeURIComponent(name)}`, '_blank');
        });

        nameSpan.after(btnId, btnMissav, btnCili);
    }


    // ✅ 扫描所有视频/文件条目
    function scanAllFiles() {
        document.querySelectorAll('li.row').forEach(enhanceFileRow);
    }

    // ✅ 页面延迟加载支持
    function retryScan(times = 10, delay = 500) {
        let count = 0;
        const timer = setInterval(() => {
            scanAllFiles();
            count++;
            if (count >= times) clearInterval(timer);
        }, delay);
    }

    retryScan();
    const observer = new MutationObserver(scanAllFiles);
    observer.observe(document.body, { childList: true, subtree: true });
    scanAllFiles();


        // 监听弹窗出现
    const dialogObserver = new MutationObserver(() => {
        const dialog = document.querySelector('.el-dialog');
        if (!dialog) return;

        // 已经加过就不重复加
        if (dialog.dataset._prefixEnhanced) return;
        dialog.dataset._prefixEnhanced = '1';

        // 找到输入框
        const input = dialog.querySelector('input.el-input__inner');
        if (!input) return;

        // 找到取消按钮
        const cancelBtn = Array.from(dialog.querySelectorAll('footer button')).find(btn =>
            btn.textContent.includes('取消')
        );
        if (!cancelBtn) return;

        // 创建“去前缀”按钮
        const btn = document.createElement('button');
        btn.innerText = '去前缀';
        btn.type = 'button';
        btn.className = 'el-button is-text';
        btn.style.marginRight = '12px';

        btn.onclick = function () {
            let val = input.value.trim();
            const m = val.match(/^(.*?)(\.[^.]*)?$/);
            let filename = m ? m[1] : val;
            let ext = m && m[2] ? m[2] : '';
            const match = filename.match(/([A-Z]{2,}-\d{2,})$/i);
            if (match) {
                input.value = match[1] + ext;
                // 关键:派发 input 事件,让按钮可点
                input.dispatchEvent(new Event('input', { bubbles: true }));
            }
        };

        // 插入到取消按钮前
        cancelBtn.parentNode.insertBefore(btn, cancelBtn);
    });

    // 监听 body 变化
    dialogObserver.observe(document.body, { childList: true, subtree: true });
})();