您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

RemoteVideoMenu.js 6.3KB

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