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.js 4.3KB

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