删除 消息记录的loading

dev/chat
Lei OT 2 years ago
parent c9e2c0c69a
commit a9f9e08553

@ -1,59 +1,37 @@
import { useEffect, useState, useRef, useMemo, memo, createRef, forwardRef } from 'react'; import { useEffect, useState, useRef, memo, createRef, forwardRef } from 'react';
import { Image, Spin, Dropdown, Button, Affix } from 'antd'; import { Image, Button } from 'antd';
import { DownOutlined } from '@ant-design/icons'; import { DownOutlined } from '@ant-design/icons';
import { MessageBox } from 'react-chat-elements'; import { MessageBox } from 'react-chat-elements';
import useConversationStore from '@/stores/ConversationStore'; import useConversationStore from '@/stores/ConversationStore';
import { useShallow } from 'zustand/react/shallow'; import { useShallow } from 'zustand/react/shallow';
import { Emoji } from 'emoji-picker-react';
import { isEmpty, olog } from '@/utils/utils'; import { isEmpty, olog } from '@/utils/utils';
const MessagesList = ({reference, ...props}) => { const MessagesList = ({ reference, ...props }) => {
const currentConversation = useConversationStore(useShallow((state) => state.currentConversation));
const setReferenceMsg = useConversationStore(useShallow((state) => state.setReferenceMsg)); const setReferenceMsg = useConversationStore(useShallow((state) => state.setReferenceMsg));
const msgListLoading = useConversationStore(useShallow((state) => state.msgListLoading));
// const activeMessages = useConversationStore(useShallow((state) => (state.currentConversation.sn ? state.activeConversations[state.currentConversation.sn] : [])));
olog('invoke msg list');
// const scrollToMessage = (id, index) => { const scrollToMessage = (id, index) => {
// const _i = index || props.dataSource.findIndex((msg) => msg.id === id); const _i = index || props.dataSource.findIndex((msg) => msg.id === id);
// if (_i >= 0) { if (_i >= 0) {
// messageRefs.current[_i].current.scrollIntoView({ behavior: 'smooth', block: 'center' }); messageRefs.current[_i].current.scrollIntoView({ behavior: 'smooth', block: 'center' });
// } }
// }; };
const messageRefs = useRef([]); const messageRefs = useRef([]);
messageRefs.current = props.dataSource.map((_, i) => messageRefs.current[i] ?? createRef()); messageRefs.current = props.dataSource.map((_, i) => messageRefs.current[i] ?? createRef());
const referance = useRef(null);
const toBottom = (e) => { const toBottom = (e) => {
if (!reference) return; if (!reference) return;
console.log(reference.current.scrollHeight, reference.current.scrollTop, reference.current.offsetHeight, 'hhhhhhhh');
reference.current.scrollTop = reference.current.scrollHeight - reference.current.offsetHeight; reference.current.scrollTop = reference.current.scrollHeight - reference.current.offsetHeight;
}; };
// useEffect(() => { const prevProps = useRef(props);
// if (dataSource.length > 0) {
// // toBottom();
// scrollToMessage(null, dataSource.length - 1);
// }
// }, [dataSource]);
const prevProps = useRef(props)
const getBottom = (e) => {
if (e.current) return e.current.scrollHeight - e.current.scrollTop - e.current.offsetHeight
return e.scrollHeight - e.scrollTop - e.offsetHeight
}
useEffect(() => { useEffect(() => {
// if (!reference) return
if (prevProps.current.dataSource.length !== props.dataSource.length) { if (prevProps.current.dataSource.length !== props.dataSource.length) {
olog(reference.current.scrollHeight, reference.current.scrollTop, 'hhhhhhhh')
// reference.current.scrollTop = reference.current.scrollHeight
toBottom(); toBottom();
} }
prevProps.current = props prevProps.current = props;
}, [prevProps, props]) }, [prevProps, props]);
const [previewVisible, setPreviewVisible] = useState(false); const [previewVisible, setPreviewVisible] = useState(false);
const [previewSrc, setPreviewSrc] = useState(); const [previewSrc, setPreviewSrc] = useState();
@ -78,7 +56,7 @@ const MessagesList = ({reference, ...props}) => {
}; };
const RenderText = memo(function renderText({ str }) { const RenderText = memo(function renderText({ str }) {
const parts = str.split(/(https?:\/\/[^\s]+|\p{Emoji_Presentation})/gmu).filter(s => s !== ''); const parts = str.split(/(https?:\/\/[^\s]+|\p{Emoji_Presentation})/gmu).filter((s) => s !== '');
const links = str.match(/https?:\/\/[\S]+/gi) || []; const links = str.match(/https?:\/\/[\S]+/gi) || [];
const emojis = str.match(/([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g) || []; const emojis = str.match(/([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g) || [];
const extraClass = isEmpty(emojis) ? '' : 'text-base leading-5 emoji-text'; const extraClass = isEmpty(emojis) ? '' : 'text-base leading-5 emoji-text';
@ -88,20 +66,21 @@ const MessagesList = ({reference, ...props}) => {
} else if (emojis.includes(curr)) { } else if (emojis.includes(curr)) {
prev.push({ type: 'emoji', key: curr }); prev.push({ type: 'emoji', key: curr });
} else { } else {
prev.push({type: 'text', key: curr}); prev.push({ type: 'text', key: curr });
} }
return prev; return prev;
}, []); }, []);
return ( return (
<span className={extraClass}> <span className={extraClass}>
{(objArr || []).map((part, index) => { {(objArr || []).map((part, index) => {
if (part.type === 'link') { if (part.type === 'link') {
return ( return (
<a href={part.key} target='_blank' key={`${part.key}${index}`} rel='noreferrer' className='text-sm'> <a href={part.key} target='_blank' key={`${part.key}${index}`} rel='noreferrer' className='text-sm'>
{part.key} {part.key}
</a> </a>
); );
} else { // if (part.type === 'emoji') } else {
// if (part.type === 'emoji')
return part.key; return part.key;
} }
})} })}
@ -116,54 +95,52 @@ const MessagesList = ({reference, ...props}) => {
)); ));
return ( return (
<div className='relative h-full overflow-y-auto flex'> <div className='relative h-full overflow-y-auto overflow-x-hidden flex'>
<div className='relative overflow-y-auto block flex-1' ref={reference}> <div className='relative overflow-y-auto block flex-1' ref={reference}>
<Spin spinning={msgListLoading} tip={'正在读取...'} wrapperClassName='pt-8 relative'> {props.dataSource.map((message, index) => (
{props.dataSource.map((message, index) => ( // <Dropdown
// <Dropdown // key={message.id}
// key={message.id} // menu={{
// menu={{ // items: [{ label: '', key: 'reply', disabled: !['text'].includes(message.whatsapp_msg_type) }],
// items: [{ label: '', key: 'reply', disabled: !['text'].includes(message.whatsapp_msg_type) }], // onClick: ({ key, domEvent }) => {
// onClick: ({ key, domEvent }) => { // domEvent.stopPropagation();
// domEvent.stopPropagation(); // switch (key) {
// switch (key) { // case 'reply':
// case 'reply': // return setReferenceMsg(message);
// return setReferenceMsg(message);
// default: // default:
// return; // return;
// } // }
// }, // },
// }} // }}
// trigger={['contextMenu']}> // trigger={['contextMenu']}>
<MessageBoxWithRef <MessageBoxWithRef
ref={messageRefs.current[index]} ref={messageRefs.current[index]}
key={message.id} key={message.id}
{...message} {...message}
position={message.sender === 'me' ? 'right' : 'left'} position={message.sender === 'me' ? 'right' : 'left'}
onReplyClick={() => setReferenceMsg(message)} onReplyClick={() => setReferenceMsg(message)}
// onReplyMessageClick={() => scrollToMessage(message.reply.id)} onReplyMessageClick={() => scrollToMessage(message.reply.id)}
onOpen={() => handlePreview(message)} onOpen={() => handlePreview(message)}
onTitleClick={() => handlePreview(message)} onTitleClick={() => handlePreview(message)}
text={<RenderText str={message?.text || ''} />} text={<RenderText str={message?.text || ''} />}
{...(message.sender === 'me' {...(message.sender === 'me'
? { ? {
styles: { backgroundColor: '#ccd4ae' }, styles: { backgroundColor: '#ccd4ae' },
notchStyle: { fill: '#ccd4ae' }, notchStyle: { fill: '#ccd4ae' },
replyButton: ['text', 'document', 'image'].includes(message.whatsapp_msg_type) && message.status !== 'failed' ? true : false, replyButton: ['text', 'document', 'image'].includes(message.whatsapp_msg_type) && message.status !== 'failed' ? true : false,
className: 'whatsappme-container whitespace-pre-wrap', className: 'whatsappme-container whitespace-pre-wrap',
} }
: { : {
replyButton: ['text', 'document', 'image'].includes(message.whatsapp_msg_type) ? true : false, replyButton: ['text', 'document', 'image'].includes(message.whatsapp_msg_type) ? true : false,
className: 'whitespace-pre-wrap', className: 'whitespace-pre-wrap',
})} })}
/> />
// </Dropdown> // </Dropdown>
))} ))}
</Spin>
<Image src={null} preview={{ visible: previewVisible, src: previewSrc, onClose: onPreviewClose }} />
</div> </div>
<Button onClick={toBottom} shape={'circle'} className=' absolute bottom-1 right-4' icon={<DownOutlined />} /> <Button onClick={toBottom} shape={'circle'} className=' absolute bottom-1 right-4' icon={<DownOutlined />} />
<Image src={null} preview={{ visible: previewVisible, src: previewSrc, onClose: onPreviewClose }} />
</div> </div>
); );
}; };

@ -1,11 +1,6 @@
import { useEffect, useState, useRef, useMemo, memo, createRef, forwardRef } from 'react'; import { useRef } from 'react';
import { Image, Spin, Dropdown, Button, Affix } from 'antd';
import { DownOutlined } from '@ant-design/icons';
import { MessageBox } from 'react-chat-elements';
import useConversationStore from '@/stores/ConversationStore'; import useConversationStore from '@/stores/ConversationStore';
import { useShallow } from 'zustand/react/shallow'; import { useShallow } from 'zustand/react/shallow';
import { Emoji } from 'emoji-picker-react';
import { isEmpty, olog } from '@/utils/utils';
import MessagesList from './MessagesList'; import MessagesList from './MessagesList';
const MessagesWrapper = () => { const MessagesWrapper = () => {

Loading…
Cancel
Save