dev/chat
Lei OT 2 years ago
parent 025289eae7
commit 4f525effce

@ -266,9 +266,9 @@ export const whatsappMsgTypeMapped = {
},
},
originText: msg.image?.caption || '',
onOpen: () => {
console.log('Open image', msg.image.link);
},
// onOpen: () => {
// console.log('Open image', msg.image.link);
// },
}),
renderForReply: (msg) => ({
id: msg.wamid,

@ -1,60 +1,61 @@
import { useEffect, useState, useRef, memo, createRef, forwardRef } from 'react';
import { Image, Button } from 'antd';
import { DownOutlined } from '@ant-design/icons';
import { useEffect, useRef, useState, forwardRef, memo } from 'react';
import { MessageBox } from 'react-chat-elements';
import useConversationStore from '@/stores/ConversationStore';
import { Button } from 'antd';
import { DownOutlined } from '@ant-design/icons';
import { useShallow } from 'zustand/react/shallow';
import useConversationStore from '@/stores/ConversationStore';
import { isEmpty, olog } from '@/utils/utils';
const MessagesList = ({ reference, contactsModalOpen, setContactsModalOpen, ...props }) => {
const MessagesList = ({ messages, handlePreview, reference }) => {
const setReferenceMsg = useConversationStore(useShallow((state) => state.setReferenceMsg));
olog('render message list');
const scrollToMessage = (id, index) => {
const _i = index || props.dataSource.findIndex((msg) => msg.id === id);
if (_i >= 0) {
messageRefs.current[_i].current.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
};
// const messagesEndRef = useRef(null);
const messageRefs = useRef([]);
messageRefs.current = props.dataSource.map((_, i) => messageRefs.current[i] ?? createRef());
const [page, setPage] = useState(1);
let timeout = null;
const toBottom = (e) => {
if (!reference) return;
reference.current.scrollTop = reference.current.scrollHeight - reference.current.offsetHeight;
const fetchNextPage = async () => {
olog('fetchNextPage')
setPage(page + 1);
// Fetch next page of messages here
};
const prevProps = useRef(props);
useEffect(() => {
if (prevProps.current.dataSource.length !== props.dataSource.length) {
toBottom();
const handleScroll = (e) => {
const { scrollTop } = e.target;
const delay = 1000; // 1 second
if (scrollTop === 0) {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(fetchNextPage, delay);
}
};
prevProps.current = props;
}, [prevProps, props]);
const scrollToBottom = () => {
if (reference.current) {
reference.current.scrollTop = reference.current.scrollHeight;
}
};
const [previewVisible, setPreviewVisible] = useState(false);
const [previewSrc, setPreviewSrc] = useState();
const onPreviewClose = () => {
setPreviewSrc('');
setPreviewVisible(false);
const scrollToMessage = (id, index) => {
const _i = index || messages.findIndex((msg) => msg.id === id);
if (reference.current && messageRefs.current[_i]) {
reference.current.scrollTop = messageRefs.current[_i].offsetTop;
}
};
const handlePreview = (msg) => {
switch (msg.type) {
case 'photo':
setPreviewVisible(true);
setPreviewSrc(msg.data.uri);
return false;
case 'file':
window.open(msg.data.link || msg.data.uri, '_blank', 'noopener,noreferrer');
return false;
useEffect(scrollToBottom, [messages]);
default:
return false;
useEffect(() => {
const messageList = reference.current;
if (messageList) {
messageList.addEventListener('scroll', handleScroll);
}
};
return () => {
if (messageList) {
messageList.removeEventListener('scroll', handleScroll);
}
};
}, []);
const RenderText = memo(function renderText({ str }) {
const parts = str.split(/(https?:\/\/[^\s]+|\p{Emoji_Presentation})/gmu).filter((s) => s !== '');
@ -88,6 +89,7 @@ const MessagesList = ({ reference, contactsModalOpen, setContactsModalOpen, ...p
</span>
);
});
// eslint-disable-next-line react/display-name
const MessageBoxWithRef = forwardRef((props, ref) => (
<div ref={ref}>
@ -96,27 +98,11 @@ const MessagesList = ({ reference, contactsModalOpen, setContactsModalOpen, ...p
));
return (
<div className='relative h-full overflow-y-auto overflow-x-hidden flex'>
<div className='relative overflow-y-auto block flex-1' ref={reference}>
{props.dataSource.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);
// default:
// return;
// }
// },
// }}
// trigger={['contextMenu']}>
<div className='relative h-full overflow-y-auto overflow-x-hidden flex flex-1'>
<div ref={reference} className='relative overflow-y-auto overflow-x-hidden block flex-1'>
{messages.map((message, index) => (
<MessageBoxWithRef
ref={messageRefs.current[index]}
ref={(el) => (messageRefs.current[index] = el)}
key={message.id}
{...message}
position={message.sender === 'me' ? 'right' : 'left'}
@ -149,11 +135,9 @@ const MessagesList = ({ reference, contactsModalOpen, setContactsModalOpen, ...p
}
: {})}
/>
// </Dropdown>
))}
</div>
<Button onClick={toBottom} ghost type={'dashed'} shape={'circle'} className=' absolute bottom-1 right-4' icon={<DownOutlined />} />
<Image src={null} preview={{ visible: previewVisible, src: previewSrc, onClose: onPreviewClose }} />
<Button onClick={scrollToBottom} ghost type={'dashed'} shape={'circle'} className=' absolute bottom-1 right-4' icon={<DownOutlined />} />
</div>
);
};

@ -1,15 +1,39 @@
import { useRef } from 'react';
import { useRef, useState } from 'react';
import useConversationStore from '@/stores/ConversationStore';
import { useShallow } from 'zustand/react/shallow';
import { Image, } from 'antd';
import MessagesList from './MessagesList';
const MessagesWrapper = () => {
const activeMessages = useConversationStore(useShallow((state) => (state.currentConversation.sn && state.activeConversations[state.currentConversation.sn] ? state.activeConversations[state.currentConversation.sn]: [])));
const reference = useRef(null);
const [previewVisible, setPreviewVisible] = useState(false);
const [previewSrc, setPreviewSrc] = useState();
const onPreviewClose = () => {
setPreviewSrc('');
setPreviewVisible(false);
};
const handlePreview = (msg) => {
switch (msg.whatsapp_msg_type) {
case 'image':
setPreviewVisible(true);
setPreviewSrc(msg.data.uri);
return false;
case 'document':
window.open(msg.data.link || msg.data.uri, '_blank', 'noopener,noreferrer');
return false;
default:
return false;
}
};
return (
<>
<MessagesList dataSource={activeMessages} reference={reference} />
<MessagesList messages={activeMessages} {...{ reference, handlePreview }} />
<Image width={0} height={0} src={null} preview={{ visible: previewVisible, src: previewSrc, onClose: onPreviewClose }} />
</>
);
};

@ -67,7 +67,7 @@
.chatwindow-wrapper .rce-mbox-reply-message,
.chatwindow-wrapper .emoji
{
font-family: "Noto Color Emoji", 'Apple Color Emoji', 'Twemoji Mozilla', 'Segoe UI Emoji', 'Segoe UI Symbol', 'EmojiOne Color', 'Android Emoji', sans-serif;
font-family: "Noto Color Emoji", 'Apple Color Emoji', 'Twemoji Mozilla', 'Segoe UI Emoji', 'Segoe UI Symbol', 'EmojiOne Color', 'Android Emoji', Arial, sans-serif;
font-weight: 500;
}
.chatwindow-wrapper .rce-mbox-text a{

Loading…
Cancel
Save