Perplexity Scroll Buttons (AFU IT)

Adds Apple-style scroll buttons with auto-scroll enabled by default

Устаревшая версия за 07.05.2025. Перейдите к последней версии.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         Perplexity Scroll Buttons (AFU IT)
// @namespace    PerplexityTools
// @version      1.1
// @description  Adds Apple-style scroll buttons with auto-scroll enabled by default
// @author       AFU IT
// @match        https://*.perplexity.ai/*
// @license      MIT
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    
    // Configuration
    const buttonColor = '#20b8cd';
    let autoScrollInterval = null;
    let isAutoScrollEnabled = true; // Set to true by default
    
    // Create and add the scroll buttons
    function addScrollButtons() {
        // Remove existing buttons if any
        const existingBottomButton = document.getElementById('scroll-bottom-btn');
        const existingTopButton = document.getElementById('scroll-top-btn');
        const existingAutoButton = document.getElementById('auto-scroll-btn');
        
        if (existingBottomButton) existingBottomButton.remove();
        if (existingTopButton) existingTopButton.remove();
        if (existingAutoButton) existingAutoButton.remove();
        
        // Create the bottom scroll button
        const bottomButton = document.createElement('div');
        bottomButton.id = 'scroll-bottom-btn';
        bottomButton.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M19 12l-7 7-7-7"></path></svg>';
        bottomButton.title = 'Scroll to bottom';
        
        // Style the bottom button
        bottomButton.style.cssText = `
            position: fixed;
            right: 20px;
            bottom: 120px;
            width: 32px;
            height: 32px;
            background: ${buttonColor};
            color: white;
            border-radius: 50%;
            font-size: 18px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            z-index: 99999;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            transition: transform 0.2s;
        `;
        
        // Add hover effect
        bottomButton.addEventListener('mouseover', function() {
            this.style.transform = 'scale(1.1)';
        });
        
        bottomButton.addEventListener('mouseout', function() {
            this.style.transform = 'scale(1)';
        });
        
        // Add click event for bottom button
        bottomButton.addEventListener('click', function() {
            const scrollContainer = document.querySelector('.scrollable-container.scrollbar');
            if (scrollContainer) {
                scrollContainer.scrollTop = scrollContainer.scrollHeight;
            }
        });
        
        // Create the top scroll button
        const topButton = document.createElement('div');
        topButton.id = 'scroll-top-btn';
        topButton.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19V5M5 12l7-7 7 7"></path></svg>';
        topButton.title = 'Scroll to top';
        
        // Style the top button
        topButton.style.cssText = `
            position: fixed;
            right: 20px;
            bottom: 162px;
            width: 32px;
            height: 32px;
            background: ${buttonColor};
            color: white;
            border-radius: 50%;
            font-size: 18px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            z-index: 99999;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            transition: transform 0.2s;
        `;
        
        // Add hover effect
        topButton.addEventListener('mouseover', function() {
            this.style.transform = 'scale(1.1)';
        });
        
        topButton.addEventListener('mouseout', function() {
            this.style.transform = 'scale(1)';
        });
        
        // Add click event for top button
        topButton.addEventListener('click', function() {
            const scrollContainer = document.querySelector('.scrollable-container.scrollbar');
            if (scrollContainer) {
                scrollContainer.scrollTop = 0;
            }
        });
        
        // Create the auto-scroll toggle button with mouse scroll wheel icon
        const autoButton = document.createElement('div');
        autoButton.id = 'auto-scroll-btn';
        // Mouse scroll wheel SVG icon
        autoButton.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="3" width="12" height="18" rx="6" ry="6"></rect><line x1="12" y1="7" x2="12" y2="11"></line></svg>';
        autoButton.title = 'Toggle auto-scroll';
        
        // Style the auto-scroll button - active by default
        autoButton.style.cssText = `
            position: fixed;
            right: 20px;
            bottom: 204px;
            width: 32px;
            height: 32px;
            background: ${isAutoScrollEnabled ? buttonColor : '#888888'};
            color: white;
            border-radius: 50%;
            font-size: 16px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            z-index: 99999;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            transition: transform 0.2s, background-color 0.3s;
        `;
        
        // Add hover effect
        autoButton.addEventListener('mouseover', function() {
            this.style.transform = 'scale(1.1)';
        });
        
        autoButton.addEventListener('mouseout', function() {
            this.style.transform = 'scale(1)';
        });
        
        // Add click event for auto-scroll button
        autoButton.addEventListener('click', function() {
            toggleAutoScroll();
            this.style.backgroundColor = isAutoScrollEnabled ? buttonColor : '#888888';
        });
        
        // Add to document
        document.body.appendChild(bottomButton);
        document.body.appendChild(topButton);
        document.body.appendChild(autoButton);
    }
    
    // Function to check if Perplexity is generating content
    function isGenerating() {
        return !!document.querySelector('button[aria-label="Stop generating response"]');
    }
    
    // Function to scroll to bottom
    function scrollToBottom() {
        const scrollContainer = document.querySelector('.scrollable-container.scrollbar');
        if (scrollContainer) {
            scrollContainer.scrollTop = scrollContainer.scrollHeight;
        }
    }
    
    // Toggle auto-scroll functionality
    function toggleAutoScroll() {
        isAutoScrollEnabled = !isAutoScrollEnabled;
        
        if (isAutoScrollEnabled) {
            // Start auto-scrolling
            startAutoScroll();
        } else {
            // Stop auto-scrolling
            stopAutoScroll();
        }
    }
    
    // Start auto-scrolling
    function startAutoScroll() {
        if (!autoScrollInterval) {
            autoScrollInterval = setInterval(() => {
                if (isGenerating()) {
                    scrollToBottom();
                }
            }, 300);
        }
    }
    
    // Stop auto-scrolling
    function stopAutoScroll() {
        if (autoScrollInterval) {
            clearInterval(autoScrollInterval);
            autoScrollInterval = null;
        }
    }
    
    // Initialize everything
    function initialize() {
        // Add the buttons
        addScrollButtons();
        
        // Start auto-scroll by default
        startAutoScroll();
        
        // Watch for URL changes
        let lastUrl = location.href;
        new MutationObserver(() => {
            if (location.href !== lastUrl) {
                lastUrl = location.href;
                setTimeout(() => {
                    addScrollButtons();
                    if (isAutoScrollEnabled) {
                        startAutoScroll();
                    }
                }, 1000);
            }
        }).observe(document, {subtree: true, childList: true});
        
        // Make sure buttons are always present
        setInterval(() => {
            if (!document.getElementById('auto-scroll-btn')) {
                addScrollButtons();
                if (isAutoScrollEnabled) {
                    startAutoScroll();
                }
            }
        }, 5000);
    }
    
    // Start when the page is ready
    if (document.readyState === 'complete') {
        initialize();
    } else {
        window.addEventListener('load', initialize);
    }
})();