diff --git a/shared/event/index.ts b/shared/event/index.ts index 9b1b01ab..3e755012 100644 --- a/shared/event/index.ts +++ b/shared/event/index.ts @@ -1,4 +1,5 @@ import { EventEmitter } from 'events'; +import type { SendMessagePayload } from '../model/message'; /** * 共享事件类型 @@ -15,6 +16,11 @@ export interface SharedEventMap { updateNetworkStatus: ( status: 'connected' | 'reconnecting' | 'disconnected' ) => void; + + /** + * 发送消息 + */ + sendMessage: (payload: SendMessagePayload) => void; } export type SharedEventType = keyof SharedEventMap; diff --git a/shared/redux/hooks/useConverseMessage.ts b/shared/redux/hooks/useConverseMessage.ts index 945fcabc..86dd9726 100644 --- a/shared/redux/hooks/useConverseMessage.ts +++ b/shared/redux/hooks/useConverseMessage.ts @@ -20,6 +20,7 @@ import { } from '../..'; import { MessageHelper } from '../../utils/message-helper'; import { ChatConverseType } from '../../model/converse'; +import { sharedEvent } from '../../event'; function useHandleSendMessage(context: ConverseContext) { const { converseId } = context; @@ -52,6 +53,7 @@ function useHandleSendMessage(context: ConverseContext) { // TODO: 增加临时消息, 对网络环境不佳的状态进行优化 + sharedEvent.emit('sendMessage', payload); const message = await sendMessage(payload); dispatch( chatActions.appendConverseMessage({ diff --git a/web/src/components/ChatBox/ChatMessageList/VirtualizedList.tsx b/web/src/components/ChatBox/ChatMessageList/VirtualizedList.tsx index 883ffe62..d93de4f1 100644 --- a/web/src/components/ChatBox/ChatMessageList/VirtualizedList.tsx +++ b/web/src/components/ChatBox/ChatMessageList/VirtualizedList.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useRef } from 'react'; +import React, { useEffect, useMemo, useRef } from 'react'; import { buildMessageItemRow } from './Item'; import type { MessageListProps } from './types'; import { @@ -6,7 +6,7 @@ import { Virtuoso, VirtuosoGridHandle, } from 'react-virtuoso'; -import type { ChatMessage } from 'tailchat-shared'; +import { ChatMessage, sharedEvent } from 'tailchat-shared'; import _last from 'lodash/last'; const PREPEND_OFFSET = 10 ** 7; @@ -24,6 +24,22 @@ export const VirtualizedMessageList: React.FC = React.memo( const listRef = useRef(); const numItemsPrepended = usePrependedMessagesCount(props.messages); + useEffect(() => { + const onSendMessage = () => { + listRef.current?.scrollToIndex({ + index: 'LAST', + align: 'end', + behavior: 'smooth', + }); + }; + + sharedEvent.on('sendMessage', onSendMessage); + + return () => { + sharedEvent.off('sendMessage', onSendMessage); + }; + }, []); + const handleLoadMore = () => { if (props.isLoadingMore) { return;