changes
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user