您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds UI controls, hides buttons, toggles custom CSS, and auto-paginates on JanitorAI
当前为
// ==UserScript== // @name JanitorAI Enhanced UI with CSS Toggle and Auto Pagination // @namespace http://tampermonkey.net/ // @version 3.7 // @description Adds UI controls, hides buttons, toggles custom CSS, and auto-paginates on JanitorAI // @author Fefnik // @match https://janitorai.com/* // @grant none // ==/UserScript== (function() { 'use strict'; let MIN_TOKENS = parseInt(localStorage.getItem('janitorAITokenFilter')) || 500; let isSidebarHidden = localStorage.getItem('janitorAISidebarHidden') === 'true'; let isAutoScrollEnabled = localStorage.getItem('janitorAIAutoScroll') !== 'false'; let isMenuVisible = false; let isCustomCssDisabled = localStorage.getItem('janitorAICustomCssDisabled') === 'true'; let isAutoPaginationEnabled = localStorage.getItem('janitorAIAutoPagination') !== 'false'; // Новая настройка let sliderElement = null; let sliderContainer = null; let controlPanel = null; let controlsContainer = null; let emblaSlide = null; const isAllowedPage = () => { const path = window.location.pathname; return path === '/' || path.startsWith('/search') || path === '/my_characters' || path.startsWith('/profiles/'); }; const isChatsPage = () => window.location.pathname.startsWith('/chats'); const parseTokens = (text) => { try { text = text.replace(/<!--[\s\S]*?-->/g, '').replace('tokens', '').trim(); return text.includes('k') ? parseFloat(text.replace('k', '')) * 1000 : parseInt(text, 10) || 0; } catch { return 0; } }; const filterCards = () => { document.querySelectorAll('.chakra-stack.css-1s5evre, .css-1s5evre').forEach(card => { const tokenElement = card.querySelector('.chakra-text.css-jccmq6, .css-jccmq6'); if (!tokenElement) return; const tokenCount = parseTokens(tokenElement.textContent); const parent = card.closest('.css-1sxhvxh, .css-1dbw1r8'); if (parent) parent.style.display = tokenCount < MIN_TOKENS ? 'none' : ''; }); }; const setupPaginationScroll = () => { document.querySelectorAll('.css-kzd6o0').forEach(button => { button.removeEventListener('click', handlePaginationClick); button.addEventListener('click', handlePaginationClick); }); }; const handlePaginationClick = () => { if (isAutoScrollEnabled) { setTimeout(() => window.scrollTo({ top: 0, behavior: 'smooth' }), 300); } }; // Функция для поиска следующей страницы const getNextPageElement = () => { const currentPage = document.querySelector('.css-1xdrgup'); if (!currentPage) return null; let nextElement = currentPage.nextElementSibling; while (nextElement) { if (nextElement.classList.contains('css-kzd6o0') || nextElement.classList.contains('css-15aspjy')) { return nextElement; } nextElement = nextElement.nextElementSibling; } return null; }; // Проверка полного достижения конца страницы const isAtVeryBottom = () => { const scrollPosition = window.scrollY + window.innerHeight; const pageHeight = document.documentElement.scrollHeight; return pageHeight - scrollPosition <= 1; }; // Логика автоперехода const setupAutoPagination = () => { let isNavigating = false; let scrollCount = 0; const requiredScrolls = 3; window.addEventListener('wheel', function(event) { if (isAutoPaginationEnabled && event.deltaY > 0 && isAtVeryBottom() && !isNavigating) { scrollCount++; if (scrollCount >= requiredScrolls) { const nextPage = getNextPageElement(); if (nextPage) { isNavigating = true; nextPage.click(); setTimeout(() => { isNavigating = false; scrollCount = 0; }, 2000); } } } else if (!isAtVeryBottom()) { scrollCount = 0; } }, { passive: true }); }; const toggleSidebar = () => { const sidebar = document.querySelector('.css-h988mi'); const css70qvj9 = document.querySelector('.css-70qvj9'); if (sidebar) { isSidebarHidden = !isSidebarHidden; sidebar.style.display = isSidebarHidden ? 'none' : ''; if (!emblaSlide) { emblaSlide = document.querySelector('.is-in-view.is-snapped.embla__slide'); } if (emblaSlide) { emblaSlide.style.display = isSidebarHidden ? 'none' : ''; } if (css70qvj9) { css70qvj9.style.display = isSidebarHidden ? 'none' : ''; } localStorage.setItem('janitorAISidebarHidden', isSidebarHidden); updateControlText(); } }; const toggleAutoScroll = () => { isAutoScrollEnabled = !isAutoScrollEnabled; localStorage.setItem('janitorAIAutoScroll', isAutoScrollEnabled); updateControlText(); }; const toggleAutoPagination = () => { isAutoPaginationEnabled = !isAutoPaginationEnabled; localStorage.setItem('janitorAIAutoPagination', isAutoPaginationEnabled); updateControlText(); }; const toggleMenu = () => { isMenuVisible = !isMenuVisible; updateElementsVisibility(); updateControlText(); }; const toggleCustomCss = () => { isCustomCssDisabled = !isCustomCssDisabled; localStorage.setItem('janitorAICustomCssDisabled', isCustomCssDisabled); applyCustomCssToggle(); updateControlText(); }; const applyCustomCssToggle = () => { if (isCustomCssDisabled) { removeCustomStyles(); blockCustomElements(); } }; const removeCustomStyles = () => { const styles = document.querySelectorAll('body style'); styles.forEach(style => style.remove()); }; const blockCustomElements = () => { document.querySelectorAll('.css-1bn1yyx').forEach(element => { element.style.display = 'none'; }); document.querySelectorAll('*').forEach(element => { const style = window.getComputedStyle(element); const bgImage = style.backgroundImage; if (bgImage && bgImage.includes('ella.janitorai.com/background-image/')) { element.style.backgroundImage = 'none'; } }); }; const updateControlText = () => { const sidebarText = document.getElementById('sidebar-toggle-text'); const scrollText = document.getElementById('auto-scroll-text'); const paginationText = document.getElementById('auto-pagination-text'); const cssToggleText = document.getElementById('css-toggle-text'); if (sidebarText) { sidebarText.textContent = isSidebarHidden ? 'Topbar: OFF' : 'Topbar: ON'; sidebarText.style.color = isSidebarHidden ? '#fff' : '#ccc'; } if (scrollText) { scrollText.textContent = `Auto-Scroll: ${isAutoScrollEnabled ? 'ON' : 'OFF'}`; scrollText.style.color = isAutoScrollEnabled ? '#fff' : '#ccc'; } if (paginationText) { paginationText.textContent = `Auto-Page: ${isAutoPaginationEnabled ? 'ON' : 'OFF'}`; paginationText.style.color = isAutoPaginationEnabled ? '#fff' : '#ccc'; } if (cssToggleText) { cssToggleText.textContent = `Custom CSS: ${isCustomCssDisabled ? 'OFF' : 'ON'}`; cssToggleText.style.color = isCustomCssDisabled ? '#fff' : '#ccc'; } }; const createControlPanel = () => { if (controlPanel) return; controlPanel = document.createElement('div'); controlPanel.id = 'janitor-control-panel'; Object.assign(controlPanel.style, { position: 'fixed', top: '75px', left: '10px', zIndex: '100000', display: 'flex', flexDirection: 'column', gap: '5px', alignItems: 'flex-start' }); const settingsButton = document.createElement('button'); settingsButton.id = 'token-filter-toggle'; settingsButton.textContent = '⚙️'; Object.assign(settingsButton.style, { width: '30px', height: '30px', padding: '0', backgroundColor: 'rgba(74, 74, 74, 0.7)', color: '#fff', border: 'none', borderRadius: '5px', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '16px', transition: 'background-color 0.2s' }); settingsButton.addEventListener('click', toggleMenu); controlsContainer = document.createElement('div'); controlsContainer.id = 'controls-container'; Object.assign(controlsContainer.style, { display: 'none', flexDirection: 'column', gap: '5px', backgroundColor: 'rgba(74, 74, 74, 0.7)', padding: '5px', borderRadius: '5px', zIndex: '100001' }); const sidebarText = document.createElement('span'); sidebarText.id = 'sidebar-toggle-text'; sidebarText.style.cursor = 'pointer'; sidebarText.style.fontSize = '12px'; sidebarText.addEventListener('click', toggleSidebar); const scrollText = document.createElement('span'); scrollText.id = 'auto-scroll-text'; scrollText.style.cursor = 'pointer'; scrollText.style.fontSize = '12px'; scrollText.addEventListener('click', toggleAutoScroll); const paginationText = document.createElement('span'); paginationText.id = 'auto-pagination-text'; paginationText.style.cursor = 'pointer'; paginationText.style.fontSize = '12px'; paginationText.addEventListener('click', toggleAutoPagination); const cssToggleText = document.createElement('span'); cssToggleText.id = 'css-toggle-text'; cssToggleText.style.cursor = 'pointer'; cssToggleText.style.fontSize = '12px'; cssToggleText.addEventListener('click', toggleCustomCss); controlsContainer.appendChild(sidebarText); controlsContainer.appendChild(scrollText); controlsContainer.appendChild(paginationText); controlsContainer.appendChild(cssToggleText); controlPanel.appendChild(settingsButton); controlPanel.appendChild(controlsContainer); document.body.appendChild(controlPanel); updateControlText(); }; const createOrUpdateSlider = () => { if (sliderElement) return; sliderContainer = document.createElement('div'); sliderContainer.id = 'token-filter-container'; Object.assign(sliderContainer.style, { position: 'fixed', top: '75px', left: '50px', zIndex: '100002', display: 'none', flexDirection: 'row', alignItems: 'center', gap: '10px', padding: '5px', backgroundColor: 'rgba(74, 74, 74, 0.7)', borderRadius: '5px' }); sliderElement = document.createElement('input'); sliderElement.type = 'range'; sliderElement.id = 'token-filter-slider'; Object.assign(sliderElement, { min: '0', max: '6000', step: '100', value: MIN_TOKENS }); Object.assign(sliderElement.style, { width: '150px', height: '20px', backgroundColor: '#4a4a4a', cursor: 'pointer', appearance: 'none', outline: 'none', borderRadius: '5px', padding: '0', zIndex: '100003' }); const style = document.createElement('style'); style.textContent = ` #token-filter-slider { -webkit-appearance: none; appearance: none; background: #4a4a4a; border-radius: 5px; z-index: 100003; } #token-filter-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 10px; height: 20px; background: #ffffff; cursor: pointer; border-radius: 50%; border: 2px solid #000; box-shadow: 0 0 2px rgba(0,0,0,0.5); transform: translateY(0px); z-index: 100004; } #token-filter-slider::-moz-range-thumb { width: 20px; height: 20px; background: #ffffff; cursor: pointer; border-radius: 50%; border: 2px solid #000; box-shadow: 0 0 2px rgba(0,0,0,0.5); transform: translateY(-10px); z-index: 100004; } #token-filter-slider::-webkit-slider-runnable-track { height: '10px', background: #4a4a4a; border-radius: 5px; } #token-filter-slider::-moz-range-track { height: '10px', background: #4a4a4a; border-radius: 5px; } `; document.head.appendChild(style); const label = document.createElement('span'); label.id = 'token-filter-label'; label.style.color = '#fff'; label.style.fontSize = '12px'; label.style.minWidth = '60px'; label.textContent = `${MIN_TOKENS} tokens`; sliderElement.addEventListener('input', (e) => { MIN_TOKENS = parseInt(e.target.value); label.textContent = `${MIN_TOKENS} tokens`; localStorage.setItem('janitorAITokenFilter', MIN_TOKENS); filterCards(); }); sliderContainer.appendChild(sliderElement); sliderContainer.appendChild(label); document.body.appendChild(sliderContainer); }; const applySidebarState = () => { const sidebar = document.querySelector('.css-h988mi'); const css70qvj9 = document.querySelector('.css-70qvj9'); emblaSlide = document.querySelector('.is-in-view.is-snapped.embla__slide'); if (sidebar && isSidebarHidden) { sidebar.style.display = 'none'; if (emblaSlide) emblaSlide.style.display = 'none'; if (css70qvj9) css70qvj9.style.display = 'none'; } }; const updateElementsVisibility = () => { const shouldShow = isAllowedPage() && !isChatsPage(); if (controlPanel) controlPanel.style.display = shouldShow ? 'flex' : 'none'; if (sliderContainer) sliderContainer.style.display = shouldShow && isMenuVisible ? 'flex' : 'none'; if (controlsContainer) controlsContainer.style.display = shouldShow && isMenuVisible ? 'flex' : 'none'; }; const initialize = () => { createControlPanel(); createOrUpdateSlider(); applySidebarState(); updateElementsVisibility(); setupAutoPagination(); // Инициализация автоперехода if (isAllowedPage() && !isChatsPage()) { filterCards(); setupPaginationScroll(); applyCustomCssToggle(); new MutationObserver(() => { filterCards(); setupPaginationScroll(); applyCustomCssToggle(); applySidebarState(); }).observe(document.body, { childList: true, subtree: true }); const originalAppendChild = Element.prototype.appendChild; Element.prototype.appendChild = function(node) { if (isCustomCssDisabled && node.tagName === 'STYLE' && this.tagName === 'HEAD') { return node; } return originalAppendChild.call(this, node); }; } }; const tryInitialize = () => { if (document.body) { initialize(); let lastPath = window.location.pathname; setInterval(() => { if (lastPath !== window.location.pathname) { lastPath = window.location.pathname; updateElementsVisibility(); if (isAllowedPage() && !isChatsPage()) { filterCards(); setupPaginationScroll(); applyCustomCssToggle(); applySidebarState(); } } }, 500); } else { setTimeout(tryInitialize, 1000); } }; tryInitialize(); })();