JanitorAI Token Filter

Filters character cards on JanitorAI by token count

目前为 2025-04-09 提交的版本。查看 最新版本

// ==UserScript==
// @name         JanitorAI Token Filter
// @namespace    http://tampermonkey.net/
// @version      0.9
// @description  Filters character cards on JanitorAI by token count
// @author       You
// @match        https://janitorai.com/*
// @grant        none
// @license      FFA
// ==/UserScript==

(function() {
    'use strict';

    let MIN_TOKENS = 500;

    function parseTokens(tokenText) {
        try {
            let cleanText = tokenText.replace(/<!--[\s\S]*?-->/g, '').replace('tokens', '').trim();
            if (cleanText.includes('k')) {
                return parseFloat(cleanText.replace('k', '')) * 1000;
            }
            return parseInt(cleanText, 10) || 0;
        } catch (error) {
            return 0;
        }
    }

    function filterCards() {
        const cards = document.querySelectorAll('.chakra-stack.css-1s5evre');
        cards.forEach(card => {
            const tokenElement = card.querySelector('.chakra-text.css-jccmq6');
            if (!tokenElement) return;

            const tokenCount = parseTokens(tokenElement.textContent);
            const parentContainer = card.closest('.css-1sxhvxh');
            if (parentContainer) {
                parentContainer.style.display = tokenCount < MIN_TOKENS ? 'none' : '';
            }
        });
    }

    function createTokenSelector() {
        const select = document.createElement('select');
        select.id = 'token-filter-select';
        select.style.position = 'fixed';
        select.style.top = '10px';
        select.style.left = '10px';
        select.style.zIndex = '99999';
        select.style.padding = '4px 8px';
        select.style.backgroundColor = '#4a4a4a'; // Темно-серый фон
        select.style.border = '1px solid #666'; // Чуть светлее серая граница
        select.style.borderRadius = '4px';
        select.style.fontSize = '12px';
        select.style.color = '#fff'; // Белый текст для контраста
        select.style.cursor = 'pointer';

        const options = [500, 1000, 1500, 2000, 2500, 3000, 4000, 5000];
        options.forEach(value => {
            const option = document.createElement('option');
            option.value = value;
            option.text = `${value} tokens`;
            if (value === MIN_TOKENS) option.selected = true;
            select.appendChild(option);
        });

        select.addEventListener('change', (e) => {
            MIN_TOKENS = parseInt(e.target.value);
            filterCards();
        });

        const appendSelector = () => {
            if (document.body) {
                document.body.appendChild(select);
            } else {
                setTimeout(appendSelector, 500);
            }
        };
        appendSelector();
    }

    function initialize() {
        createTokenSelector();
        filterCards();
    }

    const tryInitialize = () => {
        if (document.body) {
            initialize();
            const observer = new MutationObserver(() => {
                setTimeout(filterCards, 500);
            });
            observer.observe(document.body, { childList: true, subtree: true });
        } else {
            setTimeout(tryInitialize, 1000);
        }
    };

    tryInitialize();
})();