From b67247e3406914cf3da7c07f6ed46eb8f8f15f8e Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Fri, 30 Jan 2026 10:46:34 -0500 Subject: [PATCH] Replace pin button with floating scroll-to-bottom button Co-Authored-By: Claude Opus 4.5 --- public/index.html | 78 ++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/public/index.html b/public/index.html index dc496ba..c57b35d 100644 --- a/public/index.html +++ b/public/index.html @@ -201,36 +201,38 @@ display: block; } - .pin-scroll-btn { + .scroll-to-bottom-btn { position: absolute; bottom: 12px; right: 12px; background: rgba(42, 42, 42, 0.9); border: 1px solid #3a3a3a; - border-radius: 6px; - padding: 8px 12px; - font-size: 16px; + border-radius: 50%; + width: 44px; + height: 44px; + font-size: 20px; cursor: pointer; - transition: background 0.2s, opacity 0.2s; + transition: background 0.2s, opacity 0.2s, transform 0.2s; z-index: 10; - min-width: 44px; - min-height: 44px; display: flex; align-items: center; justify-content: center; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); } - .pin-scroll-btn:hover { + .scroll-to-bottom-btn:hover { background: rgba(58, 58, 58, 0.95); + transform: translateY(-2px); } - .pin-scroll-btn:active { + .scroll-to-bottom-btn:active { opacity: 0.7; + transform: translateY(0); } - .pin-scroll-btn.pinned { - background: rgba(255, 152, 0, 0.2); - border-color: #ff9800; + .scroll-to-bottom-btn.hidden { + opacity: 0; + pointer-events: none; } .terminal { @@ -1369,10 +1371,10 @@ ${renderStatsWidget(s)}
-
${s.output}
@@ -1400,9 +1402,15 @@ $output.innerHTML += newChunk; session.outputRenderedLength = session.output.length; } - // Only auto-scroll if session is expanded and autoScroll is enabled - if (session.expanded && session.autoScroll) { - $output.parentElement.scrollTop = $output.parentElement.scrollHeight; + + const $outputContainer = document.getElementById(`session-output-${sessionId}`); + if ($outputContainer) { + // Only auto-scroll if session is expanded and autoScroll is enabled + if (session.expanded && session.autoScroll) { + $outputContainer.scrollTop = $outputContainer.scrollHeight; + } + // Re-attach scroll listener after DOM update + attachScrollListener(sessionId, $outputContainer); } } } @@ -2108,7 +2116,7 @@ if (session.autoScroll !== isAtBottom) { session.autoScroll = isAtBottom; - updatePinButton(sessionId); + updateScrollButton(sessionId); } }; @@ -2116,37 +2124,31 @@ scrollListeners.set(sessionId, listener); } - window.toggleAutoScroll = (sessionId) => { + window.scrollToBottom = (sessionId) => { const session = state.sessions.get(sessionId); if (!session) return; - session.autoScroll = !session.autoScroll; - - // If enabling auto-scroll, scroll to bottom immediately - if (session.autoScroll) { - const $outputContainer = document.getElementById(`session-output-${sessionId}`); - if ($outputContainer) { - $outputContainer.scrollTop = $outputContainer.scrollHeight; - } + // Scroll to bottom + const $outputContainer = document.getElementById(`session-output-${sessionId}`); + if ($outputContainer) { + $outputContainer.scrollTop = $outputContainer.scrollHeight; } - updatePinButton(sessionId); + // Re-enable auto-scroll + session.autoScroll = true; + updateScrollButton(sessionId); }; - function updatePinButton(sessionId) { + function updateScrollButton(sessionId) { const session = state.sessions.get(sessionId); if (!session) return; - const $btn = document.querySelector(`#session-output-${sessionId} .pin-scroll-btn`); + const $btn = document.querySelector(`#session-output-${sessionId} .scroll-to-bottom-btn`); if ($btn) { if (session.autoScroll) { - $btn.classList.add('pinned'); - $btn.textContent = '📌'; - $btn.title = 'Auto-scroll enabled'; + $btn.classList.add('hidden'); } else { - $btn.classList.remove('pinned'); - $btn.textContent = '📍'; - $btn.title = 'Auto-scroll disabled'; + $btn.classList.remove('hidden'); } } }