|
|
|
@ -1,7 +1,7 @@
|
|
|
|
|
import { create } from 'zustand';
|
|
|
|
|
import { RealTimeAPI } from '@/lib/realTimeAPI';
|
|
|
|
|
import { olog, isEmpty } from '@/utils/utils';
|
|
|
|
|
import { receivedMsgTypeMapped } from '@/lib/msgUtils';
|
|
|
|
|
import { receivedMsgTypeMapped, handleNotification } from '@/lib/msgUtils';
|
|
|
|
|
import { fetchConversationsList, fetchTemplates } from '@/actions/ConversationActions';
|
|
|
|
|
import { devtools } from 'zustand/middleware';
|
|
|
|
|
import { WS_URL } from '@/config';
|
|
|
|
@ -57,7 +57,7 @@ const websocketSlice = (set, get) => ({
|
|
|
|
|
setWebsocketRetrytimes(0);
|
|
|
|
|
},
|
|
|
|
|
() => {
|
|
|
|
|
setWebsocketOpened(false)
|
|
|
|
|
setWebsocketOpened(false);
|
|
|
|
|
const newMsgList = Object.keys(activeConversations).reduce((acc, key) => {
|
|
|
|
|
const newMsgList = activeConversations[key].slice(-10);
|
|
|
|
|
acc[key] = newMsgList;
|
|
|
|
@ -72,7 +72,7 @@ const websocketSlice = (set, get) => ({
|
|
|
|
|
realtimeAPI.onMessage(handleMessage);
|
|
|
|
|
realtimeAPI.onCompletion(() => addError('Connection broken'));
|
|
|
|
|
|
|
|
|
|
olog('Connecting to websocket...', realtimeAPI)
|
|
|
|
|
olog('Connecting to websocket...', realtimeAPI);
|
|
|
|
|
setWebsocket(realtimeAPI);
|
|
|
|
|
},
|
|
|
|
|
disconnectWebsocket: () => {
|
|
|
|
@ -81,7 +81,7 @@ const websocketSlice = (set, get) => ({
|
|
|
|
|
return set({ websocket: null });
|
|
|
|
|
},
|
|
|
|
|
reconnectWebsocket: (userId) => {
|
|
|
|
|
const {disconnectWebsocket, connectWebsocket} = get();
|
|
|
|
|
const { disconnectWebsocket, connectWebsocket } = get();
|
|
|
|
|
disconnectWebsocket();
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
connectWebsocket(userId);
|
|
|
|
@ -112,18 +112,9 @@ const websocketSlice = (set, get) => ({
|
|
|
|
|
}
|
|
|
|
|
if (!isEmpty(msgRender)) {
|
|
|
|
|
sentOrReceivedNewMessage(msgRender.conversationid, msgRender);
|
|
|
|
|
window.Notification.requestPermission().then(function (permission) {
|
|
|
|
|
if (permission === 'granted') {
|
|
|
|
|
const notification = new Notification(`${msgRender.senderName}`, {
|
|
|
|
|
body: msgRender?.text || `[ ${msgRender.type} ]`,
|
|
|
|
|
requireInteraction: true, // 设置手动关闭
|
|
|
|
|
tag: 'global-sales-notification', // 通知ID,同类通知建议设置相同ID,避免通知过多遮挡桌面
|
|
|
|
|
...(msgRender.type === 'photo' ? { image: msgRender.data.uri } : {}),
|
|
|
|
|
});
|
|
|
|
|
notification.onclick = function () {
|
|
|
|
|
window.parent.parent.focus();
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
handleNotification(msgRender.senderName, {
|
|
|
|
|
body: msgRender?.text || `[ ${msgRender.type} ]`,
|
|
|
|
|
...(msgRender.type === 'photo' ? { image: msgRender.data.uri } : {}),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
console.log('handleMessage*******************');
|
|
|
|
@ -160,7 +151,7 @@ const conversationSlice = (set, get) => ({
|
|
|
|
|
return set((state) => ({
|
|
|
|
|
conversationsList: [...newConversations, ...state.conversationsList],
|
|
|
|
|
activeConversations: { ...activeConversations, ...newConversationsMapped },
|
|
|
|
|
totalNotify: state.totalNotify + newConversations.map(ele => ele.unread_msg_count).reduce((acc, cur) => acc + (cur || 0), 0),
|
|
|
|
|
totalNotify: state.totalNotify + newConversations.map((ele) => ele.unread_msg_count).reduce((acc, cur) => acc + (cur || 0), 0),
|
|
|
|
|
}));
|
|
|
|
|
},
|
|
|
|
|
delConversationitem: (conversation) => {
|
|
|
|
@ -180,10 +171,12 @@ const conversationSlice = (set, get) => ({
|
|
|
|
|
const { conversationsList, totalNotify } = get();
|
|
|
|
|
const targetId = conversation.sn;
|
|
|
|
|
const targetIndex = conversationsList.findIndex((ele) => String(ele.sn) === String(targetId));
|
|
|
|
|
targetIndex !== -1 ? conversationsList.splice(targetIndex, 1, {
|
|
|
|
|
...conversationsList[targetIndex],
|
|
|
|
|
unread_msg_count: 0,
|
|
|
|
|
}) : null;
|
|
|
|
|
targetIndex !== -1
|
|
|
|
|
? conversationsList.splice(targetIndex, 1, {
|
|
|
|
|
...conversationsList[targetIndex],
|
|
|
|
|
unread_msg_count: 0,
|
|
|
|
|
})
|
|
|
|
|
: null;
|
|
|
|
|
|
|
|
|
|
return set({ totalNotify: totalNotify - (conversation.unread_msg_count || 0), currentConversation: conversation, referenceMsg: {}, conversationsList: [...conversationsList] });
|
|
|
|
|
},
|
|
|
|
@ -194,11 +187,13 @@ 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
|
|
|
|
|
receivedMessageList: (conversationid, msgList) =>
|
|
|
|
|
set((state) => ({
|
|
|
|
|
msgListLoading: false,
|
|
|
|
|
activeConversations: { ...state.activeConversations, [String(conversationid)]: msgList },
|
|
|
|
|
})),
|
|
|
|
|
updateMessageItem: (message) => {
|
|
|
|
|
// msgUpdate
|
|
|
|
|
console.log('UPDATE_SENT_MESSAGE_ITEM-----------------------------------------------------------------');
|
|
|
|
|
// 更新会话中的消息
|
|
|
|
|
const { activeConversations, conversationsList } = get();
|
|
|
|
@ -233,7 +228,8 @@ const messageSlice = (set, get) => ({
|
|
|
|
|
// conversationsList: [...conversationsList],
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
sentOrReceivedNewMessage: (targetId, message) => { // msgRender:
|
|
|
|
|
sentOrReceivedNewMessage: (targetId, message) => {
|
|
|
|
|
// msgRender:
|
|
|
|
|
const { activeConversations, conversationsList, currentConversation, totalNotify } = get();
|
|
|
|
|
const targetMsgs = activeConversations[String(targetId)] || [];
|
|
|
|
|
const targetIndex = conversationsList.findIndex((ele) => String(ele.sn) === String(targetId));
|
|
|
|
@ -257,7 +253,7 @@ const messageSlice = (set, get) => ({
|
|
|
|
|
conversationsList.splice(targetIndex, 1);
|
|
|
|
|
conversationsList.unshift(newConversation);
|
|
|
|
|
return set({
|
|
|
|
|
totalNotify: totalNotify+newConversation.unread_msg_count,
|
|
|
|
|
totalNotify: totalNotify + newConversation.unread_msg_count,
|
|
|
|
|
activeConversations: { ...activeConversations, [String(targetId)]: [...targetMsgs, message] },
|
|
|
|
|
conversationsList: [...conversationsList],
|
|
|
|
|
currentConversation: {
|
|
|
|
@ -265,35 +261,36 @@ const messageSlice = (set, get) => ({
|
|
|
|
|
...(String(targetId) === String(currentConversation.sn) ? { last_received_time: message.date } : {}),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export const useConversationStore = create(devtools((set, get) => ({
|
|
|
|
|
...initialConversationState,
|
|
|
|
|
...websocketSlice(set, get),
|
|
|
|
|
...conversationSlice(set, get),
|
|
|
|
|
...templatesSlice(set, get),
|
|
|
|
|
...messageSlice(set, get),
|
|
|
|
|
...referenceMsgSlice(set, get),
|
|
|
|
|
...complexMsgSlice(set, get),
|
|
|
|
|
|
|
|
|
|
// state actions
|
|
|
|
|
addError: (error) => set((state) => ({ errors: [...state.errors, error] })),
|
|
|
|
|
setInitial: (v) => set({ initialState: v }),
|
|
|
|
|
|
|
|
|
|
// side effects
|
|
|
|
|
fetchInitialData: async (userId) => {
|
|
|
|
|
const { addToConversationList, setTemplates, setInitial } = get();
|
|
|
|
|
|
|
|
|
|
const conversationsList = await fetchConversationsList({ opisn: userId });
|
|
|
|
|
addToConversationList(conversationsList);
|
|
|
|
|
|
|
|
|
|
const templates = await fetchTemplates();
|
|
|
|
|
setTemplates(templates);
|
|
|
|
|
|
|
|
|
|
setInitial(true);
|
|
|
|
|
},
|
|
|
|
|
})));
|
|
|
|
|
export const useConversationStore = create(
|
|
|
|
|
devtools((set, get) => ({
|
|
|
|
|
...initialConversationState,
|
|
|
|
|
...websocketSlice(set, get),
|
|
|
|
|
...conversationSlice(set, get),
|
|
|
|
|
...templatesSlice(set, get),
|
|
|
|
|
...messageSlice(set, get),
|
|
|
|
|
...referenceMsgSlice(set, get),
|
|
|
|
|
...complexMsgSlice(set, get),
|
|
|
|
|
|
|
|
|
|
// state actions
|
|
|
|
|
addError: (error) => set((state) => ({ errors: [...state.errors, error] })),
|
|
|
|
|
setInitial: (v) => set({ initialState: v }),
|
|
|
|
|
|
|
|
|
|
// side effects
|
|
|
|
|
fetchInitialData: async (userId) => {
|
|
|
|
|
const { addToConversationList, setTemplates, setInitial } = get();
|
|
|
|
|
|
|
|
|
|
const conversationsList = await fetchConversationsList({ opisn: userId });
|
|
|
|
|
addToConversationList(conversationsList);
|
|
|
|
|
|
|
|
|
|
const templates = await fetchTemplates();
|
|
|
|
|
setTemplates(templates);
|
|
|
|
|
|
|
|
|
|
setInitial(true);
|
|
|
|
|
},
|
|
|
|
|
}))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
export default useConversationStore;
|
|
|
|
|