From be24c964e066e84d885ec18bff85d95067ee787a Mon Sep 17 00:00:00 2001 From: Lei OT Date: Mon, 19 Feb 2024 15:18:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=20useReducer=20=E7=9A=84=20C?= =?UTF-8?q?onversationContext,=20Action,=20Reducer,=20Provider?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/actions/ConversationActions.js | 98 ----------- src/main.jsx | 5 +- src/records/ConversationState.js | 18 -- src/reducers/ConversationReducer.js | 156 ------------------ src/stores/ConversationContext.js | 12 -- .../Conversations/ConversationProvider.jsx | 102 ------------ 6 files changed, 1 insertion(+), 390 deletions(-) delete mode 100644 src/records/ConversationState.js delete mode 100644 src/reducers/ConversationReducer.js delete mode 100644 src/stores/ConversationContext.js delete mode 100644 src/views/Conversations/ConversationProvider.jsx diff --git a/src/actions/ConversationActions.js b/src/actions/ConversationActions.js index 79d391b..5daa6f6 100644 --- a/src/actions/ConversationActions.js +++ b/src/actions/ConversationActions.js @@ -5,104 +5,6 @@ import { parseRenderMessageList } from '@/lib/msgUtils'; const API_HOST = 'https://p9axztuwd7x8a7.mycht.cn/whatsapp_callback'; -const NAME_SPACE = 'CONVERSATION/'; -export const initWebsocket = (socket) => ({ - type: NAME_SPACE + 'INIT_WEBSOCKET', - payload: socket, -}); -export const closeWebsocket0 = () => ({ - type: NAME_SPACE + 'CLOSE_WEBSOCKET', - payload: null, -}); -export const updateWebsocketState = (v) => ({ - type: NAME_SPACE + 'MODIFY_WEBSOCKET_STATE', - payload: v, -}); -export const updateWebsocketRetrytimes = (v) => ({ - type: NAME_SPACE + 'MODIFY_WEBSOCKET_RETRYTIMES', - payload: v, -}); - -export const receivedNewMessage = (targetId, message) => ({ - type: NAME_SPACE + 'RECEIVED_NEW_MESSAGE', - payload: { - targetId, - message, - }, -}); -export const sentNewMessage = (message) => ({ - type: NAME_SPACE + 'SENT_NEW_MESSAGE', - payload: { - targetId: message.conversationid, - message, - }, -}); - -export const addError = (error) => { - return { - type: NAME_SPACE + 'ADD_ERROR', - payload: error, - }; -}; - -export const receivedTemplates = (data) => ({ - type: NAME_SPACE + 'SET_TEMPLATE_LIST', - payload: data, -}); - -export const receivedConversationList = (data) => { - return { - type: NAME_SPACE + 'SET_CONVERSATION_LIST', - payload: data, - }; -}; -export const addConversationList = (data) => { - return { - type: NAME_SPACE + 'ADD_TO_CONVERSATIONS_LIST', - payload: data, - }; -}; -export const delConversationitem = (data) => { - return { - type: NAME_SPACE + 'DEL_CONVERSATIONS_ITEM', - payload: data, - }; -}; -// export const updateConversationListItemNew = (message) => ({ -// type: NAME_SPACE + 'UPDATE_CONVERSATION_LIST_ITEM_NEW', -// payload: message, -// }); - -export const receivedCustomerProfile = (data) => ({ - type: NAME_SPACE + 'SET_CUSTOMER_ORDER_PROFILE', - payload: data, -}); -/** - * @deprecated 在更新list时操作 - */ -export const setActiveConversations = (obj) => ({ - type: NAME_SPACE + 'SET_ACTIVE_CONVERSATIONS', - payload: obj, -}); -export const setCurrentConversation = (obj) => ({ - type: NAME_SPACE + 'SET_CURRENT_CONVERSATION', - payload: obj, -}); -export const updateMessageItem = (message) => ({ - type: NAME_SPACE + 'UPDATE_SENT_MESSAGE_ITEM', - payload: message, -}); -export const receivedMessageList = (targetId, data) => ({ - type: NAME_SPACE + 'RECEIVED_MESSAGE_LIST', - payload: { targetId, data }, -}) -export const setReplyTo = (data) => { - return { - type: NAME_SPACE + 'SET_REFERENCE_MSG', - payload: data, - }; -}; - export const fetchTemplates = async () => { const data = await fetchJSON(`${API_HOST}/listtemplates`); const canUseTemplates = (data?.result?.items || []) diff --git a/src/main.jsx b/src/main.jsx index 8f72496..e63a94d 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -3,7 +3,6 @@ import ReactDOM from 'react-dom/client' import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import { AuthContext } from '@/stores/AuthContext' import { ThemeContext } from '@/stores/ThemeContext' -import ConversationProvider from '@/views/Conversations/ConversationProvider' import AuthApp from '@/views/AuthApp' import Standlone from '@/views/Standlone' import OrderFollow from '@/views/OrderFollow' @@ -43,9 +42,7 @@ ReactDOM.createRoot(document.getElementById('root')).render( // - {/* */} -
Loading...
} /> - {/*
*/} +
Loading...
} />
//
diff --git a/src/records/ConversationState.js b/src/records/ConversationState.js deleted file mode 100644 index 0a150bd..0000000 --- a/src/records/ConversationState.js +++ /dev/null @@ -1,18 +0,0 @@ -const initialState = { - websocket: null, - websocketOpened: null, - websocketRetrying: null, - websocketRetrytimes: null, - - errors: [], // 错误信息 - - conversationsList: [], // 对话列表 - templates: [], - customerOrderProfile: {}, - - activeConversations: {}, // 激活的对话的消息列表: { [conversationId]: [] } - currentConversation: {}, // 当前对话 - - referenceMsg: {}, -}; -export default initialState; diff --git a/src/reducers/ConversationReducer.js b/src/reducers/ConversationReducer.js deleted file mode 100644 index 357a0d8..0000000 --- a/src/reducers/ConversationReducer.js +++ /dev/null @@ -1,156 +0,0 @@ -import initialState from '@/records/ConversationState'; - -const NAME_SPACE = 'CONVERSATION/'; - -const ConversationReducer = (state = initialState, action) => { - switch (action.type) { - case NAME_SPACE + 'INIT_WEBSOCKET': - return { ...state, websocket: action.payload }; - case NAME_SPACE + 'MODIFY_WEBSOCKET_STATE': - return { ...state, websocketOpened: action.payload, }; - case NAME_SPACE + 'MODIFY_WEBSOCKET_RETRYTIMES': - return { ...state, websocketRetrytimes: action.payload, websocketRetrying: action.payload > 0 }; - - case NAME_SPACE + 'SET_CONVERSATION_LIST':{ - const conversationsMapped = action.payload.reduce((r, v) => ({ ...r, [`${v.sn}`]: [] }), {}); - return { ...state, conversationsList: action.payload, activeConversations: conversationsMapped }; - } - case NAME_SPACE + 'ADD_TO_CONVERSATIONS_LIST':{ - const { activeConversations } = state; - const conversationsIds = Object.keys(activeConversations); - const newConversations = action.payload.filter((conversation) => !conversationsIds.includes(`${conversation.sn}`)); - const newConversationsMapped = newConversations.reduce((r, v) => ({ ...r, [`${v.sn}`]: [] }), {}); - - return { - ...state, - conversationsList: [...newConversations, ...state.conversationsList], - activeConversations: { ...activeConversations, ...newConversationsMapped }, - }; - } - case NAME_SPACE + 'DEL_CONVERSATIONS_ITEM': { - const { conversationsList, activeConversations, currentConversation, customerOrderProfile } = state; - const targetId = action.payload.sn; - const targetIndex = conversationsList.findIndex((ele) => String(ele.sn) === String(targetId)); - conversationsList.splice(targetIndex, 1); - return { - ...state, - conversationsList: [...conversationsList], - activeConversations: { ...activeConversations, [`${targetId}`]: [] }, - currentConversation: {}, - customerOrderProfile: {}, - }; - } - - case NAME_SPACE + 'SET_TEMPLATE_LIST': - return { ...state, templates: action.payload }; - - case NAME_SPACE + 'SET_CUSTOMER_ORDER_PROFILE': - return { ...state, customerOrderProfile: action.payload }; - - case NAME_SPACE + 'SET_CURRENT_CONVERSATION': { - // 清空未读 - const { conversationsList } = state; - const targetId = action.payload.sn; - const targetIndex = conversationsList.findIndex((ele) => String(ele.sn) === String(targetId)); - targetIndex !== -1 ? conversationsList.splice(targetIndex, 1, { - ...conversationsList[targetIndex], - unread_msg_count: 0, - }) : null; - - return { ...state, currentConversation: action.payload, conversationsList: [...conversationsList] }; - } - case NAME_SPACE + 'SET_ACTIVE_CONVERSATIONS': { - const { activeConversations } = state; - return { ...state, activeConversations: { ...activeConversations, ...action.payload } }; - } - case NAME_SPACE + 'UPDATE_SENT_MESSAGE_ITEM': { - console.log('UPDATE_SENT_MESSAGE_ITEM-----------------------------------------------------------------', action); - // 更新会话中的消息 - const { activeConversations, conversationsList, } = state; - const message = action.payload; - const targetId = message.conversationid; - const targetMsgs = (activeConversations[String(targetId)] || []).map((ele) => { - // 更新状态 - // * 已读的不再更新状态, 有时候投递结果在已读之后返回 - if (ele.id === ele.actionId && ele.actionId === message.actionId) { - return { ...ele, id: message.id, status: ele.status === 'read' ? ele.status : message.status, dateString: message.dateString }; - } else if (ele.id === message.id) { - return { ...ele, id: message.id, status: ele.status === 'read' ? ele.status : message.status, dateString: message.dateString }; - } - return ele; - }); - // 显示会话中其他客户端发送的消息 - const targetMsgsIds = targetMsgs.map((ele) => ele.id); - if ( ! targetMsgsIds.includes(message.id)) { - targetMsgs.push(message); - } - - // 更新列表的时间 - if (message.type !== 'error') { - const targetIndex = conversationsList.findIndex((ele) => String(ele.sn) === String(targetId)); - conversationsList.splice(targetIndex, 1, { - ...conversationsList[targetIndex], - last_received_time: message.date, - }); - } - - return { - ...state, - activeConversations: { ...state.activeConversations, [String(targetId)]: targetMsgs }, - conversationsList: [...conversationsList], - }; - } - case NAME_SPACE + 'RECEIVED_MESSAGE_LIST': { - const { targetId, data } = action.payload; - return { - ...state, - activeConversations: { ...state.activeConversations, [String(targetId)]: data }, - }; - } - case NAME_SPACE + 'SENT_NEW_MESSAGE': - case NAME_SPACE + 'RECEIVED_NEW_MESSAGE': { - const { activeConversations, conversationsList, currentConversation } = state; - const { targetId, message } = action.payload; - const targetMsgs = activeConversations[String(targetId)] || []; - const targetIndex = conversationsList.findIndex((ele) => String(ele.sn) === String(targetId)); - const newConversation = - targetId !== -1 - ? { - ...conversationsList[targetIndex], - last_received_time: message.date, - unread_msg_count: - String(targetId) !== String(currentConversation.sn) && message.sender !== 'me' - ? conversationsList[targetIndex].unread_msg_count + 1 - : conversationsList[targetIndex].unread_msg_count, - } - : { - ...message, - sn: targetId, - last_received_time: message.date, - unread_msg_count: message.sender === 'me' ? 0 : 1, - }; - conversationsList.splice(targetIndex, 1); - conversationsList.unshift(newConversation); - return { - ...state, - activeConversations: { ...activeConversations, [String(targetId)]: [...targetMsgs, message] }, - conversationsList: [...conversationsList], - currentConversation: { - ...state.currentConversation, - last_received_time: String(targetId) === String(currentConversation.sn) ? message.date : currentConversation.last_received_time, - }, - }; - } - case NAME_SPACE + 'SET_REFERENCE_MSG': - return {...state, referenceMsg: action.payload}; - case NAME_SPACE + 'ADD_ERROR': { - console.log('add error', state.errors, action.payload); - const prelist = state.errors || []; - return { ...state, errors: [...prelist, action.payload] }; - } - default: - // throw new Error(`Unknown action: ${action.type}`); - return state; - } -}; -export default ConversationReducer; diff --git a/src/stores/ConversationContext.js b/src/stores/ConversationContext.js deleted file mode 100644 index dca607c..0000000 --- a/src/stores/ConversationContext.js +++ /dev/null @@ -1,12 +0,0 @@ -import {createContext, useContext} from 'react'; - -export const ConversationContext = createContext(); - -export const useConversationContext = () => useContext(ConversationContext); - - -export const ConversationStateContext = createContext(); -export const ConversationDispatchContext = createContext(); - -export const useConversationState = () => useContext(ConversationStateContext); -export const useConversationDispatch = () => useContext(ConversationDispatchContext); diff --git a/src/views/Conversations/ConversationProvider.jsx b/src/views/Conversations/ConversationProvider.jsx deleted file mode 100644 index 85a0e59..0000000 --- a/src/views/Conversations/ConversationProvider.jsx +++ /dev/null @@ -1,102 +0,0 @@ -import { useContext, useReducer, useEffect } from 'react'; -import { ConversationStateContext, ConversationDispatchContext } from '@/stores/ConversationContext'; -import ConversationReducer from '@/reducers/ConversationReducer'; -import { - initWebsocket, - updateWebsocketState, - updateWebsocketRetrytimes, - addError, - fetchConversationsList, - fetchTemplates, - receivedConversationList, - receivedTemplates, - updateMessageItem, - receivedNewMessage, -} from '@/actions/ConversationActions'; -import initialState from '@/records/ConversationState'; - -import { AuthContext } from '@/stores/AuthContext'; - -import { RealTimeAPI } from '@/lib/realTimeAPI'; -import { receivedMsgTypeMapped } from '@/lib/msgUtils'; -import { isEmpty } from '@/utils/utils'; - -// const WS_URL = 'ws://202.103.68.144:8888/whatever/'; -// const WS_URL = 'ws://120.79.9.217:10022/whatever/'; -const WS_URL = 'wss://p9axztuwd7x8a7.mycht.cn/whatsapp_callback'; // prod: - -const ConversationProvider = ({ children }) => { - const { loginUser } = useContext(AuthContext); - const { userId } = loginUser; - - const [state, dispatch] = useReducer(ConversationReducer, { ...initialState, websocket: null }); - - console.log('ConversationProvider', state, dispatch); - - // useEffect(() => { - // console.log('invoke provider'); - // const realtimeAPI = new RealTimeAPI( - // { - // url: `${WS_URL}?opisn=${userId || ''}&_spam=${Date.now().toString()}`, - // protocol: 'WhatsApp', - // }, - // () => {dispatch(updateWebsocketState(true)); dispatch(updateWebsocketRetrytimes(0));}, - // () => dispatch(updateWebsocketState(false)), - // (n) => dispatch(updateWebsocketRetrytimes(n)) - // ); - - // realtimeAPI.onError(() => dispatch(addError('Error'))); - // realtimeAPI.onMessage(handleMessage); - // realtimeAPI.onCompletion(() => dispatch(addError('Connection broken'))); - - // dispatch(initWebsocket(realtimeAPI)); - // return () => { - // realtimeAPI.disconnect(); - // }; - // }, []); - - // useEffect(() => { - // fetchConversationsList({ opisn: userId }).then((data) => { - // dispatch(receivedConversationList(data)); - // }); - - // fetchTemplates().then((data) => dispatch(receivedTemplates(data))); - - // return () => {}; - // }, []); - const handleMessage = (data) => { - console.log('handleMessage------------------'); - console.log(data); - const { errcode, errmsg, result } = data; - - if (!result) { - return false; - } - let resultType = result?.action || result.type; - if (errcode !== 0) { - // addError('Error Connecting to Server'); - resultType = 'error'; - } - console.log(resultType, 'result.type'); - const msgObj = receivedMsgTypeMapped[resultType].getMsg(result); - const msgRender = receivedMsgTypeMapped[resultType].contentToRender(msgObj); - const msgUpdate = receivedMsgTypeMapped[resultType].contentToUpdate(msgObj); - console.log('msgRender msgUpdate', msgRender, msgUpdate); - if (['whatsapp.message.updated', 'message', 'error'].includes(resultType)) { - dispatch(updateMessageItem(msgUpdate)); - // return false; - } - if (!isEmpty(msgRender)) { - dispatch(receivedNewMessage(msgRender.conversationid, msgRender)); - } - console.log('handleMessage*******************'); - }; - // return {children}; - return ( - - {children} - - ); -}; - -export default ConversationProvider;