Fix updates being hidden behind pending items on unmounted components (#11898)
parent
4049193f69
commit
3198f5b0ad
|
@ -28,6 +28,9 @@ 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_LOAD_PENDING = 'NOTIFICATIONS_LOAD_PENDING';
|
export const NOTIFICATIONS_LOAD_PENDING = 'NOTIFICATIONS_LOAD_PENDING';
|
||||||
|
|
||||||
|
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' },
|
||||||
group: { id: 'notifications.group', defaultMessage: '{count} notifications' },
|
group: { id: 'notifications.group', defaultMessage: '{count} notifications' },
|
||||||
|
@ -215,3 +218,11 @@ export function setFilter (filterType) {
|
||||||
dispatch(saveSettings());
|
dispatch(saveSettings());
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const mountNotifications = () => ({
|
||||||
|
type: NOTIFICATIONS_MOUNT,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const unmountNotifications = () => ({
|
||||||
|
type: NOTIFICATIONS_UNMOUNT,
|
||||||
|
});
|
||||||
|
|
|
@ -199,7 +199,12 @@ export default class ScrollableList extends PureComponent {
|
||||||
this.clearMouseIdleTimer();
|
this.clearMouseIdleTimer();
|
||||||
this.detachScrollListener();
|
this.detachScrollListener();
|
||||||
this.detachIntersectionObserver();
|
this.detachIntersectionObserver();
|
||||||
|
|
||||||
detachFullscreenListener(this.onFullScreenChange);
|
detachFullscreenListener(this.onFullScreenChange);
|
||||||
|
|
||||||
|
if (this.props.onScrollToTop) {
|
||||||
|
this.props.onScrollToTop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onFullScreenChange = () => {
|
onFullScreenChange = () => {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import Column from '../../components/column';
|
import Column from '../../components/column';
|
||||||
import ColumnHeader from '../../components/column_header';
|
import ColumnHeader from '../../components/column_header';
|
||||||
import { expandNotifications, scrollTopNotifications, loadPending } from '../../actions/notifications';
|
import { expandNotifications, scrollTopNotifications, loadPending, mountNotifications, unmountNotifications } from '../../actions/notifications';
|
||||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
||||||
import NotificationContainer from './containers/notification_container';
|
import NotificationContainer from './containers/notification_container';
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||||
|
@ -66,11 +66,16 @@ class Notifications extends React.PureComponent {
|
||||||
trackScroll: true,
|
trackScroll: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
this.props.dispatch(mountNotifications());
|
||||||
|
}
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
this.handleLoadOlder.cancel();
|
this.handleLoadOlder.cancel();
|
||||||
this.handleScrollToTop.cancel();
|
this.handleScrollToTop.cancel();
|
||||||
this.handleScroll.cancel();
|
this.handleScroll.cancel();
|
||||||
this.props.dispatch(scrollTopNotifications(false));
|
this.props.dispatch(scrollTopNotifications(false));
|
||||||
|
this.props.dispatch(unmountNotifications());
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLoadGap = (maxId) => {
|
handleLoadGap = (maxId) => {
|
||||||
|
|
|
@ -7,6 +7,8 @@ import {
|
||||||
NOTIFICATIONS_CLEAR,
|
NOTIFICATIONS_CLEAR,
|
||||||
NOTIFICATIONS_SCROLL_TOP,
|
NOTIFICATIONS_SCROLL_TOP,
|
||||||
NOTIFICATIONS_LOAD_PENDING,
|
NOTIFICATIONS_LOAD_PENDING,
|
||||||
|
NOTIFICATIONS_MOUNT,
|
||||||
|
NOTIFICATIONS_UNMOUNT,
|
||||||
} from '../actions/notifications';
|
} from '../actions/notifications';
|
||||||
import {
|
import {
|
||||||
ACCOUNT_BLOCK_SUCCESS,
|
ACCOUNT_BLOCK_SUCCESS,
|
||||||
|
@ -22,6 +24,7 @@ const initialState = ImmutableMap({
|
||||||
items: ImmutableList(),
|
items: ImmutableList(),
|
||||||
hasMore: true,
|
hasMore: true,
|
||||||
top: false,
|
top: false,
|
||||||
|
mounted: false,
|
||||||
unread: 0,
|
unread: 0,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
});
|
});
|
||||||
|
@ -36,8 +39,9 @@ const notificationToMap = notification => ImmutableMap({
|
||||||
|
|
||||||
const normalizeNotification = (state, notification, usePendingItems) => {
|
const normalizeNotification = (state, notification, usePendingItems) => {
|
||||||
const top = state.get('top');
|
const top = state.get('top');
|
||||||
|
const mounted = state.get('mounted');
|
||||||
|
|
||||||
if (usePendingItems || !top || !state.get('pendingItems').isEmpty()) {
|
if (usePendingItems || (!top && mounted) || !state.get('pendingItems').isEmpty()) {
|
||||||
return state.update('pendingItems', list => list.unshift(notificationToMap(notification))).update('unread', unread => unread + 1);
|
return state.update('pendingItems', list => list.unshift(notificationToMap(notification))).update('unread', unread => unread + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +67,7 @@ const expandNormalizedNotifications = (state, notifications, next, isLoadingRece
|
||||||
|
|
||||||
return state.withMutations(mutable => {
|
return state.withMutations(mutable => {
|
||||||
if (!items.isEmpty()) {
|
if (!items.isEmpty()) {
|
||||||
usePendingItems = isLoadingRecent && (usePendingItems || !mutable.get('top') || !mutable.get('pendingItems').isEmpty());
|
usePendingItems = isLoadingRecent && (usePendingItems || (!mutable.get('top') && mutable.get('mounted')) || !mutable.get('pendingItems').isEmpty());
|
||||||
|
|
||||||
mutable.update(usePendingItems ? 'pendingItems' : 'items', list => {
|
mutable.update(usePendingItems ? 'pendingItems' : 'items', list => {
|
||||||
const lastIndex = 1 + list.findLastIndex(
|
const lastIndex = 1 + list.findLastIndex(
|
||||||
|
@ -134,6 +138,10 @@ export default function notifications(state = initialState, action) {
|
||||||
return action.timeline === 'home' ?
|
return action.timeline === 'home' ?
|
||||||
state.update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items) :
|
state.update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items) :
|
||||||
state;
|
state;
|
||||||
|
case NOTIFICATIONS_MOUNT:
|
||||||
|
return state.set('mounted', true);
|
||||||
|
case NOTIFICATIONS_UNMOUNT:
|
||||||
|
return state.set('mounted', false);
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue