fix(av-moderation) Check for moderation support

Show av moderation toggles on mute all / stop everyone's video dialogs only if moderation is supported
Show Ask to Unmute only for moderators
This commit is contained in:
robertpin 2021-10-01 16:47:13 +03:00 committed by Дамян Минков
parent 33503122c4
commit 1beed8c490
6 changed files with 40 additions and 11 deletions

View File

@ -63,12 +63,15 @@ export default function ParticipantQuickAction({
</QuickActionButton> </QuickActionButton>
); );
} }
default: { case QUICK_ACTION_BUTTON.ASK_TO_UNMUTE: {
return ( return (
<AskToUnmuteButton <AskToUnmuteButton
askUnmuteText = { askUnmuteText } askUnmuteText = { askUnmuteText }
participantID = { participantID } /> participantID = { participantID } />
); );
} }
default: {
return null;
}
} }
} }

View File

@ -2,6 +2,7 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { isSupported } from '../../../av-moderation/functions';
import { translate } from '../../../base/i18n'; import { translate } from '../../../base/i18n';
import { JitsiTrackEvents } from '../../../base/lib-jitsi-meet'; import { JitsiTrackEvents } from '../../../base/lib-jitsi-meet';
import { MEDIA_TYPE } from '../../../base/media'; import { MEDIA_TYPE } from '../../../base/media';
@ -9,6 +10,7 @@ import {
getLocalParticipant, getLocalParticipant,
getParticipantByIdOrUndefined, getParticipantByIdOrUndefined,
getParticipantDisplayName, getParticipantDisplayName,
isLocalParticipantModerator,
isParticipantModerator isParticipantModerator
} from '../../../base/participants'; } from '../../../base/participants';
import { connect } from '../../../base/redux'; import { connect } from '../../../base/redux';
@ -18,7 +20,7 @@ import {
isParticipantAudioMuted, isParticipantAudioMuted,
isParticipantVideoMuted isParticipantVideoMuted
} from '../../../base/tracks'; } from '../../../base/tracks';
import { ACTION_TRIGGER, type MediaState, MEDIA_STATE } from '../../constants'; import { ACTION_TRIGGER, type MediaState, MEDIA_STATE, QUICK_ACTION_BUTTON } from '../../constants';
import { import {
getParticipantAudioMediaState, getParticipantAudioMediaState,
getParticipantVideoMediaState, getParticipantVideoMediaState,
@ -51,11 +53,21 @@ type Props = {
*/ */
_displayName: string, _displayName: string,
/**
* Whether or not moderation is supported.
*/
_isModerationSupported: boolean,
/** /**
* True if the participant is the local participant. * True if the participant is the local participant.
*/ */
_local: Boolean, _local: Boolean,
/**
* Whether or not the local participant is moderator.
*/
_localModerator: boolean,
/** /**
* Shared video local participant owner. * Shared video local participant owner.
*/ */
@ -162,7 +174,9 @@ function MeetingParticipantItem({
_audioTrack, _audioTrack,
_disableModeratorIndicator, _disableModeratorIndicator,
_displayName, _displayName,
_isModerationSupported,
_local, _local,
_localModerator,
_localVideoOwner, _localVideoOwner,
_participant, _participant,
_participantID, _participantID,
@ -220,6 +234,10 @@ function MeetingParticipantItem({
askToUnmuteText = t('participantsPane.actions.allowVideo'); askToUnmuteText = t('participantsPane.actions.allowVideo');
} }
const buttonType = _isModerationSupported
? _localModerator ? QUICK_ACTION_BUTTON.ASK_TO_UNMUTE : _quickActionButtonType
: '';
return ( return (
<ParticipantItem <ParticipantItem
actionsTrigger = { ACTION_TRIGGER.HOVER } actionsTrigger = { ACTION_TRIGGER.HOVER }
@ -241,7 +259,7 @@ function MeetingParticipantItem({
&& <> && <>
<ParticipantQuickAction <ParticipantQuickAction
askUnmuteText = { askToUnmuteText } askUnmuteText = { askToUnmuteText }
buttonType = { _quickActionButtonType } buttonType = { buttonType }
muteAudio = { muteAudio } muteAudio = { muteAudio }
muteParticipantButtonText = { muteParticipantButtonText } muteParticipantButtonText = { muteParticipantButtonText }
participantID = { _participantID } /> participantID = { _participantID } />
@ -287,12 +305,16 @@ function _mapStateToProps(state, ownProps): Object {
const { disableModeratorIndicator } = state['features/base/config']; const { disableModeratorIndicator } = state['features/base/config'];
const _localModerator = isLocalParticipantModerator(state);
return { return {
_audioMediaState, _audioMediaState,
_audioTrack, _audioTrack,
_disableModeratorIndicator: disableModeratorIndicator, _disableModeratorIndicator: disableModeratorIndicator,
_displayName: getParticipantDisplayName(state, participant?.id), _displayName: getParticipantDisplayName(state, participant?.id),
_isModerationSupported: isSupported()(state),
_local: Boolean(participant?.local), _local: Boolean(participant?.local),
_localModerator,
_localVideoOwner: Boolean(ownerId === localParticipantId), _localVideoOwner: Boolean(ownerId === localParticipantId),
_participant: participant, _participant: participant,
_participantID: participant?.id, _participantID: participant?.id,

View File

@ -3,7 +3,7 @@
import React from 'react'; import React from 'react';
import { requestDisableAudioModeration, requestEnableAudioModeration } from '../../av-moderation/actions'; import { requestDisableAudioModeration, requestEnableAudioModeration } from '../../av-moderation/actions';
import { isEnabledFromState } from '../../av-moderation/functions'; import { isEnabledFromState, isSupported } from '../../av-moderation/functions';
import { Dialog } from '../../base/dialog'; import { Dialog } from '../../base/dialog';
import { MEDIA_TYPE } from '../../base/media'; import { MEDIA_TYPE } from '../../base/media';
import { getLocalParticipant, getParticipantDisplayName } from '../../base/participants'; import { getLocalParticipant, getParticipantDisplayName } from '../../base/participants';
@ -23,7 +23,8 @@ export type Props = AbstractProps & {
exclude: Array<string>, exclude: Array<string>,
title: string, title: string,
showAdvancedModerationToggle: boolean, showAdvancedModerationToggle: boolean,
isAudioModerationEnabled: boolean isAudioModerationEnabled: boolean,
isModerationSupported: boolean
}; };
type State = { type State = {
@ -135,6 +136,7 @@ export function abstractMapStateToProps(state: Object, ownProps: Props) {
title: t('dialog.muteEveryoneElseTitle', { whom }) title: t('dialog.muteEveryoneElseTitle', { whom })
} : { } : {
title: t('dialog.muteEveryoneTitle'), title: t('dialog.muteEveryoneTitle'),
isAudioModerationEnabled: isEnabledFromState(MEDIA_TYPE.AUDIO, state) isAudioModerationEnabled: isEnabledFromState(MEDIA_TYPE.AUDIO, state),
isModerationSupported: isSupported()(state)
}; };
} }

View File

@ -3,7 +3,7 @@
import React from 'react'; import React from 'react';
import { requestDisableVideoModeration, requestEnableVideoModeration } from '../../av-moderation/actions'; import { requestDisableVideoModeration, requestEnableVideoModeration } from '../../av-moderation/actions';
import { isEnabledFromState } from '../../av-moderation/functions'; import { isEnabledFromState, isSupported } from '../../av-moderation/functions';
import { Dialog } from '../../base/dialog'; import { Dialog } from '../../base/dialog';
import { MEDIA_TYPE } from '../../base/media'; import { MEDIA_TYPE } from '../../base/media';
import { getLocalParticipant, getParticipantDisplayName } from '../../base/participants'; import { getLocalParticipant, getParticipantDisplayName } from '../../base/participants';
@ -23,7 +23,8 @@ export type Props = AbstractProps & {
exclude: Array<string>, exclude: Array<string>,
title: string, title: string,
showAdvancedModerationToggle: boolean, showAdvancedModerationToggle: boolean,
isVideoModerationEnabled: boolean isVideoModerationEnabled: boolean,
isModerationSupported: boolean
}; };
type State = { type State = {
@ -137,6 +138,7 @@ export function abstractMapStateToProps(state: Object, ownProps: Props) {
title: t('dialog.muteEveryoneElsesVideoTitle', { whom }) title: t('dialog.muteEveryoneElsesVideoTitle', { whom })
} : { } : {
title: t('dialog.muteEveryonesVideoTitle'), title: t('dialog.muteEveryonesVideoTitle'),
isVideoModerationEnabled isVideoModerationEnabled,
isModerationSupported: isSupported()(state)
}; };
} }

View File

@ -48,7 +48,7 @@ class MuteEveryoneDialog extends AbstractMuteEveryoneDialog<Props> {
width = 'small'> width = 'small'>
<div className = 'mute-dialog'> <div className = 'mute-dialog'>
{ this.state.content } { this.state.content }
{this.props.exclude.length === 0 && ( { this.props.isModerationSupported && this.props.exclude.length === 0 && (
<> <>
<div className = 'separator-line' /> <div className = 'separator-line' />
<div className = 'control-row'> <div className = 'control-row'>

View File

@ -48,7 +48,7 @@ class MuteEveryonesVideoDialog extends AbstractMuteEveryonesVideoDialog<Props> {
width = 'small'> width = 'small'>
<div className = 'mute-dialog'> <div className = 'mute-dialog'>
{this.state.content} {this.state.content}
{this.props.exclude.length === 0 && ( { this.props.isModerationSupported && this.props.exclude.length === 0 && (
<> <>
<div className = 'separator-line' /> <div className = 'separator-line' />
<div className = 'control-row'> <div className = 'control-row'>