UNPKG

@droppii-org/chat-sdk

Version:

Droppii React Chat SDK

207 lines (206 loc) 8.93 kB
import { useEffect, useState } from "react"; import { ViewType, MessageType } from "@openim/wasm-client-sdk"; import { DChatSDK } from "../../constants/sdk"; import { useLatest, useRequest } from "ahooks"; import emitter, { emit } from "../../utils/events"; import isEmpty from "lodash/isEmpty"; const PAGE_SIZE = 50; export const visibleTypeMessage = [ MessageType.TextMessage, MessageType.PictureMessage, MessageType.VoiceMessage, MessageType.VideoMessage, MessageType.FileMessage, MessageType.AtTextMessage, MessageType.MergeMessage, MessageType.CardMessage, MessageType.LocationMessage, MessageType.CustomMessage, MessageType.QuoteMessage, MessageType.FaceMessage, MessageType.UrlTextMessage, ]; export const useMessage = (conversationId, searchClientMsgID) => { const [loadState, setLoadState] = useState({ initLoading: true, hasMoreOld: true, hasMoreNew: false, messageList: [], }); const latestLoadState = useLatest(loadState); const { loading: moreOldLoading, runAsync: getMoreOldMessages } = useRequest(async (loadMore = true) => { var _a, _b, _c, _d, _e; const reqConversationID = conversationId; const params = { count: PAGE_SIZE, startClientMsgID: loadMore ? ((_e = (_b = (_a = latestLoadState.current) === null || _a === void 0 ? void 0 : _a.messageList) === null || _b === void 0 ? void 0 : _b[((_d = (_c = latestLoadState.current) === null || _c === void 0 ? void 0 : _c.messageList) === null || _d === void 0 ? void 0 : _d.length) - 1]) === null || _e === void 0 ? void 0 : _e.clientMsgID) || "" : "", conversationID: conversationId !== null && conversationId !== void 0 ? conversationId : "", viewType: ViewType.History, }; const { data } = await DChatSDK.getAdvancedHistoryMessageList(params); if (conversationId !== reqConversationID) return; setTimeout(() => setLoadState((preState) => { let messageList = [ ...(loadMore ? preState.messageList : []), ...data.messageList.toReversed(), ]; messageList = removeDuplicateMessages(messageList); return Object.assign(Object.assign({}, preState), { initLoading: false, hasMoreOld: !data.isEnd, messageList }); })); }, { manual: true, }); const { loading: moreNewLoading, runAsync: getMoreNewMessages } = useRequest(async (loadMore = true) => { var _a, _b; const reqConversationID = conversationId; const { data } = await DChatSDK.getAdvancedHistoryMessageListReverse({ count: PAGE_SIZE, startClientMsgID: loadMore ? ((_b = (_a = latestLoadState.current) === null || _a === void 0 ? void 0 : _a.messageList[0]) === null || _b === void 0 ? void 0 : _b.clientMsgID) || "" : "", conversationID: conversationId !== null && conversationId !== void 0 ? conversationId : "", viewType: ViewType.Search, }); if (conversationId !== reqConversationID) return; setTimeout(() => setLoadState((preState) => { let messageList = [ ...data.messageList.toReversed(), ...(loadMore ? preState.messageList : []), ]; messageList = removeDuplicateMessages(messageList); return Object.assign(Object.assign({}, preState), { initLoading: false, hasMoreNew: !data.isEnd, messageList }); })); }, { manual: true, }); const { runAsync: searchMessages } = useRequest(async () => { var _a, _b; if (!searchClientMsgID || !conversationId) return; const reqConversationID = conversationId; const { data: dataPrev } = await DChatSDK.getAdvancedHistoryMessageList({ count: 10, startClientMsgID: searchClientMsgID, conversationID: conversationId !== null && conversationId !== void 0 ? conversationId : "", viewType: ViewType.History, }); const { data: dataNext } = await DChatSDK.getAdvancedHistoryMessageListReverse({ count: 10, startClientMsgID: searchClientMsgID, conversationID: conversationId !== null && conversationId !== void 0 ? conversationId : "", viewType: ViewType.Search, }); const { data: dataCurrent } = await DChatSDK.findMessageList([ { conversationID: conversationId !== null && conversationId !== void 0 ? conversationId : "", clientMsgIDList: [searchClientMsgID !== null && searchClientMsgID !== void 0 ? searchClientMsgID : ""], }, ]); const currentMessages = ((_b = (_a = dataCurrent === null || dataCurrent === void 0 ? void 0 : dataCurrent.findResultItems) === null || _a === void 0 ? void 0 : _a.find((item) => item.conversationID === conversationId)) === null || _b === void 0 ? void 0 : _b.messageList) || []; if (conversationId !== reqConversationID) return; setTimeout(() => { setLoadState((preState) => { let messageList = [ ...dataNext.messageList.toReversed(), ...currentMessages, ...dataPrev.messageList.toReversed(), ]; messageList = removeDuplicateMessages(messageList); return Object.assign(Object.assign({}, preState), { initLoading: false, hasMoreOld: !dataPrev.isEnd, hasMoreNew: !dataNext.isEnd, messageList }); }); }); setTimeout(() => { emit("CHAT_LIST_SCROLL_TO_MESSAGE", searchClientMsgID); console.log("emit scroll to message"); }, 200); }, { manual: true, }); useEffect(() => { const pushNewMessage = (message) => { var _a, _b; if ((_b = (_a = latestLoadState.current) === null || _a === void 0 ? void 0 : _a.messageList) === null || _b === void 0 ? void 0 : _b.find((item) => item.clientMsgID === message.clientMsgID)) { return; } setLoadState((preState) => { const messageList = [message, ...preState.messageList]; return Object.assign(Object.assign({}, preState), { messageList }); }); }; const updateOneMessage = (message) => { setLoadState((preState) => { const tmpList = [...preState.messageList]; const idx = tmpList.findIndex((msg) => msg.clientMsgID === message.clientMsgID); if (idx < 0) { return preState; } tmpList[idx] = Object.assign(Object.assign({}, tmpList[idx]), message); return Object.assign(Object.assign({}, preState), { messageList: tmpList }); }); }; emitter.on("PUSH_NEW_MSG", pushNewMessage); emitter.on("UPDATE_ONE_MSG", updateOneMessage); return () => { emitter.off("PUSH_NEW_MSG", pushNewMessage); emitter.off("UPDATE_ONE_MSG", updateOneMessage); }; }, []); useEffect(() => { if (!conversationId) return; if (!isEmpty(searchClientMsgID)) { searchMessages(); } else { getMoreOldMessages(false); } return () => { setLoadState(() => ({ initLoading: true, hasMoreOld: true, hasMoreNew: false, messageList: [], })); }; }, [conversationId, searchClientMsgID]); return { loadState, latestLoadState, moreOldLoading, getMoreOldMessages, moreNewLoading, getMoreNewMessages, }; }; export const pushNewMessage = (message) => emit("PUSH_NEW_MSG", message); export const updateOneMessage = (message) => emit("UPDATE_ONE_MSG", message); export const getVisibleNeighbor = (allMessages, current, direction) => { const currentIndex = allMessages.findIndex((m) => m.clientMsgID === current.clientMsgID); if (currentIndex === -1) return undefined; const step = direction === "prev" ? 1 : -1; let index = currentIndex + step; while (index >= 0 && index < allMessages.length) { const candidate = allMessages[index]; if (visibleTypeMessage.includes(candidate.contentType)) { return candidate; } index += step; } return undefined; }; const removeDuplicateMessages = (messages) => { const seen = new Set(); return messages.filter((msg) => { if (seen.has(msg.clientMsgID)) { return false; } seen.add(msg.clientMsgID); return true; }); };