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.

ContextMenuMore.tsx 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import React, { useCallback } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { TouchableOpacity, View, ViewStyle } from 'react-native';
  4. import { Divider, Text } from 'react-native-paper';
  5. import { useDispatch, useSelector } from 'react-redux';
  6. import { IReduxState } from '../../../app/types';
  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 { getCurrentConference } from '../../../base/conference/functions';
  18. import { hideSheet, openDialog } from '../../../base/dialog/actions';
  19. import BottomSheet from '../../../base/dialog/components/native/BottomSheet';
  20. import Icon from '../../../base/icons/components/Icon';
  21. import { IconCheck, IconRaiseHand, IconVideoOff } from '../../../base/icons/svg';
  22. import { MEDIA_TYPE } from '../../../base/media/constants';
  23. import { raiseHand } from '../../../base/participants/actions';
  24. import { getParticipantCount, getRaiseHandsQueue, isEveryoneModerator, isLocalParticipantModerator }
  25. from '../../../base/participants/functions';
  26. import { LOWER_HAND_MESSAGE } from '../../../base/tracks/constants';
  27. import MuteEveryonesVideoDialog
  28. from '../../../video-menu/components/native/MuteEveryonesVideoDialog';
  29. import styles from './styles';
  30. export const ContextMenuMore = () => {
  31. const dispatch = useDispatch();
  32. const muteAllVideo = useCallback(() => {
  33. dispatch(openDialog(MuteEveryonesVideoDialog));
  34. dispatch(hideSheet());
  35. }, [ dispatch ]);
  36. const conference = useSelector(getCurrentConference);
  37. const raisedHandsQueue = useSelector(getRaiseHandsQueue);
  38. const moderator = useSelector(isLocalParticipantModerator);
  39. const lowerAllHands = useCallback(() => {
  40. dispatch(raiseHand(false));
  41. conference?.sendEndpointMessage('', { name: LOWER_HAND_MESSAGE });
  42. dispatch(hideSheet());
  43. }, [ dispatch ]);
  44. const { t } = useTranslation();
  45. const isModerationSupported = useSelector((state: IReduxState) => isAvModerationSupported()(state));
  46. const allModerators = useSelector(isEveryoneModerator);
  47. const participantCount = useSelector(getParticipantCount);
  48. const isAudioModerationEnabled = useSelector(isAvModerationEnabled(MEDIA_TYPE.AUDIO));
  49. const isVideoModerationEnabled = useSelector(isAvModerationEnabled(MEDIA_TYPE.VIDEO));
  50. const disableAudioModeration = useCallback(() => dispatch(requestDisableAudioModeration()), [ dispatch ]);
  51. const disableVideoModeration = useCallback(() => dispatch(requestDisableVideoModeration()), [ dispatch ]);
  52. const enableAudioModeration = useCallback(() => dispatch(requestEnableAudioModeration()), [ dispatch ]);
  53. const enableVideoModeration = useCallback(() => dispatch(requestEnableVideoModeration()), [ dispatch ]);
  54. return (
  55. <BottomSheet
  56. addScrollViewPadding = { false }
  57. showSlidingView = { true }>
  58. <TouchableOpacity
  59. onPress = { muteAllVideo }
  60. style = { styles.contextMenuItem as ViewStyle }>
  61. <Icon
  62. size = { 24 }
  63. src = { IconVideoOff } />
  64. <Text style = { styles.contextMenuItemText }>{t('participantsPane.actions.stopEveryonesVideo')}</Text>
  65. </TouchableOpacity>
  66. { moderator && raisedHandsQueue.length !== 0 && <TouchableOpacity
  67. onPress = { lowerAllHands }
  68. style = { styles.contextMenuItem as ViewStyle }>
  69. <Icon
  70. size = { 24 }
  71. src = { IconRaiseHand } />
  72. <Text style = { styles.contextMenuItemText }>{t('participantsPane.actions.lowerAllHands')}</Text>
  73. </TouchableOpacity> }
  74. {isModerationSupported && ((participantCount === 1 || !allModerators)) && <>
  75. {/* @ts-ignore */}
  76. <Divider style = { styles.divider } />
  77. <View style = { styles.contextMenuItem as ViewStyle }>
  78. <Text style = { styles.contextMenuItemText }>{t('participantsPane.actions.allow')}</Text>
  79. </View>
  80. {isAudioModerationEnabled
  81. ? <TouchableOpacity
  82. onPress = { disableAudioModeration }
  83. style = { styles.contextMenuItem as ViewStyle }>
  84. <Text style = { styles.contextMenuItemTextNoIcon }>
  85. {t('participantsPane.actions.audioModeration')}
  86. </Text>
  87. </TouchableOpacity>
  88. : <TouchableOpacity
  89. onPress = { enableAudioModeration }
  90. style = { styles.contextMenuItem as ViewStyle }>
  91. <Icon
  92. size = { 24 }
  93. src = { IconCheck } />
  94. <Text style = { styles.contextMenuItemText }>
  95. {t('participantsPane.actions.audioModeration')}
  96. </Text>
  97. </TouchableOpacity> }
  98. {isVideoModerationEnabled
  99. ? <TouchableOpacity
  100. onPress = { disableVideoModeration }
  101. style = { styles.contextMenuItem as ViewStyle }>
  102. <Text style = { styles.contextMenuItemTextNoIcon }>
  103. {t('participantsPane.actions.videoModeration')}
  104. </Text>
  105. </TouchableOpacity>
  106. : <TouchableOpacity
  107. onPress = { enableVideoModeration }
  108. style = { styles.contextMenuItem as ViewStyle }>
  109. <Icon
  110. size = { 24 }
  111. src = { IconCheck } />
  112. <Text style = { styles.contextMenuItemText }>
  113. {t('participantsPane.actions.videoModeration')}
  114. </Text>
  115. </TouchableOpacity>}
  116. </>}
  117. </BottomSheet>
  118. );
  119. };