diff --git a/src/components/DndModal.jsx b/src/components/DndModal.jsx
new file mode 100644
index 0000000..cb5ac65
--- /dev/null
+++ b/src/components/DndModal.jsx
@@ -0,0 +1,61 @@
+import { createContext, useEffect, useState } from 'react';
+import {} from 'antd';
+import Modal from '@dckj/react-better-modal';
+import '@dckj/react-better-modal/dist/index.css';
+import { isEmpty } from '@/utils/commons';
+
+const DnDModal = ({ children, open, setOpen, onCancel, initial = {}, title, ...props }) => {
+ // const [open, setOpen] = useState(false);
+ function onHandleMove(e) {
+ console.log(e, '--->>> onHandleMove');
+ }
+ function onHandleResize(e) {
+ console.log(e, '--->>> onHandleResize');
+ }
+
+ function onHandleOk() {
+ console.log('onOk callback');
+ }
+
+ function onHandleCancel() {
+ console.log('onCancel callback');
+ if (typeof onCancel === 'function') {
+ onCancel();
+ }
+ setOpen(false);
+ }
+ function onStageChange({ state }) {
+ console.log(state);
+ }
+ return (
+ >}
+ onMove={onHandleMove}
+ onResize={onHandleResize}
+ onCancel={onHandleCancel}
+ // onOk={onHandleOk}
+ onStageChange={onStageChange}
+ footer={null}>
+ <>{children}>
+
+ );
+};
+export default DnDModal;
diff --git a/src/views/Conversations/Online/Components/MessageListFilter.jsx b/src/views/Conversations/Online/Components/MessageListFilter.jsx
index d6d9ebf..5c40895 100644
--- a/src/views/Conversations/Online/Components/MessageListFilter.jsx
+++ b/src/views/Conversations/Online/Components/MessageListFilter.jsx
@@ -1,11 +1,15 @@
-import { createContext, useEffect, useState } from 'react';
-import { Button, Tag, Radio, Popover, Form, Dropdown, Tabs, List, Image, Empty, Avatar, Card } from 'antd';
-import { FileSearchOutlined, FilterOutlined, FilterTwoTone } from '@ant-design/icons';
-import { FilterIcon, InboxIcon, MailSendIcon, SendPlaneFillIcon, SendPlaneLineIcon } from '@/components/Icons';
-import { groupBy, isEmpty, objectMapper, stringToColour } from '@/utils/commons';
+import { useEffect, useState } from 'react';
+import { App, Button, Popover, Tabs, List, Image, Avatar, Card } from 'antd';
+import { FileSearchOutlined, LoadingOutlined } from '@ant-design/icons';
+import { InboxIcon, SendPlaneFillIcon } from '@/components/Icons';
+import { groupBy, stringToColour } from '@/utils/commons';
import useConversationStore from '@/stores/ConversationStore';
import { useShallow } from 'zustand/react/shallow';
import EmailDetail from './EmailDetail';
+import { MESSAGE_PAGE_SIZE, fetchMessagesHistory } from '@/actions/ConversationActions';
+import DnDModal from '@/components/DnDModal';
+
+const BIG_PAGE_SIZE = MESSAGE_PAGE_SIZE * 10;
const CalColorStyle = (tag, outerStyle = true) => {
const color = stringToColour(tag);
@@ -13,72 +17,143 @@ const CalColorStyle = (tag, outerStyle = true) => {
return { color: `${color}`, ...outerStyleObj };
};
const getVideoName = (vUrl) => {
+ if ( ! vUrl) return '';
const url = new URL(vUrl);
return url.pathname.split('/').pop();
};
+/**
+ * 消息记录筛选----------------------------------------------------------------------------------------------------
+ */
const MessageListFilter = ({ ...props }) => {
const activeMessages = useConversationStore(
useShallow((state) => (state.currentConversation.sn && state.activeConversations[state.currentConversation.sn] ? state.activeConversations[state.currentConversation.sn] : []))
);
+ const currentConversation = useConversationStore((state) => state.currentConversation);
+ const { opi_sn: opisn, whatsapp_phone_number: whatsappid } = currentConversation;
+
+ const { message: appMessage } = App.useApp();
- const LongList = () => {
+ const LongList = () => {
return <>>;
};
+ const [loading, setLoading] = useState(false);
+
+ const [paramsForMsgList, setParamsForMsgList] = useState({});
+ const [historyMessages, setHistoryMessages] = useState([]);
+ const getMessagesPre = async (param) => {
+ setLoading(true);
+ const chatItem = { opisn, whatsappid };
+ const data = await fetchMessagesHistory({ ...chatItem, lasttime: param.pretime, pagedir: 'pre', pagesize: BIG_PAGE_SIZE });
+ setLoading(false);
+ setHistoryMessages((prevValue) => [].concat(data, prevValue));
+ const loadPrePage = !(data.length === 0 || data.length < BIG_PAGE_SIZE);
+ // if (data.length > 0) {
+ // setParamsForMsgList({ loadPrePage, pretime: data[0].orgmsgtime });
+ // }
+ setParamsForMsgList((preVal) => ({ ...preVal, loadPrePage, pretime: data.length > 0 ? data[0].orgmsgtime : preVal.pretime }));
+ };
+ const onLoadMore = async () => {
+ await getMessagesPre(paramsForMsgList);
+ };
+ const loadMore = paramsForMsgList.loadPrePage ? (
+
+ {!loading ? (
+
+ ) : (
+
+ )}
+
+ ) : null;
+
+ const handleCopyClick = (url) => {
+ try {
+ navigator.clipboard.writeText(url)
+ appMessage.success('复制成功😀');
+ } catch (error) {
+ appMessage.warning('不支持自动复制, 请手动复制');
+ }
+ }
+
+ useEffect(() => {
+ if (activeMessages.length > 0) {
+ setHistoryMessages(activeMessages);
+ }
+ const { opi_sn: opisn, whatsapp_phone_number: whatsappid } = currentConversation;
+ setParamsForMsgList({ loadPrePage: true, pretime: activeMessages.length > 0 ? activeMessages[0].orgmsgtime : '', opisn, whatsappid });
+
+ return () => {};
+ }, [activeMessages, currentConversation.sn]);
+
const Album = () => {
- const data = (activeMessages || []).filter((item) => item.type === 'photo').reverse();
+ const data = historyMessages.filter((item) => item.type === 'photo').reverse();
const byDate = groupBy(data, (item) => item.localDate.slice(0, 10));
return (
<>
- {data.length === 0 && }
-
-
- {Object.keys(byDate).map((date, index) => (
-
-
- {byDate[date].map((img) => (
-
- ))}
-
-
- ))}
-
-
+
+ (
+
+
+
+ {byDate[date].map((img) => (
+
+ ))}
+
+
+
+ )}
+ />
+
>
);
};
const Videos = () => {
- // todo: 打开视频播放
- const data = (activeMessages || []).filter((item) => item.type === 'video').reverse();
+ const data = historyMessages.filter((item) => item.type === 'video').reverse();
+
+ const [videoUrl, setVideoUrl] = useState('');
+ const [openVideoPlay, setOpenVideoPlay] = useState(false);
+ const handleOpenVideoPlay = (vurl) => {
+ setVideoUrl(vurl);
+ setOpenVideoPlay(true);
+ setOpenPopup(false);
+ };
+
return (
<>
- {/* {data.length === 0 && }
-
- {data.map((item) => (
-
- ))}
-
*/}
(
-
+ loadMore={loadMore}
+ loading={loading}
+ renderItem={(item) => (
+ handleCopyClick(item.data.videoURL)} type='link' size='small'>
+ 复制🔗
+ ,
+ item.localDate,
+ ]}
+ className='items-center'>
}
avatar={
{item.senderName}
}
title={
-
+ handleOpenVideoPlay(item?.data.videoURL)}>
{getVideoName(item?.data.videoURL)}
-
+
}
description={item.text}
/>
@@ -86,18 +161,26 @@ const MessageListFilter = ({ ...props }) => {
)}
/>
+
+
+
>
);
};
const Audios = () => {
- const data = (activeMessages || []).filter((item) => item.type === 'audio').reverse();
+ const data = historyMessages.filter((item) => item.type === 'audio').reverse();
return (
<>
(
+ loadMore={loadMore}
+ loading={loading}
+ renderItem={(item) => (
{
};
const FileList = () => {
- const data = (activeMessages || []).filter((item) => item.type === 'file').reverse();
+ const data = historyMessages.filter((item) => item.type === 'file').reverse();
return (
<>
{/* {data.length === 0 && } */}
(
-
+ loadMore={loadMore}
+ loading={loading}
+ renderItem={(item) => (
+ handleCopyClick(item.data.uri)} type='link' size='small'>
+ 复制🔗
+ ,item.localDate]}>
}
avatar={
@@ -148,8 +236,7 @@ const MessageListFilter = ({ ...props }) => {
};
const EmailList = () => {
- // todo: 打开邮件
- const data = (activeMessages || []).filter((item) => item.type === 'email').reverse();
+ const data = historyMessages.filter((item) => item.type === 'email').reverse();
const [openEmailDetail, setOpenEmailDetail] = useState(false);
const [emailDetail, setEmailDetail] = useState({});
@@ -163,42 +250,39 @@ const MessageListFilter = ({ ...props }) => {
{/* {data.length === 0 && } */}
(
-
+ loadMore={loadMore}
+ loading={loading}
+ renderItem={({ emailOrigin, ...item }) => (
+ {
+ onOpenEmail({ emailOrigin, ...item });
+ setOpenPopup(false);
+ }}>
:
+ item.sender === 'me' ? :
//
// {item.senderName.substring(0, 3)}
//
}
- title={
-
- }
+ title={emailOrigin.subject}
description={`To: ${emailOrigin.toEmail}`}
/>
{emailOrigin.abstract}
)}
/>
-
+
>
);
};
const [openPopup, setOpenPopup] = useState(false);
- // todo: 实时请求列表
+
return (
<>