From 1afae50923c06905fa966289680dc7703029723b Mon Sep 17 00:00:00 2001 From: Calin Chitu Date: Tue, 15 Jun 2021 10:31:58 +0300 Subject: [PATCH] feat(native-participants-pane) dialog for blocking audio/video --- .../components/native/ContextMenuMore.js | 7 ++- react/features/video-menu/actions.any.js | 4 +- .../AbstractBlockAudioVideoDialog.js | 51 +++++++++++++++++++ .../native/BlockAudioVideoDialog.js | 32 ++++++++++++ .../video-menu/components/native/index.js | 1 + 5 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 react/features/video-menu/components/AbstractBlockAudioVideoDialog.js create mode 100644 react/features/video-menu/components/native/BlockAudioVideoDialog.js diff --git a/react/features/participants-pane/components/native/ContextMenuMore.js b/react/features/participants-pane/components/native/ContextMenuMore.js index d64b39ba6..1dd70b2bc 100644 --- a/react/features/participants-pane/components/native/ContextMenuMore.js +++ b/react/features/participants-pane/components/native/ContextMenuMore.js @@ -6,13 +6,14 @@ import { TouchableOpacity } from 'react-native'; import { Text } from 'react-native-paper'; import { useDispatch } from 'react-redux'; -import { hideDialog } from '../../../base/dialog'; +import { openDialog, hideDialog } from '../../../base/dialog/actions'; import BottomSheet from '../../../base/dialog/components/native/BottomSheet'; import { Icon, IconMicDisabledHollow, IconVideoOff } from '../../../base/icons'; import { MEDIA_TYPE } from '../../../base/media'; +import { BlockAudioVideoDialog } from '../../../video-menu'; import { muteAllParticipants } from '../../../video-menu/actions.any'; @@ -33,6 +34,7 @@ type Props = { export const ContextMenuMore = ({ exclude }: Props) => { const dispatch = useDispatch(); + const blockAudioVideo = useCallback(() => dispatch(openDialog(BlockAudioVideoDialog)), [ dispatch ]); const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]); const muteEveryoneVideo = useCallback(() => dispatch(muteAllParticipants(exclude, MEDIA_TYPE.VIDEO)), [ dispatch ]); const { t } = useTranslation(); @@ -50,12 +52,13 @@ export const ContextMenuMore = ({ exclude }: Props) => { {t('participantsPane.actions.stopEveryonesVideo')} - {t('participantsPane.actions.dontAllowUnmute')} + {t('participantsPane.actions.blockAudioVideo')} ); diff --git a/react/features/video-menu/actions.any.js b/react/features/video-menu/actions.any.js index 1bb73c11f..e9f2dcc5a 100644 --- a/react/features/video-menu/actions.any.js +++ b/react/features/video-menu/actions.any.js @@ -129,11 +129,11 @@ export function admitAllKnockingParticipants(knockingParticipants: Array /** - * Don't allow participants to unmute. + * Don't allow participants to unmute video/audio. * * @returns {Function} */ -export function dontAllowUnmute() { +export function blockParticipantsAudioVideo() { return (dispatch: Dispatch, getState: Function) => { const state = getState(); const participants = state['features/base/participants']; diff --git a/react/features/video-menu/components/AbstractBlockAudioVideoDialog.js b/react/features/video-menu/components/AbstractBlockAudioVideoDialog.js new file mode 100644 index 000000000..994f98acb --- /dev/null +++ b/react/features/video-menu/components/AbstractBlockAudioVideoDialog.js @@ -0,0 +1,51 @@ +// @flow + +import { Component } from 'react'; + +import { blockParticipantsAudioVideo } from '../actions.any'; + +type Props = { + + /** + * The Redux dispatch function. + */ + dispatch: Function, + + /** + * Function to translate i18n labels. + */ + t: Function +}; + +/** + * Abstract dialog to confirm blocking mic and camera for all participants. + */ +export default class AbstractBlockAudioVideoDialog + extends Component { + /** + * Initializes a new {@code AbstractBlockAudioVideoDialog} instance. + * + * @inheritdoc + */ + constructor(props: Props) { + super(props); + + this._onSubmit = this._onSubmit.bind(this); + } + + _onSubmit: () => boolean; + + /** + * Callback for the confirm button. + * + * @private + * @returns {boolean} - True (to note that the modal should be closed). + */ + _onSubmit() { + const { dispatch } = this.props; + + dispatch(blockParticipantsAudioVideo()); + + return true; + } +} diff --git a/react/features/video-menu/components/native/BlockAudioVideoDialog.js b/react/features/video-menu/components/native/BlockAudioVideoDialog.js new file mode 100644 index 000000000..6b374252a --- /dev/null +++ b/react/features/video-menu/components/native/BlockAudioVideoDialog.js @@ -0,0 +1,32 @@ +// @flow + +import React from 'react'; + +import { ConfirmDialog } from '../../../base/dialog'; +import { translate } from '../../../base/i18n'; +import { connect } from '../../../base/redux'; +import AbstractBlockAudioVideoDialog + from '../AbstractBlockAudioVideoDialog'; + +/** + * Dialog to confirm a remote participant kick action. + */ +class BlockAudioVideoDialog extends AbstractBlockAudioVideoDialog { + /** + * Implements React's {@link Component#render()}. + * + * @inheritdoc + * @returns {ReactElement} + */ + render() { + return ( + + ); + } + + _onSubmit: () => boolean; +} + +export default translate(connect()(BlockAudioVideoDialog)); diff --git a/react/features/video-menu/components/native/index.js b/react/features/video-menu/components/native/index.js index c013bf2b0..3ee816ff2 100644 --- a/react/features/video-menu/components/native/index.js +++ b/react/features/video-menu/components/native/index.js @@ -1,5 +1,6 @@ // @flow +export { default as BlockAudioVideoDialog } from './BlockAudioVideoDialog'; export { default as GrantModeratorDialog } from './GrantModeratorDialog'; export { default as KickRemoteParticipantDialog } from './KickRemoteParticipantDialog'; export { default as MuteEveryoneDialog } from './MuteEveryoneDialog';