Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

FooterContextMenu.tsx 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import React, { useCallback } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { useDispatch, useSelector } from 'react-redux';
  4. import { makeStyles } from 'tss-react/mui';
  5. import { IReduxState } from '../../../app/types';
  6. import {
  7. requestDisableAudioModeration,
  8. requestDisableVideoModeration,
  9. requestEnableAudioModeration,
  10. requestEnableVideoModeration
  11. } from '../../../av-moderation/actions';
  12. import {
  13. isEnabled as isAvModerationEnabled,
  14. isSupported as isAvModerationSupported
  15. } from '../../../av-moderation/functions';
  16. import { openDialog } from '../../../base/dialog/actions';
  17. import {
  18. IconCheck,
  19. IconDotsHorizontal,
  20. IconVideoOff
  21. } from '../../../base/icons/svg';
  22. import { MEDIA_TYPE } from '../../../base/media/constants';
  23. import {
  24. getParticipantCount,
  25. getRaiseHandsQueue,
  26. isEveryoneModerator
  27. } from '../../../base/participants/functions';
  28. import { withPixelLineHeight } from '../../../base/styles/functions.web';
  29. import ContextMenu from '../../../base/ui/components/web/ContextMenu';
  30. import ContextMenuItemGroup from '../../../base/ui/components/web/ContextMenuItemGroup';
  31. import { isInBreakoutRoom } from '../../../breakout-rooms/functions';
  32. import { openSettingsDialog } from '../../../settings/actions.web';
  33. import { SETTINGS_TABS } from '../../../settings/constants';
  34. import { shouldShowModeratorSettings } from '../../../settings/functions.web';
  35. import LowerHandButton from '../../../video-menu/components/web/LowerHandButton';
  36. import MuteEveryonesVideoDialog from '../../../video-menu/components/web/MuteEveryonesVideoDialog';
  37. const useStyles = makeStyles()(theme => {
  38. return {
  39. contextMenu: {
  40. bottom: 'auto',
  41. margin: '0',
  42. right: 0,
  43. top: '-8px',
  44. transform: 'translateY(-100%)',
  45. width: '283px'
  46. },
  47. text: {
  48. ...withPixelLineHeight(theme.typography.bodyShortRegular),
  49. color: theme.palette.text02,
  50. padding: '10px 16px',
  51. height: '40px',
  52. overflow: 'hidden',
  53. display: 'flex',
  54. alignItems: 'center',
  55. boxSizing: 'border-box'
  56. },
  57. indentedLabel: {
  58. '& > span': {
  59. marginLeft: '36px'
  60. }
  61. }
  62. };
  63. });
  64. interface IProps {
  65. /**
  66. * Whether the menu is open.
  67. */
  68. isOpen: boolean;
  69. /**
  70. * Drawer close callback.
  71. */
  72. onDrawerClose: (e?: React.MouseEvent) => void;
  73. /**
  74. * Callback for the mouse leaving this item.
  75. */
  76. onMouseLeave?: (e?: React.MouseEvent) => void;
  77. }
  78. export const FooterContextMenu = ({ isOpen, onDrawerClose, onMouseLeave }: IProps) => {
  79. const dispatch = useDispatch();
  80. const isModerationSupported = useSelector((state: IReduxState) => isAvModerationSupported()(state));
  81. const raisedHandsQueue = useSelector(getRaiseHandsQueue);
  82. const allModerators = useSelector(isEveryoneModerator);
  83. const isModeratorSettingsTabEnabled = useSelector(shouldShowModeratorSettings);
  84. const participantCount = useSelector(getParticipantCount);
  85. const isAudioModerationEnabled = useSelector(isAvModerationEnabled(MEDIA_TYPE.AUDIO));
  86. const isVideoModerationEnabled = useSelector(isAvModerationEnabled(MEDIA_TYPE.VIDEO));
  87. const isBreakoutRoom = useSelector(isInBreakoutRoom);
  88. const { t } = useTranslation();
  89. const disableAudioModeration = useCallback(() => dispatch(requestDisableAudioModeration()), [ dispatch ]);
  90. const disableVideoModeration = useCallback(() => dispatch(requestDisableVideoModeration()), [ dispatch ]);
  91. const enableAudioModeration = useCallback(() => dispatch(requestEnableAudioModeration()), [ dispatch ]);
  92. const enableVideoModeration = useCallback(() => dispatch(requestEnableVideoModeration()), [ dispatch ]);
  93. const { classes } = useStyles();
  94. const muteAllVideo = useCallback(
  95. () => dispatch(openDialog(MuteEveryonesVideoDialog)), [ dispatch ]);
  96. const openModeratorSettings = () => dispatch(openSettingsDialog(SETTINGS_TABS.MODERATOR));
  97. const actions = [
  98. {
  99. accessibilityLabel: t('participantsPane.actions.audioModeration'),
  100. className: isAudioModerationEnabled ? classes.indentedLabel : '',
  101. id: isAudioModerationEnabled
  102. ? 'participants-pane-context-menu-stop-audio-moderation'
  103. : 'participants-pane-context-menu-start-audio-moderation',
  104. icon: !isAudioModerationEnabled && IconCheck,
  105. onClick: isAudioModerationEnabled ? disableAudioModeration : enableAudioModeration,
  106. text: t('participantsPane.actions.audioModeration')
  107. }, {
  108. accessibilityLabel: t('participantsPane.actions.videoModeration'),
  109. className: isVideoModerationEnabled ? classes.indentedLabel : '',
  110. id: isVideoModerationEnabled
  111. ? 'participants-pane-context-menu-stop-video-moderation'
  112. : 'participants-pane-context-menu-start-video-moderation',
  113. icon: !isVideoModerationEnabled && IconCheck,
  114. onClick: isVideoModerationEnabled ? disableVideoModeration : enableVideoModeration,
  115. text: t('participantsPane.actions.videoModeration')
  116. }
  117. ];
  118. return (
  119. <ContextMenu
  120. activateFocusTrap = { true }
  121. className = { classes.contextMenu }
  122. hidden = { !isOpen }
  123. isDrawerOpen = { isOpen }
  124. onDrawerClose = { onDrawerClose }
  125. onMouseLeave = { onMouseLeave }>
  126. <ContextMenuItemGroup
  127. actions = { [ {
  128. accessibilityLabel: t('participantsPane.actions.stopEveryonesVideo'),
  129. id: 'participants-pane-context-menu-stop-video',
  130. icon: IconVideoOff,
  131. onClick: muteAllVideo,
  132. text: t('participantsPane.actions.stopEveryonesVideo')
  133. } ] } />
  134. {raisedHandsQueue.length !== 0 && <LowerHandButton />}
  135. {!isBreakoutRoom && isModerationSupported && (participantCount === 1 || !allModerators) && (
  136. <ContextMenuItemGroup actions = { actions }>
  137. <div className = { classes.text }>
  138. <span>{t('participantsPane.actions.allow')}</span>
  139. </div>
  140. </ContextMenuItemGroup>
  141. )}
  142. {isModeratorSettingsTabEnabled && (
  143. <ContextMenuItemGroup
  144. actions = { [ {
  145. accessibilityLabel: t('participantsPane.actions.moreModerationControls'),
  146. id: 'participants-pane-open-moderation-control-settings',
  147. icon: IconDotsHorizontal,
  148. onClick: openModeratorSettings,
  149. text: t('participantsPane.actions.moreModerationControls')
  150. } ] } />
  151. )}
  152. </ContextMenu>
  153. );
  154. };