Fix “slow mode” issues (#11859)

* Fix weird scroll-jumping behavior with pending items

* Treat pending items as unread items

* Fix scroll position being altered because of the “X new items” button
This commit is contained in:
ThibG 2019-09-16 15:45:06 +02:00 committed by Eugen Rochko
parent 5eff29b28c
commit f109867578
5 changed files with 15 additions and 7 deletions

View file

@ -172,8 +172,9 @@ export default class ScrollableList extends PureComponent {
const someItemInserted = React.Children.count(prevProps.children) > 0 && const someItemInserted = React.Children.count(prevProps.children) > 0 &&
React.Children.count(prevProps.children) < React.Children.count(this.props.children) && React.Children.count(prevProps.children) < React.Children.count(this.props.children) &&
this.getFirstChildKey(prevProps) !== this.getFirstChildKey(this.props); this.getFirstChildKey(prevProps) !== this.getFirstChildKey(this.props);
const pendingChanged = (prevProps.numPending > 0) !== (this.props.numPending > 0);
if (someItemInserted && (this.getScrollTop() > 0 || this.mouseMovedRecently)) { if (pendingChanged || someItemInserted && (this.getScrollTop() > 0 || this.mouseMovedRecently)) {
return this.getScrollHeight() - this.getScrollTop(); return this.getScrollHeight() - this.getScrollTop();
} else { } else {
return null; return null;
@ -261,6 +262,13 @@ export default class ScrollableList extends PureComponent {
handleLoadPending = e => { handleLoadPending = e => {
e.preventDefault(); e.preventDefault();
this.props.onLoadPending(); this.props.onLoadPending();
// Prevent the weird scroll-jumping behavior, as we explicitly don't want to
// scroll to top, and we know the scroll height is going to change
this.scrollToTopOnMouseIdle = false;
this.lastScrollWasSynthetic = false;
this.clearMouseIdleTimer();
this.mouseIdleTimer = setTimeout(this.handleMouseIdle, MOUSE_IDLE_DELAY);
this.mouseMovedRecently = true;
} }
render () { render () {

View file

@ -20,7 +20,7 @@ const mapStateToProps = (state, { onlyMedia, columnId }) => {
const index = columns.findIndex(c => c.get('uuid') === uuid); const index = columns.findIndex(c => c.get('uuid') === uuid);
return { return {
hasUnread: state.getIn(['timelines', `community${onlyMedia ? ':media' : ''}`, 'unread']) > 0, hasUnread: state.getIn(['timelines', `community${onlyMedia ? ':media' : ''}`, 'unread']) > 0 || state.getIn(['timelines', `community${onlyMedia ? ':media' : ''}`, 'pendingItems']).size > 0,
onlyMedia: (columnId && index >= 0) ? columns.get(index).getIn(['params', 'other', 'onlyMedia']) : state.getIn(['settings', 'community', 'other', 'onlyMedia']), onlyMedia: (columnId && index >= 0) ? columns.get(index).getIn(['params', 'other', 'onlyMedia']) : state.getIn(['settings', 'community', 'other', 'onlyMedia']),
}; };
}; };

View file

@ -39,7 +39,7 @@ const mapStateToProps = state => ({
showFilterBar: state.getIn(['settings', 'notifications', 'quickFilter', 'show']), showFilterBar: state.getIn(['settings', 'notifications', 'quickFilter', 'show']),
notifications: getNotifications(state), notifications: getNotifications(state),
isLoading: state.getIn(['notifications', 'isLoading'], true), isLoading: state.getIn(['notifications', 'isLoading'], true),
isUnread: state.getIn(['notifications', 'unread']) > 0, isUnread: state.getIn(['notifications', 'unread']) > 0 || state.getIn(['notifications', 'pendingItems']).size > 0,
hasMore: state.getIn(['notifications', 'hasMore']), hasMore: state.getIn(['notifications', 'hasMore']),
numPending: state.getIn(['notifications', 'pendingItems'], ImmutableList()).size, numPending: state.getIn(['notifications', 'pendingItems'], ImmutableList()).size,
}); });

View file

@ -36,7 +36,7 @@ const notificationToMap = notification => ImmutableMap({
const normalizeNotification = (state, notification, usePendingItems) => { const normalizeNotification = (state, notification, usePendingItems) => {
if (usePendingItems) { if (usePendingItems) {
return state.update('pendingItems', list => list.unshift(notificationToMap(notification))); return state.update('pendingItems', list => list.unshift(notificationToMap(notification))).update('unread', unread => unread + 1);
} }
const top = state.get('top'); const top = state.get('top');
@ -91,7 +91,7 @@ const filterNotifications = (state, accountIds) => {
const updateTop = (state, top) => { const updateTop = (state, top) => {
if (top) { if (top) {
state = state.set('unread', 0); state = state.set('unread', state.get('pendingItems').size);
} }
return state.set('top', top); return state.set('top', top);

View file

@ -65,7 +65,7 @@ const updateTimeline = (state, timeline, status, usePendingItems) => {
return state; return state;
} }
return state.update(timeline, initialTimeline, map => map.update('pendingItems', list => list.unshift(status.get('id')))); return state.update(timeline, initialTimeline, map => map.update('pendingItems', list => list.unshift(status.get('id'))).update('unread', unread => unread + 1));
} }
const top = state.getIn([timeline, 'top']); const top = state.getIn([timeline, 'top']);
@ -128,7 +128,7 @@ const filterTimeline = (timeline, state, relationship, statuses) => {
const updateTop = (state, timeline, top) => { const updateTop = (state, timeline, top) => {
return state.update(timeline, initialTimeline, map => map.withMutations(mMap => { return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
if (top) mMap.set('unread', 0); if (top) mMap.set('unread', mMap.get('pendingItems').size);
mMap.set('top', top); mMap.set('top', top);
})); }));
}; };