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.

RemoteVideoMenu.js 5.3KB

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