Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

reducer.js 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /* @flow */
  2. import { MEDIA_TYPE } from '../base/media/constants';
  3. import type { MediaType } from '../base/media/constants';
  4. import {
  5. PARTICIPANT_LEFT,
  6. PARTICIPANT_UPDATED
  7. } from '../base/participants';
  8. import { ReducerRegistry } from '../base/redux';
  9. import {
  10. DISABLE_MODERATION,
  11. DISMISS_PENDING_PARTICIPANT,
  12. ENABLE_MODERATION,
  13. LOCAL_PARTICIPANT_APPROVED,
  14. PARTICIPANT_APPROVED,
  15. PARTICIPANT_PENDING_AUDIO
  16. } from './actionTypes';
  17. import { MEDIA_TYPE_TO_PENDING_STORE_KEY } from './constants';
  18. const initialState = {
  19. audioModerationEnabled: false,
  20. videoModerationEnabled: false,
  21. audioWhitelist: {},
  22. videoWhitelist: {},
  23. pendingAudio: [],
  24. pendingVideo: []
  25. };
  26. /**
  27. Updates a participant in the state for the specified media type.
  28. *
  29. * @param {MediaType} mediaType - The media type.
  30. * @param {Object} participant - Information about participant to be modified.
  31. * @param {Object} state - The current state.
  32. * @private
  33. * @returns {boolean} - Whether state instance was modified.
  34. */
  35. function _updatePendingParticipant(mediaType: MediaType, participant, state: Object = {}) {
  36. let arrayItemChanged = false;
  37. const storeKey = MEDIA_TYPE_TO_PENDING_STORE_KEY[mediaType];
  38. const arr = state[storeKey];
  39. const newArr = arr.map(pending => {
  40. if (pending.id === participant.id) {
  41. arrayItemChanged = true;
  42. return {
  43. ...pending,
  44. ...participant
  45. };
  46. }
  47. return pending;
  48. });
  49. if (arrayItemChanged) {
  50. state[storeKey] = newArr;
  51. return true;
  52. }
  53. return false;
  54. }
  55. ReducerRegistry.register('features/av-moderation', (state = initialState, action) => {
  56. switch (action.type) {
  57. case DISABLE_MODERATION: {
  58. const newState = action.mediaType === MEDIA_TYPE.AUDIO
  59. ? {
  60. audioModerationEnabled: false,
  61. audioUnmuteApproved: undefined
  62. } : {
  63. videoModerationEnabled: false,
  64. videoUnmuteApproved: undefined
  65. };
  66. return {
  67. ...state,
  68. ...newState,
  69. audioWhitelist: {},
  70. videoWhitelist: {},
  71. pendingAudio: [],
  72. pendingVideo: []
  73. };
  74. }
  75. case ENABLE_MODERATION: {
  76. const newState = action.mediaType === MEDIA_TYPE.AUDIO
  77. ? { audioModerationEnabled: true } : { videoModerationEnabled: true };
  78. return {
  79. ...state,
  80. ...newState
  81. };
  82. }
  83. case LOCAL_PARTICIPANT_APPROVED: {
  84. const newState = action.mediaType === MEDIA_TYPE.AUDIO
  85. ? { audioUnmuteApproved: true } : { videoUnmuteApproved: true };
  86. return {
  87. ...state,
  88. ...newState
  89. };
  90. }
  91. case PARTICIPANT_PENDING_AUDIO: {
  92. const { participant } = action;
  93. // Add participant to pendingAudio array only if it's not already added
  94. if (!state.pendingAudio.find(pending => pending.id === participant.id)) {
  95. const updated = [ ...state.pendingAudio ];
  96. updated.push(participant);
  97. return {
  98. ...state,
  99. pendingAudio: updated
  100. };
  101. }
  102. return state;
  103. }
  104. case PARTICIPANT_UPDATED: {
  105. const participant = action.participant;
  106. const { audioModerationEnabled, videoModerationEnabled } = state;
  107. let hasStateChanged = false;
  108. // skips changing the reference of pendingAudio or pendingVideo,
  109. // if there is no change in the elements
  110. if (audioModerationEnabled) {
  111. hasStateChanged = _updatePendingParticipant(MEDIA_TYPE.AUDIO, participant, state);
  112. }
  113. if (videoModerationEnabled) {
  114. hasStateChanged = _updatePendingParticipant(MEDIA_TYPE.VIDEO, participant, state);
  115. }
  116. // If the state has changed we need to return a new object reference in order to trigger subscriber updates.
  117. if (hasStateChanged) {
  118. return {
  119. ...state
  120. };
  121. }
  122. return state;
  123. }
  124. case PARTICIPANT_LEFT: {
  125. const participant = action.participant;
  126. const { audioModerationEnabled, videoModerationEnabled } = state;
  127. let hasStateChanged = false;
  128. // skips changing the reference of pendingAudio or pendingVideo,
  129. // if there is no change in the elements
  130. if (audioModerationEnabled) {
  131. const newPendingAudio = state.pendingAudio.filter(pending => pending.id !== participant.id);
  132. if (state.pendingAudio.length !== newPendingAudio.length) {
  133. state.pendingAudio = newPendingAudio;
  134. hasStateChanged = true;
  135. }
  136. }
  137. if (videoModerationEnabled) {
  138. const newPendingVideo = state.pendingVideo.filter(pending => pending.id !== participant.id);
  139. if (state.pendingVideo.length !== newPendingVideo.length) {
  140. state.pendingVideo = newPendingVideo;
  141. hasStateChanged = true;
  142. }
  143. }
  144. // If the state has changed we need to return a new object reference in order to trigger subscriber updates.
  145. if (hasStateChanged) {
  146. return {
  147. ...state
  148. };
  149. }
  150. return state;
  151. }
  152. case DISMISS_PENDING_PARTICIPANT: {
  153. const { participant, mediaType } = action;
  154. if (mediaType === MEDIA_TYPE.AUDIO) {
  155. return {
  156. ...state,
  157. pendingAudio: state.pendingAudio.filter(pending => pending.id !== participant.id)
  158. };
  159. }
  160. if (mediaType === MEDIA_TYPE.VIDEO) {
  161. return {
  162. ...state,
  163. pendingVideo: state.pendingVideo.filter(pending => pending.id !== participant.id)
  164. };
  165. }
  166. return state;
  167. }
  168. case PARTICIPANT_APPROVED: {
  169. const { mediaType, id } = action;
  170. if (mediaType === MEDIA_TYPE.AUDIO) {
  171. return {
  172. ...state,
  173. audioWhitelist: {
  174. ...state.audioWhitelist,
  175. [id]: true
  176. }
  177. };
  178. }
  179. if (mediaType === MEDIA_TYPE.VIDEO) {
  180. return {
  181. ...state,
  182. videoWhitelist: {
  183. ...state.videoWhitelist,
  184. [id]: true
  185. }
  186. };
  187. }
  188. return state;
  189. }
  190. }
  191. return state;
  192. });