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.3KB

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