From b45abab0aa639d4d89763bc39fb5515c9b3144c6 Mon Sep 17 00:00:00 2001 From: Meleki Date: Wed, 11 Mar 2026 11:31:41 +0100 Subject: [PATCH] feat: auto-scroll deaktivieren beim hochscrollen, reaktivieren am Ende --- wwwroot/js/chat.js | 2 ++ wwwroot/js/history.js | 6 +++++- wwwroot/js/ui-helpers.js | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/wwwroot/js/chat.js b/wwwroot/js/chat.js index 390ce1b..3878945 100644 --- a/wwwroot/js/chat.js +++ b/wwwroot/js/chat.js @@ -170,6 +170,7 @@ async function clearChat() { loadedArchiveCount = 0; _oldestLoadedSortKey = 0; _hasMoreOlderMessages = false; + _autoScroll = true; clearReply(); setMeta(`Archiviert: ${archive.chainCount} Chains, ${archive.messageCount} Messages`); @@ -346,6 +347,7 @@ async function sendMessage() { } addUserBubble(bubbleText, true, '', null, false, null, inlineImages); + scrollDownForce(); // Beim Senden immer nach unten input.value = ''; input.dispatchEvent(new Event('input')); diff --git a/wwwroot/js/history.js b/wwwroot/js/history.js index c7dbf55..9f2af22 100644 --- a/wwwroot/js/history.js +++ b/wwwroot/js/history.js @@ -68,6 +68,9 @@ async function loadHistory() { try { const sid = getCurrentSessionId(); + // Auto-Scroll initialisieren (einmalig pro Session-Load) + initAutoScroll(); + const data = await apiHistory(sid, null, isDeletedVisible()); const entries = data.entries || []; @@ -90,7 +93,8 @@ async function loadHistory() { if (entry.chain) addChainMetaBubble(entry.chain, false); } - scrollDown(); + // Beim initialen Laden immer ganz nach unten scrollen + scrollDownForce(); setMeta('Bereit'); startHistoryPolling(); } catch (e) { diff --git a/wwwroot/js/ui-helpers.js b/wwwroot/js/ui-helpers.js index 053b3db..e7ddb58 100644 --- a/wwwroot/js/ui-helpers.js +++ b/wwwroot/js/ui-helpers.js @@ -14,11 +14,36 @@ function truncate(s, max) { return s && s.length > max ? s.substring(0, max) + '...' : (s || ''); } +// Auto-Scroll: wird deaktiviert wenn User nach oben scrollt, reaktiviert wenn er ganz unten ist +var _autoScroll = true; + +function initAutoScroll() { + const chat = chatEl(); + if (!chat) return; + _autoScroll = true; + chat.addEventListener('scroll', function() { + const threshold = 60; + const atBottom = chat.scrollHeight - chat.scrollTop - chat.clientHeight <= threshold; + _autoScroll = atBottom; + }); +} + function scrollDown() { const chat = chatEl(); if (!chat) return; + if (!_autoScroll) return; chat.scrollTop = chat.scrollHeight; // Nach Font-Swap kann sich die Höhe ändern → nochmal scrollen + document.fonts.ready.then(() => { + if (_autoScroll) chat.scrollTop = chat.scrollHeight; + }); +} + +function scrollDownForce() { + const chat = chatEl(); + if (!chat) return; + _autoScroll = true; + chat.scrollTop = chat.scrollHeight; document.fonts.ready.then(() => { chat.scrollTop = chat.scrollHeight; });