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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // @flow
  2. import { batch } from 'react-redux';
  3. import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app';
  4. import { getParticipantCount } from '../base/participants';
  5. import { MiddlewareRegistry } from '../base/redux';
  6. import { updateSettings } from '../base/settings';
  7. import { playSound, registerSound, unregisterSound } from '../base/sounds';
  8. import { getDisabledSounds } from '../base/sounds/functions.any';
  9. import { NOTIFICATION_TIMEOUT, showNotification } from '../notifications';
  10. import {
  11. ADD_REACTION_BUFFER,
  12. FLUSH_REACTION_BUFFER,
  13. SEND_REACTIONS,
  14. PUSH_REACTIONS,
  15. SHOW_SOUNDS_NOTIFICATION
  16. } from './actionTypes';
  17. import { displayReactionSoundsNotification } from './actions';
  18. import {
  19. addReactionsToChat,
  20. flushReactionBuffer,
  21. pushReactions,
  22. sendReactions,
  23. setReactionQueue
  24. } from './actions.any';
  25. import {
  26. ENDPOINT_REACTION_NAME,
  27. RAISE_HAND_SOUND_ID,
  28. REACTIONS,
  29. REACTION_SOUND,
  30. SOUNDS_THRESHOLDS
  31. } from './constants';
  32. import {
  33. getReactionMessageFromBuffer,
  34. getReactionsSoundsThresholds,
  35. getReactionsWithId,
  36. sendReactionsWebhook
  37. } from './functions.any';
  38. import { RAISE_HAND_SOUND_FILE } from './sounds';
  39. declare var APP: Object;
  40. /**
  41. * Middleware which intercepts Reactions actions to handle changes to the
  42. * visibility timeout of the Reactions.
  43. *
  44. * @param {Store} store - The redux store.
  45. * @returns {Function}
  46. */
  47. MiddlewareRegistry.register(store => next => action => {
  48. const { dispatch, getState } = store;
  49. switch (action.type) {
  50. case APP_WILL_MOUNT:
  51. batch(() => {
  52. Object.keys(REACTIONS).forEach(key => {
  53. for (let i = 0; i < SOUNDS_THRESHOLDS.length; i++) {
  54. dispatch(registerSound(
  55. `${REACTIONS[key].soundId}${SOUNDS_THRESHOLDS[i]}`,
  56. REACTIONS[key].soundFiles[i]
  57. )
  58. );
  59. }
  60. }
  61. );
  62. dispatch(registerSound(RAISE_HAND_SOUND_ID, RAISE_HAND_SOUND_FILE));
  63. });
  64. break;
  65. case APP_WILL_UNMOUNT:
  66. batch(() => {
  67. Object.keys(REACTIONS).forEach(key => {
  68. for (let i = 0; i < SOUNDS_THRESHOLDS.length; i++) {
  69. dispatch(unregisterSound(`${REACTIONS[key].soundId}${SOUNDS_THRESHOLDS[i]}`));
  70. }
  71. });
  72. dispatch(unregisterSound(RAISE_HAND_SOUND_ID));
  73. });
  74. break;
  75. case ADD_REACTION_BUFFER: {
  76. const { timeoutID, buffer } = getState()['features/reactions'];
  77. const { reaction } = action;
  78. clearTimeout(timeoutID);
  79. buffer.push(reaction);
  80. action.buffer = buffer;
  81. action.timeoutID = setTimeout(() => {
  82. dispatch(flushReactionBuffer());
  83. }, 500);
  84. break;
  85. }
  86. case FLUSH_REACTION_BUFFER: {
  87. const state = getState();
  88. const { buffer } = state['features/reactions'];
  89. const participantCount = getParticipantCount(state);
  90. batch(() => {
  91. if (participantCount > 1) {
  92. dispatch(sendReactions());
  93. }
  94. dispatch(addReactionsToChat(getReactionMessageFromBuffer(buffer)));
  95. dispatch(pushReactions(buffer));
  96. });
  97. sendReactionsWebhook(state, buffer);
  98. break;
  99. }
  100. case SEND_REACTIONS: {
  101. const state = getState();
  102. const { buffer } = state['features/reactions'];
  103. const { conference } = state['features/base/conference'];
  104. if (conference) {
  105. conference.sendEndpointMessage('', {
  106. name: ENDPOINT_REACTION_NAME,
  107. reactions: buffer,
  108. timestamp: Date.now()
  109. });
  110. }
  111. break;
  112. }
  113. case PUSH_REACTIONS: {
  114. const state = getState();
  115. const { queue, notificationDisplayed } = state['features/reactions'];
  116. const { soundsReactions } = state['features/base/settings'];
  117. const disabledSounds = getDisabledSounds(state);
  118. const reactions = action.reactions;
  119. batch(() => {
  120. if (!notificationDisplayed && soundsReactions && !disabledSounds.includes(REACTION_SOUND)
  121. && displayReactionSoundsNotification) {
  122. dispatch(displayReactionSoundsNotification());
  123. }
  124. if (soundsReactions) {
  125. const reactionSoundsThresholds = getReactionsSoundsThresholds(reactions);
  126. reactionSoundsThresholds.forEach(reaction =>
  127. dispatch(playSound(`${REACTIONS[reaction.reaction].soundId}${reaction.threshold}`))
  128. );
  129. }
  130. dispatch(setReactionQueue([ ...queue, ...getReactionsWithId(reactions) ]));
  131. });
  132. break;
  133. }
  134. case SHOW_SOUNDS_NOTIFICATION: {
  135. dispatch(showNotification({
  136. titleKey: 'toolbar.disableReactionSounds',
  137. customActionNameKey: 'notify.reactionSounds',
  138. customActionHandler: () => dispatch(updateSettings({
  139. soundsReactions: false
  140. }))
  141. }, NOTIFICATION_TIMEOUT));
  142. break;
  143. }
  144. }
  145. return next(action);
  146. });