feat(thumbnails) Add changes to mobile context menu

- long touch on thumbnail opens context menu
- hide context menu icon
- add button for connection info to context menu
This commit is contained in:
hmuresan
2021-06-30 19:12:12 +03:00
committed by Horatiu Muresan
parent 0507f8c2f9
commit b995221a2b
15 changed files with 817 additions and 241 deletions

View File

@@ -2,6 +2,9 @@
import React, { Component } from 'react';
import ConnectionIndicatorContent from
'../../../../features/connection-indicator/components/web/ConnectionIndicatorContent';
import { isMobileBrowser } from '../../../base/environment/utils';
import { translate } from '../../../base/i18n';
import { Icon, IconMenuThumb } from '../../../base/icons';
import { getLocalParticipant, getParticipantById, PARTICIPANT_ROLE } from '../../../base/participants';
@@ -9,11 +12,14 @@ import { Popover } from '../../../base/popover';
import { connect } from '../../../base/redux';
import { requestRemoteControl, stopController } from '../../../remote-control';
import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
import { renderConnectionStatus } from '../../actions.web';
import ConnectionStatusButton from './ConnectionStatusButton';
import MuteEveryoneElseButton from './MuteEveryoneElseButton';
import MuteEveryoneElsesVideoButton from './MuteEveryoneElsesVideoButton';
import { REMOTE_CONTROL_MENU_STATES } from './RemoteControlButton';
import {
GrantModeratorButton,
MuteButton,
@@ -26,7 +32,6 @@ import {
} from './';
declare var $: Object;
declare var interfaceConfig: Object;
/**
* The type of the React {@code Component} props of
@@ -71,12 +76,16 @@ type Props = {
*/
_remoteControlState: number,
/**
* The redux dispatch function.
*/
dispatch: Function,
/**
* Gets a ref to the current component instance.
*/
getRef: Function,
/**
* A value between 0 and 1 indicating the volume of the participant's
* audio element.
@@ -99,6 +108,11 @@ type Props = {
*/
_participantDisplayName: string,
/**
* Whether the popover should render the Connection Info stats.
*/
_showConnectionInfo: Boolean,
/**
* Invoked to obtain translated strings.
*/
@@ -112,6 +126,59 @@ type Props = {
* @extends {Component}
*/
class RemoteVideoMenuTriggerButton extends Component<Props> {
/**
* Reference to the Popover instance.
*/
popoverRef: Object;
/**
* Initializes a new RemoteVideoMenuTriggerButton instance.
*
* @param {Object} props - The read-only React Component props with which
* the new instance is to be initialized.
*/
constructor(props: Props) {
super(props);
this.popoverRef = React.createRef();
this._onPopoverClose = this._onPopoverClose.bind(this);
}
/**
* Triggers showing the popover's context menu.
*
* @returns {void}
*/
showContextMenu() {
if (this.popoverRef && this.popoverRef.current) {
this.popoverRef.current.showDialog();
}
}
/**
* Calls the ref(instance) getter.
*
* @inheritdoc
* @returns {void}
*/
componentDidMount() {
if (this.props.getRef) {
this.props.getRef(this);
}
}
/**
* Calls the ref(instance) getter.
*
* @inheritdoc
* @returns {void}
*/
componentWillUnmount() {
if (this.props.getRef) {
this.props.getRef(null);
}
}
/**
* Implements React's {@link Component#render()}.
*
@@ -119,32 +186,50 @@ class RemoteVideoMenuTriggerButton extends Component<Props> {
* @returns {ReactElement}
*/
render() {
const content = this._renderRemoteVideoMenu();
const { _showConnectionInfo, _participantDisplayName, participantID } = this.props;
const content = _showConnectionInfo
? <ConnectionIndicatorContent participantId = { participantID } />
: this._renderRemoteVideoMenu();
if (!content) {
return null;
}
const username = this.props._participantDisplayName;
const username = _participantDisplayName;
return (
<Popover
content = { content }
onPopoverClose = { this._onPopoverClose }
overflowDrawer = { this.props._overflowDrawer }
position = { this.props._menuPosition }>
<span className = 'popover-trigger remote-video-menu-trigger'>
<Icon
ariaLabel = { this.props.t('dialog.remoteUserControls', { username }) }
role = 'button'
size = '1.4em'
src = { IconMenuThumb }
tabIndex = { 0 }
title = { this.props.t('dialog.remoteUserControls', { username }) } />
</span>
position = { this.props._menuPosition }
ref = { this.popoverRef }>
{!isMobileBrowser() && (
<span className = 'popover-trigger remote-video-menu-trigger'>
<Icon
ariaLabel = { this.props.t('dialog.remoteUserControls', { username }) }
role = 'button'
size = '1.4em'
src = { IconMenuThumb }
tabIndex = { 0 }
title = { this.props.t('dialog.remoteUserControls', { username }) } />
</span>
)}
</Popover>
);
}
_onPopoverClose: () => void;
/**
* Render normal context menu next time popover dialog opens.
*
* @returns {void}
*/
_onPopoverClose() {
this.props.dispatch(renderConnectionStatus(false));
}
/**
* Creates a new {@code VideoMenu} with buttons for interacting with
* the remote participant.
@@ -232,6 +317,12 @@ class RemoteVideoMenuTriggerButton extends Component<Props> {
participantID = { participantID } />
);
if (isMobileBrowser()) {
buttons.push(
<ConnectionStatusButton
participantId = { participantID } />
);
}
if (onVolumeChange && typeof initialVolumeValue === 'number' && !isNaN(initialVolumeValue)) {
buttons.push(
@@ -276,6 +367,7 @@ function _mapStateToProps(state, ownProps) {
const { requestedParticipant, controlled } = controller;
const activeParticipant = requestedParticipant || controlled;
const { overflowDrawer } = state['features/toolbox'];
const { showConnectionInfo } = state['features/base/connection'];
if (_supportsRemoteControl
&& ((!active && !_isRemoteControlSessionActive) || activeParticipant === participantID)) {
@@ -310,7 +402,8 @@ function _mapStateToProps(state, ownProps) {
_menuPosition,
_overflowDrawer: overflowDrawer,
_participantDisplayName,
_disableGrantModerator: Boolean(disableGrantModerator)
_disableGrantModerator: Boolean(disableGrantModerator),
_showConnectionInfo: showConnectionInfo
};
}