Perplexity Scroll Buttons (AFU IT)

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

// ==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);
    }
})();