Keep track of unread notifications when the notification column isn't mounted

This commit is contained in:
Thibaut Girka 2018-09-06 15:47:13 +02:00 committed by ThibG
parent 711826cb37
commit c8875b4d8a
3 changed files with 58 additions and 7 deletions

View file

@ -25,6 +25,9 @@ export const NOTIFICATIONS_EXPAND_FAIL = 'NOTIFICATIONS_EXPAND_FAIL';
export const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR'; export const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR';
export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP'; export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
export const NOTIFICATIONS_MOUNT = 'NOTIFICATIONS_MOUNT';
export const NOTIFICATIONS_UNMOUNT = 'NOTIFICATIONS_UNMOUNT';
defineMessages({ defineMessages({
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' }, mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
}); });
@ -216,3 +219,15 @@ export function deleteMarkedNotificationsSuccess() {
type: NOTIFICATIONS_DELETE_MARKED_SUCCESS, type: NOTIFICATIONS_DELETE_MARKED_SUCCESS,
}; };
}; };
export function mountNotifications() {
return {
type: NOTIFICATIONS_MOUNT,
};
};
export function unmountNotifications() {
return {
type: NOTIFICATIONS_UNMOUNT,
};
};

View file

@ -8,6 +8,8 @@ import {
enterNotificationClearingMode, enterNotificationClearingMode,
expandNotifications, expandNotifications,
scrollTopNotifications, scrollTopNotifications,
mountNotifications,
unmountNotifications,
} from 'flavours/glitch/actions/notifications'; } from 'flavours/glitch/actions/notifications';
import { addColumn, removeColumn, moveColumn } from 'flavours/glitch/actions/columns'; import { addColumn, removeColumn, moveColumn } from 'flavours/glitch/actions/columns';
import NotificationContainer from './containers/notification_container'; import NotificationContainer from './containers/notification_container';
@ -42,6 +44,12 @@ const mapDispatchToProps = dispatch => ({
onEnterCleaningMode(yes) { onEnterCleaningMode(yes) {
dispatch(enterNotificationClearingMode(yes)); dispatch(enterNotificationClearingMode(yes));
}, },
onMount() {
dispatch(mountNotifications());
},
onUnmount() {
dispatch(unmountNotifications());
},
dispatch, dispatch,
}); });
@ -62,6 +70,8 @@ export default class Notifications extends React.PureComponent {
localSettings: ImmutablePropTypes.map, localSettings: ImmutablePropTypes.map,
notifCleaningActive: PropTypes.bool, notifCleaningActive: PropTypes.bool,
onEnterCleaningMode: PropTypes.func, onEnterCleaningMode: PropTypes.func,
onMount: PropTypes.func,
onUnmount: PropTypes.func,
}; };
static defaultProps = { static defaultProps = {
@ -126,6 +136,20 @@ export default class Notifications extends React.PureComponent {
} }
} }
componentDidMount () {
const { onMount } = this.props;
if (onMount) {
onMount();
}
}
componentWillUnmount () {
const { onUnmount } = this.props;
if (onUnmount) {
onUnmount();
}
}
render () { render () {
const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore } = this.props; const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore } = this.props;
const pinned = !!columnId; const pinned = !!columnId;

View file

@ -1,4 +1,6 @@
import { import {
NOTIFICATIONS_MOUNT,
NOTIFICATIONS_UNMOUNT,
NOTIFICATIONS_UPDATE, NOTIFICATIONS_UPDATE,
NOTIFICATIONS_EXPAND_SUCCESS, NOTIFICATIONS_EXPAND_SUCCESS,
NOTIFICATIONS_EXPAND_REQUEST, NOTIFICATIONS_EXPAND_REQUEST,
@ -24,6 +26,7 @@ const initialState = ImmutableMap({
items: ImmutableList(), items: ImmutableList(),
hasMore: true, hasMore: true,
top: true, top: true,
mounted: 0,
unread: 0, unread: 0,
lastReadId: '0', lastReadId: '0',
isLoading: false, isLoading: false,
@ -41,7 +44,7 @@ const notificationToMap = (state, notification) => ImmutableMap({
}); });
const normalizeNotification = (state, notification) => { const normalizeNotification = (state, notification) => {
const top = state.get('top'); const top = state.get('top') && state.get('mounted') > 0;
if (top) { if (top) {
state = state.set('lastReadId', notification.id); state = state.set('lastReadId', notification.id);
@ -59,7 +62,7 @@ const normalizeNotification = (state, notification) => {
}; };
const expandNormalizedNotifications = (state, notifications, next) => { const expandNormalizedNotifications = (state, notifications, next) => {
const top = state.get('top'); const top = state.get('top') && state.get('mounted') > 0;
const lastReadId = state.get('lastReadId'); const lastReadId = state.get('lastReadId');
let items = ImmutableList(); let items = ImmutableList();
@ -102,18 +105,23 @@ const filterNotifications = (state, relationship) => {
return state.update('items', list => list.filterNot(item => item !== null && item.get('account') === relationship.id)); return state.update('items', list => list.filterNot(item => item !== null && item.get('account') === relationship.id));
}; };
const clearUnread = (state) => {
state = state.set('unread', 0);
const lastNotification = state.get('items').find(item => item !== null);
return state.set('lastReadId', lastNotification ? lastNotification.get('id') : '0');
}
const updateTop = (state, top) => { const updateTop = (state, top) => {
if (top) { if (top && state.get('mounted') > 0) {
state = state.set('unread', 0); state = clearUnread(state);
const lastNotification = state.get('items').find(item => item !== null);
state = state.set('lastReadId', lastNotification ? lastNotification.get('id') : '0');
} }
return state.set('top', top); return state.set('top', top);
}; };
const deleteByStatus = (state, statusId) => { const deleteByStatus = (state, statusId) => {
if (!state.get('top')) { const top = state.get('top') && state.get('mounted') > 0;
if (!top) {
const lastReadId = state.get('lastReadId'); const lastReadId = state.get('lastReadId');
const deletedUnread = state.get('items').filter(item => item !== null && item.get('status') === statusId && compareId(item.get('id'), lastReadId) > 0); const deletedUnread = state.get('items').filter(item => item !== null && item.get('status') === statusId && compareId(item.get('id'), lastReadId) > 0);
state = state.update('unread', unread => unread - deletedUnread.size); state = state.update('unread', unread => unread - deletedUnread.size);
@ -153,6 +161,10 @@ export default function notifications(state = initialState, action) {
let st; let st;
switch(action.type) { switch(action.type) {
case NOTIFICATIONS_MOUNT:
return (state.get('top') ? clearUnread(state) : state).update('mounted', count => count + 1);
case NOTIFICATIONS_UNMOUNT:
return state.update('mounted', count => count - 1);
case NOTIFICATIONS_EXPAND_REQUEST: case NOTIFICATIONS_EXPAND_REQUEST:
case NOTIFICATIONS_DELETE_MARKED_REQUEST: case NOTIFICATIONS_DELETE_MARKED_REQUEST:
return state.set('isLoading', true); return state.set('isLoading', true);