yt-chat-components 2.0.5 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yt-chat-components",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "main": "build/static/js/bundle.min.js",
5
5
  "module": "build/static/js/bundle.min.js",
6
6
  "types": "build/static/js/index.d.ts",
@@ -214,6 +214,7 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({
214
214
  // 滚动事件处理,选择文件时,文件内容超出显示框时,显示左右箭头
215
215
  const messageContainerRef = useRef<HTMLDivElement>(null);
216
216
  const [isUserScrolledUp, setIsUserScrolledUp] = useState(false);
217
+ const isUserScrolledUpRef = useRef(false);
217
218
 
218
219
  useImperativeHandle(ref, () => ({
219
220
  handleCallButtonClick:handleCallButtonClick
@@ -234,6 +235,10 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({
234
235
  }
235
236
  };
236
237
 
238
+ useEffect(() => {
239
+ isUserScrolledUpRef.current = isUserScrolledUp;
240
+ }, [isUserScrolledUp]);
241
+
237
242
  /**
238
243
  * 监听用户滚动标志,一旦出现滚动事件就会执行判断
239
244
  * 若处于底部且之前激活向上滚动,则使向上滚动标志失效
@@ -245,37 +250,43 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({
245
250
 
246
251
  const handleScroll = () => {
247
252
  const { scrollTop, scrollHeight, clientHeight } = container;
248
- const isAtBottom = scrollHeight - scrollTop - clientHeight <= 10; // <= 更稳妥
249
- console.log("与底部距离===", scrollHeight - scrollTop - clientHeight)
250
- console.log("此前是否向上滚动", isUserScrolledUp)
251
- if (!isAtBottom && !isUserScrolledUp) {
252
- setIsUserScrolledUp(true);
253
- } else if (isAtBottom && isUserScrolledUp) {
254
- setIsUserScrolledUp(false);
253
+ const isAtBottom = scrollHeight - scrollTop - clientHeight <= 10;
254
+
255
+ if (!isAtBottom) {
256
+ // 用户向上滚动了,标记为“已干预”
257
+ if (!isUserScrolledUpRef.current) {
258
+ setIsUserScrolledUp(true);
259
+ }
260
+ } else {
261
+ // 只有在底部时才允许重置“已干预”状态
262
+ if (isUserScrolledUpRef.current) {
263
+ setIsUserScrolledUp(false);
264
+ }
255
265
  }
256
266
  };
257
267
 
258
268
  container.addEventListener('scroll', handleScroll);
259
269
  return () => container.removeEventListener('scroll', handleScroll);
260
- }, [isUserScrolledUp]);
270
+ // ✅ 依赖为空,靠 useRef 获取最新状态
271
+ }, []);
261
272
 
262
273
 
263
274
  /**
264
275
  * 判断是否需要滚动到底部
265
276
  * */
266
- const judgeToScrollEnd = (isForce) => {
277
+ const judgeToScrollEnd = (isForce = false) => {
267
278
  const container = messageContainerRef.current;
268
279
  if (!container) return;
269
280
 
270
- const { scrollTop, scrollHeight, clientHeight } = container;
271
- const isCurrentlyAtBottom = scrollHeight - scrollTop - clientHeight < 120; //
272
281
  if (isForce) {
273
- container.scrollTop = scrollHeight;
274
- // setIsUserScrolledUp(false); // 强制滚动后认为用户在底部
282
+ setIsUserScrolledUp(false);
283
+ container.scrollTop = container.scrollHeight;
275
284
  return;
276
285
  }
277
- if (isCurrentlyAtBottom) {
278
- container.scrollTop = scrollHeight;
286
+
287
+ // 👉 核心改进:只要用户没有主动向上滚动,就自动滚动到底
288
+ if (!isUserScrolledUpRef.current) {
289
+ container.scrollTop = container.scrollHeight;
279
290
  }
280
291
  };
281
292
 
@@ -366,7 +377,7 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({
366
377
  // 流式输出消息,实时显示(token为流式输出内容,end为结束输出,整体输出一次)
367
378
  const handleMessageContent = (event, data) => {
368
379
  // console.log(`--- event = ${event}, content_ns = ${content_ns}, content_id = ${content_id}, data = `, data)
369
-
380
+ setTimeout(() => judgeToScrollEnd(), 0)
370
381
  if (event == 'add_message' && data['sender'] == 'Machine') {
371
382
  getHistoryList();
372
383
  }
@@ -413,10 +424,6 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({
413
424
  updateMessageItem({updateSrc: "3", chunk, loadingMessage: loading_message || ''})
414
425
  }
415
426
  }
416
-
417
- if (lastMessage.current) {
418
- setTimeout(()=>judgeToScrollEnd(),100)
419
- }
420
427
  }
421
428
  else if (event == 't_token') {
422
429
  let { chunk, id, r_id, ns, name, icon, loading_message } = data
@@ -430,10 +437,6 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({
430
437
  }else {
431
438
  updateMessageItem({updateSrc: "4", chunk, status:null, isThinkChunk:true, loadingMessage: loading_message || ''})
432
439
  }
433
-
434
- if (lastMessage.current) {
435
- setTimeout(()=>judgeToScrollEnd(),100)
436
- }
437
440
  }
438
441
  else if (event == 'status') {
439
442
  // 更新状态