Commit
·
990088c
1
Parent(s):
8add1ef
✨ ENHANCE CHAT COMPONENT: Improve scrolling behavior and user experience
Browse files✅ Changes made:
- Implemented user scrolling detection to prevent auto-scrolling when the user is manually scrolling.
- Updated the scrollToBottom function to respect user scrolling state.
- Added a handleScroll function to manage scrolling behavior effectively.
🛠️ These enhancements contribute to a more intuitive and user-friendly chat interface!
frontend/src/components/ui/chat.tsx
CHANGED
|
@@ -38,14 +38,38 @@ const Chat = React.forwardRef<HTMLDivElement, ChatProps>(
|
|
| 38 |
) => {
|
| 39 |
const messagesEndRef = React.useRef<HTMLDivElement>(null);
|
| 40 |
const messagesContainerRef = React.useRef<HTMLDivElement>(null);
|
|
|
|
|
|
|
| 41 |
|
| 42 |
const scrollToBottom = () => {
|
| 43 |
-
if (messagesContainerRef.current) {
|
| 44 |
messagesContainerRef.current.scrollTop =
|
| 45 |
messagesContainerRef.current.scrollHeight;
|
| 46 |
}
|
| 47 |
};
|
| 48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
React.useEffect(() => {
|
| 50 |
console.log(
|
| 51 |
"Chat component - messages updated:",
|
|
@@ -56,11 +80,13 @@ const Chat = React.forwardRef<HTMLDivElement, ChatProps>(
|
|
| 56 |
content: m.content.slice(0, 50) + "...",
|
| 57 |
}))
|
| 58 |
);
|
| 59 |
-
//
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
|
|
|
|
|
|
| 64 |
|
| 65 |
return (
|
| 66 |
<div
|
|
@@ -71,6 +97,7 @@ const Chat = React.forwardRef<HTMLDivElement, ChatProps>(
|
|
| 71 |
{/* Messages */}
|
| 72 |
<div
|
| 73 |
ref={messagesContainerRef}
|
|
|
|
| 74 |
className="flex-1 overflow-y-auto p-4 space-y-4 scroll-smooth"
|
| 75 |
>
|
| 76 |
{messages.length === 0 ? (
|
|
|
|
| 38 |
) => {
|
| 39 |
const messagesEndRef = React.useRef<HTMLDivElement>(null);
|
| 40 |
const messagesContainerRef = React.useRef<HTMLDivElement>(null);
|
| 41 |
+
const [userIsScrolling, setUserIsScrolling] = React.useState(false);
|
| 42 |
+
const scrollTimeoutRef = React.useRef<number>();
|
| 43 |
|
| 44 |
const scrollToBottom = () => {
|
| 45 |
+
if (messagesContainerRef.current && !userIsScrolling) {
|
| 46 |
messagesContainerRef.current.scrollTop =
|
| 47 |
messagesContainerRef.current.scrollHeight;
|
| 48 |
}
|
| 49 |
};
|
| 50 |
|
| 51 |
+
const handleScroll = () => {
|
| 52 |
+
if (messagesContainerRef.current) {
|
| 53 |
+
const { scrollTop, scrollHeight, clientHeight } =
|
| 54 |
+
messagesContainerRef.current;
|
| 55 |
+
const isNearBottom = scrollHeight - scrollTop - clientHeight < 100;
|
| 56 |
+
|
| 57 |
+
// Only prevent auto-scroll if user is NOT near the bottom
|
| 58 |
+
setUserIsScrolling(!isNearBottom);
|
| 59 |
+
|
| 60 |
+
if (scrollTimeoutRef.current) {
|
| 61 |
+
clearTimeout(scrollTimeoutRef.current);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
// Reset user scrolling state after a delay if they're not near bottom
|
| 65 |
+
if (!isNearBottom) {
|
| 66 |
+
scrollTimeoutRef.current = setTimeout(() => {
|
| 67 |
+
setUserIsScrolling(false);
|
| 68 |
+
}, 2000);
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
};
|
| 72 |
+
|
| 73 |
React.useEffect(() => {
|
| 74 |
console.log(
|
| 75 |
"Chat component - messages updated:",
|
|
|
|
| 80 |
content: m.content.slice(0, 50) + "...",
|
| 81 |
}))
|
| 82 |
);
|
| 83 |
+
// Only auto-scroll if user isn't manually scrolling
|
| 84 |
+
if (!userIsScrolling) {
|
| 85 |
+
setTimeout(() => {
|
| 86 |
+
scrollToBottom();
|
| 87 |
+
}, 100);
|
| 88 |
+
}
|
| 89 |
+
}, [messages, userIsScrolling]);
|
| 90 |
|
| 91 |
return (
|
| 92 |
<div
|
|
|
|
| 97 |
{/* Messages */}
|
| 98 |
<div
|
| 99 |
ref={messagesContainerRef}
|
| 100 |
+
onScroll={handleScroll}
|
| 101 |
className="flex-1 overflow-y-auto p-4 space-y-4 scroll-smooth"
|
| 102 |
>
|
| 103 |
{messages.length === 0 ? (
|
static/assets/index-1c58a2b7.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
static/assets/index-1c58a2b7.js.map
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
static/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
| 5 |
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
<title>Edge LLM</title>
|
| 8 |
-
<script type="module" crossorigin src="/assets/index-
|
| 9 |
<link rel="stylesheet" href="/assets/index-531e3561.css">
|
| 10 |
</head>
|
| 11 |
<body>
|
|
|
|
| 5 |
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
<title>Edge LLM</title>
|
| 8 |
+
<script type="module" crossorigin src="/assets/index-1c58a2b7.js"></script>
|
| 9 |
<link rel="stylesheet" href="/assets/index-531e3561.css">
|
| 10 |
</head>
|
| 11 |
<body>
|