Merge pull request #8377 from jitsi/tavram/notifications

feat(external_api) allow notifications to be configured
This commit is contained in:
Avram Tudor 2021-01-12 14:52:31 +02:00 committed by GitHub
commit 1ab0f1993a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 111 additions and 48 deletions

View File

@ -695,6 +695,65 @@ var config = {
ignoreStartMuted
*/
/**
Use this array to configure which notifications will be shown to the user
The items correspond to the title or description key of that notification
Some of these notifications also depend on some other internal logic to be displayed or not,
so adding them here will not ensure they will always be displayed
A falsy value for this prop will result in having all notifications enabled (e.g null, undefined, false)
*/
// notifications: [
// 'connection.CONNFAIL', // shown when the connection fails,
// 'dialog.cameraNotSendingData', // shown when there's no feed from user's camera
// 'dialog.kickTitle', // shown when user has been kicked
// 'dialog.liveStreaming', // livestreaming notifications (pending, on, off, limits)
// 'dialog.lockTitle', // shown when setting conference password fails
// 'dialog.maxUsersLimitReached', // shown when maximmum users limit has been reached
// 'dialog.micNotSendingData', // shown when user's mic is not sending any audio
// 'dialog.passwordNotSupportedTitle', // shown when setting conference password fails due to password format
// 'dialog.recording', // recording notifications (pending, on, off, limits)
// 'dialog.remoteControlTitle', // remote control notifications (allowed, denied, start, stop, error)
// 'dialog.reservationError',
// 'dialog.serviceUnavailable', // shown when server is not reachable
// 'dialog.sessTerminated', // shown when there is a failed conference session
// 'dialog.tokenAuthFailed', // show when an invalid jwt is used
// 'dialog.transcribing', // transcribing notifications (pending, off)
// 'dialOut.statusMessage', // shown when dial out status is updated.
// 'liveStreaming.busy', // shown when livestreaming service is busy
// 'liveStreaming.failedToStart', // shown when livestreaming fails to start
// 'liveStreaming.unavailableTitle', // shown when livestreaming service is not reachable
// 'lobby.joinRejectedMessage', // shown when while in a lobby, user's request to join is rejected
// 'lobby.notificationTitle', // shown when lobby is toggled and when join requests are allowed / denied
// 'localRecording.localRecording', // shown when a local recording is started
// 'notify.disconnected', // shown when a participant has left
// 'notify.grantedTo', // shown when moderator rights were granted to a participant
// 'notify.invitedOneMember', // shown when 1 participant has been invited
// 'notify.invitedThreePlusMembers', // shown when 3+ participants have been invited
// 'notify.invitedTwoMembers', // shown when 2 participants have been invited
// 'notify.kickParticipant', // shown when a participant is kicked
// 'notify.mutedRemotelyTitle', // shown when user is muted by a remote party
// 'notify.mutedTitle', // shown when user has been muted upon joining,
// 'notify.newDeviceAudioTitle', // prompts the user to use a newly detected audio device
// 'notify.newDeviceCameraTitle', // prompts the user to use a newly detected camera
// 'notify.passwordRemovedRemotely', // shown when a password has been removed remotely
// 'notify.passwordSetRemotely', // shown when a password has been set remotely
// 'notify.raisedHand', // shown when a partcipant used raise hand,
// 'notify.startSilentTitle', // shown when user joined with no audio
// 'prejoin.errorDialOut',
// 'prejoin.errorDialOutDisconnected',
// 'prejoin.errorDialOutFailed',
// 'prejoin.errorDialOutStatus',
// 'prejoin.errorStatusCode',
// 'prejoin.errorValidation',
// 'recording.busy', // shown when recording service is busy
// 'recording.failedToStart', // shown when recording fails to start
// 'recording.unavailableTitle', // shown when recording service is not reachable
// 'toolbar.noAudioSignalTitle', // shown when a broken mic is detected
// 'toolbar.noisyAudioInputTitle', // shown when noise is detected for the current microphone
// 'toolbar.talkWhileMutedPopup', // shown when user tries to speak while muted
// 'transcribing.failedToStart' // shown when transcribing fails to start
// ]
// Allow all above example options to include a trailing comma and
// prevent fear when commenting out the last value.

View File

@ -132,6 +132,7 @@ export default [
'liveStreamingEnabled',
'localRecording',
'maxFullResolutionParticipants',
'notifications',
'openBridgeChannel',
'openSharedDocumentOnJoin',
'opusMaxAverageBitrate',

View File

@ -46,14 +46,14 @@ MiddlewareRegistry.register(({ getState, dispatch }) => next => action => {
recordingController.onWarning = (messageKey, messageParams) => {
dispatch(showNotification({
title: i18next.t('localRecording.localRecording'),
titleKey: 'localRecording.localRecording',
description: i18next.t(messageKey, messageParams)
}, 10000));
};
recordingController.onNotify = (messageKey, messageParams) => {
dispatch(showNotification({
title: i18next.t('localRecording.localRecording'),
titleKey: 'localRecording.localRecording',
description: i18next.t(messageKey, messageParams)
}, 10000));
};

View File

@ -108,20 +108,20 @@ async function _handleNoAudioSignalNotification({ dispatch, getState }, action)
};
}
const notification = showNotification({
const notification = await dispatch(showNotification({
titleKey: 'toolbar.noAudioSignalTitle',
description: <DialInLink />,
descriptionKey,
customActionNameKey,
customActionHandler
});
dispatch(notification);
}));
dispatch(playSound(NO_AUDIO_SIGNAL_SOUND_ID));
// Store the current notification uid so we can check for this state and hide it in case
// a new track was added, thus changing the context of the notification
dispatch(setNoAudioSignalNotificationUid(notification.uid));
if (notification) {
// Store the current notification uid so we can check for this state and hide it in case
// a new track was added, thus changing the context of the notification
dispatch(setNoAudioSignalNotificationUid(notification.uid));
}
});
}

View File

@ -37,17 +37,18 @@ MiddlewareRegistry.register(store => next => action => {
}
});
conference.on(
JitsiConferenceEvents.NOISY_MIC, () => {
const notification = showNotification({
JitsiConferenceEvents.NOISY_MIC, async () => {
const notification = await dispatch(showNotification({
titleKey: 'toolbar.noisyAudioInputTitle',
descriptionKey: 'toolbar.noisyAudioInputDesc'
});
}));
dispatch(notification);
dispatch(playSound(NOISY_AUDIO_INPUT_SOUND_ID));
// we store the last notification id so we can hide it if the mic is muted
dispatch(setNoisyAudioInputNotificationUid(notification.uid));
if (notification) {
// we store the last notification id so we can hide it if the mic is muted
dispatch(setNoisyAudioInputNotificationUid(notification.uid));
}
});
break;
}

View File

@ -76,19 +76,23 @@ export function showErrorNotification(props: Object) {
* @param {Object} props - The props needed to show the notification component.
* @param {number} timeout - How long the notification should display before
* automatically being hidden.
* @returns {{
* type: SHOW_NOTIFICATION,
* props: Object,
* timeout: number,
* uid: number
* }}
* @returns {Function}
*/
export function showNotification(props: Object = {}, timeout: ?number) {
return {
type: SHOW_NOTIFICATION,
props,
timeout,
uid: window.Date.now()
return function(dispatch: Function, getState: Function) {
const { notifications } = getState()['features/base/config'];
const shouldDisplay = !notifications
|| notifications.includes(props.descriptionKey)
|| notifications.includes(props.titleKey);
if (shouldDisplay) {
return dispatch({
type: SHOW_NOTIFICATION,
props,
timeout,
uid: window.Date.now()
});
}
};
}

View File

@ -75,7 +75,7 @@ export function setLiveStreamKey(streamKey: string) {
* @returns {Function}
*/
export function showPendingRecordingNotification(streamType: string) {
return (dispatch: Function) => {
return async (dispatch: Function) => {
const isLiveStreaming
= streamType === JitsiMeetJS.constants.recording.mode.STREAM;
const dialogProps = isLiveStreaming ? {
@ -85,15 +85,14 @@ export function showPendingRecordingNotification(streamType: string) {
descriptionKey: 'recording.pending',
titleKey: 'dialog.recording'
};
const showNotificationAction = showNotification({
const notification = await dispatch(showNotification({
isDismissAllowed: false,
...dialogProps
});
}));
dispatch(showNotificationAction);
dispatch(_setPendingRecordingNotificationUid(
showNotificationAction.uid, streamType));
if (notification) {
dispatch(_setPendingRecordingNotificationUid(notification.uid, streamType));
}
};
}

View File

@ -40,20 +40,20 @@ MiddlewareRegistry.register(store => next => action => {
}
});
conference.on(
JitsiConferenceEvents.TALK_WHILE_MUTED, () => {
const notification = showNotification({
JitsiConferenceEvents.TALK_WHILE_MUTED, async () => {
const notification = await dispatch(showNotification({
titleKey: 'toolbar.talkWhileMutedPopup',
customActionNameKey: 'notify.unmute',
customActionHandler: () => dispatch(setAudioMuted(false))
});
dispatch(notification);
}));
dispatch(playSound(TALK_WHILE_MUTED_SOUND_ID));
// we store the last start muted notification id that we showed,
// so we can hide it when unmuted mic is detected
dispatch(setCurrentNotificationUid(notification.uid));
if (notification) {
// we store the last start muted notification id that we showed,
// so we can hide it when unmuted mic is detected
dispatch(setCurrentNotificationUid(notification.uid));
}
});
break;
}

View File

@ -69,17 +69,16 @@ export function potentialTranscriberJoined(participantId: string) {
* @returns {Function}
*/
export function showPendingTranscribingNotification() {
return (dispatch: Function) => {
const showNotificationAction = showNotification({
return async (dispatch: Function) => {
const notification = await dispatch(showNotification({
descriptionKey: 'transcribing.pending',
isDismissAllowed: false,
titleKey: 'dialog.transcribing'
});
}));
dispatch(showNotificationAction);
dispatch(setPendingTranscribingNotificationUid(
showNotificationAction.uid));
if (notification) {
dispatch(setPendingTranscribingNotificationUid(notification.uid));
}
};
}