From a3b818d22762c5155226bd615c0a26c38ac72602 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Sat, 4 Sep 2021 16:08:10 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E8=81=8A?= =?UTF-8?q?=E5=A4=A9=E5=88=97=E8=A1=A8=E9=80=BB=E8=BE=91=EF=BC=8C=E5=BD=93?= =?UTF-8?q?=E5=8F=91=E9=80=81=E6=B6=88=E6=81=AF=E6=97=B6=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E5=88=B0=E5=BA=95=E9=83=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ChatBox/ChatMessageList/index.tsx | 106 +++++++++++------- web/src/components/ChatBox/index.tsx | 15 ++- 2 files changed, 74 insertions(+), 47 deletions(-) diff --git a/web/src/components/ChatBox/ChatMessageList/index.tsx b/web/src/components/ChatBox/ChatMessageList/index.tsx index e1accb71..cd6b936d 100644 --- a/web/src/components/ChatBox/ChatMessageList/index.tsx +++ b/web/src/components/ChatBox/ChatMessageList/index.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useImperativeHandle, useRef } from 'react'; import { ChatMessage, getMessageTimeDiff, @@ -10,49 +10,73 @@ import { Divider } from 'antd'; interface ChatMessageListProps { messages: ChatMessage[]; } -export const ChatMessageList: React.FC = React.memo( - (props) => { - return ( -
-
- {props.messages.map((message, index, arr) => { - let showDate = true; - let showAvatar = true; - const messageCreatedAt = new Date(message.createdAt ?? ''); - if (index > 0) { - // 当不是第一条数据时 +export interface ChatMessageListRef { + scrollToBottom: () => void; +} +export const ChatMessageList = React.forwardRef< + ChatMessageListRef, + ChatMessageListProps +>((props, ref) => { + const containerRef = useRef(null); + + useImperativeHandle(ref, () => ({ + scrollToBottom() { + requestAnimationFrame(() => { + if (!containerRef.current) { + return; + } + + containerRef.current.scrollTo({ + top: containerRef.current.scrollHeight, + behavior: 'smooth', + }); + }); + }, + })); - // 进行时间合并 - const prevMessage = arr[index - 1]; - if ( - !shouldShowMessageTime( - new Date(prevMessage.createdAt ?? ''), - messageCreatedAt - ) - ) { - showDate = false; - } + return ( +
+
+ {props.messages.map((message, index, arr) => { + let showDate = true; + let showAvatar = true; + const messageCreatedAt = new Date(message.createdAt ?? ''); + if (index > 0) { + // 当不是第一条数据时 + + // 进行时间合并 + const prevMessage = arr[index - 1]; + if ( + !shouldShowMessageTime( + new Date(prevMessage.createdAt ?? ''), + messageCreatedAt + ) + ) { + showDate = false; + } - // 进行头像合并(在同一时间块下) - if (showDate === false) { - showAvatar = prevMessage.author !== message.author; - } + // 进行头像合并(在同一时间块下 且发送者为同一人) + if (showDate === false) { + showAvatar = prevMessage.author !== message.author; } + } - return ( -
- {showDate && ( - - {getMessageTimeDiff(messageCreatedAt)} - - )} - -
- ); - })} -
+ return ( +
+ {showDate && ( + + {getMessageTimeDiff(messageCreatedAt)} + + )} + +
+ ); + })}
- ); - } -); +
+ ); +}); ChatMessageList.displayName = 'ChatMessageList'; diff --git a/web/src/components/ChatBox/index.tsx b/web/src/components/ChatBox/index.tsx index 1ba671c0..6dfccce8 100644 --- a/web/src/components/ChatBox/index.tsx +++ b/web/src/components/ChatBox/index.tsx @@ -1,9 +1,9 @@ import { Skeleton } from 'antd'; -import React from 'react'; +import React, { useRef } from 'react'; import { useConverseMessage } from 'tailchat-shared'; import { AlertErrorView } from '../AlertErrorView'; import { ChatInputBox } from './ChatInputBox'; -import { ChatMessageList } from './ChatMessageList'; +import { ChatMessageList, ChatMessageListRef } from './ChatMessageList'; const ChatBoxPlaceholder: React.FC = React.memo(() => { return ( @@ -40,6 +40,7 @@ export const ChatBox: React.FC = React.memo((props) => { converseId, isGroup, }); + const chatMessageListRef = useRef(null); if (loading) { return ; @@ -51,16 +52,18 @@ export const ChatBox: React.FC = React.memo((props) => { return (
- + + onSendMsg={(msg) => { handleSendMessage({ converseId: props.converseId, groupId: props.groupId, content: msg, - }) - } + }).then(() => { + chatMessageListRef.current?.scrollToBottom(); + }); + }} />
);