You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

actions.js 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // @flow
  2. import { getInviteURL } from '../base/connection';
  3. import { inviteVideoRooms } from '../videosipgw';
  4. import {
  5. BEGIN_ADD_PEOPLE,
  6. UPDATE_DIAL_IN_NUMBERS_FAILED,
  7. UPDATE_DIAL_IN_NUMBERS_SUCCESS
  8. } from './actionTypes';
  9. import {
  10. getDialInConferenceID,
  11. getDialInNumbers,
  12. invitePeopleAndChatRooms
  13. } from './functions';
  14. const logger = require('jitsi-meet-logger').getLogger(__filename);
  15. /**
  16. * Creates a (redux) action to signal that a click/tap has been performed on
  17. * {@link InviteButton} and that the execution flow for adding/inviting people
  18. * to the current conference/meeting is to begin.
  19. *
  20. * @returns {{
  21. * type: BEGIN_ADD_PEOPLE
  22. * }}
  23. */
  24. export function beginAddPeople() {
  25. return {
  26. type: BEGIN_ADD_PEOPLE
  27. };
  28. }
  29. /**
  30. * Invites (i.e. sends invites to) an array of invitees (which may be a
  31. * combination of users, rooms, phone numbers, and video rooms).
  32. *
  33. * @param {Array<Object>} invitees - The recepients to send invites to.
  34. * @returns {Promise<Array<Object>>} A {@code Promise} resolving with an array
  35. * of invitees who were not invited (i.e. invites were not sent to them).
  36. */
  37. export function invite(invitees: Array<Object>) {
  38. return (
  39. dispatch: Dispatch<*>,
  40. getState: Function): Promise<Array<Object>> => {
  41. let allInvitePromises = [];
  42. let invitesLeftToSend = [ ...invitees ];
  43. const state = getState();
  44. const { conference } = state['features/base/conference'];
  45. const {
  46. callFlowsEnabled,
  47. inviteServiceUrl,
  48. inviteServiceCallFlowsUrl
  49. } = state['features/base/config'];
  50. const inviteUrl = getInviteURL(state);
  51. const { jwt } = state['features/base/jwt'];
  52. // First create all promises for dialing out.
  53. if (conference) {
  54. const phoneNumbers
  55. = invitesLeftToSend.filter(({ type }) => type === 'phone');
  56. // For each number, dial out. On success, remove the number from
  57. // {@link invitesLeftToSend}.
  58. const phoneInvitePromises = phoneNumbers.map(item => {
  59. const numberToInvite = item.number;
  60. return conference.dial(numberToInvite)
  61. .then(() => {
  62. invitesLeftToSend
  63. = invitesLeftToSend.filter(
  64. invitee => invitee !== item);
  65. })
  66. .catch(error =>
  67. logger.error('Error inviting phone number:', error));
  68. });
  69. allInvitePromises = allInvitePromises.concat(phoneInvitePromises);
  70. }
  71. const usersAndRooms
  72. = invitesLeftToSend.filter(
  73. ({ type }) => type === 'user' || type === 'room');
  74. if (usersAndRooms.length) {
  75. // Send a request to invite all the rooms and users. On success,
  76. // filter all rooms and users from {@link invitesLeftToSend}.
  77. const peopleInvitePromise
  78. = invitePeopleAndChatRooms(
  79. callFlowsEnabled
  80. ? inviteServiceCallFlowsUrl : inviteServiceUrl,
  81. inviteUrl,
  82. jwt,
  83. usersAndRooms)
  84. .then(() => {
  85. invitesLeftToSend
  86. = invitesLeftToSend.filter(
  87. ({ type }) => type !== 'user' && type !== 'room');
  88. })
  89. .catch(error => logger.error('Error inviting people:', error));
  90. allInvitePromises.push(peopleInvitePromise);
  91. }
  92. // Sipgw calls are fire and forget. Invite them to the conference, then
  93. // immediately remove them from invitesLeftToSend.
  94. const vrooms
  95. = invitesLeftToSend.filter(({ type }) => type === 'videosipgw');
  96. conference
  97. && vrooms.length > 0
  98. && dispatch(inviteVideoRooms(conference, vrooms));
  99. invitesLeftToSend
  100. = invitesLeftToSend.filter(({ type }) => type !== 'videosipgw');
  101. return (
  102. Promise.all(allInvitePromises)
  103. .then(() => invitesLeftToSend));
  104. };
  105. }
  106. /**
  107. * Sends AJAX requests for dial-in numbers and conference ID.
  108. *
  109. * @returns {Function}
  110. */
  111. export function updateDialInNumbers() {
  112. return (dispatch: Dispatch<*>, getState: Function) => {
  113. const state = getState();
  114. const { dialInConfCodeUrl, dialInNumbersUrl, hosts }
  115. = state['features/base/config'];
  116. const mucURL = hosts && hosts.muc;
  117. if (!dialInConfCodeUrl || !dialInNumbersUrl || !mucURL) {
  118. // URLs for fetching dial in numbers not defined
  119. return;
  120. }
  121. const { room } = state['features/base/conference'];
  122. Promise.all([
  123. getDialInNumbers(dialInNumbersUrl),
  124. getDialInConferenceID(dialInConfCodeUrl, room, mucURL)
  125. ])
  126. .then(([ dialInNumbers, { conference, id, message } ]) => {
  127. if (!conference || !id) {
  128. return Promise.reject(message);
  129. }
  130. dispatch({
  131. type: UPDATE_DIAL_IN_NUMBERS_SUCCESS,
  132. conferenceID: id,
  133. dialInNumbers
  134. });
  135. })
  136. .catch(error => {
  137. dispatch({
  138. type: UPDATE_DIAL_IN_NUMBERS_FAILED,
  139. error
  140. });
  141. });
  142. };
  143. }