您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

middleware.native.js 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. // @flow
  2. import i18next from 'i18next';
  3. import { NativeEventEmitter, NativeModules } from 'react-native';
  4. import { MiddlewareRegistry } from '../base/redux';
  5. import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app';
  6. import {
  7. BEGIN_ADD_PEOPLE,
  8. _SET_EMITTER_SUBSCRIPTIONS
  9. } from './actionTypes';
  10. import {
  11. getInviteResultsForQuery,
  12. isAddPeopleEnabled,
  13. isDialOutEnabled
  14. } from './functions';
  15. import { sendInvitesForItems } from './actions';
  16. import './middleware.any';
  17. /**
  18. * The react-native module of the feature invite.
  19. */
  20. const { Invite } = NativeModules;
  21. /**
  22. * The middleware of the feature invite specific to mobile/react-native.
  23. *
  24. * @param {Store} store - The redux store.
  25. * @returns {Function}
  26. */
  27. Invite && MiddlewareRegistry.register(store => next => action => {
  28. switch (action.type) {
  29. case _SET_EMITTER_SUBSCRIPTIONS:
  30. return _setEmitterSubscriptions(store, next, action);
  31. case APP_WILL_MOUNT:
  32. return _appWillMount(store, next, action);
  33. case APP_WILL_UNMOUNT: {
  34. const result = next(action);
  35. store.dispatch({
  36. type: _SET_EMITTER_SUBSCRIPTIONS,
  37. emitterSubscriptions: undefined
  38. });
  39. return result;
  40. }
  41. case BEGIN_ADD_PEOPLE:
  42. return _beginAddPeople(store, next, action);
  43. }
  44. return next(action);
  45. });
  46. /**
  47. * Notifies the feature jwt that the action {@link APP_WILL_MOUNT} is being
  48. * dispatched within a specific redux {@code store}.
  49. *
  50. * @param {Store} store - The redux store in which the specified {@code action}
  51. * is being dispatched.
  52. * @param {Dispatch} next - The redux dispatch function to dispatch the
  53. * specified {@code action} to the specified {@code store}.
  54. * @param {Action} action - The redux action {@code APP_WILL_MOUNT} which is
  55. * being dispatched in the specified {@code store}.
  56. * @private
  57. * @returns {*} The value returned by {@code next(action)}.
  58. */
  59. function _appWillMount({ dispatch, getState }, next, action) {
  60. const result = next(action);
  61. const emitter = new NativeEventEmitter(Invite);
  62. const context = {
  63. dispatch,
  64. getState
  65. };
  66. dispatch({
  67. type: _SET_EMITTER_SUBSCRIPTIONS,
  68. emitterSubscriptions: [
  69. emitter.addListener(
  70. 'org.jitsi.meet:features/invite#invite',
  71. _onInvite,
  72. context),
  73. emitter.addListener(
  74. 'org.jitsi.meet:features/invite#performQuery',
  75. _onPerformQuery,
  76. context)
  77. ]
  78. });
  79. return result;
  80. }
  81. /**
  82. * Notifies the feature invite that the action {@link BEGIN_ADD_PEOPLE} is being
  83. * dispatched within a specific redux {@code store}.
  84. *
  85. * @param {Store} store - The redux store in which the specified {@code action}
  86. * is being dispatched.
  87. * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
  88. * specified {@code action} to the specified {@code store}.
  89. * @param {Action} action - The redux action {@code BEGIN_ADD_PEOPLE} which is
  90. * being dispatched in the specified {@code store}.
  91. * @private
  92. * @returns {*} The value returned by {@code next(action)}.
  93. */
  94. function _beginAddPeople({ getState }, next, action) {
  95. const result = next(action);
  96. // The JavaScript App needs to provide uniquely identifying information to
  97. // the native Invite module so that the latter may match the former to the
  98. // native JitsiMeetView which hosts it.
  99. const { app } = getState()['features/app'];
  100. if (app) {
  101. const { externalAPIScope } = app.props;
  102. if (externalAPIScope) {
  103. Invite.beginAddPeople(externalAPIScope);
  104. }
  105. }
  106. return result;
  107. }
  108. /**
  109. * Handles the {@code invite} event of the feature invite i.e. invites specific
  110. * invitees to the current, ongoing conference.
  111. *
  112. * @param {Object} event - The details of the event.
  113. * @returns {void}
  114. */
  115. function _onInvite(
  116. { addPeopleControllerScope, externalAPIScope, invitees }) {
  117. const { dispatch, getState } = this; // eslint-disable-line no-invalid-this
  118. // If there are multiple JitsiMeetView instances alive, they will all get
  119. // the event, since there is a single bridge, so make sure we don't act if
  120. // the event is not for us.
  121. if (getState()['features/app'].app.props.externalAPIScope
  122. !== externalAPIScope) {
  123. return;
  124. }
  125. dispatch(sendInvitesForItems(invitees))
  126. .then(failedInvitees =>
  127. Invite.inviteSettled(
  128. externalAPIScope,
  129. addPeopleControllerScope,
  130. failedInvitees));
  131. }
  132. /**
  133. * Handles the {@code performQuery} event of the feature invite i.e. queries for
  134. * invitees who may subsequently be invited to the current, ongoing conference.
  135. *
  136. * @param {Object} event - The details of the event.
  137. * @returns {void}
  138. */
  139. function _onPerformQuery(
  140. { addPeopleControllerScope, externalAPIScope, query }) {
  141. const { getState } = this; // eslint-disable-line no-invalid-this
  142. const state = getState();
  143. // If there are multiple JitsiMeetView instances alive, they will all get
  144. // the event, since there is a single bridge, so make sure we don't act if
  145. // the event is not for us.
  146. if (state['features/app'].app.props.externalAPIScope !== externalAPIScope) {
  147. return;
  148. }
  149. const {
  150. dialOutAuthUrl,
  151. peopleSearchQueryTypes,
  152. peopleSearchUrl
  153. } = state['features/base/config'];
  154. const options = {
  155. dialOutAuthUrl,
  156. addPeopleEnabled: isAddPeopleEnabled(state),
  157. dialOutEnabled: isDialOutEnabled(state),
  158. jwt: state['features/base/jwt'].jwt,
  159. peopleSearchQueryTypes,
  160. peopleSearchUrl
  161. };
  162. getInviteResultsForQuery(query, options)
  163. .catch(() => [])
  164. .then(results => {
  165. const translatedResults = results.map(result => {
  166. if (result.type === 'phone') {
  167. result.title = i18next.t('addPeople.telephone', {
  168. number: result.number
  169. });
  170. if (result.showCountryCodeReminder) {
  171. result.subtitle = i18next.t(
  172. 'addPeople.countryReminder'
  173. );
  174. }
  175. }
  176. return result;
  177. }).filter(result => result.type !== 'phone' || result.allowed);
  178. Invite.receivedResults(
  179. externalAPIScope,
  180. addPeopleControllerScope,
  181. query,
  182. translatedResults);
  183. });
  184. }
  185. /**
  186. * Notifies the feature invite that the action
  187. * {@link _SET_EMITTER_SUBSCRIPTIONS} is being dispatched within a specific
  188. * redux {@code store}.
  189. *
  190. * @param {Store} store - The redux store in which the specified {@code action}
  191. * is being dispatched.
  192. * @param {Dispatch} next - The redux dispatch function to dispatch the
  193. * specified {@code action} to the specified {@code store}.
  194. * @param {Action} action - The redux action {@code _SET_EMITTER_SUBSCRIPTIONS}
  195. * which is being dispatched in the specified {@code store}.
  196. * @private
  197. * @returns {*}
  198. */
  199. function _setEmitterSubscriptions({ getState }, next, action) {
  200. const { emitterSubscriptions } = getState()['features/invite'];
  201. if (emitterSubscriptions) {
  202. for (const subscription of emitterSubscriptions) {
  203. subscription.remove();
  204. }
  205. }
  206. return next(action);
  207. }