From 3f36c648f91fd6c7b7fd7ffd29c1e1d44f9bec0c Mon Sep 17 00:00:00 2001 From: Lei OT Date: Thu, 10 Oct 2024 15:28:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B6=88=E6=81=AF=E7=AD=9B=E9=80=89:=20?= =?UTF-8?q?=E5=AE=9E=E6=97=B6=E8=AF=B7=E6=B1=82;=20=E6=89=93=E5=BC=80?= =?UTF-8?q?=E8=A7=86=E9=A2=91=E6=92=AD=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DndModal.jsx | 61 +++++ .../Online/Components/MessageListFilter.jsx | 214 ++++++++++++------ 2 files changed, 210 insertions(+), 65 deletions(-) create mode 100644 src/components/DndModal.jsx 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 ( <>