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.

functions.ts 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import { IReduxState } from '../app/types';
  2. import { MEDIA_TYPE, type MediaType } from '../base/media/constants';
  3. import { isLocalParticipantModerator } from '../base/participants/functions';
  4. import { IParticipant } from '../base/participants/types';
  5. import { isInBreakoutRoom } from '../breakout-rooms/functions';
  6. import { MEDIA_TYPE_TO_PENDING_STORE_KEY, MEDIA_TYPE_TO_WHITELIST_STORE_KEY } from './constants';
  7. /**
  8. * Returns this feature's root state.
  9. *
  10. * @param {IReduxState} state - Global state.
  11. * @returns {Object} Feature state.
  12. */
  13. const getState = (state: IReduxState) => state['features/av-moderation'];
  14. /**
  15. * We use to construct once the empty array so we can keep the same instance between calls
  16. * of getParticipantsAskingToAudioUnmute.
  17. *
  18. * @type {any[]}
  19. */
  20. const EMPTY_ARRAY: any[] = [];
  21. /**
  22. * Returns whether moderation is enabled per media type.
  23. *
  24. * @param {MEDIA_TYPE} mediaType - The media type to check.
  25. * @param {IReduxState} state - Global state.
  26. * @returns {boolean}
  27. */
  28. export const isEnabledFromState = (mediaType: MediaType, state: IReduxState) =>
  29. (mediaType === MEDIA_TYPE.AUDIO
  30. ? getState(state)?.audioModerationEnabled
  31. : getState(state)?.videoModerationEnabled) === true;
  32. /**
  33. * Returns whether moderation is enabled per media type.
  34. *
  35. * @param {MEDIA_TYPE} mediaType - The media type to check.
  36. * @returns {boolean}
  37. */
  38. export const isEnabled = (mediaType: MediaType) => (state: IReduxState) => isEnabledFromState(mediaType, state);
  39. /**
  40. * Returns whether moderation is supported by the backend.
  41. *
  42. * @returns {boolean}
  43. */
  44. export const isSupported = () => (state: IReduxState) => {
  45. const { conference } = state['features/base/conference'];
  46. return Boolean(!isInBreakoutRoom(state) && conference?.isAVModerationSupported());
  47. };
  48. /**
  49. * Returns whether local participant is approved to unmute a media type.
  50. *
  51. * @param {MEDIA_TYPE} mediaType - The media type to check.
  52. * @param {IReduxState} state - Global state.
  53. * @returns {boolean}
  54. */
  55. export const isLocalParticipantApprovedFromState = (mediaType: MediaType, state: IReduxState) => {
  56. const approved = (mediaType === MEDIA_TYPE.AUDIO
  57. ? getState(state).audioUnmuteApproved
  58. : getState(state).videoUnmuteApproved) === true;
  59. return approved || isLocalParticipantModerator(state);
  60. };
  61. /**
  62. * Returns whether local participant is approved to unmute a media type.
  63. *
  64. * @param {MEDIA_TYPE} mediaType - The media type to check.
  65. * @returns {boolean}
  66. */
  67. export const isLocalParticipantApproved = (mediaType: MediaType) =>
  68. (state: IReduxState) =>
  69. isLocalParticipantApprovedFromState(mediaType, state);
  70. /**
  71. * Returns a selector creator which determines if the participant is approved or not for a media type.
  72. *
  73. * @param {string} id - The participant id.
  74. * @param {MEDIA_TYPE} mediaType - The media type to check.
  75. * @returns {boolean}
  76. */
  77. export const isParticipantApproved = (id: string, mediaType: MediaType) => (state: IReduxState) => {
  78. const storeKey = MEDIA_TYPE_TO_WHITELIST_STORE_KEY[mediaType];
  79. const avModerationState = getState(state);
  80. const stateForMediaType = avModerationState[storeKey as keyof typeof avModerationState];
  81. return Boolean(stateForMediaType && stateForMediaType[id as keyof typeof stateForMediaType]);
  82. };
  83. /**
  84. * Returns a selector creator which determines if the participant is pending or not for a media type.
  85. *
  86. * @param {IParticipant} participant - The participant.
  87. * @param {MEDIA_TYPE} mediaType - The media type to check.
  88. * @returns {boolean}
  89. */
  90. export const isParticipantPending = (participant: IParticipant, mediaType: MediaType) => (state: IReduxState) => {
  91. const storeKey = MEDIA_TYPE_TO_PENDING_STORE_KEY[mediaType];
  92. const arr = getState(state)[storeKey];
  93. return Boolean(arr.find(pending => pending.id === participant.id));
  94. };
  95. /**
  96. * Selector which returns a list with all the participants asking to audio unmute.
  97. * This is visible only for the moderator.
  98. *
  99. * @param {Object} state - The global state.
  100. * @returns {Array<Object>}
  101. */
  102. export const getParticipantsAskingToAudioUnmute = (state: IReduxState) => {
  103. if (isLocalParticipantModerator(state)) {
  104. return getState(state).pendingAudio;
  105. }
  106. return EMPTY_ARRAY;
  107. };
  108. /**
  109. * Returns true if a special notification can be displayed when a participant
  110. * tries to unmute.
  111. *
  112. * @param {MediaType} mediaType - 'audio' or 'video' media type.
  113. * @param {Object} state - The global state.
  114. * @returns {boolean}
  115. */
  116. export const shouldShowModeratedNotification = (mediaType: MediaType, state: IReduxState) =>
  117. isEnabledFromState(mediaType, state)
  118. && !isLocalParticipantApprovedFromState(mediaType, state);