import { useRef, useEffect, useState, forwardRef, memo } from 'react'; import { App, Flex, List, Button, } from 'antd'; import { LoadingOutlined } from '@ant-design/icons'; import { MessageBox } from 'react-chat-elements'; import { MESSAGE_PAGE_SIZE, fetchMessagesHistory } from '@/actions/ConversationActions'; import useFormStore from '@/stores/FormStore'; import { isEmpty, stringToColour, groupBy, isNotEmpty } from '@/utils/commons'; import { useShallow } from 'zustand/react/shallow'; import MergeConversationTo from './MergeConversationTo'; import BubbleIM from '../Online/Components/BubbleIM'; import BubbleEmail from '../Online/Components/BubbleEmail'; const BIG_PAGE_SIZE = MESSAGE_PAGE_SIZE * 20; const MessagesList = ({ ...listProps }) => { const { message: appMessage } = App.useApp(); const [formValues] = useFormStore((state) => [state.chatHistoryForm]); const [selectedConversation] = useFormStore((state) => [state.chatHistorySelectChat]); const [paramsForMsgList, setParamsForMsgList] = useFormStore((state) => [state.msgListParams, state.setMsgListParams]); const [selectMatch, setSelectedMatch] = useFormStore((state) => [state.msgHistorySelectMatch, state.setMsgHistorySelectMatch]); const [setImageAlbumList, setImagePreviewSrc] = useFormStore(useShallow((state) => [state.setImageAlbum, state.setImagePreviewSrc])); const [chatItemMessages, setChatItemMessages] = useState([]); const [messageListPreLoading, setMessageListPreLoading] = useState(false); const [messageListLoading, setMessageListLoading] = useState(false); const getMessagesPre = async (chatItem) => { setMessageListPreLoading(true); const data = await fetchMessagesHistory({ ...chatItem, lasttime: chatItem.pretime, pagedir: 'pre', pagesize: BIG_PAGE_SIZE }); setMessageListPreLoading(false); // const prevChatItemMessages = chatItemMessages; // setChatItemMessages([].concat(data, prevChatItemMessages)); setChatItemMessages((prevValue) => [].concat(data, prevValue)); const loadPrePage = !(data.length === 0 || data.length < BIG_PAGE_SIZE); if (data.length > 0) { setParamsForMsgList({ loadPrePage, pretime: data[0].orgmsgtime }); } }; const getMessagesNext = async (chatItem) => { setMessageListLoading(true); const data = await fetchMessagesHistory({ ...chatItem, pagedir: 'next', pagesize: BIG_PAGE_SIZE }); setMessageListLoading(false); // const prevChatItemMessages = chatItemMessages; // setChatItemMessages([].concat(prevChatItemMessages, data)); setChatItemMessages((prevValue) => [].concat(prevValue, data)); const loadNextPage = !(data.length === 0 || data.length < BIG_PAGE_SIZE); if (data.length > 0) { setParamsForMsgList({ loadNextPage, lasttime: data[data.length - 1].orgmsgtime }); } }; // 选择指定消息之后, 定位 const scrollToSelectedMessage = (selected) => { const findIndex = chatItemMessages.findIndex((item) => item.id === selected.id); if (findIndex !== -1) { scrollToMessage(selected.id, findIndex); } }; // 选中会话之后, 获取消息记录 useEffect(() => { setChatItemMessages([]); setParamsForMsgList({}); setSelectedMatch({}); setFocusMsg(''); if (isEmpty(selectedConversation.conversationid)) { return () => {}; } // opisn: (selectedConversation.opi_sn || 0), whatsappid: selectedConversation.whatsapp_phone_number, const firstActionPageParams = { conversationid: selectedConversation.conversationid , loadNextPage: true }; // if (isEmpty(selectedConversation.matchMsgList)) { if (!isEmpty(formValues?.from_date)) { firstActionPageParams.lasttime = formValues.from_date; firstActionPageParams.loadPrePage = true; } if (!isEmpty(formValues?.search) && !isEmpty(selectedConversation.matchMsgList)) { firstActionPageParams.pretime = selectedConversation.matchMsgList[0].orgmsgtime; firstActionPageParams.lasttime = selectedConversation.matchMsgList[0].orgmsgtime; firstActionPageParams.loadPrePage = true; } setParamsForMsgList(firstActionPageParams); async function getFirstNext() { await getMessagesNext(firstActionPageParams); } getFirstNext(); return () => {}; }, [selectedConversation.conversationid]); // 点击匹配的记录, 定位滚动 useEffect(() => { async function getFirstPre(_params) { await getMessagesPre(_params); } const findIndex = chatItemMessages.findIndex((item) => item.id === selectMatch.id); if (findIndex === -1) { setMessageListLoading(true); getFirstPre({ ...paramsForMsgList }); setMessageListLoading(false); } scrollToSelectedMessage(selectMatch); return () => {}; }, [selectMatch.id]); // 更新是否需要显示上一页,下一页按钮 useEffect(() => { if (chatItemMessages.length > 0) { // setParamsForMsgList({ pretime: chatItemMessages[0].orgmsgtime, lasttime: chatItemMessages[chatItemMessages.length - 1].orgmsgtime }); const album = chatItemMessages.filter((ele) => ele.whatsapp_msg_type === 'image').map((ele) => ele.data.uri); setImageAlbumList(album); } return () => {}; }, [chatItemMessages]); const onLoadMore = () => { getMessagesNext(paramsForMsgList); // window.dispatchEvent(new Event('resize')); }; const loadMore = !messageListLoading && paramsForMsgList.loadNextPage ? (
) : null; const onLoadMorePre = () => { getMessagesPre(paramsForMsgList); // window.dispatchEvent(new Event('resize')); }; const loadMorePre = paramsForMsgList.loadPrePage && chatItemMessages.length > 0 ? (
{messageListPreLoading ? : }
) : null; const messagesEndRef = useRef(null); const messageRefs = useRef([]); const [focusMsg, setFocusMsg] = useState(''); const scrollToMessage = (id, index) => { const _i = index || chatItemMessages.findIndex((msg) => msg.id === id); if (_i >= 0) { messageRefs.current[_i].scrollIntoView({ behavior: 'smooth', block: 'start' }); setFocusMsg(id); } }; const RenderText = memo(function renderText({ str, className, template }) { let headerObj, footerObj, buttonsArr; if (!isEmpty(template) && !isEmpty(template.components)) { const componentsObj = groupBy(template.components, (item) => item.type); headerObj = componentsObj?.header?.[0]; footerObj = componentsObj?.footer?.[0]; buttonsArr = componentsObj?.buttons?.reduce((r, c) => r.concat(c.buttons), []); } const parts = str.split(/(https?:\/\/[^\s()]+|\p{Emoji_Presentation})/gmu).filter((s) => s !== ''); 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 extraClass = isEmpty(emojis) ? '' : ''; const objArr = parts.reduce((prev, curr, index) => { if (links.includes(curr)) { prev.push({ type: 'link', key: curr }); } else if (emojis.includes(curr)) { prev.push({ type: 'emoji', key: curr }); } else { prev.push({ type: 'text', key: curr }); } return prev; }, []); return ( {headerObj ? (
{'text' === (headerObj?.parameters?.[0]?.type || '').toLowerCase() &&
{headerObj.text}
} {'image' === (headerObj?.parameters?.[0]?.type || '').toLowerCase() && } {['document', 'video'].includes((headerObj?.parameters?.[0]?.type || '').toLowerCase()) && ( [ {headerObj.parameters[0].type} ] )}
) : null} {(objArr || []).map((part, index) => { if (part.type === 'link') { return ( {part.key} ); } else { return part.key; } })}
); }); // eslint-disable-next-line react/display-name const MessageBoxWithRef = forwardRef((props, ref) => (
  • {['waba', 'wai'].includes((props.msg_source || '').toLowerCase()) && } {props.msg_source === 'email' && }
  • )); const handlePreview = (msg) => { switch (msg.whatsapp_msg_type) { case 'image': setImagePreviewSrc(msg.data.uri); return false; case 'document': window.open(msg.data.link || msg.data.uri, '_blank', 'noopener,noreferrer'); return false; default: return false; } }; return ( <>
    {selectedConversation.whatsapp_name} {selectedConversation.whatsapp_phone_number}
    {selectedConversation.whatsapp_phone_number && }
    ( // // } title={item.title} description={item.msgTime} /> //
    {item.content}
    //
    (messageRefs.current[index] = el)} key={message.id} {...message} // position={message.sender === 'me' ? 'right' : 'left'} position={'left'} replyButton={false} onReplyMessageClick={() => scrollToMessage(message.reply.id)} onOpen={() => handlePreview(message)} onTitleClick={() => handlePreview(message)} notch={false} title={message.whatsapp_msg_type === 'text' ? '' : message.title} text={} copiableDate={true} dateString={message.dateString || message.localDate} className={[ 'whitespace-pre-wrap mb-2', message.whatsapp_msg_type === 'sticker' ? 'bg-transparent' : '', message.sender === 'me' ? 'whatsappme-container' : '', focusMsg === message.id ? 'message-box-focus' : '', message.status === 'failed' ? 'failed-msg' : '', ].join(' ')} style={{ backgroundColor: message.sender === 'me' ? '#ccd4ae' : '#fff', }} {...(message.type === 'meetingLink' ? { actionButtons: [ { onClickButton: () => { navigator.clipboard.writeText(message.text); appMessage.success('复制成功😀'); }, Component: () =>
    复制
    , }, ], } : {})} renderAddCmp={
    {message.msg_direction === 'outbound' ? selectedConversation.OPI_Name : message.senderName} {message.dateString || message.localDate} {message.statusCN}
    } // date={null} // status={null} /> )} />
    ); }; export default MessagesList;