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