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 4.6KB

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