feat(notifications) reset same type notification timeout

This commit is contained in:
Tudor D. Pop 2022-02-03 15:17:34 +02:00 committed by GitHub
parent 2a8d0b6e33
commit b9f3448379
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 97 additions and 92 deletions

View File

@ -603,7 +603,6 @@ function _raiseHandUpdated({ dispatch, getState }, conference, participantId, ne
titleKey: 'notify.somebody',
title: notificationTitle,
descriptionKey: 'notify.raisedHand',
raiseHandNotification: true,
concatText: true,
uid: RAISE_HAND_NOTIFICATION_ID,
...action

View File

@ -45,13 +45,3 @@ export const SHOW_NOTIFICATION = 'SHOW_NOTIFICATION';
* }
*/
export const SET_NOTIFICATIONS_ENABLED = 'SET_NOTIFICATIONS_ENABLED';
/**
* The type of (redux) action which signals that raise hand notifications
* should be dismissed.
*
* {
* type: HIDE_RAISE_HAND_NOTIFICATIONS
* }
*/
export const HIDE_RAISE_HAND_NOTIFICATIONS = 'HIDE_RAISE_HAND_NOTIFICATIONS';

View File

@ -9,7 +9,6 @@ import { getParticipantCount } from '../base/participants/functions';
import {
CLEAR_NOTIFICATIONS,
HIDE_NOTIFICATION,
HIDE_RAISE_HAND_NOTIFICATIONS,
SET_NOTIFICATIONS_ENABLED,
SHOW_NOTIFICATION
} from './actionTypes';
@ -71,19 +70,6 @@ export function hideNotification(uid: string) {
};
}
/**
* Removes the raise hand notifications.
*
* @returns {{
* type: HIDE_RAISE_HAND_NOTIFICATIONS
* }}
*/
export function hideRaiseHandNotifications() {
return {
type: HIDE_RAISE_HAND_NOTIFICATIONS
};
}
/**
* Stops notifications from being displayed.
*

View File

@ -104,7 +104,7 @@ class NotificationsContainer extends Component<Props> {
if (notification !== previousNotification) {
this._clearNotificationDismissTimeout();
if (notification && notification.timeout && notification.props.isDismissAllowed !== false) {
if (notification && notification.timeout) {
const {
timeout,
uid

View File

@ -147,24 +147,6 @@ class NotificationsContainer extends Component<Props> {
};
}
/**
* Sets a timeout for each notification, where applicable.
*
* @inheritdoc
*/
componentDidMount() {
this._updateTimeouts();
}
/**
* Sets a timeout for each notification, where applicable.
*
* @inheritdoc
*/
componentDidUpdate() {
this._updateTimeouts();
}
/**
* Implements React's {@link Component#render()}.
*
@ -249,31 +231,6 @@ class NotificationsContainer extends Component<Props> {
);
});
}
/**
* Updates the timeouts for every notification.
*
* @returns {void}
*/
_updateTimeouts() {
const { _notifications } = this.props;
for (const notification of _notifications) {
if (notification.timeout
&& notification.props.isDismissAllowed !== false
&& !this._timeouts.has(notification.uid)) {
const {
timeout,
uid
} = notification;
const timerID = setTimeout(() => {
this._onDismissed(uid);
}, timeout);
this._timeouts.set(uid, timerID);
}
}
}
}
/**

View File

@ -13,15 +13,65 @@ import {
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
import { PARTICIPANTS_PANE_OPEN } from '../participants-pane/actionTypes';
import {
CLEAR_NOTIFICATIONS,
HIDE_NOTIFICATION,
SHOW_NOTIFICATION
} from './actionTypes';
import {
clearNotifications,
hideRaiseHandNotifications,
hideNotification,
showNotification,
showParticipantJoinedNotification,
showParticipantLeftNotification
} from './actions';
import { NOTIFICATION_TIMEOUT_TYPE } from './constants';
import { joinLeaveNotificationsDisabled } from './functions';
import {
NOTIFICATION_TIMEOUT_TYPE,
RAISE_HAND_NOTIFICATION_ID
} from './constants';
import { areThereNotifications, joinLeaveNotificationsDisabled } from './functions';
/**
* Map of timers.
*
* @type {Map}
*/
const timers = new Map();
/**
* Function that creates a timeout id for specific notification.
*
* @param {Object} notification - Notification for which we want to create a timeout.
* @param {Function} dispatch - The Redux dispatch function.
* @returns {void}
*/
const createTimeoutId = (notification, dispatch) => {
const {
timeout,
uid
} = notification;
if (timeout) {
const timerID = setTimeout(() => {
dispatch(hideNotification(uid));
}, timeout);
timers.set(uid, timerID);
}
};
/**
* Returns notifications state.
*
* @param {Object} state - Global state.
* @returns {Array<Object>} - Notifications state.
*/
const getNotifications = state => {
const _visible = areThereNotifications(state);
const { notifications } = state['features/notifications'];
return _visible ? notifications : [];
};
/**
* Middleware that captures actions to display notifications.
@ -30,12 +80,52 @@ import { joinLeaveNotificationsDisabled } from './functions';
* @returns {Function}
*/
MiddlewareRegistry.register(store => next => action => {
const { dispatch, getState } = store;
const state = getState();
switch (action.type) {
case CLEAR_NOTIFICATIONS: {
if (navigator.product !== 'ReactNative') {
const _notifications = getNotifications(state);
for (const notification of _notifications) {
if (timers.has(notification.uid)) {
const timeout = timers.get(notification.uid);
clearTimeout(timeout);
timers.delete(notification.uid);
}
}
timers.clear();
}
break;
}
case SHOW_NOTIFICATION: {
if (navigator.product !== 'ReactNative') {
if (timers.has(action.uid)) {
const timer = timers.get(action.uid);
clearTimeout(timer);
timers.delete(action.uid);
}
createTimeoutId(action, dispatch);
}
break;
}
case HIDE_NOTIFICATION: {
if (navigator.product !== 'ReactNative') {
const timer = timers.get(action.uid);
clearTimeout(timer);
timers.delete(action.uid);
}
break;
}
case PARTICIPANT_JOINED: {
const result = next(action);
const { participant: p } = action;
const { dispatch, getState } = store;
const state = getState();
const { conference } = state['features/base/conference'];
if (conference && !p.local && !joinLeaveNotificationsDisabled() && !p.isReplacing) {
@ -48,8 +138,6 @@ MiddlewareRegistry.register(store => next => action => {
}
case PARTICIPANT_LEFT: {
if (!joinLeaveNotificationsDisabled()) {
const { dispatch, getState } = store;
const state = getState();
const participant = getParticipantById(
store.getState(),
action.participant.id
@ -65,7 +153,6 @@ MiddlewareRegistry.register(store => next => action => {
return next(action);
}
case PARTICIPANT_UPDATED: {
const state = store.getState();
const { disableModeratorIndicator } = state['features/base/config'];
if (disableModeratorIndicator) {
@ -93,7 +180,7 @@ MiddlewareRegistry.register(store => next => action => {
return next(action);
}
case PARTICIPANTS_PANE_OPEN: {
store.dispatch(hideRaiseHandNotifications());
store.dispatch(hideNotification(RAISE_HAND_NOTIFICATION_ID));
break;
}
}

View File

@ -5,7 +5,6 @@ import { ReducerRegistry } from '../base/redux';
import {
CLEAR_NOTIFICATIONS,
HIDE_NOTIFICATION,
HIDE_RAISE_HAND_NOTIFICATIONS,
SET_NOTIFICATIONS_ENABLED,
SHOW_NOTIFICATION
} from './actionTypes';
@ -44,14 +43,6 @@ ReducerRegistry.register('features/notifications',
notification => notification.uid !== action.uid)
};
case HIDE_RAISE_HAND_NOTIFICATIONS:
return {
...state,
notifications: state.notifications.filter(
notification => !notification.props.raiseHandNotification
)
};
case SET_NOTIFICATIONS_ENABLED:
return {
...state,

View File

@ -96,7 +96,6 @@ export function showPendingRecordingNotification(streamType: string) {
titleKey: 'dialog.recording'
};
const notification = await dispatch(showNotification({
isDismissAllowed: false,
...dialogProps
}, NOTIFICATION_TIMEOUT_TYPE.MEDIUM));
@ -172,7 +171,6 @@ export function showStartedRecordingNotification(
let dialogProps = {
descriptionKey: participantName ? 'liveStreaming.onBy' : 'liveStreaming.on',
descriptionArguments: { name: participantName },
isDismissAllowed: true,
titleKey: 'dialog.liveStreaming'
};
@ -185,7 +183,6 @@ export function showStartedRecordingNotification(
customActionNameKey: undefined,
descriptionKey: participantName ? 'recording.onBy' : 'recording.on',
descriptionArguments: { name: participantName },
isDismissAllowed: true,
titleKey: 'dialog.recording'
};
@ -210,7 +207,6 @@ export function showStartedRecordingNotification(
dialogProps.customActionHandler = [ () => copyText(link) ];
dialogProps.titleKey = 'recording.on';
dialogProps.descriptionKey = 'recording.linkGenerated';
dialogProps.isDismissAllowed = false;
} catch (err) {
dispatch(showErrorNotification({
titleKey: 'recording.errorFetchingLink'

View File

@ -72,7 +72,6 @@ export function showPendingTranscribingNotification() {
return async (dispatch: Function) => {
const notification = await dispatch(showNotification({
descriptionKey: 'transcribing.pending',
isDismissAllowed: false,
titleKey: 'dialog.transcribing'
}, NOTIFICATION_TIMEOUT_TYPE.LONG));