ref(remote-control): Use React/Redux.

This commit is contained in:
Hristo Terezov
2020-11-13 22:09:25 -06:00
parent f88061db06
commit af6c794fda
30 changed files with 1348 additions and 1455 deletions

View File

@@ -4,12 +4,15 @@ import React, { Component } from 'react';
import { Icon, IconMenuThumb } from '../../../base/icons';
import { MEDIA_TYPE } from '../../../base/media';
import { getLocalParticipant, PARTICIPANT_ROLE } from '../../../base/participants';
import { getLocalParticipant, getParticipantById, PARTICIPANT_ROLE } from '../../../base/participants';
import { Popover } from '../../../base/popover';
import { connect } from '../../../base/redux';
import { isRemoteTrackMuted } from '../../../base/tracks';
import { requestRemoteControl, stopController } from '../../../remote-control';
import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
import MuteEveryoneElseButton from './MuteEveryoneElseButton';
import { REMOTE_CONTROL_MENU_STATES } from './RemoteControlButton';
import {
GrantModeratorButton,
@@ -50,6 +53,24 @@ type Props = {
*/
_isModerator: boolean,
/**
* The position relative to the trigger the remote menu should display
* from. Valid values are those supported by AtlasKit
* {@code InlineDialog}.
*/
_menuPosition: string,
/**
* The current state of the participant's remote control session.
*/
_remoteControlState: number,
/**
* The redux dispatch function.
*/
dispatch: Function,
/**
* A value between 0 and 1 indicating the volume of the participant's
* audio element.
@@ -61,34 +82,16 @@ type Props = {
*/
onMenuDisplay: Function,
/**
* Callback to invoke choosing to start a remote control session with
* the participant.
*/
onRemoteControlToggle: Function,
/**
* Callback to invoke when changing the level of the participant's
* audio element.
*/
onVolumeChange: Function,
/**
* The position relative to the trigger the remote menu should display
* from. Valid values are those supported by AtlasKit
* {@code InlineDialog}.
*/
menuPosition: string,
/**
* The ID for the participant on which the remote video menu will act.
*/
participantID: string,
/**
* The current state of the participant's remote control session.
*/
remoteControlState: number
};
/**
@@ -138,7 +141,7 @@ class RemoteVideoMenuTriggerButton extends Component<Props> {
<Popover
content = { content }
onPopoverOpen = { this._onShowRemoteMenu }
position = { this.props.menuPosition }>
position = { this.props._menuPosition }>
<span
className = 'popover-trigger remote-video-menu-trigger'>
<Icon
@@ -175,10 +178,10 @@ class RemoteVideoMenuTriggerButton extends Component<Props> {
_disableRemoteMute,
_isAudioMuted,
_isModerator,
dispatch,
initialVolumeValue,
onRemoteControlToggle,
onVolumeChange,
remoteControlState,
_remoteControlState,
participantID
} = this.props;
@@ -214,13 +217,21 @@ class RemoteVideoMenuTriggerButton extends Component<Props> {
}
}
if (remoteControlState) {
if (_remoteControlState) {
let onRemoteControlToggle = null;
if (_remoteControlState === REMOTE_CONTROL_MENU_STATES.STARTED) {
onRemoteControlToggle = () => dispatch(stopController(true));
} else if (_remoteControlState === REMOTE_CONTROL_MENU_STATES.NOT_STARTED) {
onRemoteControlToggle = () => dispatch(requestRemoteControl(participantID));
}
buttons.push(
<RemoteControlButton
key = 'remote-control'
onClick = { onRemoteControlToggle }
participantID = { participantID }
remoteControlState = { remoteControlState } />
remoteControlState = { _remoteControlState } />
);
}
@@ -258,7 +269,12 @@ class RemoteVideoMenuTriggerButton extends Component<Props> {
* @param {Object} ownProps - The own props of the component.
* @private
* @returns {{
* _isModerator: boolean
* _isAudioMuted: boolean,
* _isModerator: boolean,
* _disableKick: boolean,
* _disableRemoteMute: boolean,
* _menuPosition: string,
* _remoteControlState: number
* }}
*/
function _mapStateToProps(state, ownProps) {
@@ -267,12 +283,46 @@ function _mapStateToProps(state, ownProps) {
const localParticipant = getLocalParticipant(state);
const { remoteVideoMenu = {}, disableRemoteMute } = state['features/base/config'];
const { disableKick } = remoteVideoMenu;
let _remoteControlState = null;
const participant = getParticipantById(state, participantID);
const _isRemoteControlSessionActive = participant?.remoteControlSessionStatus ?? false;
const _supportsRemoteControl = participant?.supportsRemoteControl ?? false;
const { active, controller } = state['features/remote-control'];
const { requestedParticipant, controlled } = controller;
const activeParticipant = requestedParticipant || controlled;
if (_supportsRemoteControl
&& ((!active && !_isRemoteControlSessionActive) || activeParticipant === participantID)) {
if (requestedParticipant === participantID) {
_remoteControlState = REMOTE_CONTROL_MENU_STATES.REQUESTING;
} else if (controlled) {
_remoteControlState = REMOTE_CONTROL_MENU_STATES.STARTED;
} else {
_remoteControlState = REMOTE_CONTROL_MENU_STATES.NOT_STARTED;
}
}
const currentLayout = getCurrentLayout(state);
let _menuPosition;
switch (currentLayout) {
case LAYOUTS.TILE_VIEW:
_menuPosition = 'left top';
break;
case LAYOUTS.VERTICAL_FILMSTRIP_VIEW:
_menuPosition = 'left bottom';
break;
default:
_menuPosition = 'top center';
}
return {
_isAudioMuted: isRemoteTrackMuted(tracks, MEDIA_TYPE.AUDIO, participantID) || false,
_isModerator: Boolean(localParticipant?.role === PARTICIPANT_ROLE.MODERATOR),
_disableKick: Boolean(disableKick),
_disableRemoteMute: Boolean(disableRemoteMute)
_disableRemoteMute: Boolean(disableRemoteMute),
_remoteControlState,
_menuPosition
};
}