From 9bf02ccdf356917cab9f99862d2a2b40fdb0fbfa Mon Sep 17 00:00:00 2001 From: rattatwinko Date: Sun, 24 Aug 2025 19:23:06 +0000 Subject: [PATCH] QoL - U3 improved on scrolling --- src/templates/chat.html | 85 ++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/src/templates/chat.html b/src/templates/chat.html index af21582..77796fa 100644 --- a/src/templates/chat.html +++ b/src/templates/chat.html @@ -147,6 +147,7 @@ const messagesWrapper = document.getElementById('messagesWrapper'); if (diff > 150) { // Keyboard is likely open + keyboardOpen = true; if (messagesWrapper) { messagesWrapper.style.paddingBottom = '140px'; // Even more padding for mobile keyboard // Reset scroll state and aggressively scroll to bottom @@ -177,6 +178,7 @@ } } } else { + keyboardOpen = false; if (messagesWrapper) { messagesWrapper.style.paddingBottom = '80px'; // Scroll to bottom when keyboard closes too @@ -248,32 +250,45 @@ // Mobile-optimized auto-scroll functionality let isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || window.innerWidth <= 768; let isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent); + let keyboardOpen = false; function scrollToBottom(smooth = true) { const messagesWrapper = document.getElementById('messagesWrapper'); if (messagesWrapper) { // On mobile, especially iOS, direct scrollTop assignment is more reliable if (isMobile) { - // Force scroll to absolute bottom with extra padding - const targetScroll = messagesWrapper.scrollHeight + 100; + // Different scroll behavior based on keyboard state + const extraPadding = keyboardOpen ? 200 : 100; + const targetScroll = messagesWrapper.scrollHeight + extraPadding; messagesWrapper.scrollTop = targetScroll; // Multiple aggressive scroll attempts for mobile reliability setTimeout(() => { - messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 100; + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + extraPadding; }, 50); setTimeout(() => { - messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 100; + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + extraPadding; }, 150); setTimeout(() => { - messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 100; + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + extraPadding; }, 300); + // Extra attempts when just viewing (no keyboard) + if (!keyboardOpen) { + setTimeout(() => { + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 150; + }, 500); + setTimeout(() => { + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 150; + }, 750); + } + // Final iOS-specific attempt if (isIOS) { + const finalPadding = keyboardOpen ? 250 : 200; setTimeout(() => { - messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 200; - }, 500); + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + finalPadding; + }, keyboardOpen ? 500 : 1000); } } else { if (smooth) { @@ -374,24 +389,42 @@ // Only auto-scroll if user hasn't manually scrolled up if (!userScrolled) { - // Multiple scroll attempts for mobile with extra padding const messagesWrapper = document.getElementById('messagesWrapper'); if (messagesWrapper) { + // Immediate first scroll + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 100; + + // Progressive scroll attempts with different padding setTimeout(() => { - messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 150; + const padding = keyboardOpen ? 200 : 150; + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + padding; }, 100); + setTimeout(() => { - messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 150; + const padding = keyboardOpen ? 200 : 150; + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + padding; }, 250); - if (isMobile) { + + // Extra attempts when just viewing (no keyboard) + if (!keyboardOpen && isMobile) { setTimeout(() => { messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 200; }, 400); - if (isIOS) { - setTimeout(() => { - messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 200; - }, 600); - } + setTimeout(() => { + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 250; + }, 600); + // Final attempt for stubborn browsers + setTimeout(() => { + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 300; + }, 1000); + } + + // iOS-specific final attempt + if (isIOS) { + const finalPadding = keyboardOpen ? 250 : 300; + setTimeout(() => { + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + finalPadding; + }, keyboardOpen ? 600 : 1200); } } } @@ -442,16 +475,30 @@ if (hasNewMessage && !userScrolled) { const messagesWrapper = document.getElementById('messagesWrapper'); if (messagesWrapper) { + // Immediate scroll + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 100; + setTimeout(() => { - messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 150; + const padding = keyboardOpen ? 200 : 150; + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + padding; }, 100); setTimeout(() => { - messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 200; + const padding = keyboardOpen ? 250 : 200; + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + padding; }, 300); - if (isMobile) { + + // Extra scrolling when just viewing (no keyboard) + if (!keyboardOpen && isMobile) { setTimeout(() => { messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 250; }, 500); + setTimeout(() => { + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 300; + }, 800); + // Final aggressive attempt for viewing mode + setTimeout(() => { + messagesWrapper.scrollTop = messagesWrapper.scrollHeight + 350; + }, 1200); } } }