This commit is contained in:
Zacharias-Brohn
2026-01-14 21:01:36 +01:00
parent ac2f9d6fcd
commit 85ba44bab5
+54 -2
View File
@@ -1,6 +1,6 @@
'use client'; 'use client';
import { useEffect, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { import {
IconLayoutSidebar, IconLayoutSidebar,
IconMessage, IconMessage,
@@ -93,6 +93,51 @@ export default function ChatLayout() {
const [_isGenerating, setIsGenerating] = useState(false); const [_isGenerating, setIsGenerating] = useState(false);
const [streamingMessageId, setStreamingMessageId] = useState<string | null>(null); const [streamingMessageId, setStreamingMessageId] = useState<string | null>(null);
// Scroll state
const scrollViewportRef = useRef<HTMLDivElement>(null);
const isUserScrolledUp = useRef(false);
// Check if user is at bottom of scroll area
const checkIfAtBottom = () => {
const viewport = scrollViewportRef.current;
if (!viewport) {
return true;
}
const threshold = 50; // pixels from bottom to consider "at bottom"
return viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight < threshold;
};
// Handle scroll events to track if user scrolled up
const handleScroll = () => {
isUserScrolledUp.current = !checkIfAtBottom();
};
// Scroll to bottom smoothly
const scrollToBottom = () => {
const viewport = scrollViewportRef.current;
if (viewport && !isUserScrolledUp.current) {
viewport.scrollTo({
top: viewport.scrollHeight,
behavior: 'smooth',
});
}
};
// Auto-scroll when messages change (during streaming)
useEffect(() => {
if (streamingMessageId) {
scrollToBottom();
}
}, [messages, streamingMessageId]);
// Scroll to bottom when user sends a message
useEffect(() => {
if (streamingMessageId) {
isUserScrolledUp.current = false;
scrollToBottom();
}
}, [streamingMessageId]);
// Fetch chats and models on load // Fetch chats and models on load
useEffect(() => { useEffect(() => {
fetchChats(); fetchChats();
@@ -381,7 +426,14 @@ export default function ChatLayout() {
h="calc(100vh - 100px)" h="calc(100vh - 100px)"
style={{ display: 'flex', flexDirection: 'column' }} style={{ display: 'flex', flexDirection: 'column' }}
> >
<ScrollArea flex={1} mb="md" type="auto" offsetScrollbars> <ScrollArea
flex={1}
mb="md"
type="auto"
offsetScrollbars
viewportRef={scrollViewportRef}
onScrollPositionChange={handleScroll}
>
<Stack gap="xl" px="md" py="lg"> <Stack gap="xl" px="md" py="lg">
{messages.map((message) => ( {messages.map((message) => (
<Group <Group