@asteriskzuo/react-native-easemob
Version:
easemob chat sdk of react-native.
953 lines (912 loc) • 32.6 kB
text/typescript
import type { NativeEventEmitter } from 'react-native';
import {
ChatConversation,
ChatConversationType,
} from './common/ChatConversation';
import { ChatCursorResult } from './common/ChatCursorResult';
import { ChatError } from './common/ChatError';
import { ChatGroupMessageAck } from './common/ChatGroup';
import {
ChatMessage,
ChatMessageStatus,
ChatMessageStatusCallback,
} from './common/ChatMessage';
import {
MethodTypeackConversationRead,
MethodTypeackGroupMessageRead,
MethodTypeackMessageRead,
MethodTypeasyncFetchGroupAcks,
MethodTypedeleteConversation,
MethodTypedeleteRemoteConversation,
MethodTypedownloadAttachment,
MethodTypedownloadThumbnail,
MethodTypefetchHistoryMessages,
MethodTypegetConversation,
MethodTypegetConversationsFromServer,
MethodTypegetMessage,
MethodTypegetUnreadMessageCount,
MethodTypeimportMessages,
MethodTypeloadAllConversations,
MethodTypemarkAllChatMsgAsRead,
MethodTypeonCmdMessagesReceived,
MethodTypeonConversationHasRead,
MethodTypeonConversationUpdate,
MethodTypeonGroupMessageRead,
MethodTypeonMessageError,
MethodTypeonMessageProgressUpdate,
MethodTypeonMessagesDelivered,
MethodTypeonMessagesRead,
MethodTypeonMessagesRecalled,
MethodTypeonMessagesReceived,
MethodTypeonMessageSuccess,
MethodTyperecallMessage,
MethodTyperesendMessage,
MethodTypesearchChatMsgFromDB,
MethodTypesendMessage,
MethodTypeupdateChatMessage,
} from './_internal/Consts';
import { Native } from './_internal/Native';
/**
* The message search direction type.
*/
export enum ChatSearchDirection {
/**
* The search older messages type
*/
UP,
/**
* The search newer messages type.
*/
DOWN,
}
/**
* The message event listener.
*
* This listener is used to check whether messages are received. If messages are sent successfully, a delivery receipt will be returned (delivery receipt needs to be enabled: {@link ChatOptions#requireDeliveryAck(boolean)}.
*
* If the peer reads the received message, a read receipt will be returned (read receipt needs to be enabled: {@link ChatOptions#requireAck(boolean)})
*
* During message delivery, the message ID will be changed from a local uuid to a global unique ID that is generated by the server to uniquely identify a message on all devices using the SDK.
* This API should be implemented in the app to listen for message status changes.
*
* Adds the message listener:
* ```typescript
* let msgListener = new (class ss implements ChatManagerListener {
* onMessagesReceived(messages: ChatMessage[]): void {
* console.log('ConnectScreen.onMessagesReceived', messages);
* }
* onCmdMessagesReceived(messages: ChatMessage[]): void {
* console.log('ConnectScreen.onCmdMessagesReceived', messages);
* }
* onMessagesRead(messages: ChatMessage[]): void {
* console.log('ConnectScreen.onMessagesRead', messages);
* }
* onGroupMessageRead(groupMessageAcks: ChatGroupMessageAck[]): void {
* console.log('ConnectScreen.onGroupMessageRead', groupMessageAcks);
* }
* onMessagesDelivered(messages: ChatMessage[]): void {
* console.log('ConnectScreen.onMessagesDelivered', messages);
* }
* onMessagesRecalled(messages: ChatMessage[]): void {
* console.log('ConnectScreen.onMessagesRecalled', messages);
* }
* onConversationsUpdate(): void {
* console.log('ConnectScreen.onConversationsUpdate');
* }
* onConversationRead(from: string, to?: string): void {
* console.log('ConnectScreen.onConversationRead', from, to);
* }
* })();
* ChatClient.getInstance().chatManager.addListener(msgListener);
* ```
*
* Removes the message listener:
* ```typescript
* ChatClient.getInstance().chatManager.delListener(this.msgListener);
* ```
*/
export interface ChatManagerListener {
/**
* Occurs when a message is received.
*
* This callback is triggered to notify the user when a message such as texts or an image, video, voice, location, or file is received.
*
* @param messages The received messages.
*/
onMessagesReceived(messages: Array<ChatMessage>): void;
/**
* Occurs when a command message is received.
*
* This callback only contains a command message body that is usually invisible to users.
*
* @param messages The received cmd messages.
*/
onCmdMessagesReceived(messages: Array<ChatMessage>): void;
/**
* Occurs when a read receipt is received for a message.
*
* @param messages The has read messages.
*/
onMessagesRead(messages: Array<ChatMessage>): void;
/**
* Occurs when a read receipt is received for a group message.
*
* @param groupMessageAcks The group message acks.
*/
onGroupMessageRead(groupMessageAcks: Array<ChatGroupMessageAck>): void;
/**
* Occurs when a delivery receipt is received.
*
* @param messages The has delivered messages.
*/
onMessagesDelivered(messages: Array<ChatMessage>): void;
/**
* Occurs when a received message is recalled.
*
* @param messages The recalled messages.
*/
onMessagesRecalled(messages: Array<ChatMessage>): void;
/**
* Occurs when the conversation updated.
*/
onConversationsUpdate(): void;
/**
* Occurs when received conversation read receipt.
*
* Occurs in the following scenarios:
*
* (1) The message is read by the receiver (The conversation receipt is sent). Upon receiving this event, the SDK sets the `isAcked` property of the message in the conversation to `true` in the local database.
*
* (2) In the multi-device login scenario, when one device sends a Conversation receipt,
* the server will set the number of unread messages to 0, and the callback occurs on the other devices. and sets the `isRead` property of the message in the conversation to `true` in the local database.
* @param from The user who sends the read receipt.
* @param to The user who receives the read receipt.
*/
onConversationRead(from: string, to?: string): void;
}
/**
* The chat manager. This class is responsible for managing conversations.
* (such as: load, delete), sending messages, downloading attachments and so on.
*
* Such as, send a text message:
* ```typescript
* let msg = ChatMessage.createTextMessage(
* 'asteriskhx2',
* Date.now().toString(),
* ChatMessageChatType.PeerChat
* );
* let callback = new (class s implements ChatMessageStatusCallback {
* onProgress(progress: number): void {
* console.log('ConnectScreen.sendMessage.onProgress ', progress);
* }
* onError(error: ChatError): void {
* console.log('ConnectScreen.sendMessage.onError ', error);
* }
* onSuccess(): void {
* console.log('ConnectScreen.sendMessage.onSuccess');
* }
* onReadAck(): void {
* console.log('ConnectScreen.sendMessage.onReadAck');
* }
* onDeliveryAck(): void {
* console.log('ConnectScreen.sendMessage.onDeliveryAck');
* }
* onStatusChanged(status: ChatMessageStatus): void {
* console.log('ConnectScreen.sendMessage.onStatusChanged ', status);
* }
* })();
* ChatClient.getInstance()
* .chatManager.sendMessage(msg, callback)
* .then((nmsg: ChatMessage) => {
* console.log(`${msg}, ${nmsg}`);
* })
* .catch();
* ```
*/
export class ChatManager extends Native {
static TAG = 'ChatManager';
private _messageListeners: Set<ChatManagerListener>;
private _eventEmitter?: NativeEventEmitter;
constructor() {
super();
this._messageListeners = new Set<ChatManagerListener>();
}
public setNativeListener(eventEmitter: NativeEventEmitter) {
this._eventEmitter = eventEmitter;
eventEmitter.removeAllListeners(MethodTypeonMessagesReceived);
eventEmitter.addListener(
MethodTypeonMessagesReceived,
this.onMessagesReceived.bind(this)
);
eventEmitter.removeAllListeners(MethodTypeonCmdMessagesReceived);
eventEmitter.addListener(
MethodTypeonCmdMessagesReceived,
this.onCmdMessagesReceived.bind(this)
);
eventEmitter.removeAllListeners(MethodTypeonMessagesRead);
eventEmitter.addListener(
MethodTypeonMessagesRead,
this.onMessagesRead.bind(this)
);
eventEmitter.removeAllListeners(MethodTypeonGroupMessageRead);
eventEmitter.addListener(
MethodTypeonGroupMessageRead,
this.onGroupMessageRead.bind(this)
);
eventEmitter.removeAllListeners(MethodTypeonMessagesDelivered);
eventEmitter.addListener(
MethodTypeonMessagesDelivered,
this.onMessagesDelivered.bind(this)
);
eventEmitter.removeAllListeners(MethodTypeonMessagesRecalled);
eventEmitter.addListener(
MethodTypeonMessagesRecalled,
this.onMessagesRecalled.bind(this)
);
eventEmitter.removeAllListeners(MethodTypeonConversationUpdate);
eventEmitter.addListener(
MethodTypeonConversationUpdate,
this.onConversationsUpdate.bind(this)
);
eventEmitter.removeAllListeners(MethodTypeonConversationHasRead);
eventEmitter.addListener(
MethodTypeonConversationHasRead,
this.onConversationHasRead.bind(this)
);
}
private onMessagesReceived(messages: any[]): void {
console.log(`${ChatManager.TAG}: onMessagesReceived: ${messages}`);
this._messageListeners.forEach((listener: ChatManagerListener) => {
let list: Array<ChatMessage> = [];
messages.forEach((message: any) => {
let m = ChatMessage.createReceiveMessage(message);
list.push(m);
});
listener.onMessagesReceived(list);
});
}
private onCmdMessagesReceived(messages: any[]): void {
console.log(`${ChatManager.TAG}: onCmdMessagesReceived: ${messages}`);
this._messageListeners.forEach((listener: ChatManagerListener) => {
let list: Array<ChatMessage> = [];
messages.forEach((message: any) => {
let m = ChatMessage.createReceiveMessage(message);
list.push(m);
});
listener.onCmdMessagesReceived(list);
});
}
private onMessagesRead(messages: any[]): void {
console.log(`${ChatManager.TAG}: onMessagesRead: ${messages}`);
this._messageListeners.forEach((listener: ChatManagerListener) => {
let list: Array<ChatMessage> = [];
messages.forEach((message: any) => {
let m = ChatMessage.createReceiveMessage(message);
list.push(m);
});
listener.onMessagesRead(list);
});
}
private onGroupMessageRead(messages: any[]): void {
console.log(`${ChatManager.TAG}: onGroupMessageRead: ${messages}`);
this._messageListeners.forEach((listener: ChatManagerListener) => {
let list: Array<ChatGroupMessageAck> = [];
messages.forEach((message: any) => {
let m = new ChatGroupMessageAck(message);
list.push(m);
});
listener.onGroupMessageRead(messages);
});
}
private onMessagesDelivered(messages: any[]): void {
console.log(`${ChatManager.TAG}: onMessagesDelivered: ${messages}`);
this._messageListeners.forEach((listener: ChatManagerListener) => {
let list: Array<ChatMessage> = [];
messages.forEach((message: any) => {
let m = ChatMessage.createReceiveMessage(message);
list.push(m);
});
listener.onMessagesDelivered(list);
});
}
private onMessagesRecalled(messages: any[]): void {
console.log(`${ChatManager.TAG}: onMessagesRecalled: ${messages}`);
this._messageListeners.forEach((listener: ChatManagerListener) => {
let list: Array<ChatMessage> = [];
messages.forEach((message: any) => {
let m = ChatMessage.createReceiveMessage(message);
list.push(m);
});
listener.onMessagesRecalled(list);
});
}
private onConversationsUpdate(): void {
console.log(`${ChatManager.TAG}: onConversationsUpdate: `);
this._messageListeners.forEach((listener: ChatManagerListener) => {
listener.onConversationsUpdate();
});
}
private onConversationHasRead(params: any): void {
console.log(`${ChatManager.TAG}: onConversationHasRead: ${params}`);
this._messageListeners.forEach((listener: ChatManagerListener) => {
let from = params?.from;
let to = params?.to;
listener.onConversationRead(from, to);
});
}
private static handleSendMessageCallback(
self: ChatManager,
message: ChatMessage,
callback?: ChatMessageStatusCallback
): void {
if (callback && self._eventEmitter) {
const subscription = self._eventEmitter.addListener(
MethodTypesendMessage,
(params: any) => {
const localMsgId: string = params.localTime.toString();
if (message.localMsgId === localMsgId) {
const callbackType: String = params.callbackType;
if (callbackType === MethodTypeonMessageSuccess) {
const m = params.message;
callback.onSuccess(new ChatMessage(m));
subscription.remove();
} else if (callbackType === MethodTypeonMessageError) {
const e = params.error;
callback.onError(localMsgId, new ChatError(e));
subscription.remove();
} else if (callbackType === MethodTypeonMessageProgressUpdate) {
const progress: number = params.progress;
callback.onProgress(localMsgId, progress);
}
}
}
);
}
}
/**
* Add message listener
* @param listener The message listener.
*/
public addListener(listener: ChatManagerListener): void {
this._messageListeners.add(listener);
}
/**
* Remove message listener
* @param listener The message listener.
*/
public removeListener(listener: ChatManagerListener): void {
this._messageListeners.delete(listener);
}
/**
* Remove all message listener
*/
public removeAllListener(): void {
this._messageListeners.clear();
}
/**
* Sends a message.
*
* Reference:
* If the message is voice, picture and other message with attachment, the SDK will automatically upload the attachment. You can set whether to upload the attachment to the chat sever by {@link ChatOptions}.
* @param message The message object to be sent. Make sure to set the param.
* @param callback The listener that Listen for message changes.
*
* @throws Error, see {@link ChatError}
*/
public async sendMessage(
message: ChatMessage,
callback?: ChatMessageStatusCallback
): Promise<void> {
console.log(
`${ChatManager.TAG}: sendMessage: ${message.msgId}, ${message.localTime}`
);
message.status = ChatMessageStatus.PROGRESS;
ChatManager.handleSendMessageCallback(this, message, callback);
let r: any = await Native._callMethod(MethodTypesendMessage, {
[MethodTypesendMessage]: message,
});
Native.hasErrorFromResult(r);
}
/**
* Resends a message.
*
* @param message The failed message.
* @param callback The listener that Listen for message changes.
*
* @throws Error, see {@link ChatError}
*/
public async resendMessage(
message: ChatMessage,
callback: ChatMessageStatusCallback
): Promise<void> {
console.log(
`${ChatManager.TAG}: resendMessage: ${message.msgId}, ${message.localTime}`
);
message.status = ChatMessageStatus.PROGRESS;
ChatManager.handleSendMessageCallback(this, message, callback);
let r: any = await Native._callMethod(MethodTyperesendMessage, {
[MethodTypesendMessage]: message,
});
Native.hasErrorFromResult(r);
}
/**
* Sends the read receipt to the server.
*
* This method applies to one-to-one chats only.
*
* **Warning**
* This method only takes effect if you set {@link ChatOptions#requireAck(bool)} as `true`.
*
* **Note**
* To send the group message read receipt, call {@link #sendGroupMessageReadAck(String, String, String)}.
*
* We recommend that you call {@link #sendConversationReadAck(String)} when entering a chat page, and call this method to reduce the number of method calls.
*
* @param message The failed message.
*
* @throws Error, see {@link ChatError}
*/
public async sendMessageReadAck(message: ChatMessage): Promise<void> {
console.log(
`${ChatManager.TAG}: sendMessageReadAck: ${message.msgId}, ${message.localTime}`
);
let r: any = await Native._callMethod(MethodTypeackMessageRead, {
[MethodTypeackMessageRead]: {
to: message.from,
msg_id: message.msgId,
},
});
Native.hasErrorFromResult(r);
}
/**
* Sends the group message receipt to the server.
*
* You can call the method only after setting the following method: {@link ChatOptions#requireAck(bool)} and {@link ChatMessage#needGroupAck(bool)}.
*
* **Note**
* - This method takes effect only after you set {@link ChatOptions#requireAck} and {@link ChatMessage#needGroupAck} as `true`.
* This method applies to group messages only. To send a one-to-one chat message receipt, call `sendMessageReadAck`; to send a conversation receipt, call `sendConversationReadAck`.
*
* @param msgId The message ID.
* @param groupId The group ID.
* @param opt The extension information, which is a custom keyword that specifies a custom action or command.
*
* @throws Error, see {@link ChatError}
*/
public async sendGroupMessageReadAck(
msgId: string,
groupId: string,
opt?: { content: string }
): Promise<void> {
console.log(
`${ChatManager.TAG}: sendGroupMessageReadAck: ${msgId}, ${groupId}`
);
let s = opt?.content
? {
msg_id: msgId,
group_id: groupId,
content: opt?.content,
}
: {
msg_id: msgId,
group_id: groupId,
};
let r: any = await Native._callMethod(MethodTypeackGroupMessageRead, {
[MethodTypeackGroupMessageRead]: s,
});
Native.hasErrorFromResult(r);
}
/**
* Sends the conversation read receipt to the server. This method is only for one-to-one chat conversations.
*
* This method informs the server to set the unread message count of the conversation to 0. In multi-device scenarios, all the devices receive the {@link ChatManagerListener#onConversationRead(String, String)} callback.
* @param convId The conversation ID.
*
* @throws Error, see {@link ChatError}
*/
public async sendConversationReadAck(convId: string): Promise<void> {
console.log(`${ChatManager.TAG}: sendConversationReadAck: ${convId}`);
let r: any = await Native._callMethod(MethodTypeackConversationRead, {
[MethodTypeackConversationRead]: {
convId: convId,
},
});
Native.hasErrorFromResult(r);
}
/**
* Recalls the sent message.
*
* @param msgId The message ID.
*
* @throws Error, see {@link ChatError}
*/
public async recallMessage(msgId: string): Promise<void> {
console.log(`${ChatManager.TAG}: recallMessage: ${msgId}`);
let r: any = await Native._callMethod(MethodTyperecallMessage, {
[MethodTyperecallMessage]: {
msg_id: msgId,
},
});
Native.hasErrorFromResult(r);
}
/**
* Loads a message from the local database by message ID.
*
* @param msgId The message ID.
* @returns The message.
*
* @throws Error, see {@link ChatError}
*/
public async getMessage(msgId: string): Promise<ChatMessage> {
console.log(`${ChatManager.TAG}: getMessage: ${msgId}`);
let r: any = await Native._callMethod(MethodTypegetMessage, {
[MethodTypegetMessage]: {
msg_id: msgId,
},
});
Native.hasErrorFromResult(r);
return new ChatMessage(r?.[MethodTypegetMessage]);
}
/**
* Gets the conversation by conversation ID and conversation type.
*
* @param convId The conversation ID.
* @param convType The conversation type: {@link ChatConversationType}.
* @param createIfNeed Whether to create a conversation is the specified conversation is not found:
* - `true`: Yes.
* - `false`: No.
*
* @returns The conversation object found according to the ID and type. Returns null if the conversation is not found.
*
* @throws Error, see {@link ChatError}
*/
public async getConversation(
convId: string,
convType: ChatConversationType,
createIfNeed: boolean = true
): Promise<ChatConversation> {
console.log(
`${ChatManager.TAG}: getConversation: ${convId}, ${convType}, ${createIfNeed}`
);
let r: any = await Native._callMethod(MethodTypegetConversation, {
[MethodTypegetConversation]: {
con_id: convId,
type: convType as number,
createIfNeed: createIfNeed,
},
});
Native.hasErrorFromResult(r);
return new ChatConversation(r?.[MethodTypegetConversation]);
}
/**
* Marks all messages as read.
*
* This method is for the local conversations only.
*
* @throws Error, see {@link ChatError}
*/
public async markAllConversationsAsRead(): Promise<void> {
console.log(`${ChatManager.TAG}: markAllConversationsAsRead: `);
let r: any = await Native._callMethod(MethodTypemarkAllChatMsgAsRead);
Native.hasErrorFromResult(r);
}
/**
* Gets the count of the unread messages.
*
* @returns The count of the unread messages.
*
* @throws Error, see {@link ChatError}
*/
public async getUnreadMessageCount(): Promise<number> {
console.log(`${ChatManager.TAG}: getUnreadMessageCount: `);
let r: any = await Native._callMethod(MethodTypegetUnreadMessageCount);
Native.hasErrorFromResult(r);
return r?.[MethodTypegetUnreadMessageCount] as number;
}
/**
* Updates the local message.
*
* @param message The message will be updated both in the cache and local database.
*
* @throws Error, see {@link ChatError}
*/
public async updateMessage(message: ChatMessage): Promise<void> {
console.log(
`${ChatManager.TAG}: updateMessage: ${message.msgId}, ${message.localTime}`
);
let r: any = await Native._callMethod(MethodTypeupdateChatMessage, {
[MethodTypeupdateChatMessage]: {
message: message,
},
});
Native.hasErrorFromResult(r);
}
/**
* Imports messages to the local database.
*
* Before importing, ensure that the sender or receiver of the message is the current user.
*
* @param messages The message list.
*
* @throws Error, see {@link ChatError}
*/
public async importMessages(messages: Array<ChatMessage>): Promise<void> {
console.log(`${ChatManager.TAG}: importMessages: ${messages.length}`);
let r: any = await Native._callMethod(MethodTypeimportMessages, {
[MethodTypeimportMessages]: {
messages: messages,
},
});
Native.hasErrorFromResult(r);
}
/**
* Downloads the attachment files from the server.
*
* You can call the method again if the attachment download fails.
*
* @param message The message with the attachment that is to be downloaded.
*
* @throws Error, see {@link ChatError}
*/
public async downloadAttachment(message: ChatMessage): Promise<void> {
console.log(
`${ChatManager.TAG}: downloadAttachment: ${message.msgId}, ${message.localTime}`
);
let r: any = await Native._callMethod(MethodTypedownloadAttachment, {
[MethodTypedownloadAttachment]: {
message: message,
},
});
Native.hasErrorFromResult(r);
}
/**
* Downloads the thumbnail if the message has not been downloaded before or if the download fails.
*
* @param message The message object.
*
* @throws Error, see {@link ChatError}
*/
public async downloadThumbnail(message: ChatMessage): Promise<void> {
console.log(
`${ChatManager.TAG}: downloadThumbnail: ${message.msgId}, ${message.localTime}`
);
let r: any = await Native._callMethod(MethodTypedownloadThumbnail, {
[MethodTypedownloadThumbnail]: {
message: message,
},
});
Native.hasErrorFromResult(r);
}
/**
* Gets all conversations from the local database.
*
* Conversations will be first loaded from the cache. If no conversation is found, the SDK loads from the local database.
*
* @returns All the conversations from the cache or local database.
*
* @throws Error, see {@link ChatError}
*/
public async loadAllConversations(): Promise<Array<ChatConversation>> {
console.log(`${ChatManager.TAG}: loadAllConversations:`);
let r: any = await Native._callMethod(MethodTypeloadAllConversations);
Native.hasErrorFromResult(r);
let ret = new Array<ChatConversation>(10);
(r?.[MethodTypeloadAllConversations] as Array<any>).forEach((element) => {
ret.push(new ChatConversation(element));
});
return ret;
}
/**
* Gets the conversation list from the server.
*
* To use this function, you need to contact our business manager to activate it. After this function is activated, users can pull 10 conversations within 7 days by default (each convesation contains the latest historical message). If you want to adjust the number of conversations or time limit, please contact our business manager.
*
* @returns The conversation list of the current user.
*
* @throws Error, see {@link ChatError}
*/
public async getConversationsFromServer(): Promise<Array<ChatConversation>> {
console.log(`${ChatManager.TAG}: getConversationsFromServer:`);
let r: any = await Native._callMethod(MethodTypegetConversationsFromServer);
Native.hasErrorFromResult(r);
let ret = new Array<ChatConversation>(10);
(r?.[MethodTypegetConversationsFromServer] as Array<any>).forEach(
(element) => {
ret.push(new ChatConversation(element));
}
);
return ret;
}
/**
* Deletes a conversation and its related messages from the local database.
*
* If you set `deleteMessages` to `true`, the local historical messages are deleted when the conversation is deleted.
*
* @param convId The conversation ID.
* @param withMessage Whether to delete the historical messages when deleting the conversation.
* - `true`: (default) Yes.
* - `false`: No.
* @returns Whether the conversation is successfully deleted.
* - `true`: (default) Yes.
* - `false`: No.
*
* @throws Error, see {@link ChatError}
*/
public async deleteConversation(
convId: string,
withMessage: boolean = true
): Promise<void> {
console.log(
`${ChatManager.TAG}: deleteConversation: ${convId}, ${withMessage}`
);
let r: any = await Native._callMethod(MethodTypedeleteConversation, {
[MethodTypedeleteConversation]: {
con_id: convId,
deleteMessages: withMessage,
},
});
Native.hasErrorFromResult(r);
}
/**
* Gets historical messages of the conversation from the server with pagination.
*
* @param convId The conversation ID.
* @param chatType The conversation type. See {@link ChatConversationType}.
* @param pageSize The number of messages per page.
* @param startMsgId he ID of the message from which you start to get the historical messages. If `null` is passed, the SDK gets messages in reverse chronological order.
* @returns The obtained messages and the cursor for the next fetch action.
*
* @throws Error, see {@link ChatError}
*/
public async fetchHistoryMessages(
convId: string,
chatType: ChatConversationType,
pageSize: number = 20,
startMsgId: string = ''
): Promise<ChatCursorResult<ChatMessage>> {
console.log(
`${ChatManager.TAG}: fetchHistoryMessages: ${convId}, ${chatType}, ${pageSize}, ${startMsgId}`
);
let r: any = await Native._callMethod(MethodTypefetchHistoryMessages, {
[MethodTypefetchHistoryMessages]: {
con_id: convId,
type: chatType as number,
pageSize: pageSize,
startMsgId: startMsgId,
},
});
Native.hasErrorFromResult(r);
let ret = new ChatCursorResult<ChatMessage>({
cursor: r?.[MethodTypefetchHistoryMessages].cursor,
list: r?.[MethodTypefetchHistoryMessages].list,
opt: {
map: (param: any) => {
return new ChatMessage(param);
},
},
});
return ret;
}
/**
* Retrieves messages from the database according to the parameters.
*
* **Note**
* Pay attention to the memory usage when the maxCount is large. Currently, a maximum of 400 historical messages can be retrieved each time.
* @param keywords The keywords in message.
* @param timestamp The Unix timestamp for search, in milliseconds.
* @param maxCount The maximum number of messages to retrieve each time.
* @param from A username or group ID at which the retrieval is targeted. Usually, it is the conversation ID.
* @param direction Search the direction of the message.
* @returns The list of messages.
*
* @throws Error, see {@link ChatError}
*/
public async searchMsgFromDB(
keywords: string,
timestamp: number = -1,
maxCount: number = 20,
from: string = '',
direction: ChatSearchDirection = ChatSearchDirection.UP
): Promise<Array<ChatMessage>> {
console.log(
`${ChatManager.TAG}: searchMsgFromDB: ${keywords}, ${timestamp}, ${maxCount}, ${from}`
);
let r: any = await Native._callMethod(MethodTypesearchChatMsgFromDB, {
[MethodTypesearchChatMsgFromDB]: {
keywords: keywords,
timestamp: timestamp,
maxCount: maxCount,
from: from,
direction: direction === ChatSearchDirection.UP ? 'up' : 'down',
},
});
Native.hasErrorFromResult(r);
let ret = new Array<ChatMessage>(10);
(r?.[MethodTypesearchChatMsgFromDB] as Array<any>).forEach((element) => {
ret.push(new ChatMessage(element));
});
return ret;
}
/**
* Gets read receipts for group messages from the server with pagination.
*
* See also:
* or how to send read receipts for group messages, see {@link {@link #sendConversationReadAck(String)}.
*
* @param msgId The message ID.
* @param startAckId The starting read receipt ID for query. If you set it as null, the SDK retrieves the read receipts in the in reverse chronological order.
* @param pageSize The number of read receipts per page.
* @returns The list of obtained read receipts and the cursor for next query.
*
* @throws Error, see {@link ChatError}
*/
public async fetchGroupAcks(
msgId: string,
startAckId?: string,
pageSize: number = 0
): Promise<ChatCursorResult<ChatGroupMessageAck>> {
console.log(
`${ChatManager.TAG}: asyncFetchGroupAcks: ${msgId}, ${startAckId}, ${pageSize}`
);
let r: any = await Native._callMethod(MethodTypeasyncFetchGroupAcks, {
[MethodTypeasyncFetchGroupAcks]: {
msg_id: msgId,
ack_id: startAckId,
pageSize: pageSize,
},
});
Native.hasErrorFromResult(r);
let ret = new ChatCursorResult<ChatGroupMessageAck>({
cursor: r?.[MethodTypeasyncFetchGroupAcks].cursor,
list: r?.[MethodTypeasyncFetchGroupAcks].list,
opt: {
map: (param: any) => {
return new ChatGroupMessageAck(param);
},
},
});
return ret;
}
/**
* Deletes the specified conversation and the related historical messages from the server.
*
* @param convId The conversation ID.
* @param convType The conversation type. See {@link ChatConversationType}.
* @param isDeleteMessage Whether to delete the chat history when deleting the conversation.
* - `true`: (default) Yes.
* - `false`: No.
*
* @throws Error, see {@link ChatError}
*/
public async deleteRemoteConversation(
convId: string,
convType: ChatConversationType,
isDeleteMessage: boolean = true
): Promise<void> {
console.log(
`${ChatManager.TAG}: deleteRemoteConversation: ${convId}, ${convType}, ${isDeleteMessage}`
);
let ct = 0;
switch (convType) {
case ChatConversationType.PeerChat:
ct = 0;
break;
case ChatConversationType.GroupChat:
ct = 1;
break;
case ChatConversationType.RoomChat:
ct = 2;
break;
default:
throw new Error('no have this type');
}
let r = await Native._callMethod(MethodTypedeleteRemoteConversation, {
[MethodTypedeleteRemoteConversation]: {
conversationId: convId,
conversationType: ct,
isDeleteRemoteMessage: isDeleteMessage,
},
});
Native.hasErrorFromResult(r);
}
}