diff --git a/src/lib/msgUtils.js b/src/lib/msgUtils.js index 2ffb741..1860e34 100644 --- a/src/lib/msgUtils.js +++ b/src/lib/msgUtils.js @@ -31,7 +31,7 @@ export const sentMsgTypeMapped = { renderId: msg.id, to: msg.to, msgtype: 'text', - msgcontent: { body: msg.text, ...(msg.context ? { context: msg.context, message_origin: msg.message_origin } : {}) }, + msgcontent: { body: msg.text, ...(msg.context ? { context: msg.context, message_origin: msg.message_origin.msgOrigin } : {}) }, }), contentToRender: (msg) => ({ ...msg, @@ -39,7 +39,12 @@ export const sentMsgTypeMapped = { conversationid: msg.id.split('.')[0], ...(msg.context ? { - reply: { message: msg.message_origin.text, title: msg.message_origin.senderName || 'Reference' }, + reply: { + message: msg.message_origin.text, + title: msg.message_origin.senderName || 'Reference', + titleColor: msg.message_origin?.senderName !== 'me' ? '#a791ff' : "#128c7e", + // titleColor: "#a791ff", + }, } : {}), }), @@ -63,7 +68,7 @@ export const sentMsgTypeMapped = { conversationid: msg.id.split('.')[0], ...(msg.context ? { - reply: { message: msg.message_origin.text, title: msg.message_origin.senderName || 'Reference' }, + reply: { message: msg.message_origin.text, title: msg.message_origin.senderName || 'Reference', titleColor: "#a791ff", }, } : {}), }), @@ -91,7 +96,7 @@ const whatsappMsgMapped = { 'whatsapp.inbound_message.received': { getMsg: (result) => { console.log('whatsapp.inbound_message.received', result); - return isEmpty(result?.whatsappInboundMessage) ? null : { ...result.whatsappInboundMessage, conversationid: result.conversationid }; + return isEmpty(result?.whatsappInboundMessage) ? null : { ...result.whatsappInboundMessage, conversationid: result.conversationid, messageorigin: result.messageorigin }; }, contentToRender: (contentObj) => { console.log('whatsapp.inbound_message.received to render', contentObj); @@ -165,6 +170,7 @@ export const whatsappMsgTypeMapped = { text: { type: 'text', data: (msg) => ({ id: msg.wamid, text: msg.text.body }), + renderForReply: (msg) => ({ id: msg.wamid, message: msg.text.body }), }, image: { type: 'photo', @@ -216,7 +222,7 @@ export const whatsappMsgTypeMapped = { unsupported: { type: 'system', data: (msg) => ({ text: 'Message type is currently not supported.' }) }, reaction: { type: 'text', - data: (msg) => ({ id: msg.wamid, text: msg.reaction?.emoji || msg.reaction?.text?.body || 'Reaction', reply: { message: '{content}', title: 'React from', titleColor: '#1ba784' } }), // todo: + data: (msg) => ({ id: msg.wamid, text: msg.reaction?.emoji || '', }), }, document: { type: 'file', @@ -234,8 +240,8 @@ export const whatsappMsgTypeMapped = { return { id: msg.wamid, text: templateDataMapped?.body?.text || templateDataMapped?.body?.parameters?.[0]?.text || '', title: msg.template.name } }, renderForReply: (msg) => { - const templateDataMapped = msg.template?.components ? msg.template.components.reduce((r, v) => ({...r, [v.type]: v}), {}) : null; - return { id: msg.wamid, message: templateDataMapped?.body?.text || templateDataMapped?.body?.parameters?.[0]?.text || '', title: `${msg.template.name}` } + const templateDataMapped = msg.template?.components ? msg.template.components.reduce((r, v) => ({ ...r, [v.type]: v }), {}) : null; + return { id: msg.wamid, message: templateDataMapped?.body?.text || templateDataMapped?.body?.parameters?.[0]?.text || '', title: `${msg.template.name}` }; }, }, }; @@ -245,11 +251,13 @@ export const whatsappMsgTypeMapped = { export const parseRenderMessageItem = (msg) => { console.log('parseRenderMessageItem', msg); return { + msgOrigin: msg, date: msg?.sendTime || msg?.createTime || '', ...(whatsappMsgTypeMapped?.[msg.type]?.data(msg) || {}), conversationid: msg.conversationid, ...(typeof whatsappMsgTypeMapped[msg.type].type === 'function' ? whatsappMsgTypeMapped[msg.type].type(msg) : { type: whatsappMsgTypeMapped[msg.type].type || 'text' }), // type: whatsappMsgTypeMapped?.[msg.type]?.type || 'text', + from: msg.from, sender: msg.from, senderName: msg?.customerProfile?.name || msg.from, // title: msg.customerProfile.name, @@ -257,13 +265,18 @@ export const parseRenderMessageItem = (msg) => { whatsapp_name: msg?.customerProfile?.name || '', whatsapp_phone_number: msg.from, whatsapp_msg_type: msg.type, - ...(isEmpty(msg.context) + ...(isEmpty(msg.context) && isEmpty(msg.reaction) ? {} : { reply: { - message: `${msg.context.id}`, // todo: msg.context.text?.body || msg.context.text, - title: msg?.customerProfile?.name || msg.from, - titleColor: "#53bdeb", // "#128c7e", + /** + * reply: { message: msg.messageorigin, title: 'React from', titleColor: '#1ba784' } + */ + title: msg.messageorigin?.customerProfile?.name || 'me', + ...(typeof whatsappMsgTypeMapped[msg?.messageorigin?.type]?.renderForReply === 'function' + ? whatsappMsgTypeMapped[msg.messageorigin.type].renderForReply(msg.messageorigin) + : {}), + titleColor: msg.messageorigin?.customerProfile?.name ? '#a791ff' : "#128c7e", }, origin: msg.context, }), @@ -279,10 +292,12 @@ export const parseRenderMessageList = (messages, conversationid = null) => { const msgType = msgContent.type; // const parseMethod = msgContent.bizType === 'whatsapp' ? cloneDeep(whatsappMsgTypeMapped) : {}; return { + msgOrigin: msgContent, ...(whatsappMsgTypeMapped?.[msgType]?.data(msgContent) || {}), type: msgContent.type, ...(typeof whatsappMsgTypeMapped[msgType].type === 'function' ? whatsappMsgTypeMapped[msgType].type(msg) : { type: whatsappMsgTypeMapped[msgType].type || 'text' }), date: msgContent?.sendTime || msg.msgtime || '', + from: msgContent.from, sender: msgContent.from, senderName: msgContent?.customerProfile?.name || msgContent.from, ...(msg.msg_direction === 'outbound' @@ -298,11 +313,12 @@ export const parseRenderMessageList = (messages, conversationid = null) => { : { reply: { message: msg.messageorigin_AsJOSN.text?.body || msg.messageorigin_AsJOSN.text, - title: msg.messageorigin_AsJOSN.senderName || '@', // msg.messageorigin_AsJOSN.from + title: msg.messageorigin_AsJOSN?.customerProfile?.name || 'me', // msg.messageorigin_AsJOSN.senderName || '@', ...(typeof whatsappMsgTypeMapped[msg.messageorigin_AsJOSN.type]?.renderForReply === 'function' ? whatsappMsgTypeMapped[msg.messageorigin_AsJOSN.type].renderForReply(msg.messageorigin_AsJOSN) : {}), - titleColor: '#53bdeb', // "#128c7e", // todo: 原始消息的方向 + titleColor: msg.messageorigin_AsJOSN?.customerProfile?.name ? '#a791ff' : "#128c7e", + // titleColor: msg.messageorigin_direction === 'inbound' ? '#a791ff' : "#128c7e", }, origin: msg.messageorigin_AsJOSN, }), diff --git a/src/stores/ConversationStore.js b/src/stores/ConversationStore.js index 22e55d0..c815290 100644 --- a/src/stores/ConversationStore.js +++ b/src/stores/ConversationStore.js @@ -16,6 +16,7 @@ const initialConversationState = { // websocketRetrytimes: null, errors: [], // 错误信息 + initialState: false, // templates: [], @@ -26,7 +27,6 @@ const initialConversationState = { // referenceMsg: {}, }; -olog('initialConversationState'); export const templatesSlice = (set) => ({ templates: [], @@ -167,8 +167,11 @@ export const conversationSlice = (set, get) => ({ }); export const messageSlice = (set, get) => ({ + msgListLoading: false, activeConversations: {}, + setMsgLoading: (msgListLoading) => set({ msgListLoading }), receivedMessageList: (conversationid, msgList) => set((state) => ({ + msgListLoading: false, activeConversations: { ...state.activeConversations, [String(conversationid)]: msgList } })), updateMessageItem: (message) => { // msgUpdate @@ -250,18 +253,20 @@ export const useConversationStore = create(devtools((set, get) => ({ // state actions addError: (error) => set((state) => ({ errors: [...state.errors, error] })), + setInitial: (v) => set({ initialState: v }), // side effects fetchInitialData: async (userId) => { - olog('fetch init'); - const { addToConversationList, setTemplates } = get(); + const { addToConversationList, setTemplates, setInitial } = get(); const conversationsList = await fetchConversationsList({ opisn: userId }); addToConversationList(conversationsList); const templates = await fetchTemplates(); setTemplates(templates); + + setInitial(true); }, }))); -// window.store = useConversationStore; // debug: + export default useConversationStore; diff --git a/src/views/Conversations/ChatWindow.jsx b/src/views/Conversations/ChatWindow.jsx index 76dcda7..c498262 100644 --- a/src/views/Conversations/ChatWindow.jsx +++ b/src/views/Conversations/ChatWindow.jsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import { Layout, Spin, Button } from 'antd'; -import { RightCircleOutlined, RightOutlined, MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'; +import { RightCircleOutlined, RightOutlined, ReloadOutlined, MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'; // import { useParams, useNavigate } from 'react-router-dom'; import MessagesHeader from './Components/MessagesHeader'; import Messages from './Components/Messages'; @@ -52,9 +52,10 @@ const ChatWindow = () => { -
+
diff --git a/src/views/Conversations/Components/ConversationsList.jsx b/src/views/Conversations/Components/ConversationsList.jsx index de79ac8..a778263 100644 --- a/src/views/Conversations/Components/ConversationsList.jsx +++ b/src/views/Conversations/Components/ConversationsList.jsx @@ -3,11 +3,7 @@ import { useParams, useNavigate, useLocation } from 'react-router-dom'; import { Button, Dropdown } from 'antd'; import { MoreOutlined } from '@ant-design/icons'; import { useAuthContext } from '@/stores/AuthContext'; -import { - fetchOrderConversationsList, - fetchConversationItemClose, - fetchMessages, -} from '@/actions/ConversationActions'; +import { fetchOrderConversationsList, fetchConversationItemClose, fetchMessages } from '@/actions/ConversationActions'; import { ChatList, } from 'react-chat-elements'; import { isEmpty } from '@/utils/utils'; import useConversationStore from '@/stores/ConversationStore'; @@ -50,7 +46,7 @@ const Conversations = () => { const navigate = useNavigate(); const { loginUser } = useAuthContext(); const { userId } = loginUser; - const { activeConversations, currentConversation, conversationsList, addToConversationList, setCurrentConversation, receivedMessageList, } = useConversationStore(); + const { initialState, activeConversations, currentConversation, conversationsList, addToConversationList, setCurrentConversation, receivedMessageList, setMsgLoading } = useConversationStore(); const [chatlist, setChatlist] = useState([]); useEffect(() => { setChatlist( @@ -80,12 +76,12 @@ const Conversations = () => { const [shouldFetchCList, setShouldFetchCList] = useState(true); useEffect(() => { - if (order_sn && shouldFetchCList) { + if (order_sn && shouldFetchCList && initialState) { getOrderConversationList(order_sn); } return () => {}; - }, [order_sn, shouldFetchCList]); + }, [order_sn, shouldFetchCList, initialState]); const getOrderConversationList = async (colisn) => { const { whatsapp_phone_number } = switchToC; @@ -93,19 +89,26 @@ const Conversations = () => { const data = await fetchOrderConversationsList({ opisn: userId, colisn: colisn, whatsappid: whatsappID }); if (!isEmpty(data)) { addToConversationList(data); - const ifCurrent = data.findIndex((item) => item.sn === currentConversation.sn); - switchConversation(data[ifCurrent === -1 ? 0 : ifCurrent]); + } + // const ifCurrent = data.findIndex((item) => item.sn === currentConversation.sn); + const ifCurrent = conversationsList.findIndex((item) => item.coli_sn === Number(colisn)); + if (ifCurrent !== -1) { + switchConversation(conversationsList[ifCurrent === -1 ? 0 : ifCurrent]); } else { // reset chat window setCurrentConversation({ sn: '', customer_name: '', coli_sn: order_sn }); return false; } }; + const getMessages = async (item) => { + setMsgLoading(true); + const data = await fetchMessages({ opisn: userId, whatsappid: item.whatsapp_phone_number }); + receivedMessageList(item.sn, data); + }; const switchConversation = async (item) => { const messagesList = activeConversations[`${item.sn}`] || []; - if (isEmpty(messagesList)) { - const data = await fetchMessages({ opisn: userId, whatsappid: item.whatsapp_phone_number }); - receivedMessageList(item.sn, data); + if (messagesList.length < 20) { + await getMessages(item); } if (String(item.sn) === String(currentConversation.sn)) { return false; diff --git a/src/views/Conversations/Components/InputComposer.jsx b/src/views/Conversations/Components/InputComposer.jsx index 5e70192..35f73a7 100644 --- a/src/views/Conversations/Components/InputComposer.jsx +++ b/src/views/Conversations/Components/InputComposer.jsx @@ -71,7 +71,8 @@ const InputBox = () => {
{referenceMsg.id && ( -
{referenceMsg.text}
+
+ {referenceMsg.senderName}{referenceMsg.text}