選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

middleware.js 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // @flow
  2. import { CONFERENCE_WILL_JOIN } from '../base/conference';
  3. import {
  4. JitsiConferenceEvents,
  5. JitsiSIPVideoGWStatus
  6. } from '../base/lib-jitsi-meet';
  7. import { MiddlewareRegistry } from '../base/redux';
  8. import {
  9. showErrorNotification,
  10. showNotification,
  11. showWarningNotification
  12. } from '../notifications';
  13. import {
  14. SIP_GW_AVAILABILITY_CHANGED,
  15. SIP_GW_INVITE_ROOMS
  16. } from './actionTypes';
  17. import logger from './logger';
  18. /**
  19. * Middleware that captures conference video sip gw events and stores
  20. * the global sip gw availability in redux or show appropriate notification
  21. * for sip gw sessions.
  22. * Captures invitation actions that create sip gw sessions or display
  23. * appropriate error/warning notifications.
  24. *
  25. * @param {Store} store - The redux store.
  26. * @returns {Function}
  27. */
  28. MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
  29. const result = next(action);
  30. switch (action.type) {
  31. case CONFERENCE_WILL_JOIN: {
  32. const conference = getState()['features/base/conference'].joining;
  33. conference.on(
  34. JitsiConferenceEvents.VIDEO_SIP_GW_AVAILABILITY_CHANGED,
  35. (...args) => dispatch(_availabilityChanged(...args)));
  36. conference.on(
  37. JitsiConferenceEvents.VIDEO_SIP_GW_SESSION_STATE_CHANGED,
  38. event => {
  39. const toDispatch = _sessionStateChanged(event);
  40. // sessionStateChanged can decide there is nothing to dispatch
  41. if (toDispatch) {
  42. dispatch(toDispatch);
  43. }
  44. });
  45. break;
  46. }
  47. case SIP_GW_INVITE_ROOMS:
  48. _inviteRooms(action.rooms, action.conference, dispatch);
  49. break;
  50. }
  51. return result;
  52. });
  53. /**
  54. * Signals that sip gw availability had changed.
  55. *
  56. * @param {string} status - The new status of the service.
  57. * @returns {{
  58. * type: SIP_GW_AVAILABILITY_CHANGED,
  59. * status: string
  60. * }}
  61. * @private
  62. */
  63. function _availabilityChanged(status: string) {
  64. return {
  65. type: SIP_GW_AVAILABILITY_CHANGED,
  66. status
  67. };
  68. }
  69. /**
  70. * Processes the action from the actionType {@code SIP_GW_INVITE_ROOMS} by
  71. * inviting rooms into the conference or showing an error message.
  72. *
  73. * @param {Array} rooms - The conference rooms to invite.
  74. * @param {Object} conference - The JitsiConference to invite the rooms to.
  75. * @param {Function} dispatch - The redux dispatch function for emitting state
  76. * changes (queuing error notifications).
  77. * @private
  78. * @returns {void}
  79. */
  80. function _inviteRooms(rooms, conference, dispatch) {
  81. for (const room of rooms) {
  82. const { id: sipAddress, name: displayName } = room;
  83. if (sipAddress && displayName) {
  84. const newSession = conference
  85. .createVideoSIPGWSession(sipAddress, displayName);
  86. if (newSession instanceof Error) {
  87. const e = newSession;
  88. switch (e.message) {
  89. case JitsiSIPVideoGWStatus.ERROR_NO_CONNECTION: {
  90. dispatch(showErrorNotification({
  91. descriptionKey: 'videoSIPGW.errorInvite',
  92. titleKey: 'videoSIPGW.errorInviteTitle'
  93. }));
  94. return;
  95. }
  96. case JitsiSIPVideoGWStatus.ERROR_SESSION_EXISTS: {
  97. dispatch(showWarningNotification({
  98. titleKey: 'videoSIPGW.errorAlreadyInvited',
  99. titleArguments: { displayName }
  100. }));
  101. return;
  102. }
  103. }
  104. logger.error(
  105. 'Unknown error trying to create sip videogw session',
  106. e);
  107. return;
  108. }
  109. newSession.start();
  110. } else {
  111. logger.error(`No display name or sip number for ${
  112. JSON.stringify(room)}`);
  113. }
  114. }
  115. }
  116. /**
  117. * Signals that a session we created has a change in its status.
  118. *
  119. * @param {string} event - The event describing the session state change.
  120. * @returns {{
  121. * type: SHOW_NOTIFICATION
  122. * }}|null
  123. * @private
  124. */
  125. function _sessionStateChanged(
  126. event: Object) {
  127. switch (event.newState) {
  128. case JitsiSIPVideoGWStatus.STATE_PENDING: {
  129. return showNotification({
  130. titleKey: 'videoSIPGW.pending',
  131. titleArguments: {
  132. displayName: event.displayName
  133. }
  134. }, 2000);
  135. }
  136. case JitsiSIPVideoGWStatus.STATE_FAILED: {
  137. return showErrorNotification({
  138. titleKey: 'videoSIPGW.errorInviteFailedTitle',
  139. titleArguments: {
  140. displayName: event.displayName
  141. },
  142. descriptionKey: 'videoSIPGW.errorInviteFailed'
  143. });
  144. }
  145. case JitsiSIPVideoGWStatus.STATE_OFF: {
  146. if (event.failureReason === JitsiSIPVideoGWStatus.STATUS_BUSY) {
  147. return showErrorNotification({
  148. descriptionKey: 'videoSIPGW.busy',
  149. titleKey: 'videoSIPGW.busyTitle'
  150. });
  151. } else if (event.failureReason) {
  152. logger.error(`Unknown sip videogw error ${event.newState} ${
  153. event.failureReason}`);
  154. }
  155. }
  156. }
  157. // nothing to show
  158. return null;
  159. }