Skip to content

Commit

Permalink
fix(av-moderation): When we are allowed to unmute make the notificati…
Browse files Browse the repository at this point in the history
…on sticky.

If the notification disappears, we don't have any other indication about this.
We were not showing any notification if only video is allowed.
Adds option to unmute audio or video, depend on what was allowed.
  • Loading branch information
damencho committed Feb 19, 2025
1 parent ebb3261 commit 5ad4cf4
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 16 deletions.
5 changes: 3 additions & 2 deletions lang/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@
"focusFail": "{{component}} not available - retry in {{ms}} sec",
"gifsMenu": "GIPHY",
"groupTitle": "Notifications",
"hostAskedUnmute": "The moderator would like you to speak",
"hostAskedUnmute": "The moderator would like you to unmute.",
"invalidTenant": "Invalid tenant",
"invalidTenantHyphenDescription": "The tenant you are using is invalid (starts or ends with '-').",
"invalidTenantLengthDescription": "The tenant you are using is too long.",
Expand Down Expand Up @@ -826,7 +826,8 @@
"suggestRecordingAction": "Start",
"suggestRecordingDescription": "Would you like to start a recording?",
"suggestRecordingTitle": "Record this meeting",
"unmute": "Unmute",
"unmute": "Unmute Audio",
"unmuteVideo": "Unmute Video",
"videoMutedRemotelyDescription": "You can always turn it on again.",
"videoMutedRemotelyTitle": "Your video has been turned off by {{participantDisplayName}}",
"videoUnmuteBlockedDescription": "Camera unmute and desktop sharing operation have been temporarily blocked because of system limits.",
Expand Down
51 changes: 39 additions & 12 deletions react/features/av-moderation/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app/actionTypes';
import { getConferenceState } from '../base/conference/functions';
import { JitsiConferenceEvents } from '../base/lib-jitsi-meet';
import { MEDIA_TYPE, MediaType } from '../base/media/constants';
import { isAudioMuted, isVideoMuted } from '../base/media/functions';
import { PARTICIPANT_UPDATED } from '../base/participants/actionTypes';
import { raiseHand } from '../base/participants/actions';
import {
Expand Down Expand Up @@ -208,24 +209,50 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
*/
StateListenerRegistry.register(
state => state['features/base/conference'].conference,
(conference, { dispatch }, previousConference) => {
(conference, { dispatch, getState }, previousConference) => {
if (conference && !previousConference) {
// local participant is allowed to unmute
conference.on(JitsiConferenceEvents.AV_MODERATION_APPROVED, ({ mediaType }: { mediaType: MediaType; }) => {
dispatch(localParticipantApproved(mediaType));

// Audio & video moderation are both enabled at the same time.
// Avoid displaying 2 different notifications.
if (mediaType === MEDIA_TYPE.AUDIO) {
dispatch(showNotification({
titleKey: 'notify.hostAskedUnmute',
sticky: true,
customActionNameKey: [ 'notify.unmute' ],
customActionHandler: [ () => dispatch(muteLocal(false, MEDIA_TYPE.AUDIO)) ],
uid: ASKED_TO_UNMUTE_NOTIFICATION_ID
}, NOTIFICATION_TIMEOUT_TYPE.MEDIUM));
dispatch(playSound(ASKED_TO_UNMUTE_SOUND_ID));
// hide any existing notification as we will show a new one
// the case where first audio is approved and then video is approved, we avoid double notification
dispatch(hideNotification(ASKED_TO_UNMUTE_NOTIFICATION_ID));

const customActionNameKey = [];
const customActionHandler = [];

if ((mediaType === MEDIA_TYPE.AUDIO || getState()['features/av-moderation'].audioUnmuteApproved)
&& isAudioMuted(getState())) {
customActionNameKey.push('notify.unmute');
customActionHandler.push(() => {
dispatch(muteLocal(false, MEDIA_TYPE.AUDIO));
dispatch(hideNotification(ASKED_TO_UNMUTE_NOTIFICATION_ID));
});
}

if ((mediaType === MEDIA_TYPE.VIDEO || getState()['features/av-moderation'].videoUnmuteApproved)
&& isVideoMuted(getState())) {
customActionNameKey.push('notify.unmuteVideo');
customActionHandler.push(() => {
dispatch(muteLocal(false, MEDIA_TYPE.VIDEO));
dispatch(hideNotification(ASKED_TO_UNMUTE_NOTIFICATION_ID));

// lower hand as there will be no audio and change in dominant speaker to clear it
dispatch(raiseHand(false));

});
}

dispatch(showNotification({
titleKey: 'notify.hostAskedUnmute',
sticky: true,
customActionNameKey,
customActionHandler,
uid: ASKED_TO_UNMUTE_NOTIFICATION_ID
}, NOTIFICATION_TIMEOUT_TYPE.STICKY));

dispatch(playSound(ASKED_TO_UNMUTE_SOUND_ID));
});

conference.on(JitsiConferenceEvents.AV_MODERATION_REJECTED, ({ mediaType }: { mediaType: MediaType; }) => {
Expand Down
4 changes: 2 additions & 2 deletions react/features/video-menu/actions.any.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { shouldShowModeratedNotification } from '../av-moderation/functions';
import { setAudioMuted, setVideoMuted } from '../base/media/actions';
import { MEDIA_TYPE, MediaType, VIDEO_MUTISM_AUTHORITY } from '../base/media/constants';
import { muteRemoteParticipant } from '../base/participants/actions';
import { getLocalParticipant, getRemoteParticipants } from '../base/participants/functions';
import { getRemoteParticipants } from '../base/participants/functions';
import { toggleScreensharing } from '../base/tracks/actions';
import { isModerationNotificationDisplayed } from '../notifications/functions';

Expand All @@ -36,7 +36,7 @@ export function muteLocal(enable: boolean, mediaType: MediaType, stopScreenShari
}

// check for A/V Moderation when trying to unmute
if (!enable && shouldShowModeratedNotification(MEDIA_TYPE.AUDIO, getState())) {
if (isAudio && !enable && shouldShowModeratedNotification(MEDIA_TYPE.AUDIO, getState())) {
if (!isModerationNotificationDisplayed(MEDIA_TYPE.AUDIO, getState())) {
dispatch(showModeratedNotification(MEDIA_TYPE.AUDIO));
}
Expand Down

0 comments on commit 5ad4cf4

Please sign in to comment.