123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- // @flow
-
- import type { Dispatch } from 'redux';
-
- import { getInviteURL } from '../base/connection';
- import { getLocalParticipant, getParticipantCount } from '../base/participants';
- import { inviteVideoRooms } from '../videosipgw';
-
- import {
- ADD_PENDING_INVITE_REQUEST,
- BEGIN_ADD_PEOPLE,
- HIDE_ADD_PEOPLE_DIALOG,
- REMOVE_PENDING_INVITE_REQUESTS,
- SET_CALLEE_INFO_VISIBLE,
- UPDATE_DIAL_IN_NUMBERS_FAILED,
- UPDATE_DIAL_IN_NUMBERS_SUCCESS
- } from './actionTypes';
- import { INVITE_TYPES } from './constants';
- import {
- getDialInConferenceID,
- getDialInNumbers,
- invitePeopleAndChatRooms,
- inviteSipEndpoints
- } from './functions';
- import logger from './logger';
-
- /**
- * Creates a (redux) action to signal that a click/tap has been performed on
- * {@link InviteButton} and that the execution flow for adding/inviting people
- * to the current conference/meeting is to begin.
- *
- * @returns {{
- * type: BEGIN_ADD_PEOPLE
- * }}
- */
- export function beginAddPeople() {
- return {
- type: BEGIN_ADD_PEOPLE
- };
- }
-
- /**
- * Creates a (redux) action to signal that the {@code AddPeopleDialog}
- * should close.
- *
- * @returns {{
- * type: HIDE_ADD_PEOPLE_DIALOG
- * }}
- */
- export function hideAddPeopleDialog() {
- return {
- type: HIDE_ADD_PEOPLE_DIALOG
- };
- }
-
-
- /**
- * Invites (i.e. Sends invites to) an array of invitees (which may be a
- * combination of users, rooms, phone numbers, and video rooms.
- *
- * @param {Array<Object>} invitees - The recipients to send invites to.
- * @param {Array<Object>} showCalleeInfo - Indicates whether the
- * {@code CalleeInfo} should be displayed or not.
- * @returns {Promise<Array<Object>>} A {@code Promise} resolving with an array
- * of invitees who were not invited (i.e. Invites were not sent to them).
- */
- export function invite(
- invitees: Array<Object>,
- showCalleeInfo: boolean = false) {
- return (
- dispatch: Dispatch<any>,
- getState: Function): Promise<Array<Object>> => {
- const state = getState();
- const participantsCount = getParticipantCount(state);
- const { calleeInfoVisible } = state['features/invite'];
-
- if (showCalleeInfo
- && !calleeInfoVisible
- && invitees.length === 1
- && invitees[0].type === INVITE_TYPES.USER
- && participantsCount === 1) {
- dispatch(setCalleeInfoVisible(true, invitees[0]));
- }
-
- const { conference, password } = state['features/base/conference'];
-
- if (typeof conference === 'undefined') {
- // Invite will fail before CONFERENCE_JOIN. The request will be
- // cached in order to be executed on CONFERENCE_JOIN.
- return new Promise(resolve => {
- dispatch(addPendingInviteRequest({
- invitees,
- callback: failedInvitees => resolve(failedInvitees)
- }));
- });
- }
-
- let allInvitePromises = [];
- let invitesLeftToSend = [ ...invitees ];
-
- const {
- callFlowsEnabled,
- inviteServiceUrl,
- inviteServiceCallFlowsUrl
- } = state['features/base/config'];
- const inviteUrl = getInviteURL(state);
- const { sipInviteUrl } = state['features/base/config'];
- const { locationURL } = state['features/base/connection'];
- const { jwt } = state['features/base/jwt'];
- const { name: displayName } = getLocalParticipant(state);
-
- // First create all promises for dialing out.
- const phoneNumbers
- = invitesLeftToSend.filter(({ type }) => type === INVITE_TYPES.PHONE);
-
- // For each number, dial out. On success, remove the number from
- // {@link invitesLeftToSend}.
- const phoneInvitePromises = phoneNumbers.map(item => {
- const numberToInvite = item.number;
-
- return conference.dial(numberToInvite)
- .then(() => {
- invitesLeftToSend
- = invitesLeftToSend.filter(
- invitee => invitee !== item);
- })
- .catch(error =>
- logger.error('Error inviting phone number:', error));
- });
-
- allInvitePromises = allInvitePromises.concat(phoneInvitePromises);
-
- const usersAndRooms
- = invitesLeftToSend.filter(
- ({ type }) => [ INVITE_TYPES.USER, INVITE_TYPES.ROOM ].includes(type));
-
- if (usersAndRooms.length) {
- // Send a request to invite all the rooms and users. On success,
- // filter all rooms and users from {@link invitesLeftToSend}.
- const peopleInvitePromise
- = invitePeopleAndChatRooms(
- callFlowsEnabled
- ? inviteServiceCallFlowsUrl : inviteServiceUrl,
- inviteUrl,
- jwt,
- usersAndRooms)
- .then(() => {
- invitesLeftToSend
- = invitesLeftToSend.filter(
- ({ type }) => ![ INVITE_TYPES.USER, INVITE_TYPES.ROOM ].includes(type));
- })
- .catch(error => {
- dispatch(setCalleeInfoVisible(false));
- logger.error('Error inviting people:', error);
- });
-
- allInvitePromises.push(peopleInvitePromise);
- }
-
- // Sipgw calls are fire and forget. Invite them to the conference, then
- // immediately remove them from invitesLeftToSend.
- const vrooms
- = invitesLeftToSend.filter(({ type }) => type === INVITE_TYPES.VIDEO_ROOM);
-
- conference
- && vrooms.length > 0
- && dispatch(inviteVideoRooms(conference, vrooms));
-
- invitesLeftToSend
- = invitesLeftToSend.filter(({ type }) => type !== INVITE_TYPES.VIDEO_ROOM);
-
- const sipEndpoints
- = invitesLeftToSend.filter(({ type }) => type === INVITE_TYPES.SIP);
-
- conference && inviteSipEndpoints(
- sipEndpoints,
- locationURL,
- sipInviteUrl,
- jwt,
- conference.options.name,
- password,
- displayName
- );
-
- invitesLeftToSend
- = invitesLeftToSend.filter(({ type }) => type !== INVITE_TYPES.SIP);
-
- return (
- Promise.all(allInvitePromises)
- .then(() => invitesLeftToSend));
- };
- }
-
- /**
- * Sends AJAX requests for dial-in numbers and conference ID.
- *
- * @returns {Function}
- */
- export function updateDialInNumbers() {
- return (dispatch: Dispatch<any>, getState: Function) => {
- const state = getState();
- const { dialInConfCodeUrl, dialInNumbersUrl, hosts }
- = state['features/base/config'];
- const { numbersFetched } = state['features/invite'];
- const mucURL = hosts && hosts.muc;
-
- if (numbersFetched || !dialInConfCodeUrl || !dialInNumbersUrl || !mucURL) {
- // URLs for fetching dial in numbers not defined
- return;
- }
-
- const { room } = state['features/base/conference'];
-
- Promise.all([
- getDialInNumbers(dialInNumbersUrl, room, mucURL),
- getDialInConferenceID(dialInConfCodeUrl, room, mucURL)
- ])
- .then(([ dialInNumbers, { conference, id, message, sipUri } ]) => {
- if (!conference || !id) {
- return Promise.reject(message);
- }
-
- dispatch({
- type: UPDATE_DIAL_IN_NUMBERS_SUCCESS,
- conferenceID: id,
- dialInNumbers,
- sipUri
- });
- })
- .catch(error => {
- dispatch({
- type: UPDATE_DIAL_IN_NUMBERS_FAILED,
- error
- });
- });
- };
- }
-
- /**
- * Sets the visibility of {@code CalleeInfo}.
- *
- * @param {boolean|undefined} [calleeInfoVisible] - If {@code CalleeInfo} is
- * to be displayed/visible, then {@code true}; otherwise, {@code false} or
- * {@code undefined}.
- * @param {Object|undefined} [initialCalleeInfo] - Callee information.
- * @returns {{
- * type: SET_CALLEE_INFO_VISIBLE,
- * calleeInfoVisible: (boolean|undefined),
- * initialCalleeInfo
- * }}
- */
- export function setCalleeInfoVisible(
- calleeInfoVisible: boolean,
- initialCalleeInfo: ?Object) {
- return {
- type: SET_CALLEE_INFO_VISIBLE,
- calleeInfoVisible,
- initialCalleeInfo
- };
- }
-
- /**
- * Adds pending invite request.
- *
- * @param {Object} request - The request.
- * @returns {{
- * type: ADD_PENDING_INVITE_REQUEST,
- * request: Object
- * }}
- */
- export function addPendingInviteRequest(
- request: { invitees: Array<Object>, callback: Function }) {
- return {
- type: ADD_PENDING_INVITE_REQUEST,
- request
- };
- }
-
- /**
- * Removes all pending invite requests.
- *
- * @returns {{
- * type: REMOVE_PENDING_INVITE_REQUEST
- * }}
- */
- export function removePendingInviteRequests() {
- return {
- type: REMOVE_PENDING_INVITE_REQUESTS
- };
- }
|