Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

RemoteVideoMenu.js 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. // @flow
  2. import React, { PureComponent } from 'react';
  3. import { Text, View } from 'react-native';
  4. import { Divider } from 'react-native-paper';
  5. import { Avatar } from '../../../base/avatar';
  6. import { ColorSchemeRegistry } from '../../../base/color-scheme';
  7. import { BottomSheet, isDialogOpen } from '../../../base/dialog';
  8. import { KICK_OUT_ENABLED, getFeatureFlag } from '../../../base/flags';
  9. import { translate } from '../../../base/i18n';
  10. import {
  11. getParticipantById,
  12. getParticipantDisplayName
  13. } from '../../../base/participants';
  14. import { connect } from '../../../base/redux';
  15. import { StyleType } from '../../../base/styles';
  16. import { getBreakoutRooms, getCurrentRoomId } from '../../../breakout-rooms/functions';
  17. import PrivateMessageButton from '../../../chat/components/native/PrivateMessageButton';
  18. import { hideRemoteVideoMenu } from '../../actions.native';
  19. import ConnectionStatusButton from '../native/ConnectionStatusButton';
  20. import AskUnmuteButton from './AskUnmuteButton';
  21. import GrantModeratorButton from './GrantModeratorButton';
  22. import KickButton from './KickButton';
  23. import MuteButton from './MuteButton';
  24. import MuteEveryoneElseButton from './MuteEveryoneElseButton';
  25. import MuteVideoButton from './MuteVideoButton';
  26. import PinButton from './PinButton';
  27. import SendToBreakoutRoom from './SendToBreakoutRoom';
  28. import styles from './styles';
  29. // import VolumeSlider from './VolumeSlider';
  30. /**
  31. * Size of the rendered avatar in the menu.
  32. */
  33. const AVATAR_SIZE = 24;
  34. type Props = {
  35. /**
  36. * The Redux dispatch function.
  37. */
  38. dispatch: Function,
  39. /**
  40. * The ID of the participant for which this menu opened for.
  41. */
  42. participantId: String,
  43. /**
  44. * The color-schemed stylesheet of the BottomSheet.
  45. */
  46. _bottomSheetStyles: StyleType,
  47. /**
  48. * The id of the current room.
  49. */
  50. _currentRoomId: String,
  51. /**
  52. * Whether or not to display the kick button.
  53. */
  54. _disableKick: boolean,
  55. /**
  56. * Whether or not to display the send private message button.
  57. */
  58. _disablePrivateChat: Boolean,
  59. /**
  60. * Whether or not to display the remote mute buttons.
  61. */
  62. _disableRemoteMute: boolean,
  63. /**
  64. * Whether or not to display the grant moderator button.
  65. */
  66. _disableGrantModerator: Boolean,
  67. /**
  68. * True if the menu is currently open, false otherwise.
  69. */
  70. _isOpen: boolean,
  71. /**
  72. * Whether the participant is present in the room or not.
  73. */
  74. _isParticipantAvailable?: boolean,
  75. /**
  76. * Display name of the participant retrieved from Redux.
  77. */
  78. _participantDisplayName: string,
  79. /**
  80. * Array containing the breakout rooms.
  81. */
  82. _rooms: Array<Object>,
  83. /**
  84. * Translation function.
  85. */
  86. t: Function
  87. }
  88. // eslint-disable-next-line prefer-const
  89. let RemoteVideoMenu_;
  90. /**
  91. * Class to implement a popup menu that opens upon long pressing a thumbnail.
  92. */
  93. class RemoteVideoMenu extends PureComponent<Props> {
  94. /**
  95. * Constructor of the component.
  96. *
  97. * @inheritdoc
  98. */
  99. constructor(props: Props) {
  100. super(props);
  101. this._onCancel = this._onCancel.bind(this);
  102. this._renderMenuHeader = this._renderMenuHeader.bind(this);
  103. }
  104. /**
  105. * Implements {@code Component#render}.
  106. *
  107. * @inheritdoc
  108. */
  109. render() {
  110. const {
  111. _disableKick,
  112. _disablePrivateChat,
  113. _disableRemoteMute,
  114. _disableGrantModerator,
  115. _isParticipantAvailable,
  116. _rooms,
  117. _currentRoomId,
  118. participantId,
  119. t
  120. } = this.props;
  121. const buttonProps = {
  122. afterClick: this._onCancel,
  123. showLabel: true,
  124. participantID: participantId,
  125. styles: this.props._bottomSheetStyles.buttons
  126. };
  127. return (
  128. <BottomSheet
  129. onCancel = { this._onCancel }
  130. renderHeader = { this._renderMenuHeader }
  131. showSlidingView = { _isParticipantAvailable }>
  132. <AskUnmuteButton { ...buttonProps } />
  133. { !_disableRemoteMute && <MuteButton { ...buttonProps } /> }
  134. <MuteEveryoneElseButton { ...buttonProps } />
  135. { !_disableRemoteMute && <MuteVideoButton { ...buttonProps } /> }
  136. <Divider style = { styles.divider } />
  137. { !_disableKick && <KickButton { ...buttonProps } /> }
  138. { !_disableGrantModerator && <GrantModeratorButton { ...buttonProps } /> }
  139. <PinButton { ...buttonProps } />
  140. { !_disablePrivateChat && <PrivateMessageButton { ...buttonProps } /> }
  141. <ConnectionStatusButton { ...buttonProps } />
  142. {_rooms.length > 1 && <>
  143. <Divider style = { styles.divider } />
  144. <View style = { styles.contextMenuItem }>
  145. <Text style = { styles.contextMenuItemText }>
  146. {t('breakoutRooms.actions.sendToBreakoutRoom')}
  147. </Text>
  148. </View>
  149. {_rooms.map(room => _currentRoomId !== room.id && (<SendToBreakoutRoom
  150. key = { room.id }
  151. room = { room }
  152. { ...buttonProps } />))}
  153. </>}
  154. {/* <VolumeSlider participantID = { participantId } />*/}
  155. </BottomSheet>
  156. );
  157. }
  158. _onCancel: () => boolean;
  159. /**
  160. * Callback to hide the {@code RemoteVideoMenu}.
  161. *
  162. * @private
  163. * @returns {boolean}
  164. */
  165. _onCancel() {
  166. if (this.props._isOpen) {
  167. this.props.dispatch(hideRemoteVideoMenu());
  168. return true;
  169. }
  170. return false;
  171. }
  172. _renderMenuHeader: () => React$Element<any>;
  173. /**
  174. * Function to render the menu's header.
  175. *
  176. * @returns {React$Element}
  177. */
  178. _renderMenuHeader() {
  179. const { _bottomSheetStyles, participantId } = this.props;
  180. return (
  181. <View
  182. style = { [
  183. _bottomSheetStyles.sheet,
  184. styles.participantNameContainer ] }>
  185. <Avatar
  186. participantId = { participantId }
  187. size = { AVATAR_SIZE } />
  188. <Text style = { styles.participantNameLabel }>
  189. { this.props._participantDisplayName }
  190. </Text>
  191. </View>
  192. );
  193. }
  194. }
  195. /**
  196. * Function that maps parts of Redux state tree into component props.
  197. *
  198. * @param {Object} state - Redux state.
  199. * @param {Object} ownProps - Properties of component.
  200. * @private
  201. * @returns {Props}
  202. */
  203. function _mapStateToProps(state, ownProps) {
  204. const kickOutEnabled = getFeatureFlag(state, KICK_OUT_ENABLED, true);
  205. const { participantId } = ownProps;
  206. const { remoteVideoMenu = {}, disableRemoteMute } = state['features/base/config'];
  207. const isParticipantAvailable = getParticipantById(state, participantId);
  208. const { disableKick, disablePrivateChat } = remoteVideoMenu;
  209. const _rooms = Object.values(getBreakoutRooms(state));
  210. const _currentRoomId = getCurrentRoomId(state);
  211. const shouldDisableKick = disableKick || !kickOutEnabled;
  212. return {
  213. _bottomSheetStyles: ColorSchemeRegistry.get(state, 'BottomSheet'),
  214. _currentRoomId,
  215. _disableKick: Boolean(shouldDisableKick),
  216. _disableRemoteMute: Boolean(disableRemoteMute),
  217. _disablePrivateChat: Boolean(disablePrivateChat),
  218. _isOpen: isDialogOpen(state, RemoteVideoMenu_),
  219. _isParticipantAvailable: Boolean(isParticipantAvailable),
  220. _participantDisplayName: getParticipantDisplayName(state, participantId),
  221. _rooms
  222. };
  223. }
  224. RemoteVideoMenu_ = translate(connect(_mapStateToProps)(RemoteVideoMenu));
  225. export default RemoteVideoMenu_;