GreasyFork Busca Avançada (em Português, Ordenado por Atualização)

Mostra todos os scripts do GreasyFork para o domínio atual, organizados por atualização, separados por novos e antigos, com textos em português 🇧🇷🆕📅♾️

// ==UserScript==
// @name         GreasyFork Busca Avançada (em Português, Ordenado por Atualização)
// @namespace    https://gf.qytechs.cn/
// @version      3.5
// @description  Mostra todos os scripts do GreasyFork para o domínio atual, organizados por atualização, separados por novos e antigos, com textos em português 🇧🇷🆕📅♾️
// @author       Você
// @match        *://*/*
// @grant        GM_xmlhttpRequest
// @connect      gf.qytechs.cn
// ==/UserScript==

(function () {
    'use strict';

    const dominio = window.location.hostname.replace(/^www\./, '');
    const baseURL = `https://gf.qytechs.cn/pt-BR/scripts?filter_locale=0&q=${encodeURIComponent(dominio)}`;
    const HOJE = new Date();
    const LIMITE_DIAS = 30;

    function formatarDataBR(dataISO) {
        if (!dataISO) return '';
        const data = new Date(dataISO);
        if (!(data instanceof Date) || isNaN(data.getTime())) return '';
        return data.toLocaleDateString('pt-BR');
    }

    function legendaAtualizacao(dataISO) {
        if (!dataISO) return '';
        const data = new Date(dataISO);
        if (!(data instanceof Date) || isNaN(data.getTime())) return '';
        const dias = Math.floor((HOJE - data) / (1000 * 60 * 60 * 24));

        if (dias === 0) return '<b style="color:#28a745;">🆕 Atualizado hoje</b>';
        if (dias === 1) return '<b style="color:#28a745;">🆕 Atualizado ontem</b>';
        if (dias <= 7) return `<b style=\"color:#28a745;\">🆕 Atualizado há ${dias} dias</b>`;
        if (dias <= 30) return `Atualizado há ${dias} dias`;
        return `Atualizado em ${formatarDataBR(dataISO)}`;
    }

    const estilo = document.createElement('style');
    estilo.textContent = `
        #gf-btn {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: #0073e6;
            color: white;
            border: none;
            border-radius: 50%;
            width: 50px;
            height: 50px;
            font-size: 22px;
            cursor: pointer;
            z-index: 9999;
            box-shadow: 0 6px 12px rgba(0,0,0,0.3);
        }
        #gf-btn:hover { background: #005bb5; }
        #gf-painel {
            position: fixed;
            bottom: 80px;
            right: 20px;
            width: 420px;
            max-height: 80vh;
            overflow-y: auto;
            background: #f9f9f9;
            border: 1px solid #ccc;
            border-radius: 12px;
            padding: 16px;
            font-family: "Segoe UI", sans-serif;
            font-size: 14px;
            color: #222;
            z-index: 9999;
            box-shadow: 0 8px 20px rgba(0,0,0,0.2);
            display: none;
        }
        .gf-card {
            background: white;
            border-radius: 8px;
            padding: 12px;
            margin-bottom: 12px;
            box-shadow: 0 2px 6px rgba(0,0,0,0.1);
            border-left: 4px solid transparent;
        }
        .gf-card.recent { border-left-color: #28a745; }
        .gf-card a.title {
            color: #0073e6;
            font-weight: bold;
            text-decoration: none;
            font-size: 15px;
        }
        .gf-card a.install {
            display: inline-block;
            margin-top: 6px;
            color: white;
            background: #28a745;
            padding: 4px 10px;
            border-radius: 4px;
            text-decoration: none;
            font-size: 13px;
        }
        .gf-card small {
            color: #555;
            display: block;
            margin-top: 4px;
        }
        @media (prefers-color-scheme: dark) {
            #gf-painel { background: #1e1e1e; border: 1px solid #444; color: #ddd; }
            .gf-card { background: #2b2b2b; box-shadow: 0 2px 6px rgba(0,0,0,0.5); }
            .gf-card a.title { color: #58a6ff; }
            .gf-card a.install { background: #2ea043; }
            #gf-btn { background: #005bb5; }
            #gf-btn:hover { background: #0073e6; }
        }
    `;
    document.head.appendChild(estilo);

    const botao = document.createElement('button');
    botao.id = 'gf-btn';
    botao.textContent = '🔍';
    document.body.appendChild(botao);

    const painel = document.createElement('div');
    painel.id = 'gf-painel';
    document.body.appendChild(painel);

    function renderizarCartao(scriptEl) {
        const nameEl = scriptEl.querySelector('a[href^="/pt-BR/scripts/"]');
        const descEl = scriptEl.querySelector('.script-description');
        const link = nameEl ? 'https://gf.qytechs.cn' + nameEl.getAttribute('href') : '#';
        const nome = nameEl?.textContent || 'Sem título';
        const descricao = descEl?.textContent || '';
        const installURL = link + '/code/script.user.js';
        const rawUpdated = scriptEl.getAttribute('data-script-updated-at') || scriptEl.getAttribute('data-script-created-at');
        const dias = (HOJE - new Date(rawUpdated)) / (1000 * 60 * 60 * 24);

        const card = document.createElement('div');
        card.className = 'gf-card' + (dias <= LIMITE_DIAS ? ' recent' : '');
        card.innerHTML = `
            <a class="title" href="${link}" target="_blank">${nome}</a>
            <div>${descricao}</div>
            <small>${legendaAtualizacao(rawUpdated)}</small>
            <a class="install" href="${installURL}" target="_blank">📥 Instalar</a>
        `;
        painel.appendChild(card);
    }

    botao.addEventListener('click', () => {
        if (painel.style.display === 'block') {
            painel.style.display = 'none';
            return;
        }

        painel.style.display = 'block';
        painel.innerHTML = `<p>🔍 Buscando scripts para <strong>${dominio}</strong>...</p>`;

        let pagina = 1;
        let todosScripts = [];

        function buscarPagina() {
            const url = `${baseURL}&page=${pagina}`;
            painel.innerHTML = `<p>🔄 Carregando página ${pagina}...</p>`;

            GM_xmlhttpRequest({
                method: "GET",
                url,
                onload: function (res) {
                    const parser = new DOMParser();
                    const doc = parser.parseFromString(res.responseText, 'text/html');
                    const scriptItems = Array.from(doc.querySelectorAll('#browse-script-list li'));

                    if (!scriptItems.length) {
                        renderizarTodos(todosScripts);
                        return;
                    }

                    todosScripts.push(...scriptItems);
                    pagina++;
                    buscarPagina();
                },
                onerror: function () {
                    painel.innerHTML = `<p style="color:red;">❌ Erro ao buscar página ${pagina}.</p>`;
                }
            });
        }

        function renderizarTodos(scripts) {
            if (!scripts.length) {
                painel.innerHTML = `<p>❌ Nenhum script encontrado para <strong>${dominio}</strong>.</p>`;
                return;
            }

            scripts.sort((a, b) => {
                const dA = new Date(a.getAttribute('data-script-updated-at') || a.getAttribute('data-script-created-at'));
                const dB = new Date(b.getAttribute('data-script-updated-at') || b.getAttribute('data-script-created-at'));
                return dB - dA;
            });

            const recentes = [];
            const antigos = [];

            scripts.forEach(scriptEl => {
                const updated = scriptEl.getAttribute('data-script-updated-at') || scriptEl.getAttribute('data-script-created-at');
                const dias = (HOJE - new Date(updated)) / (1000 * 60 * 60 * 24);
                (dias <= LIMITE_DIAS ? recentes : antigos).push(scriptEl);
            });

            painel.innerHTML = `<h3 style="margin-top:0;">📜 ${scripts.length} scripts encontrados para <strong>${dominio}</strong></h3>`;

            if (recentes.length) {
                const titulo = document.createElement('h4');
                titulo.textContent = '🆕 Scripts atualizados recentemente';
                painel.appendChild(titulo);
                recentes.forEach(renderizarCartao);
            }

            if (antigos.length) {
                const titulo = document.createElement('h4');
                titulo.textContent = '📂 Scripts mais antigos';
                painel.appendChild(titulo);
                antigos.forEach(renderizarCartao);
            }
        }

        buscarPagina();
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址