Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

middleware.js 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // @flow
  2. import { CONFERENCE_FAILED, CONFERENCE_JOINED } from '../base/conference';
  3. import { JitsiConferenceErrors, JitsiConferenceEvents } from '../base/lib-jitsi-meet';
  4. import { getFirstLoadableAvatarUrl, getParticipantDisplayName } from '../base/participants';
  5. import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
  6. import { isTestModeEnabled } from '../base/testing';
  7. import { NOTIFICATION_TYPE, showNotification } from '../notifications';
  8. import { shouldAutoKnock } from '../prejoin/functions';
  9. import { KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED } from './actionTypes';
  10. import {
  11. hideLobbyScreen,
  12. knockingParticipantLeft,
  13. openLobbyScreen,
  14. participantIsKnockingOrUpdated,
  15. setLobbyModeEnabled,
  16. startKnocking,
  17. setPasswordJoinFailed
  18. } from './actions';
  19. MiddlewareRegistry.register(store => next => action => {
  20. switch (action.type) {
  21. case CONFERENCE_FAILED:
  22. return _conferenceFailed(store, next, action);
  23. case CONFERENCE_JOINED:
  24. return _conferenceJoined(store, next, action);
  25. case KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED: {
  26. // We need the full update result to be in the store already
  27. const result = next(action);
  28. _findLoadableAvatarForKnockingParticipant(store, action.participant);
  29. return result;
  30. }
  31. }
  32. return next(action);
  33. });
  34. /**
  35. * Registers a change handler for state['features/base/conference'].conference to
  36. * set the event listeners needed for the lobby feature to operate.
  37. */
  38. StateListenerRegistry.register(
  39. state => state['features/base/conference'].conference,
  40. (conference, { dispatch, getState }, previousConference) => {
  41. if (conference && !previousConference) {
  42. conference.on(JitsiConferenceEvents.MEMBERS_ONLY_CHANGED, enabled => {
  43. dispatch(setLobbyModeEnabled(enabled));
  44. });
  45. conference.on(JitsiConferenceEvents.LOBBY_USER_JOINED, (id, name) => {
  46. dispatch(participantIsKnockingOrUpdated({
  47. id,
  48. name
  49. }));
  50. });
  51. conference.on(JitsiConferenceEvents.LOBBY_USER_UPDATED, (id, participant) => {
  52. dispatch(participantIsKnockingOrUpdated({
  53. ...participant,
  54. id
  55. }));
  56. });
  57. conference.on(JitsiConferenceEvents.LOBBY_USER_LEFT, id => {
  58. dispatch(knockingParticipantLeft(id));
  59. });
  60. conference.on(JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED, (origin, sender) =>
  61. _maybeSendLobbyNotification(origin, sender, {
  62. dispatch,
  63. getState
  64. })
  65. );
  66. }
  67. });
  68. /**
  69. * Function to handle the conference failed event and navigate the user to the lobby screen
  70. * based on the failure reason.
  71. *
  72. * @param {Object} store - The Redux store.
  73. * @param {Function} next - The Redux next function.
  74. * @param {Object} action - The Redux action.
  75. * @returns {Object}
  76. */
  77. function _conferenceFailed({ dispatch, getState }, next, action) {
  78. const { error } = action;
  79. const state = getState();
  80. const nonFirstFailure = Boolean(state['features/base/conference'].membersOnly);
  81. if (error.name === JitsiConferenceErrors.MEMBERS_ONLY_ERROR) {
  82. if (typeof error.recoverable === 'undefined') {
  83. error.recoverable = true;
  84. }
  85. const result = next(action);
  86. dispatch(openLobbyScreen());
  87. if (shouldAutoKnock(state)) {
  88. dispatch(startKnocking());
  89. }
  90. dispatch(setPasswordJoinFailed(nonFirstFailure));
  91. return result;
  92. }
  93. dispatch(hideLobbyScreen());
  94. if (error.name === JitsiConferenceErrors.CONFERENCE_ACCESS_DENIED) {
  95. dispatch(showNotification({
  96. appearance: NOTIFICATION_TYPE.ERROR,
  97. hideErrorSupportLink: true,
  98. titleKey: 'lobby.joinRejectedMessage'
  99. }));
  100. }
  101. return next(action);
  102. }
  103. /**
  104. * Handles cleanup of lobby state when a conference is joined.
  105. *
  106. * @param {Object} store - The Redux store.
  107. * @param {Function} next - The Redux next function.
  108. * @param {Object} action - The Redux action.
  109. * @returns {Object}
  110. */
  111. function _conferenceJoined({ dispatch }, next, action) {
  112. dispatch(hideLobbyScreen());
  113. return next(action);
  114. }
  115. /**
  116. * Finds the loadable avatar URL and updates the participant accordingly.
  117. *
  118. * @param {Object} store - The Redux store.
  119. * @param {Object} participant - The knocking participant.
  120. * @returns {void}
  121. */
  122. function _findLoadableAvatarForKnockingParticipant(store, { id }) {
  123. const { dispatch, getState } = store;
  124. const updatedParticipant = getState()['features/lobby'].knockingParticipants.find(p => p.id === id);
  125. const { disableThirdPartyRequests } = getState()['features/base/config'];
  126. if (!disableThirdPartyRequests && updatedParticipant && !updatedParticipant.loadableAvatarUrl) {
  127. getFirstLoadableAvatarUrl(updatedParticipant, store).then(loadableAvatarUrl => {
  128. if (loadableAvatarUrl) {
  129. dispatch(participantIsKnockingOrUpdated({
  130. loadableAvatarUrl,
  131. id
  132. }));
  133. }
  134. });
  135. }
  136. }
  137. /**
  138. * Check the endpoint message that arrived through the conference and
  139. * sends a lobby notification, if the message belongs to the feature.
  140. *
  141. * @param {Object} origin - The origin (initiator) of the message.
  142. * @param {Object} message - The actual message.
  143. * @param {Object} store - The Redux store.
  144. * @returns {void}
  145. */
  146. function _maybeSendLobbyNotification(origin, message, { dispatch, getState }) {
  147. if (!origin?._id || message?.type !== 'lobby-notify') {
  148. return;
  149. }
  150. const notificationProps: any = {
  151. descriptionArguments: {
  152. originParticipantName: getParticipantDisplayName(getState, origin._id),
  153. targetParticipantName: message.name
  154. },
  155. titleKey: 'lobby.notificationTitle'
  156. };
  157. switch (message.event) {
  158. case 'LOBBY-ENABLED':
  159. notificationProps.descriptionKey = `lobby.notificationLobby${message.value ? 'En' : 'Dis'}abled`;
  160. break;
  161. case 'LOBBY-ACCESS-GRANTED':
  162. notificationProps.descriptionKey = 'lobby.notificationLobbyAccessGranted';
  163. break;
  164. case 'LOBBY-ACCESS-DENIED':
  165. notificationProps.descriptionKey = 'lobby.notificationLobbyAccessDenied';
  166. break;
  167. }
  168. dispatch(showNotification(notificationProps, isTestModeEnabled(getState()) ? undefined : 5000));
  169. }