|
|
|
@ -1,13 +1,18 @@
|
|
|
|
|
import { useEffect, useState, useRef, useMemo } from 'react';
|
|
|
|
|
import { useEffect, useState, useRef, useMemo, memo } from 'react';
|
|
|
|
|
import { Image, Spin, Dropdown } from 'antd';
|
|
|
|
|
import { DownOutlined } from '@ant-design/icons';
|
|
|
|
|
import { MessageBox } from 'react-chat-elements';
|
|
|
|
|
import useConversationStore from '@/stores/ConversationStore';
|
|
|
|
|
import { useShallow } from 'zustand/react/shallow';
|
|
|
|
|
import { Emoji } from 'emoji-picker-react';
|
|
|
|
|
import { olog } from '@/utils/utils';
|
|
|
|
|
|
|
|
|
|
const Messages = () => {
|
|
|
|
|
const { currentConversation, setReferenceMsg, msgListLoading } = useConversationStore();
|
|
|
|
|
const currentConversation = useConversationStore(useShallow((state) => state.currentConversation));
|
|
|
|
|
const setReferenceMsg = useConversationStore(useShallow((state) => state.setReferenceMsg));
|
|
|
|
|
const msgListLoading = useConversationStore(useShallow((state) => state.msgListLoading));
|
|
|
|
|
const activeMessages = useConversationStore(useShallow((state) => (currentConversation.sn ? state.activeConversations[currentConversation.sn] : [])));
|
|
|
|
|
olog('invoke msg list');
|
|
|
|
|
|
|
|
|
|
const messagesList = useMemo(
|
|
|
|
|
() =>
|
|
|
|
@ -49,6 +54,28 @@ const Messages = () => {
|
|
|
|
|
setPreviewSrc(msg.data.uri);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const RenderText = memo(function renderText({str}) {
|
|
|
|
|
const parts = str.split(/(https?:\/\/[^\s]+|\p{Emoji}\uFE0F?)/gu);
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
{(parts || []).map((part, index) => {
|
|
|
|
|
if (/\p{Emoji}\uFE0F?/u.test(part)) {
|
|
|
|
|
const code = [...part].map((e) => e.codePointAt(0).toString(16)).join(`-`);
|
|
|
|
|
return <Emoji key={`${part}${index}${code}`} unified={code} size={24} emojiStyle='facebook' />;
|
|
|
|
|
} else if (/https?:\/\/[\S]+/gi.test(part)) {
|
|
|
|
|
return (
|
|
|
|
|
<a href={part} target='_blank' key={`${part}${index}`} rel='noreferrer'>
|
|
|
|
|
{part}
|
|
|
|
|
</a>
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
return <span key={`${part}${index}`}>{part}</span>;
|
|
|
|
|
}
|
|
|
|
|
})}
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<Spin spinning={msgListLoading} tip={'正在读取...'} wrapperClassName='pt-8 '>
|
|
|
|
@ -75,7 +102,7 @@ const Messages = () => {
|
|
|
|
|
{...message}
|
|
|
|
|
onReplyClick={() => setReferenceMsg(message)}
|
|
|
|
|
onOpen={() => handlePreview(message)}
|
|
|
|
|
{...(message.type === 'text' ? { text: <div dangerouslySetInnerHTML={{ __html: message.text }}></div> } : {})}
|
|
|
|
|
text={<RenderText str={message?.text || ''} />}
|
|
|
|
|
/>
|
|
|
|
|
</Dropdown>
|
|
|
|
|
))}
|
|
|
|
|