import type { EmitterSubscription, NativeEventEmitter } from 'react-native'; import type { ChatPresenceEventListener } from './ChatEvents'; import { ChatPresence } from './common/ChatPresence'; import { MTfetchPresenceStatus, MTfetchSubscribedMembersWithPageNum, MTonPresenceStatusChanged, MTpresenceSubscribe, MTpresenceUnsubscribe, MTpublishPresenceWithDescription, } from './__internal__/Consts'; import { Native } from './__internal__/Native'; export class ChatPresenceManager extends Native { private static TAG = 'ChatPresenceManager'; private _presenceListeners: Set; private _presenceSubscriptions: Map; constructor() { super(); this._presenceListeners = new Set(); this._presenceSubscriptions = new Map(); } public setNativeListener(event: NativeEventEmitter): void { console.log(`${ChatPresenceManager.TAG}: setNativeListener: `); this._presenceSubscriptions.forEach((value: EmitterSubscription) => { value.remove(); }); this._presenceSubscriptions.clear(); this._presenceSubscriptions.set( MTonPresenceStatusChanged, event.addListener(MTonPresenceStatusChanged, (params: any) => { this.invokePresenceListener(params); }) ); } private invokePresenceListener(params: any): void { this._presenceListeners.forEach((listener: ChatPresenceEventListener) => { const ret: Array = []; const l: Array = params?.[MTonPresenceStatusChanged].presences; l.forEach((value: any) => { ret.push(new ChatPresence(value)); }); listener.onPresenceStatusChanged(ret); }); } /** * Add presence listener. * * @param listener The listener to be added. */ addPresenceListener(listener: ChatPresenceEventListener): void { this._presenceListeners.add(listener); } /** * Remove presence listener. * * @param listener The listener to be deleted. */ removePresenceListener(listener: ChatPresenceEventListener): void { this._presenceListeners.delete(listener); } /** * Clear all presence listener. */ removeAllPresenceListener(): void { this._presenceListeners.clear(); } /** * Publishes a custom presence state. * * @param description The extension information of the presence state. It can be set as nil. * * @throws A description of the exception. See {@link ChatError}. */ public async publishPresenceWithDescription( description?: string ): Promise { console.log(`${ChatPresenceManager.TAG}: publishPresenceWithDescription: `); let r: any = await Native._callMethod(MTpublishPresenceWithDescription, { [MTpublishPresenceWithDescription]: { desc: description, }, }); ChatPresenceManager.checkErrorFromResult(r); } /** * Subscribes to a user's presence states. If the subscription succeeds, the subscriber will receive the callback when the user's presence state changes. * * @param members The list of IDs of users whose presence states you want to subscribe to. * @param expiry The expiration time of the presence subscription. * @returns Which contains IDs of users whose presence states you have subscribed to. * * @throws A description of the exception. See {@link ChatError}. */ public async subscribe( members: Array, expiry: number ): Promise> { console.log(`${ChatPresenceManager.TAG}: subscribe: `); let r: any = await Native._callMethod(MTpresenceSubscribe, { [MTpresenceSubscribe]: { members, expiry, }, }); ChatPresenceManager.checkErrorFromResult(r); const ret: Array = []; Object.entries(r?.[MTpresenceSubscribe]).forEach((value: [string, any]) => { ret.push(new ChatPresence(value[1])); }); return ret; } /** * Unsubscribes from a user's presence states. * * @param members The array of IDs of users whose presence states you want to unsubscribe from. * * @throws A description of the exception. See {@link ChatError}. */ public async unSubscribe(members: Array): Promise { console.log(`${ChatPresenceManager.TAG}: unSubscribe: `); let r: any = await Native._callMethod(MTpresenceUnsubscribe, { [MTpresenceUnsubscribe]: { members, }, }); ChatPresenceManager.checkErrorFromResult(r); } /** * Uses pagination to get a list of users whose presence states you have subscribed to. * * @param pageNum The current page number, starting from 1. * @param pageSize The number of subscribed users on each page. * @returns Which contains IDs of users whose presence states you have subscribed to. Returns null if you subscribe to no user's presence state. * * @throws A description of the exception. See {@link ChatError}. */ public async fetchSubscribedMembers( pageNum: number = 1, pageSize: number = 20 ): Promise> { console.log(`${ChatPresenceManager.TAG}: fetchSubscribedMembers: `); let r: any = await Native._callMethod(MTfetchSubscribedMembersWithPageNum, { [MTfetchSubscribedMembersWithPageNum]: { pageNum, pageSize, }, }); ChatPresenceManager.checkErrorFromResult(r); return r?.[MTfetchSubscribedMembersWithPageNum] as Array; } /** * Gets the current presence state of users. * * @param members The array of IDs of users whose current presence state you want to check. * @returns Which contains the users whose presence state you have subscribed to. * * @throws A description of the exception. See {@link ChatError}. */ public async fetchPresenceStatus( members: Array ): Promise> { console.log(`${ChatPresenceManager.TAG}: fetchPresenceStatus: `); let r: any = await Native._callMethod(MTfetchPresenceStatus, { [MTfetchPresenceStatus]: { members, }, }); ChatPresenceManager.checkErrorFromResult(r); const ret: Array = []; Object.entries(r?.[MTfetchPresenceStatus]).forEach( (value: [string, any]) => { ret.push(new ChatPresence(value[1])); } ); return ret; } }