Browse Source

Fix updates being hidden behind pending items on unmounted components (#11898)

master^2
Eugen Rochko 4 years ago
committed by GitHub
parent
commit
ba0de8fb68
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 4 deletions
  1. +11
    -0
      app/javascript/mastodon/actions/notifications.js
  2. +5
    -0
      app/javascript/mastodon/components/scrollable_list.js
  3. +6
    -1
      app/javascript/mastodon/features/notifications/index.js
  4. +11
    -3
      app/javascript/mastodon/reducers/notifications.js

+ 11
- 0
app/javascript/mastodon/actions/notifications.js View File

@@ -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,
});

+ 5
- 0
app/javascript/mastodon/components/scrollable_list.js View File

@@ -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 = () => {


+ 6
- 1
app/javascript/mastodon/features/notifications/index.js View File

@@ -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) => {


+ 11
- 3
app/javascript/mastodon/reducers/notifications.js View File

@@ -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…
Cancel
Save