### What problem does this PR solve? fix: remove duplicate MessageItem #1289 ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)tags/v0.9.0
| @@ -22,6 +22,26 @@ | |||
| background-color: rgba(249, 250, 251, 1); | |||
| word-break: break-all; | |||
| } | |||
| .messageTextBase() { | |||
| padding: 6px 10px; | |||
| border-radius: 8px; | |||
| & > p { | |||
| margin: 0; | |||
| } | |||
| } | |||
| .messageText { | |||
| .chunkText(); | |||
| .messageTextBase(); | |||
| background-color: #e6f4ff; | |||
| word-break: break-all; | |||
| } | |||
| .messageUserText { | |||
| .chunkText(); | |||
| .messageTextBase(); | |||
| background-color: rgb(248, 247, 247); | |||
| word-break: break-all; | |||
| text-align: justify; | |||
| } | |||
| .messageEmpty { | |||
| width: 300px; | |||
| } | |||
| @@ -3,7 +3,6 @@ import { MessageType } from '@/constants/chat'; | |||
| import { useTranslate } from '@/hooks/commonHooks'; | |||
| import { useGetDocumentUrl } from '@/hooks/documentHooks'; | |||
| import { useSelectFileThumbnails } from '@/hooks/knowledgeHook'; | |||
| import { useSelectUserInfo } from '@/hooks/userSettingHook'; | |||
| import { IReference, Message } from '@/interfaces/database/chat'; | |||
| import { IChunk } from '@/interfaces/database/knowledge'; | |||
| import classNames from 'classnames'; | |||
| @@ -16,23 +15,27 @@ import NewDocumentLink from '../new-document-link'; | |||
| import SvgIcon from '../svg-icon'; | |||
| import styles from './index.less'; | |||
| interface IProps { | |||
| item: Message; | |||
| reference: IReference; | |||
| loading?: boolean; | |||
| nickname?: string; | |||
| avatar?: string; | |||
| clickDocumentButton?: (documentId: string, chunk: IChunk) => void; | |||
| } | |||
| const MessageItem = ({ | |||
| item, | |||
| reference, | |||
| loading = false, | |||
| avatar = '', | |||
| nickname = '', | |||
| clickDocumentButton, | |||
| }: { | |||
| item: Message; | |||
| reference: IReference; | |||
| loading?: boolean; | |||
| clickDocumentButton: (documentId: string, chunk: IChunk) => void; | |||
| }) => { | |||
| const userInfo = useSelectUserInfo(); | |||
| }: IProps) => { | |||
| const isAssistant = item.role === MessageType.Assistant; | |||
| const { t } = useTranslate('chat'); | |||
| const fileThumbnails = useSelectFileThumbnails(); | |||
| const getDocumentUrl = useGetDocumentUrl(); | |||
| const { t } = useTranslate('chat'); | |||
| const isAssistant = item.role === MessageType.Assistant; | |||
| const referenceDocumentList = useMemo(() => { | |||
| return reference?.doc_aggs ?? []; | |||
| @@ -68,7 +71,7 @@ const MessageItem = ({ | |||
| <Avatar | |||
| size={40} | |||
| src={ | |||
| userInfo.avatar ?? | |||
| avatar ?? | |||
| 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png' | |||
| } | |||
| /> | |||
| @@ -76,8 +79,12 @@ const MessageItem = ({ | |||
| <AssistantIcon></AssistantIcon> | |||
| )} | |||
| <Flex vertical gap={8} flex={1}> | |||
| <b>{isAssistant ? '' : userInfo.nickname}</b> | |||
| <div className={styles.messageText}> | |||
| <b>{isAssistant ? '' : nickname}</b> | |||
| <div | |||
| className={ | |||
| isAssistant ? styles.messageText : styles.messageUserText | |||
| } | |||
| > | |||
| <MarkdownContent | |||
| content={content} | |||
| reference={reference} | |||
| @@ -120,7 +120,7 @@ export const useSetFlow = () => { | |||
| dsl?: DSL; | |||
| avatar?: string; | |||
| }) => { | |||
| const { data } = await flowService.setCanvas(params); | |||
| const { data = {} } = await flowService.setCanvas(params); | |||
| if (data.retcode === 0) { | |||
| message.success( | |||
| i18n.t(`message.${params?.id ? 'modified' : 'created'}`), | |||
| @@ -189,7 +189,10 @@ export const useSendMessageWithSse = ( | |||
| const d = val?.data; | |||
| if (typeof d !== 'boolean') { | |||
| console.info('data:', d); | |||
| setAnswer(d); | |||
| setAnswer({ | |||
| ...d, | |||
| conversationId: body?.conversation_id, | |||
| }); | |||
| } | |||
| } catch (e) { | |||
| console.warn(e); | |||
| @@ -77,6 +77,7 @@ export interface IReference { | |||
| export interface IAnswer { | |||
| answer: string; | |||
| reference: IReference; | |||
| conversationId?: string; | |||
| } | |||
| export interface Docagg { | |||
| @@ -5,82 +5,3 @@ | |||
| padding-right: 24px; | |||
| } | |||
| } | |||
| .messageItem { | |||
| padding: 24px 0; | |||
| .messageItemSection { | |||
| display: inline-block; | |||
| } | |||
| .messageItemSectionLeft { | |||
| width: 70%; | |||
| } | |||
| .messageItemSectionRight { | |||
| width: 40%; | |||
| } | |||
| .messageItemContent { | |||
| display: inline-flex; | |||
| gap: 20px; | |||
| } | |||
| .messageItemContentReverse { | |||
| flex-direction: row-reverse; | |||
| } | |||
| .messageTextBase() { | |||
| padding: 6px 10px; | |||
| border-radius: 8px; | |||
| & > p { | |||
| margin: 0; | |||
| } | |||
| } | |||
| .messageText { | |||
| .chunkText(); | |||
| .messageTextBase(); | |||
| background-color: #e6f4ff; | |||
| word-break: break-all; | |||
| } | |||
| .messageUserText { | |||
| .chunkText(); | |||
| .messageTextBase(); | |||
| background-color: rgb(248, 247, 247); | |||
| word-break: break-all; | |||
| text-align: justify; | |||
| } | |||
| .messageEmpty { | |||
| width: 300px; | |||
| } | |||
| // .referenceIcon { | |||
| // padding: 0 6px; | |||
| // } | |||
| .thumbnailImg { | |||
| max-width: 20px; | |||
| } | |||
| } | |||
| .messageItemLeft { | |||
| text-align: left; | |||
| } | |||
| .messageItemRight { | |||
| text-align: right; | |||
| } | |||
| // .referencePopoverWrapper { | |||
| // max-width: 50vw; | |||
| // } | |||
| // .referenceChunkImage { | |||
| // width: 10vw; | |||
| // object-fit: contain; | |||
| // } | |||
| // .referenceImagePreview { | |||
| // max-width: 45vw; | |||
| // max-height: 45vh; | |||
| // } | |||
| // .chunkContentText { | |||
| // .chunkText; | |||
| // max-height: 45vh; | |||
| // overflow-y: auto; | |||
| // } | |||
| // .documentLink { | |||
| // padding: 0; | |||
| // } | |||
| @@ -1,139 +1,21 @@ | |||
| import { ReactComponent as AssistantIcon } from '@/assets/svg/assistant.svg'; | |||
| import NewDocumentLink from '@/components/new-document-link'; | |||
| import MessageItem from '@/components/message-item'; | |||
| import DocumentPreviewer from '@/components/pdf-previewer'; | |||
| import { MessageType } from '@/constants/chat'; | |||
| import { useSelectFileThumbnails } from '@/hooks/knowledgeHook'; | |||
| import { useSelectUserInfo } from '@/hooks/userSettingHook'; | |||
| import { IReference, Message } from '@/interfaces/database/chat'; | |||
| import { IChunk } from '@/interfaces/database/knowledge'; | |||
| import { Avatar, Button, Drawer, Flex, Input, List, Spin } from 'antd'; | |||
| import classNames from 'classnames'; | |||
| import { useMemo } from 'react'; | |||
| import { useTranslate } from '@/hooks/commonHooks'; | |||
| import { Button, Drawer, Flex, Input, Spin } from 'antd'; | |||
| import { | |||
| useClickDrawer, | |||
| useFetchConversationOnMount, | |||
| useGetFileIcon, | |||
| useGetSendButtonDisabled, | |||
| useSelectConversationLoading, useSendButtonDisabled, | |||
| useSelectConversationLoading, | |||
| useSendButtonDisabled, | |||
| useSendMessage, | |||
| } from '../hooks'; | |||
| import MarkdownContent from '../markdown-content'; | |||
| import SvgIcon from '@/components/svg-icon'; | |||
| import { useTranslate } from '@/hooks/commonHooks'; | |||
| import { useGetDocumentUrl } from '@/hooks/documentHooks'; | |||
| import { getExtension, isPdf } from '@/utils/documentUtils'; | |||
| import { buildMessageItemReference } from '../utils'; | |||
| import styles from './index.less'; | |||
| const MessageItem = ({ | |||
| item, | |||
| reference, | |||
| loading = false, | |||
| clickDocumentButton, | |||
| }: { | |||
| item: Message; | |||
| reference: IReference; | |||
| loading?: boolean; | |||
| clickDocumentButton: (documentId: string, chunk: IChunk) => void; | |||
| }) => { | |||
| const userInfo = useSelectUserInfo(); | |||
| const fileThumbnails = useSelectFileThumbnails(); | |||
| const getDocumentUrl = useGetDocumentUrl(); | |||
| const { t } = useTranslate('chat'); | |||
| const isAssistant = item.role === MessageType.Assistant; | |||
| const referenceDocumentList = useMemo(() => { | |||
| return reference?.doc_aggs ?? []; | |||
| }, [reference?.doc_aggs]); | |||
| const content = useMemo(() => { | |||
| let text = item.content; | |||
| if (text === '') { | |||
| text = t('searching'); | |||
| } | |||
| return loading ? text?.concat('~~2$$') : text; | |||
| }, [item.content, loading, t]); | |||
| return ( | |||
| <div | |||
| className={classNames(styles.messageItem, { | |||
| [styles.messageItemLeft]: item.role === MessageType.Assistant, | |||
| [styles.messageItemRight]: item.role === MessageType.User, | |||
| })} | |||
| > | |||
| <section | |||
| className={classNames(styles.messageItemSection, { | |||
| [styles.messageItemSectionLeft]: item.role === MessageType.Assistant, | |||
| [styles.messageItemSectionRight]: item.role === MessageType.User, | |||
| })} | |||
| > | |||
| <div | |||
| className={classNames(styles.messageItemContent, { | |||
| [styles.messageItemContentReverse]: item.role === MessageType.User, | |||
| })} | |||
| > | |||
| {item.role === MessageType.User ? ( | |||
| <Avatar | |||
| size={40} | |||
| src={ | |||
| userInfo.avatar ?? | |||
| 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png' | |||
| } | |||
| /> | |||
| ) : ( | |||
| <AssistantIcon></AssistantIcon> | |||
| )} | |||
| <Flex vertical gap={8} flex={1}> | |||
| <b>{isAssistant ? '' : userInfo.nickname}</b> | |||
| <div className={isAssistant ? styles.messageText : styles.messageUserText}> | |||
| <MarkdownContent | |||
| content={content} | |||
| reference={reference} | |||
| clickDocumentButton={clickDocumentButton} | |||
| ></MarkdownContent> | |||
| </div> | |||
| {isAssistant && referenceDocumentList.length > 0 && ( | |||
| <List | |||
| bordered | |||
| dataSource={referenceDocumentList} | |||
| renderItem={(item) => { | |||
| const fileThumbnail = fileThumbnails[item.doc_id]; | |||
| const fileExtension = getExtension(item.doc_name); | |||
| return ( | |||
| <List.Item> | |||
| <Flex gap={'small'} align="center"> | |||
| {fileThumbnail ? ( | |||
| <img | |||
| src={fileThumbnail} | |||
| className={styles.thumbnailImg} | |||
| ></img> | |||
| ) : ( | |||
| <SvgIcon | |||
| name={`file-icon/${fileExtension}`} | |||
| width={24} | |||
| ></SvgIcon> | |||
| )} | |||
| <NewDocumentLink | |||
| link={getDocumentUrl(item.doc_id)} | |||
| preventDefault={!isPdf(item.doc_name)} | |||
| > | |||
| {item.doc_name} | |||
| </NewDocumentLink> | |||
| </Flex> | |||
| </List.Item> | |||
| ); | |||
| }} | |||
| /> | |||
| )} | |||
| </Flex> | |||
| </div> | |||
| </section> | |||
| </div> | |||
| ); | |||
| }; | |||
| import { useSelectUserInfo } from '@/hooks/userSettingHook'; | |||
| import styles from './index.less'; | |||
| const ChatContainer = () => { | |||
| const { | |||
| @@ -161,6 +43,7 @@ const ChatContainer = () => { | |||
| useGetFileIcon(); | |||
| const loading = useSelectConversationLoading(); | |||
| const { t } = useTranslate('chat'); | |||
| const userInfo = useSelectUserInfo(); | |||
| return ( | |||
| <> | |||
| @@ -178,6 +61,8 @@ const ChatContainer = () => { | |||
| } | |||
| key={message.id} | |||
| item={message} | |||
| nickname={userInfo.nickname} | |||
| avatar={userInfo.avatar} | |||
| reference={buildMessageItemReference(conversation, message)} | |||
| clickDocumentButton={clickDocumentButton} | |||
| ></MessageItem> | |||
| @@ -326,7 +326,7 @@ export const useSelectDerivedConversationList = () => { | |||
| return pre; | |||
| }); | |||
| }, [conversationList, dialogId, prologue]); | |||
| }, [conversationList, dialogId, prologue, t]); | |||
| useEffect(() => { | |||
| addTemporaryConversation(); | |||
| @@ -402,7 +402,7 @@ export const useSelectCurrentConversation = () => { | |||
| role: MessageType.Assistant, | |||
| content: answer, | |||
| id: uuid(), | |||
| reference: [], | |||
| reference: {}, | |||
| } as IMessage, | |||
| ], | |||
| }; | |||
| @@ -433,7 +433,6 @@ export const useSelectCurrentConversation = () => { | |||
| }, []); | |||
| const removeLatestMessage = useCallback(() => { | |||
| console.info('removeLatestMessage'); | |||
| setCurrentConversation((pre) => { | |||
| const nextMessages = pre.message?.slice(0, -2) ?? []; | |||
| return { | |||
| @@ -484,7 +483,6 @@ export const useScrollToBottom = (currentConversation: IClientConversation) => { | |||
| const ref = useRef<HTMLDivElement>(null); | |||
| const scrollToBottom = useCallback(() => { | |||
| console.info('useScrollToBottom'); | |||
| if (currentConversation.id) { | |||
| ref.current?.scrollIntoView({ behavior: 'instant' }); | |||
| } | |||
| @@ -588,7 +586,6 @@ export const useSendMessage = ( | |||
| [ | |||
| conversation?.message, | |||
| conversationId, | |||
| // fetchConversation, | |||
| handleClickConversation, | |||
| removeLatestMessage, | |||
| setValue, | |||
| @@ -612,12 +609,10 @@ export const useSendMessage = ( | |||
| ); | |||
| useEffect(() => { | |||
| if (answer.answer) { | |||
| if (answer.answer && answer?.conversationId === conversationId) { | |||
| addNewestAnswer(answer); | |||
| console.info('true?'); | |||
| console.info('send msg:', answer.answer); | |||
| } | |||
| }, [answer, addNewestAnswer]); | |||
| }, [answer, addNewestAnswer, conversationId]); | |||
| const handlePressEnter = useCallback(() => { | |||
| if (trim(value) === '') return; | |||
| @@ -639,15 +634,9 @@ export const useSendMessage = ( | |||
| }; | |||
| export const useGetFileIcon = () => { | |||
| // const req = require.context('@/assets/svg/file-icon'); | |||
| // const ret = req.keys().map(req); | |||
| // console.info(ret); | |||
| // useEffect(() => {}, []); | |||
| const getFileIcon = (filename: string) => { | |||
| const ext: string = getFileExtension(filename); | |||
| const iconPath = fileIconMap[ext as keyof typeof fileIconMap]; | |||
| // const x = require(`@/assets/svg/file-icon/${iconPath}`); | |||
| return `@/assets/svg/file-icon/${iconPath}`; | |||
| }; | |||
| @@ -28,7 +28,7 @@ const MarkdownContent = ({ | |||
| }: { | |||
| content: string; | |||
| reference: IReference; | |||
| clickDocumentButton: (documentId: string, chunk: IChunk) => void; | |||
| clickDocumentButton?: (documentId: string, chunk: IChunk) => void; | |||
| }) => { | |||
| const fileThumbnails = useSelectFileThumbnails(); | |||
| @@ -37,7 +37,7 @@ const MarkdownContent = ({ | |||
| if (!isPdf) { | |||
| return; | |||
| } | |||
| clickDocumentButton(documentId, chunk); | |||
| clickDocumentButton?.(documentId, chunk); | |||
| }, | |||
| [clickDocumentButton], | |||
| ); | |||
| @@ -11,57 +11,3 @@ | |||
| padding-right: 6px; | |||
| } | |||
| } | |||
| .messageItem { | |||
| padding: 24px 0; | |||
| .messageItemSection { | |||
| display: inline-block; | |||
| } | |||
| .messageItemSectionLeft { | |||
| width: 70%; | |||
| } | |||
| .messageItemSectionRight { | |||
| width: 40%; | |||
| } | |||
| .messageItemContent { | |||
| display: inline-flex; | |||
| gap: 20px; | |||
| } | |||
| .messageItemContentReverse { | |||
| flex-direction: row-reverse; | |||
| } | |||
| .messageTextBase() { | |||
| padding: 6px 10px; | |||
| border-radius: 8px; | |||
| & > p { | |||
| margin: 0; | |||
| } | |||
| } | |||
| .messageText { | |||
| .chunkText(); | |||
| .messageTextBase(); | |||
| background-color: #e6f4ff; | |||
| word-break: break-all; | |||
| } | |||
| .messageUserText { | |||
| .chunkText(); | |||
| .messageTextBase(); | |||
| background-color: rgb(248, 247, 247); | |||
| word-break: break-all; | |||
| text-align: justify; | |||
| } | |||
| .messageEmpty { | |||
| width: 300px; | |||
| } | |||
| .thumbnailImg { | |||
| max-width: 20px; | |||
| } | |||
| } | |||
| .messageItemLeft { | |||
| text-align: left; | |||
| } | |||
| .messageItemRight { | |||
| text-align: right; | |||
| } | |||
| @@ -1,129 +1,17 @@ | |||
| import { ReactComponent as AssistantIcon } from '@/assets/svg/assistant.svg'; | |||
| import MessageItem from '@/components/message-item'; | |||
| import { MessageType } from '@/constants/chat'; | |||
| import { useTranslate } from '@/hooks/commonHooks'; | |||
| import { IReference, Message } from '@/interfaces/database/chat'; | |||
| import { Avatar, Button, Flex, Input, List, Spin } from 'antd'; | |||
| import classNames from 'classnames'; | |||
| import NewDocumentLink from '@/components/new-document-link'; | |||
| import SvgIcon from '@/components/svg-icon'; | |||
| import { useGetDocumentUrl } from '@/hooks/documentHooks'; | |||
| import { useSelectFileThumbnails } from '@/hooks/knowledgeHook'; | |||
| import { getExtension, isPdf } from '@/utils/documentUtils'; | |||
| import { forwardRef, useMemo } from 'react'; | |||
| import MarkdownContent from '../markdown-content'; | |||
| import { useSendButtonDisabled } from '@/pages/chat/hooks'; | |||
| import { Button, Flex, Input, Spin } from 'antd'; | |||
| import { forwardRef } from 'react'; | |||
| import { | |||
| useCreateSharedConversationOnMount, | |||
| useSelectCurrentSharedConversation, | |||
| useSendSharedMessage, | |||
| } from '../shared-hooks'; | |||
| import { buildMessageItemReference } from '../utils'; | |||
| import styles from './index.less'; | |||
| import {useSendButtonDisabled} from "@/pages/chat/hooks"; | |||
| const MessageItem = ({ | |||
| item, | |||
| reference, | |||
| loading = false, | |||
| }: { | |||
| item: Message; | |||
| reference: IReference; | |||
| loading?: boolean; | |||
| }) => { | |||
| const isAssistant = item.role === MessageType.Assistant; | |||
| const { t } = useTranslate('chat'); | |||
| const fileThumbnails = useSelectFileThumbnails(); | |||
| const getDocumentUrl = useGetDocumentUrl(); | |||
| const referenceDocumentList = useMemo(() => { | |||
| return reference?.doc_aggs ?? []; | |||
| }, [reference?.doc_aggs]); | |||
| const content = useMemo(() => { | |||
| let text = item.content; | |||
| if (text === '') { | |||
| text = t('searching'); | |||
| } | |||
| return loading ? text?.concat('~~2$$') : text; | |||
| }, [item.content, loading, t]); | |||
| return ( | |||
| <div | |||
| className={classNames(styles.messageItem, { | |||
| [styles.messageItemLeft]: item.role === MessageType.Assistant, | |||
| [styles.messageItemRight]: item.role === MessageType.User, | |||
| })} | |||
| > | |||
| <section | |||
| className={classNames(styles.messageItemSection, { | |||
| [styles.messageItemSectionLeft]: item.role === MessageType.Assistant, | |||
| [styles.messageItemSectionRight]: item.role === MessageType.User, | |||
| })} | |||
| > | |||
| <div | |||
| className={classNames(styles.messageItemContent, { | |||
| [styles.messageItemContentReverse]: item.role === MessageType.User, | |||
| })} | |||
| > | |||
| {item.role === MessageType.User ? ( | |||
| <Avatar | |||
| size={40} | |||
| src={ | |||
| 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png' | |||
| } | |||
| /> | |||
| ) : ( | |||
| <AssistantIcon></AssistantIcon> | |||
| )} | |||
| <Flex vertical gap={8} flex={1}> | |||
| <b>{isAssistant ? '' : 'You'}</b> | |||
| <div className={isAssistant ? styles.messageText : styles.messageUserText}> | |||
| <MarkdownContent | |||
| reference={reference} | |||
| clickDocumentButton={() => {}} | |||
| content={content} | |||
| ></MarkdownContent> | |||
| </div> | |||
| {isAssistant && referenceDocumentList.length > 0 && ( | |||
| <List | |||
| bordered | |||
| dataSource={referenceDocumentList} | |||
| renderItem={(item) => { | |||
| const fileThumbnail = fileThumbnails[item.doc_id]; | |||
| const fileExtension = getExtension(item.doc_name); | |||
| return ( | |||
| <List.Item> | |||
| <Flex gap={'small'} align="center"> | |||
| {fileThumbnail ? ( | |||
| <img | |||
| src={fileThumbnail} | |||
| className={styles.thumbnailImg} | |||
| ></img> | |||
| ) : ( | |||
| <SvgIcon | |||
| name={`file-icon/${fileExtension}`} | |||
| width={24} | |||
| ></SvgIcon> | |||
| )} | |||
| <NewDocumentLink | |||
| link={getDocumentUrl(item.doc_id)} | |||
| preventDefault={!isPdf(item.doc_name)} | |||
| > | |||
| {item.doc_name} | |||
| </NewDocumentLink> | |||
| </Flex> | |||
| </List.Item> | |||
| ); | |||
| }} | |||
| /> | |||
| )} | |||
| </Flex> | |||
| </div> | |||
| </section> | |||
| </div> | |||
| ); | |||
| }; | |||
| import styles from './index.less'; | |||
| const ChatContainer = () => { | |||
| const { t } = useTranslate('chat'); | |||
| @@ -163,6 +51,7 @@ const ChatContainer = () => { | |||
| <MessageItem | |||
| key={message.id} | |||
| item={message} | |||
| nickname="You" | |||
| reference={buildMessageItemReference(conversation, message)} | |||
| loading={ | |||
| message.role === MessageType.Assistant && | |||
| @@ -8,6 +8,7 @@ import { Button, Drawer, Flex, Input, Spin } from 'antd'; | |||
| import { useSelectCurrentMessages, useSendMessage } from './hooks'; | |||
| import { useSelectUserInfo } from '@/hooks/userSettingHook'; | |||
| import styles from './index.less'; | |||
| const FlowChatBox = () => { | |||
| @@ -31,6 +32,7 @@ const FlowChatBox = () => { | |||
| useClickDrawer(); | |||
| useGetFileIcon(); | |||
| const { t } = useTranslate('chat'); | |||
| const userInfo = useSelectUserInfo(); | |||
| return ( | |||
| <> | |||
| @@ -47,6 +49,8 @@ const FlowChatBox = () => { | |||
| currentMessages.length - 1 === i | |||
| } | |||
| key={message.id} | |||
| nickname={userInfo.nickname} | |||
| avatar={userInfo.avatar} | |||
| item={message} | |||
| reference={buildMessageItemReference( | |||
| { message: currentMessages, reference }, | |||