From ab366b9d9404c2ca2e2d484acbcf98007d044869 Mon Sep 17 00:00:00 2001 From: robertpin Date: Wed, 15 Sep 2021 11:28:44 +0300 Subject: [PATCH] fix(av-moderation) Advanced moderation improvements (#9935) * Update moderation in effect notifications Only display one notification for each media type. Display notification for keyboard shortcuts as well * Update muted remotely notification Display name of moderator in the notification * Fix indentation on moderation menu * Update text for video moderation * Added moderator label in participant pane * Update microphone icon in participant list For participants that speak, or are noisy, but aren't dominant speaker, the icon in the participant list will look the same as the dominant speaker icon but will not change their position in the list * Added sound for asked to unmute notification * Code review changes * Code review changes Use simple var instead of function for audio media state * Move constants to constants file * Moved constants from notifications to av-moderation --- conference.js | 17 ++++- config.js | 1 + lang/main.json | 6 +- react/features/av-moderation/constants.js | 12 ++++ react/features/av-moderation/middleware.js | 21 ++++-- react/features/av-moderation/sounds.js | 6 ++ react/features/base/media/actions.js | 5 +- react/features/base/participants/actions.js | 7 +- react/features/base/tracks/middleware.js | 6 +- react/features/notifications/functions.js | 17 +++++ .../components/FooterContextMenu.js | 4 +- .../components/web/MeetingParticipantItem.js | 65 ++++++++++++++++-- .../components/web/ParticipantItem.js | 36 ++++++++-- .../components/web/styled.js | 15 ++++ react/features/video-menu/actions.any.js | 5 +- sounds/asked-unmute.mp3 | Bin 0 -> 46512 bytes 16 files changed, 193 insertions(+), 30 deletions(-) create mode 100644 react/features/av-moderation/sounds.js create mode 100644 sounds/asked-unmute.mp3 diff --git a/conference.js b/conference.js index a1aa93680d..68737e6c08 100644 --- a/conference.js +++ b/conference.js @@ -24,6 +24,8 @@ import { redirectToStaticPage, reloadWithStoredParams } from './react/features/app/actions'; +import { showModeratedNotification } from './react/features/av-moderation/actions'; +import { shouldShowModeratedNotification } from './react/features/av-moderation/functions'; import { AVATAR_URL_COMMAND, EMAIL_COMMAND, @@ -120,7 +122,7 @@ import { maybeOpenFeedbackDialog, submitFeedback } from './react/features/feedback'; -import { showNotification } from './react/features/notifications'; +import { isModerationNotificationDisplayed, showNotification } from './react/features/notifications'; import { mediaPermissionPromptVisibilityChanged, toggleSlowGUMOverlay } from './react/features/overlay'; import { suspendDetected } from './react/features/power-monitor'; import { @@ -871,13 +873,24 @@ export default { * dialogs in case of media permissions error. */ muteAudio(mute, showUI = true) { + const state = APP.store.getState(); + if (!mute - && isUserInteractionRequiredForUnmute(APP.store.getState())) { + && isUserInteractionRequiredForUnmute(state)) { logger.error('Unmuting audio requires user interaction'); return; } + // check for A/V Moderation when trying to unmute + if (!mute && shouldShowModeratedNotification(MEDIA_TYPE.AUDIO, state)) { + if (!isModerationNotificationDisplayed(MEDIA_TYPE.AUDIO, state)) { + APP.store.dispatch(showModeratedNotification(MEDIA_TYPE.AUDIO)); + } + + return; + } + // Not ready to modify track's state yet if (!this._localTracksInitialized) { // This will only modify base/media.audio.muted which is then synced diff --git a/config.js b/config.js index 47cd0edb0b..626fef7440 100644 --- a/config.js +++ b/config.js @@ -737,6 +737,7 @@ var config = { // Array of disabled sounds. // Possible values: + // - 'ASKED_TO_UNMUTE_SOUND' // - 'E2EE_OFF_SOUND' // - 'E2EE_ON_SOUND' // - 'INCOMING_MSG_SOUND' diff --git a/lang/main.json b/lang/main.json index b51fb032b3..354e1cb06e 100644 --- a/lang/main.json +++ b/lang/main.json @@ -566,9 +566,9 @@ "moderator": "You're now a moderator", "muted": "You have started the conversation muted.", "mutedTitle": "You're muted!", - "mutedRemotelyTitle": "You've been muted by the moderator", + "mutedRemotelyTitle": "You've been muted by {{moderator}}", "mutedRemotelyDescription": "You can always unmute when you're ready to speak. Mute back when you're done to keep noise away from the meeting.", - "videoMutedRemotelyTitle": "Your camera has been turned off by the moderator", + "videoMutedRemotelyTitle": "Your camera has been turned off by {{moderator}}", "videoMutedRemotelyDescription": "You can always turn it on again.", "passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) removed by another participant", "passwordSetRemotely": "$t(lockRoomPasswordUppercase) set by another participant", @@ -623,7 +623,7 @@ "stopEveryonesVideo": "Stop everyone's video", "stopVideo": "Stop video", "unblockEveryoneMicCamera": "Unblock everyone's mic and camera", - "videoModeration": "Start video" + "videoModeration": "Start their video" } }, "passwordSetRemotely": "Set by another participant", diff --git a/react/features/av-moderation/constants.js b/react/features/av-moderation/constants.js index 8c6443500d..daa086cb04 100644 --- a/react/features/av-moderation/constants.js +++ b/react/features/av-moderation/constants.js @@ -17,3 +17,15 @@ export const MEDIA_TYPE_TO_PENDING_STORE_KEY: {[key: MediaType]: string} = { [MEDIA_TYPE.AUDIO]: 'pendingAudio', [MEDIA_TYPE.VIDEO]: 'pendingVideo' }; + +export const ASKED_TO_UNMUTE_SOUND_ID = 'ASKED_TO_UNMUTE_SOUND'; + +export const AUDIO_MODERATION_NOTIFICATION_ID = 'audio-moderation'; +export const VIDEO_MODERATION_NOTIFICATION_ID = 'video-moderation'; +export const CS_MODERATION_NOTIFICATION_ID = 'screensharing-moderation'; + +export const MODERATION_NOTIFICATIONS = { + [MEDIA_TYPE.AUDIO]: AUDIO_MODERATION_NOTIFICATION_ID, + [MEDIA_TYPE.VIDEO]: VIDEO_MODERATION_NOTIFICATION_ID, + [MEDIA_TYPE.PRESENTER]: CS_MODERATION_NOTIFICATION_ID +}; diff --git a/react/features/av-moderation/middleware.js b/react/features/av-moderation/middleware.js index dd90d606d1..e1721e1859 100644 --- a/react/features/av-moderation/middleware.js +++ b/react/features/av-moderation/middleware.js @@ -1,6 +1,7 @@ // @flow import { batch } from 'react-redux'; +import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app'; import { getConferenceState } from '../base/conference'; import { JitsiConferenceEvents } from '../base/lib-jitsi-meet'; import { MEDIA_TYPE } from '../base/media'; @@ -13,6 +14,7 @@ import { raiseHand } from '../base/participants'; import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux'; +import { playSound, registerSound, unregisterSound } from '../base/sounds'; import { hideNotification, showNotification @@ -35,21 +37,31 @@ import { participantApproved, participantPendingAudio } from './actions'; +import { + ASKED_TO_UNMUTE_SOUND_ID, AUDIO_MODERATION_NOTIFICATION_ID, + CS_MODERATION_NOTIFICATION_ID, + VIDEO_MODERATION_NOTIFICATION_ID +} from './constants'; import { isEnabledFromState, isParticipantApproved, isParticipantPending } from './functions'; - -const VIDEO_MODERATION_NOTIFICATION_ID = 'video-moderation'; -const AUDIO_MODERATION_NOTIFICATION_ID = 'audio-moderation'; -const CS_MODERATION_NOTIFICATION_ID = 'video-moderation'; +import { ASKED_TO_UNMUTE_FILE } from './sounds'; MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { const { type } = action; const { conference } = getConferenceState(getState()); switch (type) { + case APP_WILL_MOUNT: { + dispatch(registerSound(ASKED_TO_UNMUTE_SOUND_ID, ASKED_TO_UNMUTE_FILE)); + break; + } + case APP_WILL_UNMOUNT: { + dispatch(unregisterSound(ASKED_TO_UNMUTE_SOUND_ID)); + break; + } case LOCAL_PARTICIPANT_MODERATION_NOTIFICATION: { let descriptionKey; let titleKey; @@ -160,6 +172,7 @@ StateListenerRegistry.register( customActionNameKey: 'notify.unmute', customActionHandler: () => dispatch(muteLocal(false, MEDIA_TYPE.AUDIO)) })); + dispatch(playSound(ASKED_TO_UNMUTE_SOUND_ID)); } }); diff --git a/react/features/av-moderation/sounds.js b/react/features/av-moderation/sounds.js new file mode 100644 index 0000000000..d15cf92138 --- /dev/null +++ b/react/features/av-moderation/sounds.js @@ -0,0 +1,6 @@ +/** + * The name of the bundled audio file which will be played for the raise hand sound. + * + * @type {string} + */ +export const ASKED_TO_UNMUTE_FILE = 'asked-unmute.mp3'; diff --git a/react/features/base/media/actions.js b/react/features/base/media/actions.js index a9b1bc7bc8..4195c361ee 100644 --- a/react/features/base/media/actions.js +++ b/react/features/base/media/actions.js @@ -4,6 +4,7 @@ import type { Dispatch } from 'redux'; import { showModeratedNotification } from '../../av-moderation/actions'; import { shouldShowModeratedNotification } from '../../av-moderation/functions'; +import { isModerationNotificationDisplayed } from '../../notifications'; import { SET_AUDIO_MUTED, @@ -113,7 +114,9 @@ export function setVideoMuted( // check for A/V Moderation when trying to unmute if (!muted && shouldShowModeratedNotification(MEDIA_TYPE.VIDEO, state)) { - ensureTrack && dispatch(showModeratedNotification(MEDIA_TYPE.VIDEO)); + if (!isModerationNotificationDisplayed(MEDIA_TYPE.VIDEO, state)) { + ensureTrack && dispatch(showModeratedNotification(MEDIA_TYPE.VIDEO)); + } return; } diff --git a/react/features/base/participants/actions.js b/react/features/base/participants/actions.js index b2822cdb52..bbd0c0227e 100644 --- a/react/features/base/participants/actions.js +++ b/react/features/base/participants/actions.js @@ -466,7 +466,7 @@ export function participantUpdated(participant = {}) { * @returns {Promise} */ export function participantMutedUs(participant, track) { - return dispatch => { + return (dispatch, getState) => { if (!participant) { return; } @@ -474,7 +474,10 @@ export function participantMutedUs(participant, track) { const isAudio = track.isAudioTrack(); dispatch(showNotification({ - titleKey: isAudio ? 'notify.mutedRemotelyTitle' : 'notify.videoMutedRemotelyTitle' + titleKey: isAudio ? 'notify.mutedRemotelyTitle' : 'notify.videoMutedRemotelyTitle', + titleArguments: { + moderator: getParticipantDisplayName(getState, participant.getId()) + } })); }; } diff --git a/react/features/base/tracks/middleware.js b/react/features/base/tracks/middleware.js index 91e6caed53..7f6bf3f7a3 100644 --- a/react/features/base/tracks/middleware.js +++ b/react/features/base/tracks/middleware.js @@ -3,7 +3,7 @@ import UIEvents from '../../../../service/UI/UIEvents'; import { showModeratedNotification } from '../../av-moderation/actions'; import { shouldShowModeratedNotification } from '../../av-moderation/functions'; -import { hideNotification } from '../../notifications'; +import { hideNotification, isModerationNotificationDisplayed } from '../../notifications'; import { isPrejoinPageVisible } from '../../prejoin/functions'; import { getAvailableDevices } from '../devices/actions'; import { @@ -142,7 +142,9 @@ MiddlewareRegistry.register(store => next => action => { // check for A/V Moderation when trying to start screen sharing if ((action.enabled || action.enabled === undefined) && shouldShowModeratedNotification(MEDIA_TYPE.VIDEO, store.getState())) { - store.dispatch(showModeratedNotification(MEDIA_TYPE.PRESENTER)); + if (!isModerationNotificationDisplayed(MEDIA_TYPE.PRESENTER, store.getState())) { + store.dispatch(showModeratedNotification(MEDIA_TYPE.PRESENTER)); + } return; } diff --git a/react/features/notifications/functions.js b/react/features/notifications/functions.js index d3ba2aae54..11cf3ed7c8 100644 --- a/react/features/notifications/functions.js +++ b/react/features/notifications/functions.js @@ -1,5 +1,7 @@ // @flow +import { MODERATION_NOTIFICATIONS } from '../av-moderation/constants'; +import { MEDIA_TYPE } from '../base/media'; import { toState } from '../base/redux'; declare var interfaceConfig: Object; @@ -26,3 +28,18 @@ export function areThereNotifications(stateful: Object | Function) { export function joinLeaveNotificationsDisabled() { return Boolean(typeof interfaceConfig !== 'undefined' && interfaceConfig?.DISABLE_JOIN_LEAVE_NOTIFICATIONS); } + +/** + * Returns whether or not the moderation notification for the given type is displayed. + * + * @param {MEDIA_TYPE} mediaType - The media type to check. + * @param {Object | Function} stateful - The redux store state. + * @returns {boolean} + */ +export function isModerationNotificationDisplayed(mediaType: MEDIA_TYPE, stateful: Object | Function) { + const state = toState(stateful); + + const { notifications } = state['features/notifications']; + + return Boolean(notifications.find(n => n.uid === MODERATION_NOTIFICATIONS[mediaType])); +} diff --git a/react/features/participants-pane/components/FooterContextMenu.js b/react/features/participants-pane/components/FooterContextMenu.js index 47512fc602..55b559e98a 100644 --- a/react/features/participants-pane/components/FooterContextMenu.js +++ b/react/features/participants-pane/components/FooterContextMenu.js @@ -55,10 +55,10 @@ const useStyles = makeStyles(() => { }, text: { color: '#C2C2C2', - padding: '10px 16px 10px 52px' + padding: '10px 16px' }, paddedAction: { - marginLeft: '36px;' + marginLeft: '36px' } }; }); diff --git a/react/features/participants-pane/components/web/MeetingParticipantItem.js b/react/features/participants-pane/components/web/MeetingParticipantItem.js index 72a9d0b4a9..578fff7a1c 100644 --- a/react/features/participants-pane/components/web/MeetingParticipantItem.js +++ b/react/features/participants-pane/components/web/MeetingParticipantItem.js @@ -1,15 +1,23 @@ // @flow -import React from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; +import { JitsiTrackEvents } from '../../../base/lib-jitsi-meet'; +import { MEDIA_TYPE } from '../../../base/media'; import { getLocalParticipant, getParticipantByIdOrUndefined, - getParticipantDisplayName + getParticipantDisplayName, + isParticipantModerator } from '../../../base/participants'; import { connect } from '../../../base/redux'; -import { isParticipantAudioMuted, isParticipantVideoMuted } from '../../../base/tracks'; -import { ACTION_TRIGGER, type MediaState } from '../../constants'; +import { + getLocalAudioTrack, + getTrackByMediaTypeAndParticipant, + isParticipantAudioMuted, + isParticipantVideoMuted +} from '../../../base/tracks'; +import { ACTION_TRIGGER, type MediaState, MEDIA_STATE } from '../../constants'; import { getParticipantAudioMediaState, getParticipantVideoMediaState, @@ -27,6 +35,11 @@ type Props = { */ _audioMediaState: MediaState, + /** + * The audio track related to the participant. + */ + _audioTrack: ?Object, + /** * Media state for video. */ @@ -136,6 +149,7 @@ type Props = { */ function MeetingParticipantItem({ _audioMediaState, + _audioTrack, _videoMediaState, _displayName, _local, @@ -155,12 +169,46 @@ function MeetingParticipantItem({ participantActionEllipsisLabel, youText }: Props) { + + const [ hasAudioLevels, setHasAudioLevel ] = useState(false); + const [ registeredEvent, setRegisteredEvent ] = useState(false); + + const _updateAudioLevel = useCallback(level => { + const audioLevel = typeof level === 'number' && !isNaN(level) + ? level : 0; + + setHasAudioLevel(audioLevel > 0.009); + }, []); + + useEffect(() => { + if (_audioTrack && !registeredEvent) { + const { jitsiTrack } = _audioTrack; + + if (jitsiTrack) { + jitsiTrack.on(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED, _updateAudioLevel); + setRegisteredEvent(true); + } + } + + return () => { + if (_audioTrack && registeredEvent) { + const { jitsiTrack } = _audioTrack; + + jitsiTrack && jitsiTrack.off(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED, _updateAudioLevel); + } + }; + }, [ _audioTrack ]); + + const audioMediaState = _audioMediaState === MEDIA_STATE.UNMUTED && hasAudioLevels + ? MEDIA_STATE.DOMINANT_SPEAKER : _audioMediaState; + return ( - + } {!overflowDrawer && _localVideoOwner && _participant?.isFakeParticipant && ( @@ -214,8 +262,13 @@ function _mapStateToProps(state, ownProps): Object { const _videoMediaState = getParticipantVideoMediaState(participant, _isVideoMuted, state); const _quickActionButtonType = getQuickActionButtonType(participant, _isAudioMuted, state); + const tracks = state['features/base/tracks']; + const _audioTrack = participantID === localParticipantId + ? getLocalAudioTrack(tracks) : getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.AUDIO, participantID); + return { _audioMediaState, + _audioTrack, _videoMediaState, _displayName: getParticipantDisplayName(state, participant?.id), _local: Boolean(participant?.local), diff --git a/react/features/participants-pane/components/web/ParticipantItem.js b/react/features/participants-pane/components/web/ParticipantItem.js index 3c3052f66a..0b4cac9edb 100644 --- a/react/features/participants-pane/components/web/ParticipantItem.js +++ b/react/features/participants-pane/components/web/ParticipantItem.js @@ -3,6 +3,7 @@ import React, { type Node, useCallback } from 'react'; import { Avatar } from '../../../base/avatar'; +import { translate } from '../../../base/i18n'; import { ACTION_TRIGGER, AudioStateIcons, @@ -14,10 +15,12 @@ import { import { RaisedHandIndicator } from './RaisedHandIndicator'; import { + ModeratorLabel, ParticipantActionsHover, ParticipantActionsPermanent, ParticipantContainer, ParticipantContent, + ParticipantDetailsContainer, ParticipantName, ParticipantNameContainer, ParticipantStates @@ -58,6 +61,11 @@ type Props = { */ isHighlighted?: boolean, + /** + * Whether or not the participant is a moderator. + */ + isModerator: boolean, + /** * True if the participant is local. */ @@ -93,6 +101,11 @@ type Props = { */ videoMediaState: MediaState, + /** + * Invoked to obtain translated strings. + */ + t: Function, + /** * The translated "you" text. */ @@ -105,9 +118,10 @@ type Props = { * @param {Props} props - The props of the component. * @returns {ReactNode} */ -export default function ParticipantItem({ +function ParticipantItem({ children, isHighlighted, + isModerator, onLeave, actionsTrigger = ACTION_TRIGGER.HOVER, audioMediaState = MEDIA_STATE.NONE, @@ -118,6 +132,7 @@ export default function ParticipantItem({ openDrawerForParticipant, overflowDrawer, raisedHand, + t, youText }: Props) { const ParticipantActions = Actions[actionsTrigger]; @@ -140,12 +155,17 @@ export default function ParticipantItem({ participantId = { participantID } size = { 32 } /> - - - { displayName } - - { local ?  ({ youText }) : null } - + + + + { displayName } + + { local ?  ({ youText }) : null } + + {isModerator && + {t('videothumbnail.moderator')} + } + { !local && } { raisedHand && } @@ -156,3 +176,5 @@ export default function ParticipantItem({ ); } + +export default translate(ParticipantItem); diff --git a/react/features/participants-pane/components/web/styled.js b/react/features/participants-pane/components/web/styled.js index 74a34c773b..4f9faf29e4 100644 --- a/react/features/participants-pane/components/web/styled.js +++ b/react/features/participants-pane/components/web/styled.js @@ -282,6 +282,7 @@ export const ParticipantContainer = styled.div` color: white; display: flex; font-size: 13px; + font-weight: normal; height: ${props => props.theme.participantItemHeight}px; margin: 0 -${props => props.theme.panePadding}px; padding-left: ${props => props.theme.panePadding}px; @@ -341,10 +342,24 @@ export const ParticipantName = styled.div` `; export const ParticipantNameContainer = styled.div` + display: flex; + flex: 1; + overflow: hidden; +`; + +export const ModeratorLabel = styled.div` + font-size: 12px; + line-height: 16px; + color: #858585; +`; + +export const ParticipantDetailsContainer = styled.div` display: flex; flex: 1; margin-right: 8px; overflow: hidden; + flex-direction: column; + justify-content: flex-start; `; export const RaisedHandIndicatorBackground = styled.div` diff --git a/react/features/video-menu/actions.any.js b/react/features/video-menu/actions.any.js index e49965b209..f272c95111 100644 --- a/react/features/video-menu/actions.any.js +++ b/react/features/video-menu/actions.any.js @@ -23,6 +23,7 @@ import { getRemoteParticipants, muteRemoteParticipant } from '../base/participants'; +import { isModerationNotificationDisplayed } from '../notifications'; declare var APP: Object; @@ -47,7 +48,9 @@ export function muteLocal(enable: boolean, mediaType: MEDIA_TYPE) { // check for A/V Moderation when trying to unmute if (!enable && shouldShowModeratedNotification(MEDIA_TYPE.AUDIO, getState())) { - dispatch(showModeratedNotification(MEDIA_TYPE.AUDIO)); + if (!isModerationNotificationDisplayed(MEDIA_TYPE.AUDIO, getState())) { + dispatch(showModeratedNotification(MEDIA_TYPE.AUDIO)); + } return; } diff --git a/sounds/asked-unmute.mp3 b/sounds/asked-unmute.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..af79c9035ed43d86abc6940289fb09c02f293cb8 GIT binary patch literal 46512 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 z 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 literal 0 HcmV?d00001