|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
import { useEffect, useState, useRef, useMemo, memo } from 'react';
|
|
|
|
|
import { useEffect, useState, useRef, useMemo, memo, createRef, forwardRef } from 'react';
|
|
|
|
|
import { Image, Spin, Dropdown } from 'antd';
|
|
|
|
|
import { DownOutlined } from '@ant-design/icons';
|
|
|
|
|
import { MessageBox } from 'react-chat-elements';
|
|
|
|
@ -14,10 +14,21 @@ const Messages = () => {
|
|
|
|
|
const activeMessages = useConversationStore(useShallow((state) => (state.currentConversation.sn ? state.activeConversations[state.currentConversation.sn] : [])));
|
|
|
|
|
olog('invoke msg list');
|
|
|
|
|
|
|
|
|
|
const messagesEndRef = useRef(null);
|
|
|
|
|
const scrollToMessage = (id, index) => {
|
|
|
|
|
const _i = index || activeMessages.findIndex((msg) => msg.id === id);
|
|
|
|
|
if (_i >= 0) {
|
|
|
|
|
messageRefs.current[_i].current.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
|
|
|
|
}, [currentConversation.last_received_time]);
|
|
|
|
|
if (activeMessages.length > 0) {
|
|
|
|
|
scrollToMessage(null, activeMessages.length - 1);
|
|
|
|
|
}
|
|
|
|
|
}, [activeMessages]);
|
|
|
|
|
|
|
|
|
|
const messageRefs = useRef([]);
|
|
|
|
|
messageRefs.current = activeMessages.map((_, i) => messageRefs.current[i] ?? createRef());
|
|
|
|
|
|
|
|
|
|
const [previewVisible, setPreviewVisible] = useState(false);
|
|
|
|
|
const [previewSrc, setPreviewSrc] = useState();
|
|
|
|
@ -59,32 +70,40 @@ const Messages = () => {
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
// eslint-disable-next-line react/display-name
|
|
|
|
|
const MessageBoxWithRef = forwardRef((props, ref) => (
|
|
|
|
|
<div ref={ref}>
|
|
|
|
|
<MessageBox {...props} />
|
|
|
|
|
</div>
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<Spin spinning={msgListLoading} tip={'正在读取...'} wrapperClassName='pt-8 '>
|
|
|
|
|
{activeMessages.map((message, index) => (
|
|
|
|
|
<Dropdown
|
|
|
|
|
key={message.id}
|
|
|
|
|
menu={{
|
|
|
|
|
items: [{ label: '回复', key: 'reply', disabled: !['text'].includes(message.whatsapp_msg_type) }],
|
|
|
|
|
onClick: ({ key, domEvent }) => {
|
|
|
|
|
domEvent.stopPropagation();
|
|
|
|
|
switch (key) {
|
|
|
|
|
case 'reply':
|
|
|
|
|
return setReferenceMsg(message);
|
|
|
|
|
// <Dropdown
|
|
|
|
|
// key={message.id}
|
|
|
|
|
// menu={{
|
|
|
|
|
// items: [{ label: '回复', key: 'reply', disabled: !['text'].includes(message.whatsapp_msg_type) }],
|
|
|
|
|
// onClick: ({ key, domEvent }) => {
|
|
|
|
|
// domEvent.stopPropagation();
|
|
|
|
|
// switch (key) {
|
|
|
|
|
// case 'reply':
|
|
|
|
|
// return setReferenceMsg(message);
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
trigger={['contextMenu']}>
|
|
|
|
|
<MessageBox
|
|
|
|
|
// default:
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
// },
|
|
|
|
|
// }}
|
|
|
|
|
// trigger={['contextMenu']}>
|
|
|
|
|
<MessageBoxWithRef
|
|
|
|
|
ref={messageRefs.current[index]}
|
|
|
|
|
key={message.id}
|
|
|
|
|
{...message}
|
|
|
|
|
position={message.sender === 'me' ? 'right' : 'left'}
|
|
|
|
|
onReplyClick={() => setReferenceMsg(message)}
|
|
|
|
|
onReplyMessageClick={() => scrollToMessage(message.reply.id)}
|
|
|
|
|
onOpen={() => handlePreview(message)}
|
|
|
|
|
text={<RenderText str={message?.text || ''} />}
|
|
|
|
|
{...(message.sender === 'me'
|
|
|
|
@ -98,11 +117,10 @@ const Messages = () => {
|
|
|
|
|
replyButton: ['text'].includes(message.whatsapp_msg_type) ? true : false,
|
|
|
|
|
})}
|
|
|
|
|
/>
|
|
|
|
|
</Dropdown>
|
|
|
|
|
// </Dropdown>
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
|
|
<Image src={previewSrc} preview={{ visible: previewVisible, src: previewSrc, onClose: onPreviewClose }} />
|
|
|
|
|
<div ref={messagesEndRef}></div>
|
|
|
|
|
</Spin>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|