react-native-voximplant
Version:
VoxImplant Mobile SDK for embedding voice and video communication into React Native apps.
483 lines (453 loc) • 21.5 kB
JavaScript
/*
* Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved.
*/
;
import {
NativeModules,
} from 'react-native';
import Message from './Message';
import MessagingShared from "./MessagingShared";
import MessengerEventTypes from "./MessengerEventTypes";
const MessagingModule = NativeModules.RNVIMessagingModule;
/**
* @memberOf Voximplant.Messaging
* @class Conversation
* @classdesc Class that may be used to manage a conversation.
*/
export default class Conversation {
/**
* @member {number} createdTime - UNIX timestamp (seconds) that specifies the time of the conversation creation.
* @memberOf Voximplant.Messaging.Conversation
*/
createdTime;
/**
* @member {object} customData - JavaScript object with custom data, up to 5kb.
*
* Note that setting this property does not send changes to the server.
* Use the {@link Voximplant.Messaging.Conversation.update} to send all changes at once.
*
* @memberOf Voximplant.Messaging.Conversation
*/
customData;
/**
* @member {boolean} direct - Check if the conversation is direct.
*
* A direct conversation can't be uber and/or public.
*
* There can be only 2 participants in a direct conversation which is unique and the only one for these participants.
* There can't be more than 1 direct conversation for the same 2 users.
*
* If one of these users tries to create a new direct conversation with the same participant via
* {@link Voximplant.Messaging.Messenger#createConversation}, the method will return the UUID of the already existing direct conversation.
*
* @memberOf Voximplant.Messaging.Conversation
*/
direct;
/**
* @member {number} lastSequence - Sequence of the last event in the conversation.
* @memberOf Voximplant.Messaging.Conversation
*/
lastSequence;
/**
* @member {number} lastUpdateTime - UNIX timestamp (seconds) that specifies the time when one of
* {@link EventHandlers.ConversationEvent} or {@link EventHandlers.MessageEvent} was the last provoked event in this conversation.
* @memberOf Voximplant.Messaging.Conversation
*/
lastUpdateTime;
/**
* @member {Array<Voximplant.Messaging.ConversationParticipant>} participants - Array of participants alongside with their permissions.
* @memberOf Voximplant.Messaging.Conversation
*/
participants;
/**
* @member {boolean} publicJoin - Check if a conversation is public or not. If true, anyone can join the conversation by UUID.
*
* A public conversation can't be direct.
*
* Note that setting this property does not send changes to the server.
* Use the {@link Voximplant.Messaging.Conversation.update} to send all changes at once.
* @memberOf Voximplant.Messaging.Conversation
*/
publicJoin;
/**
* @member {string} title - Th current conversation title.
*
* Note that setting this property does not send changes to the server.
* Use the {@link Voximplant.Messaging.Conversation.update} to send all changes at once.
*
* @memberOf Voximplant.Messaging.Conversation
*/
title;
/**
* @member {string} uuid - Universally unique identifier (UUID) of this conversation.
* @memberOf Voximplant.Messaging.Conversation
*/
uuid;
/**
* @member {boolean} uber - Check if the conversation is uber or not.
*
* A uber conversation can't be direct.
*
* Users in a uber conversation will not be able to retrieve messages that were posted to the conversation after they quit.
* @memberOf Voximplant.Messaging.Conversation
*/
uber;
/**
* @ignore
*/
constructor() {
}
/**
* Set the JS object custom data. Note that setting this property does not send changes to the server.
* Use the {@link Voximplant.Messaging.Conversation#update} to send all changes at once.
*
* @param {object} customData - New custom data of the conversation
* @memberOf Voximplant.Messaging.Conversation
*/
setCustomData(customData) {
this.customData = customData;
}
/**
* Set the public join flag. Note that setting this property does not send changes to the server.
* Use the {@link Voximplant.Messaging.Conversation#update} to send all changes at once.
*
* @param {boolean} publicJoin
* @memberOf Voximplant.Messaging.Conversation
*/
setPublicJoin(publicJoin) {
this.publicJoin = publicJoin;
}
/**
* Set the conversation title. Note that setting this property does not send changes to the server.
* Use the {@link Voximplant.Messaging.Conversation#update} to send all changes at once.
*
* @param {string} title
* @memberOf Voximplant.Messaging.Conversation
*/
setTitle(title) {
this.title = title;
}
/**
* Add new participants to the conversation.
*
* It's possible only on the following conditions:
* - the participants are users of the main Voximplant developer account or its child accounts
* - the current user can manage other participants ({@link Voximplant.Messaging.ConversationParticipant#canManageParticipants} is true)
* - the conversation is not a direct one ({@link Voximplant.Messaging.Conversation#direct} is false)
*
* Duplicated users are ignored. The promise will be rejected with {@link EventHandlers.ErrorEvent} if at least one user does not exist
* or already belongs to the conversation.
*
* Other parties of the conversation (online participants and logged in clients) can be informed about adding
* participants via the {@link Voximplant.Messaging.MessengerEventTypes.EditConversation} event.
*
* @param {Array<Voximplant.Messaging.ConversationParticipant>} participants - Array of ConversationParticipant to be added to the conversation.
* Should not be null or empty array
* @return {Promise<EventHandlers.ConversationEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Conversation
*/
addParticipants(participants) {
return new Promise((resolve, reject) => {
MessagingModule.addParticipants(this.uuid, participants, (conversationEvent, errorEvent) => {
if (conversationEvent) {
Conversation._processConversationEvent(conversationEvent);
resolve(conversationEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Edit participants' permissions. It's possible only if the current user can manage other participants
* ({@link Voximplant.Messaging.ConversationParticipant#canManageParticipants} is true).
*
* Duplicated users are ignored. The list of participants must contain all participants.
* Other parties of the conversation (online participants and logged in clients) can be informed about editing
* participants via the {@link Voximplant.Messaging.MessengerEventTypes.EditConversation} event.
*
* @param {Array<Voximplant.Messaging.ConversationParticipant>} participants - Array of ConversationParticipant to be edited in the conversation.
* Should not be null or empty array
* @return {Promise<EventHandlers.ConversationEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Conversation
*/
editParticipants(participants) {
return new Promise((resolve, reject) => {
MessagingModule.editParticipants(this.uuid, participants, (conversationEvent, errorEvent) => {
if (conversationEvent) {
Conversation._processConversationEvent(conversationEvent);
resolve(conversationEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Remove participants from the conversation.
* It's possible only on two conditions:
* - the current user can manage other participants ({@link Voximplant.Messaging.ConversationParticipant#canManageParticipants} is true).
* - the conversation is not a direct one ({@link Voximplant.Messaging.Conversation#direct} is false)
*
* Duplicated users are ignored. The promise will be rejected with {@link EventHandlers.ErrorEvent} if at least one user:
* - does not exist
* - is already removed
*
* Note that you can remove participants that are marked as deleted ({@link Voximplant.Messaging.User#isDeleted} is true).
*
* The removed participants can later get this conversation's UUID via the {@link Voximplant.Messaging.User#leaveConversationList}.
*
* Other parties of the conversation (online participants and logged in clients) can be informed about removing participants
* via the {@link Voximplant.Messaging.MessengerEventTypes.EditConversation} event.
*
* @param {Array<Voximplant.Messaging.ConversationParticipant>} participants - Array of ConversationParticipant to be removed from the conversation.
* Should not be null or empty array
* @return {Promise<EventHandlers.ConversationEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Conversation
*/
removeParticipants(participants) {
return new Promise((resolve, reject) => {
MessagingModule.removeParticipants(this.uuid, participants, (conversationEvent, errorEvent) => {
if (conversationEvent) {
Conversation._processConversationEvent(conversationEvent);
resolve(conversationEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Send conversation changes to the cloud. The sent changes are: title, public join flag and custom data.
*
* Successful update will happen if a participant is the owner ({@link Voximplant.Messaging.ConversationParticipant#owner} is true).
*
* Other parties of the conversation (online participants and logged in clients) can be informed about changing
* the title or custom data and enabling/disabling public join via
* the {@link Voximplant.Messaging.MessengerEventTypes.EditConversation} event.
*
* @return {Promise<EventHandlers.ConversationEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Conversation
*/
update() {
return new Promise((resolve, reject) => {
MessagingModule.updateConversation(this.uuid, this.title, this.publicJoin,
this.customData, this.uber, this.direct, (conversationEvent, errorEvent) => {
if (conversationEvent) {
Conversation._processConversationEvent(conversationEvent);
resolve(conversationEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Inform the cloud that the user is typing some text.
*
* The promise will be rejected with {@link EventHandlers.ErrorEvent} for the method calls within 10s interval from the last call cause.
*
* Other parties of the conversation (online participants and logged in clients) can be informed about typing
* via the {@link Voximplant.Messaging.MessengerEventTypes.Typing} event.
*
* @return {Promise<EventHandlers.ConversationServiceEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Conversation
*/
typing() {
return new Promise((resolve, reject) => {
MessagingModule.typing(this.uuid, (conversationServiceEvent, errorEvent) => {
if (conversationServiceEvent) {
resolve(conversationServiceEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Send a message to the conversation.
*
* Sending messages is available only for participants that have write permissions
* ({@link Voximplant.Messaging.ConversationParticipant#canWrite} is true).
*
* Other parties of the conversation (online participants and logged in clients) can be informed about
* sending messages to the conversation via the {@link Voximplant.Messaging.MessengerEventTypes.SendMessage} event.
*
* To be informed about sending messages while being offline, participants can subscribe
* to the {@link Voximplant.Messaging.MessengerNotification.SendMessage} messenger push notification.
*
* @param {string} text - Message text, maximum 5000 characters
* @param {Array<object>} [payload] - Message payload
* @return {Promise<EventHandlers.MessageEvent|EventHandlers.ErrorEvent>}
*
* @memberOf Voximplant.Messaging.Conversation
*/
sendMessage(text, payload) {
return new Promise((resolve, reject) => {
MessagingModule.sendMessage(this.uuid, text, payload, (messageEvent, errorEvent) => {
if (messageEvent) {
Message._processMessageEvent(messageEvent);
resolve(messageEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Mark the event with the specified sequence as read.
*
* A method call with the specified sequence makes the {@link Voximplant.Messaging.ConversationParticipant#lastReadEventSequence}
* return this sequence, i.e., such sequences can be get for each participant separately.
*
* If the sequence parameter specified less than 1, the method will mark all the events as unread (for this participant)
* except the event with the sequence equals to '1'.
*
* Other parties of the conversation (online participants and logged in clients) can be informed about marking events
* as read via the {@link Voximplant.Messaging.MessengerEventTypes.Read} event.
*
* @param {number} sequence - Sequence number of the event in the conversation to be marked as read. Shouldn't be greater than currently possible.
* @return {Promise<EventHandlers.ConversationServiceEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Conversation
*/
markAsRead(sequence) {
return new Promise((resolve, reject) => {
MessagingModule.markAsRead(this.uuid, sequence, (conversationServiceEvent, errorEvent) => {
if (conversationServiceEvent) {
resolve(conversationServiceEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Request events in the specified sequence range to be sent from the cloud to this client.
*
* Only {@link EventHandlers.ConversationEvent} and {@link EventHandlers.MessageEvent} events can be retransmitted;
* any other events can't be retransmitted.
*
* The method is used to get history or missed events in case of network disconnect. Client should use this method
* to request all events based on the last event sequence received from the cloud and last event sequence saved locally (if any).
*
* The maximum amount of retransmitted events per method call is 100. The promise will be rejected with {@link EventHandlers.ErrorEvent}
* if more than 100 events are requested.
*
* If the current user quits a {@link Voximplant.Messaging.Conversation#uber} conversation, messages that are posted
* during the user's absence will not be retransmitted later.
*
* @param {number} from - First event in range sequence, inclusive
* @param {number} to - Last event in sequence range, inclusive
* @return {Promise<EventHandlers.RetransmitEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Conversation
*/
retransmitEvents(from, to) {
return new Promise((resolve, reject) => {
MessagingModule.retransmitEvents(this.uuid, from, to, (retransmitEvent, errorEvent) => {
if (retransmitEvent) {
Conversation._processRetransmitEvent(retransmitEvent);
resolve(retransmitEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Request a number of events starting with the specified sequence to be sent from the cloud to this client.
*
* Only {@link EventHandlers.ConversationEvent} and {@link EventHandlers.MessageEvent} events can be retransmitted;
* any other events can't be retransmitted.
*
* The method is used to get history or missed events in case of network disconnect. Client should use this method
* to request all events based on the last event sequence received from the cloud and last event sequence saved locally (if any).
*
* The maximum amount of retransmitted events per method call is 100. The promise will be rejected with {@link EventHandlers.ErrorEvent}
* if more than 100 events are requested.
*
* If the current user quits a {@link Voximplant.Messaging.Conversation#uber} conversation, messages that are posted
* during the user's absence will not be retransmitted later.
*
* The result contains maximum available events for the current user even if it's less than the specified count value.
*
* @param {number} from - First event in sequence range, inclusive
* @param {number} count - Number of events
* @return {Promise<EventHandlers.RetransmitEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Conversation
*/
retransmitEventsFrom(from, count) {
return new Promise((resolve, reject) => {
MessagingModule.retransmitEventsFrom(this.uuid, from, count, (retransmitEvent, errorEvent) => {
if (retransmitEvent) {
Conversation._processRetransmitEvent(retransmitEvent);
resolve(retransmitEvent);
} else {
reject(errorEvent);
}
});
});
}
/**
* Request a number of events up to the specified sequence to be sent from the cloud to this client.
*
* Only {@link EventHandlers.ConversationEvent} and {@link EventHandlers.MessageEvent} events can be retransmitted;
* any other events can't be retransmitted.
*
* The method is used to get history or missed events in case of network disconnect. Client should use this method
* to request all events based on the last event sequence received from the cloud and last event sequence saved locally (if any).
*
* The maximum amount of retransmitted events per method call is 100. The promise will be rejected with {@link EventHandlers.ErrorEvent}
* if more than 100 events are requested.
*
* If the current user quits a {@link Voximplant.Messaging.Conversation#uber} conversation, messages that are posted
* during the user's absence will not be retransmitted later.
*
* The result contains maximum available events for the current user even if it's less than the specified count value.
*
* @param {number} to - Last event in sequence range, inclusive
* @param {number} count - Number of events
* @return {Promise<EventHandlers.RetransmitEvent|EventHandlers.ErrorEvent>}
* @memberOf Voximplant.Messaging.Conversation
*/
retransmitEventsTo(to, count) {
return new Promise((resolve, reject) => {
MessagingModule.retransmitEventsTo(this.uuid, to, count, (retransmitEvent, errorEvent) => {
if (retransmitEvent) {
Conversation._processRetransmitEvent(retransmitEvent);
resolve(retransmitEvent);
} else {
reject(errorEvent);
}
});
});
}
static _processConversationEvent(event) {
// console.log('_processConversationEvent start');
let conversation = new Conversation();
conversation.createdTime = event.conversation.createdTime;
conversation.uuid = event.conversation.uuid;
conversation.participants = event.conversation.participants;
conversation.uber = event.conversation.uber;
conversation.lastSequence = event.conversation.lastSequence;
conversation.publicJoin = event.conversation.publicJoin;
conversation.direct = event.conversation.direct;
conversation.lastUpdateTime = event.conversation.lastUpdateTime;
conversation.customData = event.conversation.customData;
conversation.title = event.conversation.title;
delete event.conversation;
event.conversation = conversation;
// console.log('_processConversationEvent end');
}
static _processRetransmitEvent(event) {
if (event.events) {
for (let retransmitEvent of event.events) {
if (retransmitEvent.hasOwnProperty('conversation')) {
Conversation._processConversationEvent(retransmitEvent);
}
if (retransmitEvent.hasOwnProperty('message')) {
Message._processMessageEvent(retransmitEvent);
}
}
}
}
}