feat(disableSelfView) Toggle self view on native (#10871)

Added toggle button in overflow menu
Created video menu with connection info and self view toggle buttons for local participant
This commit is contained in:
Robert Pintilii 2022-01-28 12:47:54 +02:00 committed by GitHub
parent 4b483f7ec8
commit 7e5c283e3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 268 additions and 9 deletions

View File

@ -1001,6 +1001,7 @@
"remoteVideoMute": "Disable camera of participant",
"security": "Security options",
"selectBackground": "Select Background",
"selfView": "Toggle self view",
"shareRoom": "Invite someone",
"shareYourScreen": "Start / Stop sharing your screen",
"shareaudio": "Share audio",
@ -1168,6 +1169,7 @@
"remoteControl": "Start / Stop remote control",
"screenSharing": "Participant is sharing their screen",
"show": "Show on stage",
"showSelfView": "Show self view",
"videoMuted": "Camera disabled",
"videomute": "Participant has stopped the camera"
},

View File

@ -23,7 +23,6 @@ import { getTrackByMediaTypeAndParticipant } from '../../../base/tracks';
import { ConnectionIndicator } from '../../../connection-indicator';
import { DisplayNameLabel } from '../../../display-name';
import {
showConnectionStatus,
showContextMenuDetails,
showSharedVideoMenu
} from '../../../participants-pane/actions.native';
@ -194,11 +193,7 @@ class Thumbnail extends PureComponent<Props> {
}
if (!_isFakeParticipant) {
if (_local) {
dispatch(showConnectionStatus(_participantId));
} else {
dispatch(showContextMenuDetails(_participantId));
}
dispatch(showContextMenuDetails(_participantId, _local));
}
}

View File

@ -2,6 +2,7 @@
import { openDialog } from '../base/dialog';
import { SharedVideoMenu } from '../video-menu';
import { LocalVideoMenu } from '../video-menu/components/native';
import ConnectionStatusComponent
from '../video-menu/components/native/ConnectionStatusComponent';
import RemoteVideoMenu from '../video-menu/components/native/RemoteVideoMenu';
@ -37,10 +38,13 @@ export function showConnectionStatus(participantID: string) {
* Displays the context menu for the selected meeting participant.
*
* @param {string} participantId - The ID of the selected meeting participant.
* @param {boolean} local - Whether the participant is local or not.
* @returns {Function}
*/
export function showContextMenuDetails(participantId: string) {
return openDialog(RemoteVideoMenu, { participantId });
export function showContextMenuDetails(participantId: string, local: boolean = false) {
return local
? openDialog(LocalVideoMenu)
: openDialog(RemoteVideoMenu, { participantId });
}
/**

View File

@ -0,0 +1,79 @@
// @flow
import { translate } from '../../../base/i18n';
import { IconAudioOnlyOff } from '../../../base/icons';
import { connect } from '../../../base/redux';
import { updateSettings } from '../../../base/settings';
import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
/**
* The type of the React {@code Component} props of {@link ToggleSelfViewButton}.
*/
type Props = AbstractButtonProps & {
/**
* Whether the self view is disabled or not.
*/
_disableSelfView: boolean,
/**
* The redux {@code dispatch} function.
*/
dispatch: Function
};
/**
* An implementation of a button for toggling the self view.
*/
class ToggleSelfViewButton extends AbstractButton<Props, *> {
accessibilityLabel = 'toolbar.accessibilityLabel.selfView';
icon = IconAudioOnlyOff;
label = 'videothumbnail.hideSelfView';
toggledLabel = 'videothumbnail.showSelfView';
/**
* Handles clicking / pressing the button.
*
* @override
* @protected
* @returns {void}
*/
_handleClick() {
const { _disableSelfView, dispatch } = this.props;
dispatch(updateSettings({
disableSelfView: !_disableSelfView
}));
}
/**
* Indicates whether this button is in toggled state or not.
*
* @override
* @protected
* @returns {boolean}
*/
_isToggled() {
return this.props._disableSelfView;
}
}
/**
* Maps (parts of) the redux state to the associated props for the
* {@code ToggleSelfViewButton} component.
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* _disableSelfView: boolean
* }}
*/
function _mapStateToProps(state): Object {
const { disableSelfView } = state['features/base/settings'];
return {
_disableSelfView: Boolean(disableSelfView)
};
}
export default translate(connect(_mapStateToProps)(ToggleSelfViewButton));

View File

@ -1,7 +1,16 @@
// @flow
import { hideDialog } from '../base/dialog';
import { RemoteVideoMenu, SharedVideoMenu } from './components/native';
import { RemoteVideoMenu, SharedVideoMenu, LocalVideoMenu } from './components/native';
/**
* Hides the local video menu.
*
* @returns {Function}
*/
export function hideLocalVideoMenu() {
return hideDialog(LocalVideoMenu);
}
/**
* Hides the remote video menu.

View File

@ -0,0 +1,169 @@
// @flow
import React, { PureComponent } from 'react';
import { Text, View } from 'react-native';
import { Avatar } from '../../../base/avatar';
import { ColorSchemeRegistry } from '../../../base/color-scheme';
import { BottomSheet, isDialogOpen } from '../../../base/dialog';
import { translate } from '../../../base/i18n';
import {
getLocalParticipant,
getParticipantDisplayName
} from '../../../base/participants';
import { connect } from '../../../base/redux';
import { StyleType } from '../../../base/styles';
import ToggleSelfViewButton from '../../../toolbox/components/native/ToggleSelfViewButton';
import { hideLocalVideoMenu } from '../../actions.native';
import ConnectionStatusButton from './ConnectionStatusButton';
import styles from './styles';
/**
* Size of the rendered avatar in the menu.
*/
const AVATAR_SIZE = 24;
type Props = {
/**
* The color-schemed stylesheet of the BottomSheet.
*/
_bottomSheetStyles: StyleType,
/**
* True if the menu is currently open, false otherwise.
*/
_isOpen: boolean,
/**
* The local participant.
*/
_participant: Object,
/**
* Display name of the participant retrieved from Redux.
*/
_participantDisplayName: string,
/**
* The Redux dispatch function.
*/
dispatch: Function,
/**
* Translation function.
*/
t: Function
}
// eslint-disable-next-line prefer-const
let LocalVideoMenu_;
/**
* Class to implement a popup menu that opens upon long pressing a thumbnail.
*/
class LocalVideoMenu extends PureComponent<Props> {
/**
* Constructor of the component.
*
* @inheritdoc
*/
constructor(props: Props) {
super(props);
this._onCancel = this._onCancel.bind(this);
this._renderMenuHeader = this._renderMenuHeader.bind(this);
}
/**
* Implements {@code Component#render}.
*
* @inheritdoc
*/
render() {
const { _participant, _bottomSheetStyles } = this.props;
const buttonProps = {
afterClick: this._onCancel,
showLabel: true,
participantID: _participant.id,
styles: _bottomSheetStyles.buttons
};
return (
<BottomSheet
onCancel = { this._onCancel }
renderHeader = { this._renderMenuHeader }
showSlidingView = { true }>
<ToggleSelfViewButton { ...buttonProps } />
<ConnectionStatusButton { ...buttonProps } />
</BottomSheet>
);
}
_onCancel: () => boolean;
/**
* Callback to hide the {@code RemoteVideoMenu}.
*
* @private
* @returns {boolean}
*/
_onCancel() {
if (this.props._isOpen) {
this.props.dispatch(hideLocalVideoMenu());
return true;
}
return false;
}
_renderMenuHeader: () => React$Element<any>;
/**
* Function to render the menu's header.
*
* @returns {React$Element}
*/
_renderMenuHeader() {
const { _bottomSheetStyles, _participant } = this.props;
return (
<View
style = { [
_bottomSheetStyles.sheet,
styles.participantNameContainer ] }>
<Avatar
participantId = { _participant.id }
size = { AVATAR_SIZE } />
<Text style = { styles.participantNameLabel }>
{ this.props._participantDisplayName }
</Text>
</View>
);
}
}
/**
* Function that maps parts of Redux state tree into component props.
*
* @param {Object} state - Redux state.
* @private
* @returns {Props}
*/
function _mapStateToProps(state) {
const participant = getLocalParticipant(state);
return {
_bottomSheetStyles: ColorSchemeRegistry.get(state, 'BottomSheet'),
_isOpen: isDialogOpen(state, LocalVideoMenu_),
_participant: participant,
_participantDisplayName: getParticipantDisplayName(state, participant.id)
};
}
LocalVideoMenu_ = translate(connect(_mapStateToProps)(LocalVideoMenu));
export default LocalVideoMenu_;

View File

@ -6,6 +6,7 @@ export { default as KickRemoteParticipantDialog } from './KickRemoteParticipantD
export { default as MuteEveryoneDialog } from './MuteEveryoneDialog';
export { default as MuteEveryonesVideoDialog } from './MuteEveryonesVideoDialog';
export { default as MuteRemoteParticipantsVideoDialog } from './MuteRemoteParticipantsVideoDialog';
export { default as LocalVideoMenu } from './LocalVideoMenu';
export { default as RemoteVideoMenu } from './RemoteVideoMenu';
export { default as SharedVideoMenu } from './SharedVideoMenu';
export { default as VolumeSlider } from './VolumeSlider';