Adds useful UI controls for JanitorAI, hides buttons on all chat pages
当前为
// ==UserScript==
// @name JanitorAI Enhanced UI
// @namespace http://tampermonkey.net/
// @version 3
// @description Adds useful UI controls for JanitorAI, hides buttons on all chat pages
// @author Fefnik
// @match https://janitorai.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Settings
let MIN_TOKENS = localStorage.getItem('janitorAITokenFilter') ? parseInt(localStorage.getItem('janitorAITokenFilter')) : 500;
let isSidebarHidden = localStorage.getItem('janitorAISidebarHidden') === 'true';
let isAutoScrollEnabled = localStorage.getItem('janitorAIAutoScroll') !== 'false';
let isMenuVisible = localStorage.getItem('janitorAIMenuVisible') === 'true';
// Elements
let sliderElement = null;
let sliderContainer = null;
let controlPanel = null;
let controlsContainer = null;
let emblaSlide = null; // Переменная для хранения ссылки на элемент .is-in-view.is-snapped.embla__slide
function isAllowedPage() {
const path = window.location.pathname;
return (path === '/' || path.startsWith('/search') || path === '/my_characters' || path.startsWith('/profiles/'));
}
function isChatsPage() {
const path = window.location.pathname;
return path.startsWith('/chats');
}
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, .css-1s5evre');
cards.forEach(card => {
const tokenElement = card.querySelector('.chakra-text.css-jccmq6, .css-jccmq6');
if (!tokenElement) return;
const tokenCount = parseTokens(tokenElement.textContent);
const parentContainer = card.closest('.css-1sxhvxh, .css-1dbw1r8');
if (parentContainer) {
parentContainer.style.display = tokenCount < MIN_TOKENS ? 'none' : '';
}
});
}
function setupPaginationScroll() {
const paginationButtons = document.querySelectorAll('.css-kzd6o0');
paginationButtons.forEach(button => {
button.removeEventListener('click', handlePaginationClick);
button.addEventListener('click', handlePaginationClick);
});
}
function handlePaginationClick() {
if (isAutoScrollEnabled) {
setTimeout(() => {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
}, 300);
}
}
function toggleSidebar() {
const sidebar = document.querySelector('.css-h988mi');
const css70qvj9 = document.querySelector('.css-70qvj9'); // Элемент .css-70qvj9
if (sidebar) {
isSidebarHidden = !isSidebarHidden;
sidebar.style.display = isSidebarHidden ? 'none' : '';
// Управление видимостью элемента .is-in-view.is-snapped.embla__slide
if (!emblaSlide && isSidebarHidden) {
emblaSlide = document.querySelector('.is-in-view.is-snapped.embla__slide');
}
if (emblaSlide) {
emblaSlide.style.display = isSidebarHidden ? 'none' : '';
}
// Управление видимостью элемента .css-70qvj9
if (css70qvj9) {
css70qvj9.style.display = isSidebarHidden ? 'none' : '';
}
localStorage.setItem('janitorAISidebarHidden', isSidebarHidden);
updateControlText();
}
}
function toggleAutoScroll() {
isAutoScrollEnabled = !isAutoScrollEnabled;
localStorage.setItem('janitorAIAutoScroll', isAutoScrollEnabled);
updateControlText();
}
function toggleMenu() {
isMenuVisible = !isMenuVisible;
localStorage.setItem('janitorAIMenuVisible', isMenuVisible);
updateElementsVisibility();
updateControlText();
}
function updateControlText() {
const sidebarText = document.getElementById('sidebar-toggle-text');
const scrollText = document.getElementById('auto-scroll-text');
if (sidebarText) {
sidebarText.textContent = isSidebarHidden ? 'Show Topbar' : 'Hide Topbar';
sidebarText.style.color = isSidebarHidden ? '#fff' : '#ccc';
}
if (scrollText) {
scrollText.textContent = isAutoScrollEnabled ? 'Auto-Scroll: ON' : 'Auto-Scroll: OFF';
scrollText.style.color = isAutoScrollEnabled ? '#fff' : '#ccc';
}
}
function createControlPanel() {
if (controlPanel) return;
controlPanel = document.createElement('div');
controlPanel.id = 'janitor-control-panel';
controlPanel.style.position = 'fixed';
controlPanel.style.top = '75px';
controlPanel.style.left = '10px';
controlPanel.style.zIndex = '100000';
controlPanel.style.display = 'flex';
controlPanel.style.flexDirection = 'column';
controlPanel.style.gap = '5px';
controlPanel.style.alignItems = 'flex-start';
const settingsButton = document.createElement('button');
settingsButton.id = 'token-filter-toggle';
settingsButton.textContent = '⚙️';
settingsButton.title = 'Toggle settings';
settingsButton.style.width = '30px';
settingsButton.style.height = '30px';
settingsButton.style.padding = '0';
settingsButton.style.backgroundColor = 'rgba(74, 74, 74, 0.7)';
settingsButton.style.color = '#fff';
settingsButton.style.border = 'none';
settingsButton.style.borderRadius = '5px';
settingsButton.style.cursor = 'pointer';
settingsButton.style.display = 'flex';
settingsButton.style.alignItems = 'center';
settingsButton.style.justifyContent = 'center';
settingsButton.style.fontSize = '16px';
settingsButton.style.transition = 'background-color 0.2s';
settingsButton.addEventListener('click', toggleMenu);
controlsContainer = document.createElement('div');
controlsContainer.id = 'controls-container';
controlsContainer.style.display = 'none';
controlsContainer.style.flexDirection = 'column';
controlsContainer.style.gap = '5px';
controlsContainer.style.backgroundColor = 'rgba(74, 74, 74, 0.7)';
controlsContainer.style.padding = '5px';
controlsContainer.style.borderRadius = '5px';
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);
controlsContainer.appendChild(sidebarText);
controlsContainer.appendChild(scrollText);
controlPanel.appendChild(settingsButton);
controlPanel.appendChild(controlsContainer);
document.body.appendChild(controlPanel);
updateControlText();
}
function createOrUpdateSlider() {
if (!sliderElement) {
sliderContainer = document.createElement('div');
sliderContainer.id = 'token-filter-container';
sliderContainer.style.position = 'fixed';
sliderContainer.style.top = '75px';
sliderContainer.style.left = '50px';
sliderContainer.style.zIndex = '99999';
sliderContainer.style.display = 'none';
sliderContainer.style.flexDirection = 'row';
sliderContainer.style.alignItems = 'center';
sliderContainer.style.gap = '10px';
sliderContainer.style.padding = '5px';
sliderContainer.style.backgroundColor = 'rgba(74, 74, 74, 0.7)';
sliderContainer.style.borderRadius = '5px';
sliderElement = document.createElement('input');
sliderElement.type = 'range';
sliderElement.id = 'token-filter-slider';
sliderElement.min = '0';
sliderElement.max = '6000';
sliderElement.step = '100';
sliderElement.value = MIN_TOKENS;
sliderElement.style.width = '150px';
sliderElement.style.height = '20px';
sliderElement.style.backgroundColor = '#4a4a4a';
sliderElement.style.cursor = 'pointer';
sliderElement.style.appearance = 'none';
sliderElement.style.outline = 'none';
sliderElement.style.borderRadius = '5px';
sliderElement.style.padding = '0';
const style = document.createElement('style');
style.textContent = `
#token-filter-slider {
-webkit-appearance: none;
appearance: none;
background: #4a4a4a;
border-radius: 5px;
}
#token-filter-slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
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(-5px);
}
#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(-5px);
}
#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);
}
}
function 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';
}
}
function initialize() {
createControlPanel();
createOrUpdateSlider();
updateElementsVisibility();
if (isAllowedPage() && !isChatsPage()) {
filterCards();
setupPaginationScroll();
const sidebar = document.querySelector('.css-h988mi');
if (sidebar && isSidebarHidden) {
sidebar.style.display = 'none';
emblaSlide = document.querySelector('.is-in-view.is-snapped.embla__slide');
if (emblaSlide) {
emblaSlide.style.display = 'none';
}
const css70qvj9 = document.querySelector('.css-70qvj9');
if (css70qvj9) {
css70qvj9.style.display = 'none'; // Скрываем при инициализации, если сайдбар скрыт
}
}
const observer = new MutationObserver(() => {
filterCards();
setupPaginationScroll();
});
observer.observe(document.body, { childList: true, subtree: true });
}
}
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();
}
}
}, 500);
} else {
setTimeout(tryInitialize, 1000);
}
};
tryInitialize();
})();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址