Perplexity Auto Scroll Buttons (AFU IT)

Adds Apple-style scroll buttons with mouse scroll icon to Perplexity.ai

目前為 2025-05-07 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Perplexity Auto Scroll Buttons (AFU IT)
// @namespace    PerplexityTools
// @version      1.0
// @description  Adds Apple-style scroll buttons with mouse scroll icon to Perplexity.ai
// @match        https://*.perplexity.ai/*
// @license      MIT
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    
    // Configuration
    const buttonColor = '#20b8cd';
    let autoScrollInterval = null;
    let isAutoScrollEnabled = false;
    
    // 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 - smaller size
        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 - smaller size
        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 - smaller size
        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
            autoScrollInterval = setInterval(() => {
                if (isGenerating()) {
                    scrollToBottom();
                }
            }, 300);
        } else {
            // Stop auto-scrolling
            if (autoScrollInterval) {
                clearInterval(autoScrollInterval);
                autoScrollInterval = null;
            }
        }
    }
    
    // Add buttons initially
    setTimeout(addScrollButtons, 1000);
    
    // Re-add buttons periodically
    setInterval(addScrollButtons, 5000);
    
    // Watch for URL changes
    let lastUrl = location.href;
    new MutationObserver(() => {
        if (location.href !== lastUrl) {
            lastUrl = location.href;
            setTimeout(addScrollButtons, 1000);
        }
    }).observe(document, {subtree: true, childList: true});
})();