// ==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 // @downloadURL https://update.greasyfork.icu/scripts/535202/Perplexity%20Scroll%20Buttons%20%28AFU%20IT%29.user.js // @updateURL https://update.greasyfork.icu/scripts/535202/Perplexity%20Scroll%20Buttons%20%28AFU%20IT%29.meta.js // ==/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 = ''; 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 = ''; 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 = ''; 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); } })();