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 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /* @flow */
  2. import { getCurrentConference } from '../base/conference';
  3. import {
  4. PARTICIPANT_JOINED,
  5. PARTICIPANT_LEFT,
  6. PARTICIPANT_ROLE,
  7. PARTICIPANT_UPDATED,
  8. getParticipantById,
  9. getParticipantDisplayName,
  10. getLocalParticipant
  11. } from '../base/participants';
  12. import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
  13. import { PARTICIPANTS_PANE_OPEN } from '../participants-pane/actionTypes';
  14. import {
  15. clearNotifications,
  16. hideRaiseHandNotifications,
  17. showNotification,
  18. showParticipantJoinedNotification
  19. } from './actions';
  20. import { NOTIFICATION_TIMEOUT } from './constants';
  21. import { joinLeaveNotificationsDisabled } from './functions';
  22. declare var interfaceConfig: Object;
  23. /**
  24. * Middleware that captures actions to display notifications.
  25. *
  26. * @param {Store} store - The redux store.
  27. * @returns {Function}
  28. */
  29. MiddlewareRegistry.register(store => next => action => {
  30. switch (action.type) {
  31. case PARTICIPANT_JOINED: {
  32. const result = next(action);
  33. const { participant: p } = action;
  34. const { dispatch, getState } = store;
  35. const state = getState();
  36. const { conference } = state['features/base/conference'];
  37. if (conference && !p.local && !joinLeaveNotificationsDisabled() && !p.isReplacing) {
  38. dispatch(showParticipantJoinedNotification(
  39. getParticipantDisplayName(state, p.id)
  40. ));
  41. }
  42. return result;
  43. }
  44. case PARTICIPANT_LEFT: {
  45. if (!joinLeaveNotificationsDisabled()) {
  46. const participant = getParticipantById(
  47. store.getState(),
  48. action.participant.id
  49. );
  50. if (typeof interfaceConfig === 'object'
  51. && participant
  52. && !participant.local
  53. && !action.participant.isReplaced) {
  54. store.dispatch(showNotification({
  55. descriptionKey: 'notify.disconnected',
  56. titleKey: 'notify.somebody',
  57. title: participant.name
  58. }, NOTIFICATION_TIMEOUT));
  59. }
  60. }
  61. return next(action);
  62. }
  63. case PARTICIPANT_UPDATED: {
  64. if (typeof interfaceConfig === 'undefined') {
  65. // Do not show the notification for mobile and also when the focus indicator is disabled.
  66. return next(action);
  67. }
  68. const { id, role } = action.participant;
  69. const state = store.getState();
  70. const localParticipant = getLocalParticipant(state);
  71. if (localParticipant.id !== id) {
  72. return next(action);
  73. }
  74. const oldParticipant = getParticipantById(state, id);
  75. const oldRole = oldParticipant?.role;
  76. if (oldRole && oldRole !== role && role === PARTICIPANT_ROLE.MODERATOR) {
  77. store.dispatch(showNotification({
  78. titleKey: 'notify.moderator'
  79. },
  80. NOTIFICATION_TIMEOUT));
  81. }
  82. return next(action);
  83. }
  84. case PARTICIPANTS_PANE_OPEN: {
  85. store.dispatch(hideRaiseHandNotifications());
  86. break;
  87. }
  88. }
  89. return next(action);
  90. });
  91. /**
  92. * StateListenerRegistry provides a reliable way to detect the leaving of a
  93. * conference, where we need to clean up the notifications.
  94. */
  95. StateListenerRegistry.register(
  96. /* selector */ state => getCurrentConference(state),
  97. /* listener */ (conference, { dispatch }) => {
  98. if (!conference) {
  99. dispatch(clearNotifications());
  100. }
  101. }
  102. );