diff --git a/src/main.jsx b/src/main.jsx
index d14fa16..f36e216 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -28,7 +28,7 @@ const router = createBrowserRouter([
element: ,
errorElement: ,
children: [
- {
+ {
element: ,
children: [
{ index: true, element: },
@@ -40,11 +40,12 @@ const router = createBrowserRouter([
{ path: 'account/profile', element: },
]
},
- {
- path: 'm',
+ {
+ path: 'm',
element: ,
children: [
{ path: 'conversation', element: },
+ { path: 'chat/:order_sn', element: },
{ path: 'chat', element: },
]
},
diff --git a/src/views/Conversations/Components/ConversationsList.jsx b/src/views/Conversations/Components/ConversationsList.jsx
index 675653d..83c0736 100644
--- a/src/views/Conversations/Components/ConversationsList.jsx
+++ b/src/views/Conversations/Components/ConversationsList.jsx
@@ -10,7 +10,8 @@ import useAuthStore from '@/stores/AuthStore';
/**
* []
*/
-const Conversations = () => {
+const Conversations = ({ mobile }) => {
+ const routerReplace = mobile === undefined ? false : true;
const { state: orderRow } = useLocation();
const { coli_guest_WhatsApp } = orderRow || {};
const { order_sn } = useParams();
@@ -22,8 +23,6 @@ const Conversations = () => {
const conversationsList = useConversationStore((state) => state.conversationsList);
const addToConversationList = useConversationStore((state) => state.addToConversationList);
const delConversationitem = useConversationStore((state) => state.delConversationitem);
- const receivedMessageList = useConversationStore((state) => state.receivedMessageList);
- const setMsgLoading = useConversationStore((state) => state.setMsgLoading);
const [tabSelectedConversation, setTabSelectedConversation] = useState({});
const [tabCnt, setTabCnt] = useState(-1);
@@ -70,34 +69,16 @@ const Conversations = () => {
return false;
}
};
- const getMessages = async (item) => {
- setMsgLoading(true);
- const data = await fetchMessages({ opisn: userId, whatsappid: item.whatsapp_phone_number, lasttime: '' });
- setMsgLoading(false);
- receivedMessageList(item.sn, data);
- const thisLastTime = data.length > 0 ? data[0].orgmsgtime : '';
- const loadNextPage = !(data.length === 0 || data.length < MESSAGE_PAGE_SIZE);
- updateCurrentConversation({ lasttime: thisLastTime, loadNextPage });
- };
-
- useEffect(() => {
- const messagesList = activeConversations[`${currentConversation.sn}`] || [];
- if (currentConversation.sn && messagesList.length < 20) {
- getMessages(currentConversation);
- }
-
- return () => {};
- }, [currentConversation.sn]);
-
const onSwitchConversation = async (item) => {
setCurrentConversation(item);
+ const routePrefix = mobile === undefined ? `/order/chat` : `/m/chat`;
if (isEmpty(item.coli_sn)) {
- navigate(`/order/chat`, { replace: true });
+ navigate(routePrefix, { replace: true });
} else {
setSwitchToC(item);
setShouldFetchCList(false);
- navigate(`/order/chat/${item.coli_sn}`, { replace: true });
+ navigate(`${routePrefix}/${item.coli_sn}`, { replace: routePrefix });
}
// if (!isEmpty(item.coli_sn)) {
// setSwitchToC(item);
@@ -113,7 +94,7 @@ const Conversations = () => {
await fetchConversationItemClose({ conversationid: item.sn, opisn: item.opi_sn });
delConversationitem(item);
if (String(order_sn) === String(item.coli_sn)) {
- navigate(`/order/chat`, { replace: true });
+ navigate(`/order/chat`, { replace: routerReplace });
}
};
diff --git a/src/views/Conversations/Components/Input/Emoji.jsx b/src/views/Conversations/Components/Input/Emoji.jsx
index 0c6d26c..157eb6e 100644
--- a/src/views/Conversations/Components/Input/Emoji.jsx
+++ b/src/views/Conversations/Components/Input/Emoji.jsx
@@ -2,7 +2,7 @@ import { useState } from 'react';
import { Popover, Button } from 'antd';
import EmojiPicker from 'emoji-picker-react';
-const InputTemplate = ({ disabled = false, inputEmoji }) => {
+const InputTemplate = ({ mobile, disabled = false, inputEmoji }) => {
const [openPopup, setOpenPopup] = useState(false);
const handlePickEmoji = (emojiData) => {
@@ -13,7 +13,7 @@ const InputTemplate = ({ disabled = false, inputEmoji }) => {
<>
}
diff --git a/src/views/Conversations/Components/Input/Template.jsx b/src/views/Conversations/Components/Input/Template.jsx
index ad257cb..8049cf8 100644
--- a/src/views/Conversations/Components/Input/Template.jsx
+++ b/src/views/Conversations/Components/Input/Template.jsx
@@ -20,7 +20,7 @@ const splitTemplate = (template) => {
}, []);
return obj;
};
-const InputTemplate = ({ disabled = false, invokeSendMessage }) => {
+const InputTemplate = ({ mobile, disabled = false, invokeSendMessage }) => {
const searchInputRef = useRef(null);
const { notification } = App.useApp();
const loginUser = useAuthStore((state) => state.loginUser);
@@ -126,7 +126,7 @@ const InputTemplate = ({ disabled = false, invokeSendMessage }) => {
return (
<>
{
- const userId = useAuthStore(state => state.loginUser.userId);
- const websocket = useConversationStore(state => state.websocket);
- const websocketOpened = useConversationStore(state => state.websocketOpened);
- const currentConversation = useConversationStore(state => state.currentConversation);
- const [referenceMsg, setReferenceMsg] = useConversationStore(state => [state.referenceMsg, state.setReferenceMsg]);
- const [complexMsg, setComplexMsg] = useConversationStore(state => [state.complexMsg, state.setComplexMsg]);
- const sentOrReceivedNewMessage = useConversationStore(state => state.sentOrReceivedNewMessage);
+const InputComposer = ({ mobile }) => {
+ const userId = useAuthStore((state) => state.loginUser.userId);
+ const websocket = useConversationStore((state) => state.websocket);
+ const websocketOpened = useConversationStore((state) => state.websocketOpened);
+ const currentConversation = useConversationStore((state) => state.currentConversation);
+ const [referenceMsg, setReferenceMsg] = useConversationStore((state) => [state.referenceMsg, state.setReferenceMsg]);
+ const [complexMsg, setComplexMsg] = useConversationStore((state) => [state.complexMsg, state.setComplexMsg]);
+ const sentOrReceivedNewMessage = useConversationStore((state) => state.sentOrReceivedNewMessage);
const talkabled = !isEmpty(currentConversation.sn) && websocketOpened;
const gt24h = currentConversation.last_received_time ? dayjs().diff(dayjs(currentConversation.last_received_time), 'hour') > 24 : true;
@@ -120,15 +120,14 @@ const InputComposer = () => {
const contentToSend = sentMsgTypeMapped[msgObjMerge.type].contentToSend(msgObjMerge);
// olog('invoke upload send +++ ', contentToSend)
websocket.sendMessage({ ...contentToSend, opi_sn: userId, coli_sn: currentConversation.coli_sn });
- }
-
+ };
const { message } = App.useApp();
const [pastedUploading, setPastedUploading] = useState(false);
const readPasted = async (file, rename = false) => {
// 使用 FileReader 读取文件对象
const reader = new FileReader();
- const suffix = file.name.slice(file.name.lastIndexOf('.')+1);
+ const suffix = file.name.slice(file.name.lastIndexOf('.') + 1);
const newName = `${uuid()}.${suffix}`; // rename ? `${uuid()}.${suffix}` : file.name;
const type = Object.keys(fileTypesExt).find((type) => fileTypesExt[type].includes(suffix));
const dataUri = aliOSSHost + newName;
@@ -161,7 +160,7 @@ const InputComposer = () => {
let isNotFile = true;
for (let i = 0; i < items.length; i++) {
// if (items[i].type.indexOf("image") !== -1) {
- if (items[i].kind.indexOf("file") !== -1) {
+ if (items[i].kind.indexOf('file') !== -1) {
isNotFile = false;
tmpfile = items[i].getAsFile();
break;
@@ -180,17 +179,17 @@ const InputComposer = () => {
setComplexMsg(_tmpFile.msgData);
setPastedUploading(true);
const { file_url } = await postUploadFileItem(tmpfile, _tmpFile.newName);
- setPastedUploading(false);
- setComplexMsg({..._tmpFile.msgData, uploadStatus: file_url ? 'done' : 'error'});
+ setPastedUploading(false); // todo: 更新data uri
+ setComplexMsg({ ..._tmpFile.msgData, uploadStatus: file_url ? 'done' : 'error' });
return;
- }
+ };
const focusInput = () => {
- textInputRef.current.focus({ cursor: 'end', preventScroll: true, });
+ textInputRef.current.focus({ cursor: 'end', preventScroll: true });
};
- const addEmoji = emoji => {
- setTextContent(prevValue => {
+ const addEmoji = (emoji) => {
+ setTextContent((prevValue) => {
return prevValue + emoji;
});
};
@@ -248,7 +247,9 @@ const InputComposer = () => {
{
/>
-
-
+
+
{/* } size={'middle'} />
} size={'middle'} />
diff --git a/src/views/Conversations/Components/MessagesWrapper.jsx b/src/views/Conversations/Components/MessagesWrapper.jsx
index 815d64b..9bf5669 100644
--- a/src/views/Conversations/Components/MessagesWrapper.jsx
+++ b/src/views/Conversations/Components/MessagesWrapper.jsx
@@ -6,13 +6,20 @@ import MessagesList from './MessagesList';
import { fetchCleanUnreadMsgCount, fetchMessages, MESSAGE_PAGE_SIZE } from '@/actions/ConversationActions';
import { fetchOrderConversationsList, } from '@/actions/ConversationActions';
import { isEmpty } from '@/utils/utils';
+import useAuthStore from '@/stores/AuthStore';
const MessagesWrapper = () => {
+ const userId = useAuthStore((state) => state.loginUser.userId);
+
const [currentConversation, updateCurrentConversation, setCurrentConversation] = useConversationStore(useShallow((state) => [state.currentConversation, state.updateCurrentConversation, state.setCurrentConversation]));
const conversationsList = useConversationStore(useShallow((state) => state.conversationsList));
+ const activeConversations = useConversationStore(useShallow((state) => state.activeConversations));
const activeMessages = useConversationStore(useShallow((state) => (state.currentConversation.sn && state.activeConversations[state.currentConversation.sn] ? state.activeConversations[state.currentConversation.sn]: [])));
const addToConversationList = useConversationStore((state) => state.addToConversationList);
+ const receivedMessageList = useConversationStore((state) => state.receivedMessageList);
+ const setMsgLoading = useConversationStore((state) => state.setMsgLoading);
+
const [longList, setLongList] = useState([]);
const [longListLoading, setLongListLoading] = useState(false);
const [shouldScrollBottom, setShouldScrollBottom] = useState(true);
@@ -29,6 +36,26 @@ const MessagesWrapper = () => {
return () => {};
}, [activeMessages, currentConversation.sn]);
+
+ const getMessages = async (item) => {
+ setMsgLoading(true);
+ const data = await fetchMessages({ opisn: userId, whatsappid: item.whatsapp_phone_number, lasttime: '' });
+ setMsgLoading(false);
+ receivedMessageList(item.sn, data);
+ const thisLastTime = data.length > 0 ? data[0].orgmsgtime : '';
+ const loadNextPage = !(data.length === 0 || data.length < MESSAGE_PAGE_SIZE);
+ updateCurrentConversation({ lasttime: thisLastTime, loadNextPage });
+ };
+
+ useEffect(() => {
+ const messagesList = activeConversations[`${currentConversation.sn}`] || [];
+ if (currentConversation.sn && messagesList.length < 20) {
+ getMessages(currentConversation);
+ }
+
+ return () => {};
+ }, [currentConversation.sn]);
+
const getMoreMessages = async () => {
setShouldScrollBottom(false);
setLongListLoading(true);
diff --git a/src/views/Conversations/Conversations.css b/src/views/Conversations/Conversations.css
index 950cf7b..3f8fba6 100644
--- a/src/views/Conversations/Conversations.css
+++ b/src/views/Conversations/Conversations.css
@@ -182,8 +182,11 @@
{
display: inline-block;
}
+.chatwindow-wrapper .rce-mbox-file>button{
+ width: 100%;
+}
-/** Chat history */
+/** Chat history ------------------------------------------------------------------------------------ */
/* .chathistory-wrapper .rce-mbox-time {
user-select: auto;
-webkit-user-select: auto;
@@ -214,3 +217,15 @@
animation-name: message-box-default-focus-x;
animation-duration: 1s;
}
+
+
+/**
+ * Mobile chat ------------------------------------------------------------------------------------
+ */
+.mobilechat-wrapper .rce-container-mbox .rce-mbox{
+ max-width: 320px;
+}
+.mobilechat-wrapper .rce-mtlink,
+.mobilechat-wrapper .rce-mtlink-item{
+ min-width: unset;
+}
diff --git a/src/views/mobile/Chat.jsx b/src/views/mobile/Chat.jsx
index 954927c..82d0c67 100644
--- a/src/views/mobile/Chat.jsx
+++ b/src/views/mobile/Chat.jsx
@@ -1,68 +1,26 @@
-import { memo, useCallback, useEffect, useRef, useState, forwardRef } from 'react'
-import { App, Avatar, List, Layout, Input, DatePicker, Button, Spin } from 'antd'
-import { ChatItem, MessageBox } from 'react-chat-elements'
-import { fetchConversationsList, fetchMessages, MESSAGE_PAGE_SIZE } from '@/actions/ConversationActions'
-import { isEmpty } from '@/utils/utils'
-import useFormStore from '@/stores/FormStore'
-import { useShallow } from 'zustand/react/shallow'
+import { Layout } from 'antd';
+import MessagesHeader from '@/views/Conversations/Components/MessagesHeader';
+import MessagesWrapper from '@/views/Conversations/Components/MessagesWrapper';
+import InputComposer from '@/views/Conversations/Components/InputComposer';
-
-import { RightOutlined } from '@ant-design/icons'
-
-import { fetchSalesAgent, fetchCustomerList } from '@/actions/CommonActions'
-import SearchInput from '@/components/SearchInput'
-
-const { Sider, Content, Header, Footer } = Layout
-const { TextArea } = Input
-const { RangePicker } = DatePicker
-
-const data = [
- {
- title: 'Tyler Dru Kelly',
- avatarUrl: 'https://api.dicebear.com/7.x/miniavs/svg?seed=' + Math.random() * 10000,
- msgTime: 'Hi Nazly Parlindungan Siregar, this is Sharon , travel advisor of Asia Highlights. We got your inquiry for your trip toJapan , are you available for a quick chat to discuss about your trip? I have some ideas to share with you . Looking forward to talking with you!',
- },
- {
- title: 'Chhavi',
- avatarUrl: 'https://api.dicebear.com/7.x/miniavs/svg?seed=' + Math.random() * 10000,
- msgTime: 'Hi Sharon, thanks for reaching out. I am extremely busy person, please feel free to write down or send me any note and I will respond to you immediately. Cheers🙏',
- },
- {
- title: 'Nathan Posey',
- avatarUrl: 'https://api.dicebear.com/7.x/miniavs/svg?seed=' + Math.random() * 10000,
- msgTime: 'It is too late to see cherry blossom from April 28, is it ok for you? For your 7 days tour, visit Tokyo and Kyoto is ok. I will suggest a tour with private car for you because your mother cannot walk too much.',
- },
-]
+const { Content, Header, Footer } = Layout;
function Chat() {
- const { notification } = App.useApp()
return (
<>
- (
-
- }
- title={{item.title}}
- description={item.msgTime}
- />
-
-
- )}
- />
-
-
+
+
+
+
+
+
+
>
- )
+ );
}
-export default Chat
+export default Chat;
diff --git a/src/views/mobile/Conversation.jsx b/src/views/mobile/Conversation.jsx
index 4536692..d49ab26 100644
--- a/src/views/mobile/Conversation.jsx
+++ b/src/views/mobile/Conversation.jsx
@@ -1,90 +1,12 @@
-import { memo, useCallback, useEffect, useRef, useState, forwardRef } from 'react'
-import { Avatar, List, Button, Input, Layout, Select, DatePicker, Form, Spin } from 'antd'
-import { ChatItem, MessageBox } from 'react-chat-elements'
-import { fetchConversationsList, fetchMessages, MESSAGE_PAGE_SIZE } from '@/actions/ConversationActions'
-import { isEmpty } from '@/utils/utils'
-import useFormStore from '@/stores/FormStore'
-import { useShallow } from 'zustand/react/shallow'
-import { useNavigate, useHref } from 'react-router-dom'
+import ConversationsList from '@/views/Conversations/Components/ConversationsList';
-
-import { RightOutlined } from '@ant-design/icons'
-
-import { fetchSalesAgent, fetchCustomerList } from '@/actions/CommonActions'
-import SearchInput from '@/components/SearchInput'
-
-const { Sider, Content, Header, Footer } = Layout
-const { Search } = Input
-const { RangePicker } = DatePicker
-
-const data = [
- {
- title: 'Tyler Dru Kelly',
- avatarUrl: 'https://api.dicebear.com/7.x/miniavs/svg?seed=' + Math.random() * 10000,
- msgTime: '15127570944',
- },
- {
- title: 'Chhavi',
- avatarUrl: 'https://api.dicebear.com/7.x/miniavs/svg?seed=' + Math.random() * 10000,
- msgTime: 'WLJ240311112',
- },
- {
- title: 'Nathan Posey',
- avatarUrl: 'https://api.dicebear.com/7.x/miniavs/svg?seed=' + Math.random() * 10000,
- msgTime: 'WLJ240311114',
- },
- {
- title: 'Philip',
- avatarUrl: 'https://api.dicebear.com/7.x/miniavs/svg?seed=' + Math.random() * 10000,
- msgTime: 'WLJ240312062',
- },
- {
- title: 'Jeanne',
- avatarUrl: 'https://api.dicebear.com/7.x/miniavs/svg?seed=' + Math.random() * 10000,
- msgTime: 'H240313032',
- },
- {
- title: 'Susan Puls',
- avatarUrl: 'https://api.dicebear.com/7.x/miniavs/svg?seed=' + Math.random() * 10000,
- msgTime: 'H240311213',
- },
- {
- title: 'Ana Beatriz',
- avatarUrl: 'https://api.dicebear.com/7.x/miniavs/svg?seed=' + Math.random() * 10000,
- msgTime: 'H240312073',
- },
- {
- title: 'Kathleen Anne Workman',
- avatarUrl: 'https://api.dicebear.com/7.x/miniavs/svg?seed=' + Math.random() * 10000,
- msgTime: 'HXY240104171',
- },
-]
-
-function Login() {
- const navigate = useNavigate()
+function Conversation() {
return (
- <>
- (
- {
- navigate('/m/chat')}}
- actions={[]}
- >
- }
- title={{item.title}}
- description={item.msgTime}
- />
-
-
- )}
- />
- >
+
+
+
)
}
-export default Login
+export default Conversation