import Text from './components/Text'; import { memo, useCallback, useEffect, useState } from 'react'; import { isEqual } from 'lodash'; import { ChatItem } from 'supersonic-chat-sdk'; import type { MsgDataType } from 'supersonic-chat-sdk'; import { MessageItem, MessageTypeEnum } from './type'; import Plugin from './components/Plugin'; import { updateMessageContainerScroll } from '@/utils/utils'; import styles from './style.less'; type Props = { id: string; chatId: number; messageList: MessageItem[]; isMobileMode?: boolean; conversationCollapsed: boolean; copilotFullscreen?: boolean; onClickMessageContainer: () => void; onMsgDataLoaded: ( data: MsgDataType, questionId: string | number, question: string, valid: boolean, ) => void; onCheckMore: (data: MsgDataType) => void; onApplyAuth: (model: string) => void; }; const MessageContainer: React.FC = ({ id, chatId, messageList, isMobileMode, conversationCollapsed, copilotFullscreen, onClickMessageContainer, onMsgDataLoaded, onCheckMore, onApplyAuth, }) => { const [triggerResize, setTriggerResize] = useState(false); const onResize = useCallback(() => { setTriggerResize(true); setTimeout(() => { setTriggerResize(false); }, 0); }, []); useEffect(() => { window.addEventListener('resize', onResize); return () => { window.removeEventListener('resize', onResize); }; }, []); useEffect(() => { onResize(); }, [conversationCollapsed]); useEffect(() => { onResize(); updateMessageContainerScroll(); }, [copilotFullscreen]); const getFollowQuestions = (index: number) => { const followQuestions: string[] = []; const currentMsg = messageList[index]; const currentMsgData = currentMsg.msgData; const msgs = messageList.slice(0, index).reverse(); for (let i = 0; i < msgs.length; i++) { const msg = msgs[i]; const msgModelId = msg.msgData?.chatContext?.modelId; const msgEntityId = msg.msgData?.entityInfo?.entityId; const currentMsgModelId = currentMsgData?.chatContext?.modelId; const currentMsgEntityId = currentMsgData?.entityInfo?.entityId; if ( (msg.type === MessageTypeEnum.QUESTION || msg.type === MessageTypeEnum.PLUGIN) && !!currentMsgModelId && msgModelId === currentMsgModelId && msgEntityId === currentMsgEntityId && msg.msg ) { followQuestions.push(msg.msg); } else { break; } } return followQuestions; }; const getFilters = (modelId?: number, entityId?: string) => { if (!modelId || !entityId) { return undefined; } return [ { value: entityId, }, ]; }; return (
{messageList.map((msgItem: MessageItem, index: number) => { const { id: msgId, modelId, entityId, type, msg, msgValue, identityMsg, msgData, score, isHistory, parseOptions, } = msgItem; const followQuestions = getFollowQuestions(index); return (
{type === MessageTypeEnum.TEXT && } {type === MessageTypeEnum.QUESTION && ( <> {identityMsg && } { onMsgDataLoaded(data, msgId, msgValue || msg || '', valid); }} onUpdateMessageScroll={updateMessageContainerScroll} /> )} {type === MessageTypeEnum.PARSE_OPTIONS && ( { onMsgDataLoaded(data, msgId, msgValue || msg || '', valid); }} onUpdateMessageScroll={updateMessageContainerScroll} /> )} {type === MessageTypeEnum.PLUGIN && ( <> { updateMessageContainerScroll(true, height); }} onCheckMore={onCheckMore} /> )}
); })}
); }; function areEqual(prevProps: Props, nextProps: Props) { if ( prevProps.id === nextProps.id && isEqual(prevProps.messageList, nextProps.messageList) && prevProps.conversationCollapsed === nextProps.conversationCollapsed && prevProps.copilotFullscreen === nextProps.copilotFullscreen ) { return true; } return false; } export default memo(MessageContainer, areEqual);