@droppii-org/chat-sdk
Version:
Droppii React Chat SDK
227 lines (226 loc) • 9.37 kB
JavaScript
import { useEffect } from "react";
import { DChatSDK } from "../../constants/sdk";
import { CbEvents, MessageType, SessionType, } from "@openim/wasm-client-sdk";
import { BusinessNotificationType, ConnectStatus, CustomType, SyncStatus, } from "../../types/chat";
import { pushNewMessage, updateOneMessage } from "../message/useMessage";
import { useChatContext } from "../../context/ChatContext";
import useConversationStore from "../../store/conversation";
import useAuthStore from "../../store/auth";
import { useRefetchChatToken } from "../../hooks/init/useChatToken";
import { updateSession } from "../session/useUpdateSession";
import { QUERY_KEYS } from "../../services/query";
import { useQueryClient } from "@tanstack/react-query";
const notPushType = [MessageType.TypingMessage, MessageType.RevokeMessage];
export const useGlobalEvent = () => {
const { user } = useChatContext();
const queryClient = useQueryClient();
const { updateConnectStatus, updateSyncStatus, getSelfUserInfo } = useChatContext();
const updateConversationList = useConversationStore((state) => state.updateConversationList);
const getConversationListByReq = useConversationStore((state) => state.getConversationListByReq);
const { mutate: refetchChatToken } = useRefetchChatToken();
const accessToken = useAuthStore((state) => state.accessToken);
const chatToken = useAuthStore((state) => state.chatToken);
const apiAddress = useAuthStore((state) => {
return state.apiAddress;
});
const revokedMessageHandler = ({ data }) => {
updateOneMessage({
clientMsgID: data.clientMsgID,
contentType: MessageType.RevokeMessage,
notificationElem: {
detail: JSON.stringify(data),
},
});
};
const inCurrentConversation = (newServerMsg) => {
const selectedSourceId = useConversationStore.getState().selectedSourceId;
switch (newServerMsg.sessionType) {
case SessionType.Single:
return (newServerMsg.sendID === selectedSourceId ||
((user === null || user === void 0 ? void 0 : user.userID) && newServerMsg.recvID === selectedSourceId));
case SessionType.Group:
case SessionType.WorkingGroup:
return newServerMsg.groupID === selectedSourceId;
case SessionType.Notification:
return newServerMsg.sendID === selectedSourceId;
default:
return false;
}
};
const handleNewMessage = (newServerMsg) => {
let customData = null;
if (newServerMsg.contentType === MessageType.CustomMessage) {
try {
customData = JSON.parse(newServerMsg.customElem.data);
}
catch (e) {
console.error("Failed to parse custom message data", e);
}
if (customData &&
CustomType.CallingInvite <= customData.customType &&
customData.customType <= CustomType.CallingHungup) {
return;
}
}
if (!inCurrentConversation(newServerMsg))
return;
if (!notPushType.includes(newServerMsg.contentType)) {
pushNewMessage(newServerMsg);
}
};
const newMessageHandler = ({ data }) => {
var _a;
(_a = data === null || data === void 0 ? void 0 : data.map) === null || _a === void 0 ? void 0 : _a.call(data, (message) => handleNewMessage(message));
};
const userTokenHandler = () => {
refetchChatToken(undefined, {
onSettled(data) {
var _a;
if (data) {
useAuthStore.getState().setChatToken((_a = data === null || data === void 0 ? void 0 : data.data) === null || _a === void 0 ? void 0 : _a.token);
getSelfUserInfo();
}
},
});
};
const initStore = () => {
getSelfUserInfo();
getConversationListByReq(false);
};
const tryLogin = async () => {
const { userID, chatToken, platformID, wsAddress } = useAuthStore.getState();
try {
await DChatSDK.login({
userID,
token: chatToken,
platformID,
apiAddr: `${apiAddress}/chat-service`,
wsAddr: `${wsAddress}/chat-service/ws`,
});
initStore();
}
catch (error) {
console.error(error);
if (error.errCode !== 10102) {
//user has logged in
}
}
};
const loginCheck = async () => {
const chatToken = useAuthStore.getState().chatToken;
const userID = useAuthStore.getState().userID;
if (!chatToken || !userID) {
return;
}
tryLogin();
};
const connectingHandler = () => {
updateConnectStatus(ConnectStatus.Connecting);
};
const connectSuccessHandler = () => {
updateConnectStatus(ConnectStatus.Connected);
};
const connectFailedHandler = () => {
updateConnectStatus(ConnectStatus.Disconnected);
};
const syncStartHandler = ({ data }) => {
updateSyncStatus(SyncStatus.Loading);
};
const syncFinishHandler = () => {
updateSyncStatus(SyncStatus.Success);
// getFriendListByReq();
// getGroupListByReq();
getConversationListByReq(false);
// getUnReadCountByReq();
};
const syncFailedHandler = () => {
updateSyncStatus(SyncStatus.Failed);
};
const businessNotificationHandler = ({ data, }) => {
console.log(data.key, "business notification");
switch (data.key) {
case BusinessNotificationType.SESSION_STATE_UPDATED:
updateSession(JSON.parse(data.data || "{}"));
break;
case BusinessNotificationType.SESSION_CREATED:
updateSession(JSON.parse(data.data || "{}"));
queryClient.invalidateQueries({
queryKey: [QUERY_KEYS.GET_LIST_SESSION_BY_CONVERSATION],
});
break;
default:
break;
}
};
const setIMListener = () => {
//account
DChatSDK.on(CbEvents.OnUserTokenExpired, userTokenHandler);
DChatSDK.on(CbEvents.OnUserTokenInvalid, userTokenHandler);
DChatSDK.on(CbEvents.OnConnecting, connectingHandler);
DChatSDK.on(CbEvents.OnConnectSuccess, connectSuccessHandler);
DChatSDK.on(CbEvents.OnConnectFailed, connectFailedHandler);
// sync
DChatSDK.on(CbEvents.OnSyncServerStart, syncStartHandler);
// DChatSDK.on(CbEvents.OnSyncServerProgress, syncProgressHandler);
DChatSDK.on(CbEvents.OnSyncServerFinish, syncFinishHandler);
DChatSDK.on(CbEvents.OnSyncServerFailed, syncFailedHandler);
// message
DChatSDK.on(CbEvents.OnRecvNewMessages, newMessageHandler);
DChatSDK.on(CbEvents.OnNewRecvMessageRevoked, revokedMessageHandler);
// conversation
DChatSDK.on(CbEvents.OnConversationChanged, conversationChangeHandler);
DChatSDK.on(CbEvents.OnNewConversation, newConversationHandler);
//busines notification
DChatSDK.on(CbEvents.OnRecvCustomBusinessMessage, businessNotificationHandler);
};
const disposeIMListener = () => {
//account
DChatSDK.off(CbEvents.OnUserTokenExpired, userTokenHandler);
DChatSDK.off(CbEvents.OnUserTokenInvalid, userTokenHandler);
DChatSDK.off(CbEvents.OnConnecting, connectingHandler);
DChatSDK.off(CbEvents.OnConnectSuccess, connectSuccessHandler);
DChatSDK.off(CbEvents.OnConnectFailed, connectFailedHandler);
// sync
DChatSDK.off(CbEvents.OnSyncServerStart, syncStartHandler);
// DChatSDK.off(CbEvents.OnSyncServerProgress, syncProgressHandler);
DChatSDK.off(CbEvents.OnSyncServerFinish, syncFinishHandler);
DChatSDK.off(CbEvents.OnSyncServerFailed, syncFailedHandler);
// message
DChatSDK.off(CbEvents.OnRecvNewMessages, newMessageHandler);
// conversation
DChatSDK.off(CbEvents.OnConversationChanged, conversationChangeHandler);
DChatSDK.off(CbEvents.OnNewConversation, newConversationHandler);
//busines notification
DChatSDK.off(CbEvents.OnRecvCustomBusinessMessage, businessNotificationHandler);
};
// conversation
const conversationChangeHandler = ({ data }) => {
updateConversationList(data, "filter");
};
const newConversationHandler = ({ data }) => {
updateConversationList(data, "push");
};
/** LIFE CYCLE */
useEffect(() => {
setIMListener();
window.addEventListener("online", () => {
DChatSDK.networkStatusChanged();
});
window.addEventListener("offline", () => {
DChatSDK.networkStatusChanged();
});
return () => {
disposeIMListener();
};
}, []);
useEffect(() => {
if (!!accessToken && apiAddress) {
userTokenHandler();
}
}, [accessToken, apiAddress]);
useEffect(() => {
if (!!chatToken && apiAddress) {
loginCheck();
}
}, [chatToken, apiAddress]);
};