@droppii-org/chat-sdk
Version:
Droppii React Chat SDK
207 lines (206 loc) • 8.93 kB
JavaScript
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;
});
};