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.

middleware.js 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // @flow
  2. import { CONFERENCE_FAILED, CONFERENCE_JOINED } from '../base/conference';
  3. import { hideDialog } from '../base/dialog';
  4. import { JitsiConferenceErrors, JitsiConferenceEvents } from '../base/lib-jitsi-meet';
  5. import { getFirstLoadableAvatarUrl } from '../base/participants';
  6. import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
  7. import { NOTIFICATION_TYPE, showNotification } from '../notifications';
  8. import { KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED } from './actionTypes';
  9. import {
  10. knockingParticipantLeft,
  11. openLobbyScreen,
  12. participantIsKnockingOrUpdated,
  13. setLobbyModeEnabled
  14. } from './actions';
  15. import { LobbyScreen } from './components';
  16. MiddlewareRegistry.register(store => next => action => {
  17. switch (action.type) {
  18. case CONFERENCE_FAILED:
  19. return _conferenceFailed(store, next, action);
  20. case CONFERENCE_JOINED:
  21. return _conferenceJoined(store, next, action);
  22. case KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED: {
  23. // We need the full update result to be in the store already
  24. const result = next(action);
  25. _findLoadableAvatarForKnockingParticipant(store, action.participant);
  26. return result;
  27. }
  28. }
  29. return next(action);
  30. });
  31. /**
  32. * Registers a change handler for state['features/base/conference'].conference to
  33. * set the event listeners needed for the lobby feature to operate.
  34. */
  35. StateListenerRegistry.register(
  36. state => state['features/base/conference'].conference,
  37. (conference, { dispatch }, previousConference) => {
  38. if (conference && !previousConference) {
  39. conference.on(JitsiConferenceEvents.MEMBERS_ONLY_CHANGED, enabled => {
  40. dispatch(setLobbyModeEnabled(enabled));
  41. });
  42. conference.on(JitsiConferenceEvents.LOBBY_USER_JOINED, (id, name) => {
  43. dispatch(participantIsKnockingOrUpdated({
  44. id,
  45. name
  46. }));
  47. });
  48. conference.on(JitsiConferenceEvents.LOBBY_USER_UPDATED, (id, participant) => {
  49. dispatch(participantIsKnockingOrUpdated({
  50. ...participant,
  51. id
  52. }));
  53. });
  54. conference.on(JitsiConferenceEvents.LOBBY_USER_LEFT, id => {
  55. dispatch(knockingParticipantLeft(id));
  56. });
  57. }
  58. });
  59. /**
  60. * Function to handle the conference failed event and navigate the user to the lobby screen
  61. * based on the failure reason.
  62. *
  63. * @param {Object} store - The Redux store.
  64. * @param {Function} next - The Redux next function.
  65. * @param {Object} action - The Redux action.
  66. * @returns {Object}
  67. */
  68. function _conferenceFailed({ dispatch }, next, action) {
  69. const { error } = action;
  70. if (error.name === JitsiConferenceErrors.MEMBERS_ONLY_ERROR) {
  71. if (typeof error.recoverable === 'undefined') {
  72. error.recoverable = true;
  73. }
  74. dispatch(openLobbyScreen());
  75. } else {
  76. dispatch(hideDialog(LobbyScreen));
  77. if (error.name === JitsiConferenceErrors.CONFERENCE_ACCESS_DENIED) {
  78. dispatch(showNotification({
  79. appearance: NOTIFICATION_TYPE.ERROR,
  80. hideErrorSupportLink: true,
  81. titleKey: 'lobby.joinRejectedMessage'
  82. }));
  83. }
  84. }
  85. return next(action);
  86. }
  87. /**
  88. * Handles cleanup of lobby state when a conference is joined.
  89. *
  90. * @param {Object} store - The Redux store.
  91. * @param {Function} next - The Redux next function.
  92. * @param {Object} action - The Redux action.
  93. * @returns {Object}
  94. */
  95. function _conferenceJoined({ dispatch }, next, action) {
  96. dispatch(hideDialog(LobbyScreen));
  97. return next(action);
  98. }
  99. /**
  100. * Finds the loadable avatar URL and updates the participant accordingly.
  101. *
  102. * @param {Object} store - The Redux store.
  103. * @param {Object} participant - The knocking participant.
  104. * @returns {void}
  105. */
  106. function _findLoadableAvatarForKnockingParticipant({ dispatch, getState }, { id }) {
  107. const updatedParticipant = getState()['features/lobby'].knockingParticipants.find(p => p.id === id);
  108. if (updatedParticipant && !updatedParticipant.loadableAvatarUrl) {
  109. getFirstLoadableAvatarUrl(updatedParticipant).then(loadableAvatarUrl => {
  110. if (loadableAvatarUrl) {
  111. dispatch(participantIsKnockingOrUpdated({
  112. loadableAvatarUrl,
  113. id
  114. }));
  115. }
  116. });
  117. }
  118. }