Fix updates being hidden behind pending items on unmounted components (#11898)
This commit is contained in:
		
							parent
							
								
									a90243a712
								
							
						
					
					
						commit
						ba0de8fb68
					
				
					 4 changed files with 33 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -28,6 +28,9 @@ export const NOTIFICATIONS_CLEAR        = 'NOTIFICATIONS_CLEAR';
 | 
			
		|||
export const NOTIFICATIONS_SCROLL_TOP   = 'NOTIFICATIONS_SCROLL_TOP';
 | 
			
		||||
export const NOTIFICATIONS_LOAD_PENDING = 'NOTIFICATIONS_LOAD_PENDING';
 | 
			
		||||
 | 
			
		||||
export const NOTIFICATIONS_MOUNT   = 'NOTIFICATIONS_MOUNT';
 | 
			
		||||
export const NOTIFICATIONS_UNMOUNT = 'NOTIFICATIONS_UNMOUNT';
 | 
			
		||||
 | 
			
		||||
defineMessages({
 | 
			
		||||
  mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
 | 
			
		||||
  group: { id: 'notifications.group', defaultMessage: '{count} notifications' },
 | 
			
		||||
| 
						 | 
				
			
			@ -215,3 +218,11 @@ export function setFilter (filterType) {
 | 
			
		|||
    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.detachScrollListener();
 | 
			
		||||
    this.detachIntersectionObserver();
 | 
			
		||||
 | 
			
		||||
    detachFullscreenListener(this.onFullScreenChange);
 | 
			
		||||
 | 
			
		||||
    if (this.props.onScrollToTop) {
 | 
			
		||||
      this.props.onScrollToTop();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onFullScreenChange = () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
 | 
			
		|||
import ImmutablePropTypes from 'react-immutable-proptypes';
 | 
			
		||||
import Column from '../../components/column';
 | 
			
		||||
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 NotificationContainer from './containers/notification_container';
 | 
			
		||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 | 
			
		||||
| 
						 | 
				
			
			@ -66,11 +66,16 @@ class Notifications extends React.PureComponent {
 | 
			
		|||
    trackScroll: true,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  componentWillMount() {
 | 
			
		||||
    this.props.dispatch(mountNotifications());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  componentWillUnmount () {
 | 
			
		||||
    this.handleLoadOlder.cancel();
 | 
			
		||||
    this.handleScrollToTop.cancel();
 | 
			
		||||
    this.handleScroll.cancel();
 | 
			
		||||
    this.props.dispatch(scrollTopNotifications(false));
 | 
			
		||||
    this.props.dispatch(unmountNotifications());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleLoadGap = (maxId) => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,8 @@ import {
 | 
			
		|||
  NOTIFICATIONS_CLEAR,
 | 
			
		||||
  NOTIFICATIONS_SCROLL_TOP,
 | 
			
		||||
  NOTIFICATIONS_LOAD_PENDING,
 | 
			
		||||
  NOTIFICATIONS_MOUNT,
 | 
			
		||||
  NOTIFICATIONS_UNMOUNT,
 | 
			
		||||
} from '../actions/notifications';
 | 
			
		||||
import {
 | 
			
		||||
  ACCOUNT_BLOCK_SUCCESS,
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +24,7 @@ const initialState = ImmutableMap({
 | 
			
		|||
  items: ImmutableList(),
 | 
			
		||||
  hasMore: true,
 | 
			
		||||
  top: false,
 | 
			
		||||
  mounted: false,
 | 
			
		||||
  unread: 0,
 | 
			
		||||
  isLoading: false,
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -35,9 +38,10 @@ const notificationToMap = notification => ImmutableMap({
 | 
			
		|||
});
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -63,7 +67,7 @@ const expandNormalizedNotifications = (state, notifications, next, isLoadingRece
 | 
			
		|||
 | 
			
		||||
  return state.withMutations(mutable => {
 | 
			
		||||
    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 => {
 | 
			
		||||
        const lastIndex = 1 + list.findLastIndex(
 | 
			
		||||
| 
						 | 
				
			
			@ -134,6 +138,10 @@ export default function notifications(state = initialState, action) {
 | 
			
		|||
    return action.timeline === 'home' ?
 | 
			
		||||
      state.update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items) :
 | 
			
		||||
      state;
 | 
			
		||||
  case NOTIFICATIONS_MOUNT:
 | 
			
		||||
    return state.set('mounted', true);
 | 
			
		||||
  case NOTIFICATIONS_UNMOUNT:
 | 
			
		||||
    return state.set('mounted', false);
 | 
			
		||||
  default:
 | 
			
		||||
    return state;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue