diff --git a/client/web/src/components/ChatBox/ChatMessageList/NormalList.tsx b/client/web/src/components/ChatBox/ChatMessageList/NormalList.tsx index 55377f5f..18c5ec52 100644 --- a/client/web/src/components/ChatBox/ChatMessageList/NormalList.tsx +++ b/client/web/src/components/ChatBox/ChatMessageList/NormalList.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useRef } from 'react'; -import { sharedEvent } from 'tailchat-shared'; +import { useMemoizedFn, useSharedEventHandler } from 'tailchat-shared'; import { ChatMessageHeader } from './ChatMessageHeader'; import { buildMessageItemRow } from './Item'; import type { MessageListProps } from './types'; @@ -10,25 +10,24 @@ import type { MessageListProps } from './types'; export const NormalMessageList: React.FC = React.memo( (props) => { const containerRef = useRef(null); + const lockRef = useRef(false); + + const scrollToBottom = useMemoizedFn(() => { + containerRef.current?.scrollTo({ top: 0, behavior: 'smooth' }); + }); useEffect(() => { if (props.messages.length === 0) { return; } - }, [props.messages.length]); - - useEffect(() => { - const onSendMessage = () => { - // 滚动到底部 - containerRef.current?.scrollTo({ top: 0, behavior: 'smooth' }); - }; - sharedEvent.on('sendMessage', onSendMessage); + // 消息长度发生变化,滚动到底部 + if (lockRef.current === false) { + scrollToBottom(); + } + }, [props.messages.length]); - return () => { - sharedEvent.off('sendMessage', onSendMessage); - }; - }, []); + useSharedEventHandler('sendMessage', scrollToBottom); const handleScroll = useCallback(() => { if (props.messages.length === 0) { @@ -41,12 +40,17 @@ export const NormalMessageList: React.FC = React.memo( if (containerRef.current.scrollTop === 0) { // 滚动到最底部 + lockRef.current = false; } else if ( -containerRef.current.scrollTop + containerRef.current.clientHeight === containerRef.current.scrollHeight ) { // 滚动条碰触到最顶部 props.onLoadMore(); + } else { + // 滚动在中间 + // 锁定位置不自动滚动 + lockRef.current = true; } }, [props.messages]);