diff --git a/lang/main.json b/lang/main.json index 5ebf9f873..638911ac7 100644 --- a/lang/main.json +++ b/lang/main.json @@ -615,6 +615,7 @@ }, "actions": { "allow": "Allow attendees to:", + "allowVideo": "Allow video", "audioModeration": "Unmute themselves", "blockEveryoneMicCamera": "Block everyone's mic and camera", "invite": "Invite Someone", diff --git a/react/features/av-moderation/actions.js b/react/features/av-moderation/actions.js index 46482e1c7..3455c6a59 100644 --- a/react/features/av-moderation/actions.js +++ b/react/features/av-moderation/actions.js @@ -2,6 +2,8 @@ import { getConferenceState } from '../base/conference'; import { MEDIA_TYPE, type MediaType } from '../base/media/constants'; +import { getParticipantById } from '../base/participants'; +import { isForceMuted } from '../participants-pane/functions'; import { DISMISS_PENDING_PARTICIPANT, @@ -27,11 +29,15 @@ import { isEnabledFromState } from './functions'; export const approveParticipant = (id: string) => (dispatch: Function, getState: Function) => { const state = getState(); const { conference } = getConferenceState(state); + const participant = getParticipantById(state, id); - if (isEnabledFromState(MEDIA_TYPE.AUDIO, state)) { + const isAudioForceMuted = isForceMuted(participant, MEDIA_TYPE.AUDIO, state); + const isVideoForceMuted = isForceMuted(participant, MEDIA_TYPE.VIDEO, state); + + if (isEnabledFromState(MEDIA_TYPE.AUDIO, state) && isAudioForceMuted) { conference.avModerationApprove(MEDIA_TYPE.AUDIO, id); } - if (isEnabledFromState(MEDIA_TYPE.VIDEO, state)) { + if (isEnabledFromState(MEDIA_TYPE.VIDEO, state) && isVideoForceMuted) { conference.avModerationApprove(MEDIA_TYPE.VIDEO, id); } }; diff --git a/react/features/participants-pane/components/web/MeetingParticipantItem.js b/react/features/participants-pane/components/web/MeetingParticipantItem.js index 578fff7a1..001a2d554 100644 --- a/react/features/participants-pane/components/web/MeetingParticipantItem.js +++ b/react/features/participants-pane/components/web/MeetingParticipantItem.js @@ -2,6 +2,7 @@ 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 { @@ -135,6 +136,11 @@ type Props = { */ participantID: ?string, + /** + * The translate function. + */ + t: Function, + /** * The translated "you" text. */ @@ -167,6 +173,7 @@ function MeetingParticipantItem({ openDrawerForParticipant, overflowDrawer, participantActionEllipsisLabel, + t, youText }: Props) { @@ -202,6 +209,12 @@ 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 (