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.

FooterContextMenu.js 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // @flow
  2. import { makeStyles } from '@material-ui/core/styles';
  3. import clsx from 'clsx';
  4. import React, { useCallback } from 'react';
  5. import { useTranslation } from 'react-i18next';
  6. import { useDispatch, useSelector } from 'react-redux';
  7. import {
  8. requestDisableAudioModeration,
  9. requestDisableVideoModeration,
  10. requestEnableAudioModeration,
  11. requestEnableVideoModeration
  12. } from '../../av-moderation/actions';
  13. import {
  14. isEnabled as isAvModerationEnabled,
  15. isSupported as isAvModerationSupported
  16. } from '../../av-moderation/functions';
  17. import { openDialog } from '../../base/dialog';
  18. import { Icon, IconCheck, IconVideoOff } from '../../base/icons';
  19. import { MEDIA_TYPE } from '../../base/media';
  20. import {
  21. getParticipantCount,
  22. isEveryoneModerator
  23. } from '../../base/participants';
  24. import { MuteEveryonesVideoDialog } from '../../video-menu/components';
  25. import {
  26. ContextMenu,
  27. ContextMenuItem,
  28. ContextMenuItemGroup
  29. } from './web/styled';
  30. const useStyles = makeStyles(() => {
  31. return {
  32. contextMenu: {
  33. bottom: 'auto',
  34. margin: '0',
  35. padding: '8px 0',
  36. right: 0,
  37. top: '-8px',
  38. transform: 'translateY(-100%)',
  39. width: '283px'
  40. },
  41. drawer: {
  42. width: '100%',
  43. top: 'auto',
  44. bottom: 0,
  45. transform: 'none',
  46. position: 'relative',
  47. '& > div': {
  48. lineHeight: '32px'
  49. }
  50. },
  51. text: {
  52. color: '#C2C2C2',
  53. padding: '10px 16px 10px 52px'
  54. },
  55. paddedAction: {
  56. marginLeft: '36px;'
  57. }
  58. };
  59. });
  60. type Props = {
  61. /**
  62. * Whether the menu is displayed inside a drawer.
  63. */
  64. inDrawer?: boolean,
  65. /**
  66. * Callback for the mouse leaving this item.
  67. */
  68. onMouseLeave?: Function
  69. };
  70. export const FooterContextMenu = ({ inDrawer, onMouseLeave }: Props) => {
  71. const dispatch = useDispatch();
  72. const isModerationSupported = useSelector(isAvModerationSupported());
  73. const allModerators = useSelector(isEveryoneModerator);
  74. const participantCount = useSelector(getParticipantCount);
  75. const isAudioModerationEnabled = useSelector(isAvModerationEnabled(MEDIA_TYPE.AUDIO));
  76. const isVideoModerationEnabled = useSelector(isAvModerationEnabled(MEDIA_TYPE.VIDEO));
  77. const { t } = useTranslation();
  78. const disableAudioModeration = useCallback(() => dispatch(requestDisableAudioModeration()), [ dispatch ]);
  79. const disableVideoModeration = useCallback(() => dispatch(requestDisableVideoModeration()), [ dispatch ]);
  80. const enableAudioModeration = useCallback(() => dispatch(requestEnableAudioModeration()), [ dispatch ]);
  81. const enableVideoModeration = useCallback(() => dispatch(requestEnableVideoModeration()), [ dispatch ]);
  82. const classes = useStyles();
  83. const muteAllVideo = useCallback(
  84. () => dispatch(openDialog(MuteEveryonesVideoDialog)), [ dispatch ]);
  85. return (
  86. <ContextMenu
  87. className = { clsx(classes.contextMenu, inDrawer && clsx(classes.drawer)) }
  88. onMouseLeave = { onMouseLeave }>
  89. <ContextMenuItemGroup>
  90. <ContextMenuItem
  91. id = 'participants-pane-context-menu-stop-video'
  92. onClick = { muteAllVideo }>
  93. <Icon
  94. size = { 20 }
  95. src = { IconVideoOff } />
  96. <span>{ t('participantsPane.actions.stopEveryonesVideo') }</span>
  97. </ContextMenuItem>
  98. </ContextMenuItemGroup>
  99. {isModerationSupported && (participantCount === 1 || !allModerators) ? (
  100. <ContextMenuItemGroup>
  101. <div className = { classes.text }>
  102. {t('participantsPane.actions.allow')}
  103. </div>
  104. { isAudioModerationEnabled ? (
  105. <ContextMenuItem
  106. id = 'participants-pane-context-menu-stop-audio-moderation'
  107. onClick = { disableAudioModeration }>
  108. <span className = { classes.paddedAction }>
  109. {t('participantsPane.actions.audioModeration') }
  110. </span>
  111. </ContextMenuItem>
  112. ) : (
  113. <ContextMenuItem
  114. id = 'participants-pane-context-menu-start-audio-moderation'
  115. onClick = { enableAudioModeration }>
  116. <Icon
  117. size = { 20 }
  118. src = { IconCheck } />
  119. <span>{t('participantsPane.actions.audioModeration') }</span>
  120. </ContextMenuItem>
  121. )}
  122. { isVideoModerationEnabled ? (
  123. <ContextMenuItem
  124. id = 'participants-pane-context-menu-stop-video-moderation'
  125. onClick = { disableVideoModeration }>
  126. <span className = { classes.paddedAction }>
  127. {t('participantsPane.actions.videoModeration')}
  128. </span>
  129. </ContextMenuItem>
  130. ) : (
  131. <ContextMenuItem
  132. id = 'participants-pane-context-menu-start-video-moderation'
  133. onClick = { enableVideoModeration }>
  134. <Icon
  135. size = { 20 }
  136. src = { IconCheck } />
  137. <span>{t('participantsPane.actions.videoModeration')}</span>
  138. </ContextMenuItem>
  139. )}
  140. </ContextMenuItemGroup>
  141. ) : undefined
  142. }
  143. </ContextMenu>
  144. );
  145. };