diff --git a/react/features/base/media/constants.ts b/react/features/base/media/constants.ts index 3b26f1e42..6fd509624 100644 --- a/react/features/base/media/constants.ts +++ b/react/features/base/media/constants.ts @@ -15,11 +15,15 @@ export type MediaType = 'audio' | 'video' | 'screenshare'; * * @enum {string} */ -export const MEDIA_TYPE: { [key: string]: MediaType; } = { - AUDIO: 'audio', - SCREENSHARE: 'screenshare', - VIDEO: 'video' -}; +export const MEDIA_TYPE: { + AUDIO: MediaType; + SCREENSHARE: MediaType; + VIDEO: MediaType; + } = { + AUDIO: 'audio', + SCREENSHARE: 'screenshare', + VIDEO: 'video' + }; /* eslint-disable no-bitwise */ diff --git a/react/features/participants-pane/components/web/MeetingParticipantItem.js b/react/features/participants-pane/components/web/MeetingParticipantItem.js index db3264f5f..6a78f6ece 100644 --- a/react/features/participants-pane/components/web/MeetingParticipantItem.js +++ b/react/features/participants-pane/components/web/MeetingParticipantItem.js @@ -2,7 +2,6 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { translate } from '../../../base/i18n'; import { JitsiTrackEvents } from '../../../base/lib-jitsi-meet'; import { MEDIA_TYPE } from '../../../base/media'; import { @@ -163,9 +162,9 @@ type Props = { participantID: ?string, /** - * The translate function. - */ - t: Function, + * Callback used to stop a participant's video. + */ + stopVideo: Function, /** * The translated "you" text. @@ -192,17 +191,15 @@ function MeetingParticipantItem({ _quickActionButtonType, _raisedHand, _videoMediaState, - askUnmuteText, isHighlighted, isInBreakoutRoom, muteAudio, - muteParticipantButtonText, onContextMenu, onLeave, openDrawerForParticipant, overflowDrawer, participantActionEllipsisLabel, - t, + stopVideo, youText }: Props) { @@ -242,12 +239,6 @@ function MeetingParticipantItem({ const audioMediaState = _audioMediaState === MEDIA_STATE.UNMUTED && hasAudioLevels ? MEDIA_STATE.DOMINANT_SPEAKER : _audioMediaState; - let askToUnmuteText = askUnmuteText; - - if (_audioMediaState !== MEDIA_STATE.FORCE_MUTED && _videoMediaState === MEDIA_STATE.FORCE_MUTED) { - askToUnmuteText = t('participantsPane.actions.allowVideo'); - } - return ( {!isInBreakoutRoom && ( + participantName = { _displayName } + stopVideo = { stopVideo } /> )} ( ); diff --git a/react/features/participants-pane/components/web/MeetingParticipants.tsx b/react/features/participants-pane/components/web/MeetingParticipants.tsx index e5e357465..8b91c6c90 100644 --- a/react/features/participants-pane/components/web/MeetingParticipants.tsx +++ b/react/features/participants-pane/components/web/MeetingParticipants.tsx @@ -5,7 +5,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { makeStyles } from 'tss-react/mui'; import { IReduxState } from '../../../app/types'; -import { rejectParticipantAudio } from '../../../av-moderation/actions'; +import { rejectParticipantAudio, rejectParticipantVideo } from '../../../av-moderation/actions'; import participantsPaneTheme from '../../../base/components/themes/participantsPaneTheme.json'; import { isToolbarButtonEnabled } from '../../../base/config/functions.web'; import { MEDIA_TYPE } from '../../../base/media/constants'; @@ -88,11 +88,14 @@ function MeetingParticipants({ const { t } = useTranslation(); const [ lowerMenu, , toggleMenu, menuEnter, menuLeave, raiseContext ] = useContextMenu(); - const muteAudio = useCallback(id => () => { dispatch(muteRemote(id, MEDIA_TYPE.AUDIO)); dispatch(rejectParticipantAudio(id)); }, [ dispatch ]); + const stopVideo = useCallback(id => () => { + dispatch(muteRemote(id, MEDIA_TYPE.VIDEO)); + dispatch(rejectParticipantVideo(id)); + }, [ dispatch ]); const [ drawerParticipant, closeDrawer, openDrawerForParticipant ] = useParticipantDrawer(); // FIXME: @@ -103,8 +106,6 @@ function MeetingParticipants({ // mounted. const participantActionEllipsisLabel = t('participantsPane.actions.moreParticipantOptions'); const youText = t('chat.you'); - const askUnmuteText = t('participantsPane.actions.askUnmute'); - const muteParticipantButtonText = t('dialog.muteParticipantButton'); const isBreakoutRoom = useSelector(isInBreakoutRoom); const visitorsCount = useSelector((state: IReduxState) => state['features/visitors'].count); @@ -130,11 +131,9 @@ function MeetingParticipants({ value = { searchString } />
diff --git a/react/features/participants-pane/components/web/ParticipantQuickAction.tsx b/react/features/participants-pane/components/web/ParticipantQuickAction.tsx index 200a4237f..0b249f0c3 100644 --- a/react/features/participants-pane/components/web/ParticipantQuickAction.tsx +++ b/react/features/participants-pane/components/web/ParticipantQuickAction.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; import { makeStyles } from 'tss-react/mui'; -import { approveParticipant } from '../../../av-moderation/actions'; +import { approveParticipantAudio, approveParticipantVideo } from '../../../av-moderation/actions'; import Button from '../../../base/ui/components/web/Button'; import { QUICK_ACTION_BUTTON } from '../../constants'; @@ -43,6 +43,12 @@ interface IProps { * The name of the participant. */ participantName: string; + + /** + * Callback used to stop a participant's video. + */ + stopVideo: Function; + } const useStyles = makeStyles()(theme => { @@ -54,19 +60,22 @@ const useStyles = makeStyles()(theme => { }); const ParticipantQuickAction = ({ - askUnmuteText, buttonType, muteAudio, - muteParticipantButtonText, participantID, - participantName + participantName, + stopVideo }: IProps) => { const { classes: styles } = useStyles(); const dispatch = useDispatch(); const { t } = useTranslation(); const askToUnmute = useCallback(() => { - dispatch(approveParticipant(participantID)); + dispatch(approveParticipantAudio(participantID)); + }, [ dispatch, participantID ]); + + const allowVideo = useCallback(() => { + dispatch(approveParticipantVideo(participantID)); }, [ dispatch, participantID ]); switch (buttonType) { @@ -75,7 +84,7 @@ const ParticipantQuickAction = ({