react-native-voximplant
Version:
VoxImplant Mobile SDK for embedding voice and video communication into React Native apps.
638 lines (596 loc) • 22.9 kB
JavaScript
/*
* Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved.
*/
;
import {
NativeModules,
NativeEventEmitter,
} from 'react-native';
import MessagingShared from "./MessagingShared";
import MessengerEventTypes from "./MessengerEventTypes";
import Conversation from "./Conversation";
import Message from "./Message";
const MessagingModule = NativeModules.RNVIMessagingModule;
const listeners = {};
const EventEmitter = new NativeEventEmitter(MessagingModule);
/**
* @memberOf Voximplant.Messaging
* @class Messenger
* @classdesc Messenger class used to control messaging functions.
*/
export default class Messenger {
/**
* @private
*/
static _instance = null;
/**
* @ignore
*/
constructor() {
if (Messenger._instance) {
throw new Error("Error - use Voximplant.getMessenger()");
}
EventEmitter.addListener('VISetStatus', this._onSetStatus);
EventEmitter.addListener('VISubscribe', this._onSubscribe);
EventEmitter.addListener('VIUnsubscribe', this._onUnsubscribe);
EventEmitter.addListener('VIEditUser', this._onEditUser);
EventEmitter.addListener('VICreateConversation', this._onCreateConversation);
EventEmitter.addListener('VIRemoveConversation', this._onRemoveConversation);
EventEmitter.addListener('VIEditConversation', this._onEditConversation);
EventEmitter.addListener('VITyping', this._onTyping);
EventEmitter.addListener('VISendMessage', this._onSendMessage);
EventEmitter.addListener('VIEditMessage', this._onEditMessage);
EventEmitter.addListener('VIRemoveMessage', this._onRemoveMessage);
EventEmitter.addListener('VIRead', this._onRead);
}
/**
* @ignore
*/
static getInstance() {
if (Messenger._instance === null) {
Messenger._instance = new Messenger();
}
return Messenger._instance;
}
/**
* Register handler for specified messenger event.
* Use {@link Voximplant.Messaging.Messenger.off} method to delete a handler.
*
* @param {Voximplant.Messaging.MessengerEventTypes} eventType
* @param {function} event
*
* @memberOf Voximplant.Messaging.Messenger
*/
on(eventType, event) {
if (!event || !(event instanceof Function)) {
console.warn(`Messenger: on: handler is not a Function`);
return;
}
if (Object.values(MessengerEventTypes).indexOf(eventType) === -1) {
console.warn(`Messenger: on: MessengerEventTypes does not contain ${eventType} event`);
return;
}
if (!listeners[eventType]) {
listeners[eventType] = new Set();
}
listeners[eventType].add(event);
}
/**
* Remove handler for specified event
*
* @param {Voximplant.Messaging.MessengerEventTypes} eventType
* @param {function} event - Handler function. If not specified, all handlers for the event type will be removed.
*
* @memberOf Voximplant.Messaging.Messenger
*/
off(eventType, event) {
if (!listeners[eventType]) {
return;
}
if (Object.values(MessengerEventTypes).indexOf(eventType) === -1) {
console.warn(`Messenger: off: MessengerEventTypes does not contain ${eventType} event`);
return;
}
if (event && event instanceof Function) {
listeners[eventType].delete(event);
} else {
listeners[eventType] = new Set();
}
}
/**
* Get the full Voximplant user identifier, for example 'username@appname.accname', for the current user
*
* @return {string}
*
* @memberOf Voximplant.Messaging.Messenger
*/
getMe() {
return MessagingShared.getInstance().getCurrentUser();
}
/**
* Get information for the user specified by the Voximplant user name, e.g., 'username@appname.accname'.
*
* It's possible to get any user of the main Voximplant developer account or its child accounts.
*
* Only the client that called the method can be informed about getting user information.
*
* @param {string} username - Voximplant user identifier
* @returns {Promise<EventHandlers.UserEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
getUserByName(username) {
return new Promise((resolve, reject) => {
MessagingModule.getUserByName(username, (userEvent, errorEvent) => {
if (userEvent) {
resolve(userEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Get information for the user specified by the IM user id.
*
* It's possible to get any user of the main Voximplant developer account or its child accounts.
*
* Only the client that called the method can be informed about getting user information.
*
* @param {number} userId - IM User id
* @return {Promise<EventHandlers.UserEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
getUserByIMId(userId) {
return new Promise((resolve, reject) => {
MessagingModule.getUserById(userId, (userEvent, errorEvent) => {
if (userEvent) {
resolve(userEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Get information for the users specified by the array of the Voximplant user names. Maximum 50 users.
*
* It's possible to get any users of the main Voximplant developer account or its child accounts.
*
* Only the client that called the method can be informed about getting users information.
*
* @param {Array<string>} users - Array of Voximplant user identifiers
* @return {Promise<Array<EventHandlers.UserEvent>|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
getUsersByName(users) {
return new Promise((resolve, reject) => {
MessagingModule.getUsersByName(users, (userEvents, errorEvent) => {
if (userEvents) {
resolve(userEvents);
} else {
reject(errorEvent);
}
});
});
}
/**
* Get information for the users specified by the array of the IM user ids. Maximum 50 users.
*
* It's possible to get any users of the main Voximplant developer account or its child accounts.
*
* Only the client that called the method can be informed about getting users information.
* @param {Array<number>} users - Array of IM user ids
* @return {Promise<Array<EventHandlers.UserEvent>|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
getUsersByIMId(users) {
return new Promise((resolve, reject) => {
MessagingModule.getUsersById(users, (userEvents, errorEvent) => {
if (userEvents) {
resolve(userEvents);
} else {
reject(errorEvent);
}
});
});
}
/**
* Edit current user information.
*
* Other users that are subscribed to the user can be informed about the editing via the
* {@link Voximplant.Messaging.MessengerEventTypes.EditUser} event.
*
* @param {object} customData - New custom data.
* If null, previously set custom data will not be changed. If empty object, previously set custom data will be removed.
* @param {object} privateCustomData - New private custom data.
* If null, previously set private custom data will not be changed. If empty object, previously set private custom data will be removed.
* @return {Promise<EventHandlers.UserEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
editUser(customData, privateCustomData) {
return new Promise((resolve, reject) => {
MessagingModule.editUser(customData, privateCustomData, (userEvent, errorEvent) => {
if (userEvent) {
resolve(userEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Set the current user status.
*
* Other users (that are subscribed to the user) and other clients (of the current user) can be informed about
* the status changing via the {@link Voximplant.Messaging.MessengerEventTypes.SetStatus} event.
*
* @param {boolean} online - True if user is available for messaging, false otherwise
* @return {Promise<EventHandlers.StatusEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
setStatus(online) {
return new Promise((resolve, reject) => {
MessagingModule.setStatus(online, (statusEvent, errorEvent) => {
if (statusEvent) {
resolve(statusEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Subscribe for other user(s) information and status changes.
*
* It's possible to subscribe for any user of the main Voximplant developer account or its child accounts.
*
* Other logged in clients (of the current user) can be informed about the subscription via
* the {@link Voximplant.Messaging.MessengerEventTypes.Subscribe} event.
*
* User(s) specified in the 'users' parameter aren't informed about the subscription.
*
* @param {Array<number>} users - Array of IM user ids
* @return {Promise<EventHandlers.SubscriptionEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
subscribe(users) {
return new Promise((resolve, reject) => {
MessagingModule.subscribe(users, (subscriptionEvent, errorEvent) => {
if (subscriptionEvent) {
resolve(subscriptionEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Unsubscribe from other user(s) information and status changes.
*
* Other logged in clients (of the current user) can be informed about the unsubscription via
* the {@link Voximplant.Messaging.MessengerEventTypes.Unsubscribe} event.
*
* User(s) specified in the 'users' parameter aren't informed about the unsubscription.
*
* @param {Array<number>} users - Array of IM user ids
* @return {Promise<EventHandlers.SubscriptionEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
unsubscribe(users) {
return new Promise((resolve, reject) => {
MessagingModule.unsubscribe(users, (subscriptionEvent, errorEvent) => {
if (subscriptionEvent) {
resolve(subscriptionEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Unsubscribe from all subscriptions.
*
* Other logged in clients (of the current user) can be informed about the unsubscription via
* the {@link Voximplant.Messaging.MessengerEventTypes.Unsubscribe} event.
*
* Other users aren't informed about the unsubscription.
* @return {Promise<EventHandlers.SubscriptionEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
unsubscribeFromAll() {
return new Promise((resolve, reject) => {
MessagingModule.unsubscribeFromAll((subscriptionEvent, errorEvent) => {
if (subscriptionEvent) {
resolve(subscriptionEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Get all current subscriptions, i.e., the array of users the current user is subscribed to.
*
* Only the client that called the method can be informed about getting subscriptions.
*
* @return {Promise<EventHandlers.SubscriptionEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
getSubscriptions() {
return new Promise((resolve, reject) => {
MessagingModule.getSubscriptions((subscriptionEvent, errorEvent) => {
if (subscriptionEvent) {
resolve(subscriptionEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Manage messenger push notification subscriptions for the current user.
*
* Other logged in clients (of the current user) can be informed about managing push notifications via
* {@link Voximplant.Messaging.MessengerEventTypes.EditUser}
*
* @param {Array<Voximplant.Messaging.MessengerNotification>} notifications - Array of messenger notification types
* @return {Promise<EventHandlers.UserEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
managePushNotifications(notifications) {
return new Promise((resolve, reject) => {
MessagingModule.manageNotifications(notifications, (userEvent, errorEvent) => {
if (userEvent) {
resolve(userEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Create a new conversation with the extended configuration.
*
* Other parties of the conversation (online participants and logged in clients) can be informed about
* the conversation creation via the {@link Voximplant.Messaging.MessengerEventTypes.CreateConversation}.
*
* @param {Voximplant.Messaging.ConversationConfig} [conversationConfig] - ConversationConfig instance with extended conversation parameters
* @return {Promise<EventHandlers.ConversationEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
createConversation(conversationConfig) {
return new Promise((resolve, reject) => {
MessagingModule.createConversation(conversationConfig, (conversationEvent, errorEvent) => {
if (conversationEvent) {
Conversation._processConversationEvent(conversationEvent);
resolve(conversationEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Get a conversation by its UUID.
*
* It's possible if:
* - the user that calls the method is/was a participant of this conversation
* - the conversation is an available public conversation (see {@link Voximplant.Messaging.Messenger#getPublicConversations})
*
* Only the client that called the method can be informed about getting conversation.
*
* @param {string} uuid - Conversation UUID
* @return {Promise<EventHandlers.ConversationEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
getConversation(uuid) {
return new Promise((resolve, reject) => {
MessagingModule.getConversation(uuid, (conversationEvent, errorEvent) => {
if (conversationEvent) {
Conversation._processConversationEvent(conversationEvent);
resolve(conversationEvent);
} else {
reject(errorEvent);
}
})
});
}
/**
* Get the multiple conversations by the list of UUIDs. Maximum 30 conversations.
*
* It's possible if:
* - the user that calls the method is/was a participant of this conversation
* - the conversation is an available public conversation (see {@link Voximplant.Messaging.Messenger#getPublicConversations})
*
* Only the client that called the method can be informed about getting conversations.
*
* @param {Array<string>} uuids - Array of UUIDs. Maximum 30 conversations.
* @return {Promise<Array<EventHandlers.ConversationEvent>|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
getConversations(uuids) {
return new Promise((resolve, reject) => {
MessagingModule.getConversations(uuids, (conversationEvents, errorEvent) => {
if (conversationEvents) {
for (let i in conversationEvents) {
if (conversationEvents.hasOwnProperty(i)) {
Conversation._processConversationEvent(conversationEvents[i]);
}
}
resolve(conversationEvents);
} else {
reject(errorEvent);
}
});
});
}
/**
* Get all public conversations ({@link Voximplant.Messaging.Conversation#publicJoin} is true).
*
* It's possible to get all public conversations (UUIDs) that were created by:
* - the current user
* - other users of the same child account
* - users of the main Voximplant developer account
*
* Only the client that called the method can be informed about getting public conversations UUIDs.
*
* @return {Promise<EventHandlers.ConversationListEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
getPublicConversations() {
return new Promise((resolve, reject) => {
MessagingModule.getPublicConversations((conversationListEvent, errorEvent) => {
if (conversationListEvent) {
resolve(conversationListEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Join the current user to any conversation specified by the UUID.
*
* It's possible only on the following conditions:
* - a conversation is created by a user of the main Voximplant developer account or its child accounts
* - public join is enabled ({@link Voximplant.Messaging.Conversation#publicJoin} is true)
* - the conversation is not a direct one ({@link Voximplant.Messaging.Conversation#direct} is false)
*
* Other parties of the conversation (online participants and logged in clients) can be informed
* about joining to the conversation via the {@link Voximplant.Messaging.MessengerEventTypes.EditConversation} event.
*
* @param {string} uuid - Conversation UUID
* @return {Promise<EventHandlers.ConversationListEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
joinConversation(uuid) {
return new Promise((resolve, reject) => {
MessagingModule.joinConversation(uuid, (conversationEvent, errorEvent) => {
if (conversationEvent) {
Conversation._processConversationEvent(conversationEvent);
resolve(conversationEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Make the current user leave a conversation specified by the UUID.
*
* It's possible only if the conversation is not a direct one ({@link Voximplant.Messaging.Conversation#direct} is false).
*
* After a successful method call the conversation's UUID will be added to {@link Voximplant.Messaging.User#leaveConversationList}.
*
* Other parties of the conversation (online participants and logged in clients) can be informed
* about leaving the conversation via the {@link Voximplant.Messaging.MessengerEventTypes.EditConversation} event.
*
* @param {string} uuid - Conversation UUID
* @return {Promise<EventHandlers.ConversationListEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Messenger
*/
leaveConversation(uuid) {
return new Promise((resolve, reject) => {
MessagingModule.leaveConversation(uuid, (conversationEvent, errorEvent) => {
if (conversationEvent) {
Conversation._processConversationEvent(conversationEvent);
resolve(conversationEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* @private
*/
_emit(event, ...args) {
const handlers = listeners[event];
if (handlers) {
for (const handler of handlers) {
handler(...args);
}
}
}
/**
* @private
*/
_onSetStatus = (event) => {
this._emit(MessengerEventTypes.SetStatus, event);
};
/**
* @private
*/
_onSubscribe = (event) => {
this._emit(MessengerEventTypes.Subscribe, event);
};
/**
* @private
*/
_onUnsubscribe = (event) => {
this._emit(MessengerEventTypes.Unsubscribe, event);
};
/**
* @private
*/
_onEditUser = (event) => {
this._emit(MessengerEventTypes.EditUser, event);
};
/**
* @private
*/
_onCreateConversation = (event) => {
Conversation._processConversationEvent(event);
this._emit(MessengerEventTypes.CreateConversation, event);
};
/**
* @private
*/
_onRemoveConversation = (event) => {
let conversation = new Conversation();
conversation.uuid = event.conversation.uuid;
delete event.conversation;
event.conversation = conversation;
this._emit(MessengerEventTypes.RemoveConversation, event);
};
/**
* @private
*/
_onEditConversation = (event) => {
Conversation._processConversationEvent(event);
this._emit(MessengerEventTypes.EditConversation, event);
};
/**
* @private
*/
_onTyping = (event) => {
this._emit(MessengerEventTypes.Typing, event);
};
/**
* @private
*/
_onSendMessage = (event) => {
Message._processMessageEvent(event);
this._emit(MessengerEventTypes.SendMessage, event);
};
/**
* @private
*/
_onEditMessage = (event) => {
Message._processMessageEvent(event);
this._emit(MessengerEventTypes.EditMessage, event);
};
/**
* @private
*/
_onRemoveMessage = (event) => {
Message._processMessageEvent(event);
this._emit(MessengerEventTypes.RemoveMessage, event);
};
/**
* @private
*/
_onRead = (event) => {
this._emit(MessengerEventTypes.Read, event);
};
}