lbry-desktop/ui/redux/reducers/notifications.js
infinite-persistence b8ec0c9967 Augment doNotificationList to get a filtered list.
Initially, the filtered list was done at the component level, and the list was simply a subset of `notifications`. But due to the limit issue explained in 5694, we now query the filtered list instead.

Considerations:
- The filtered list could contain items not listed in the 'All' list. We could add a string at the bottom of 'All' that says "not all items retrieved" if this confuses the user.
- The unseen count needs to be based on 'All' and not the filtered one, so that data needs to be stashed somehow (can't re-use the array).

Use 2 arrays for now instead of trying to accumulate "all" and "filtered" into 1 array.
2021-04-08 14:28:21 -04:00

150 lines
3.9 KiB
JavaScript

// @flow
import * as ACTIONS from 'constants/action_types';
import { handleActions } from 'util/redux-utils';
const defaultState: NotificationState = {
notifications: [],
notificationsFiltered: [],
fetchingNotifications: false,
toasts: [],
errors: [],
};
export default handleActions(
{
// Toasts
[ACTIONS.CREATE_TOAST]: (state: NotificationState, action: DoToast) => {
const toast: Toast = action.data;
const newToasts: Array<Toast> = state.toasts.slice();
newToasts.push(toast);
return {
...state,
toasts: newToasts,
};
},
[ACTIONS.DISMISS_TOAST]: (state: NotificationState) => {
const newToasts: Array<Toast> = state.toasts.slice();
newToasts.shift();
return {
...state,
toasts: newToasts,
};
},
// Notifications
[ACTIONS.NOTIFICATION_LIST_STARTED]: (state, action) => {
return {
...state,
fetchingNotifications: true,
};
},
[ACTIONS.NOTIFICATION_LIST_COMPLETED]: (state, action) => {
const { filterRule, newNotifications } = action.data;
if (filterRule && filterRule !== '') {
return {
...state,
notificationsFiltered: newNotifications,
fetchingNotifications: false,
};
} else {
return {
...state,
notifications: newNotifications,
fetchingNotifications: false,
};
}
},
[ACTIONS.NOTIFICATION_LIST_FAILED]: (state, action) => {
return {
...state,
fetchingNotifications: false,
};
},
[ACTIONS.NOTIFICATION_READ_COMPLETED]: (state, action) => {
const { notifications, notificationsFiltered } = state;
const { notificationIds } = action.data;
const markIdsAsRead = (list, ids) => {
return (
list &&
list.map((n) => {
if (ids.includes(n.id)) {
return { ...n, is_read: true };
} else {
return { ...n };
}
})
);
};
return {
...state,
notifications: markIdsAsRead(notifications, notificationIds),
notificationsFiltered: markIdsAsRead(notificationsFiltered, notificationIds),
};
},
[ACTIONS.NOTIFICATION_READ_FAILED]: (state, action) => {
return {
...state,
};
},
[ACTIONS.NOTIFICATION_SEEN_COMPLETED]: (state, action) => {
const { notifications, notificationsFiltered } = state;
const { notificationIds } = action.data;
const markIdsAsSeen = (list, ids) => {
return list.map((n) => {
if (ids.includes(n.id)) {
return { ...n, is_seen: true };
}
return n;
});
};
return {
...state,
notifications: markIdsAsSeen(notifications, notificationIds),
notificationsFiltered: markIdsAsSeen(notificationsFiltered, notificationIds),
};
},
[ACTIONS.NOTIFICATION_DELETE_COMPLETED]: (state, action) => {
const { notifications, notificationsFiltered } = state;
const { notificationId } = action.data;
const deleteId = (list, id) => {
return list.filter((n) => n.id !== id);
};
return {
...state,
notifications: deleteId(notifications, notificationId),
notificationsFiltered: deleteId(notificationsFiltered, notificationId),
};
},
// Errors
[ACTIONS.CREATE_ERROR]: (state: NotificationState, action: DoError) => {
const error: ErrorNotification = action.data;
const newErrors: Array<ErrorNotification> = state.errors.slice();
newErrors.push(error);
return {
...state,
errors: newErrors,
};
},
[ACTIONS.DISMISS_ERROR]: (state: NotificationState) => {
const newErrors: Array<ErrorNotification> = state.errors.slice();
newErrors.shift();
return {
...state,
errors: newErrors,
};
},
},
defaultState
);