wu981526092 commited on
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
- // Use setTimeout to ensure the DOM has updated
60
- setTimeout(() => {
61
- scrollToBottom();
62
- }, 100);
63
- }, [messages]);
 
 
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-6cf482b1.js"></script>
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>