From f1098675782944fe1dabec71cd58d3d091da06a0 Mon Sep 17 00:00:00 2001 From: ThibG Date: Mon, 16 Sep 2019 15:45:06 +0200 Subject: [PATCH] =?UTF-8?q?Fix=20=E2=80=9Cslow=20mode=E2=80=9D=20issues=20?= =?UTF-8?q?(#11859)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 --- app/javascript/mastodon/components/scrollable_list.js | 10 +++++++++- .../mastodon/features/community_timeline/index.js | 2 +- .../mastodon/features/notifications/index.js | 2 +- app/javascript/mastodon/reducers/notifications.js | 4 ++-- app/javascript/mastodon/reducers/timelines.js | 4 ++-- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.js index 0bf817923..253646ed0 100644 --- a/app/javascript/mastodon/components/scrollable_list.js +++ b/app/javascript/mastodon/components/scrollable_list.js @@ -172,8 +172,9 @@ export default class ScrollableList extends PureComponent { const someItemInserted = React.Children.count(prevProps.children) > 0 && React.Children.count(prevProps.children) < React.Children.count(this.props.children) && 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(); } else { return null; @@ -261,6 +262,13 @@ export default class ScrollableList extends PureComponent { handleLoadPending = e => { e.preventDefault(); 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 () { diff --git a/app/javascript/mastodon/features/community_timeline/index.js b/app/javascript/mastodon/features/community_timeline/index.js index f95fa4970..cb93f9c22 100644 --- a/app/javascript/mastodon/features/community_timeline/index.js +++ b/app/javascript/mastodon/features/community_timeline/index.js @@ -20,7 +20,7 @@ const mapStateToProps = (state, { onlyMedia, columnId }) => { const index = columns.findIndex(c => c.get('uuid') === uuid); 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']), }; }; diff --git a/app/javascript/mastodon/features/notifications/index.js b/app/javascript/mastodon/features/notifications/index.js index f2b239afe..7e5de0613 100644 --- a/app/javascript/mastodon/features/notifications/index.js +++ b/app/javascript/mastodon/features/notifications/index.js @@ -39,7 +39,7 @@ const mapStateToProps = state => ({ showFilterBar: state.getIn(['settings', 'notifications', 'quickFilter', 'show']), notifications: getNotifications(state), 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']), numPending: state.getIn(['notifications', 'pendingItems'], ImmutableList()).size, }); diff --git a/app/javascript/mastodon/reducers/notifications.js b/app/javascript/mastodon/reducers/notifications.js index 049c70cb4..69bd47940 100644 --- a/app/javascript/mastodon/reducers/notifications.js +++ b/app/javascript/mastodon/reducers/notifications.js @@ -36,7 +36,7 @@ const notificationToMap = notification => ImmutableMap({ const normalizeNotification = (state, notification, 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'); @@ -91,7 +91,7 @@ const filterNotifications = (state, accountIds) => { const updateTop = (state, top) => { if (top) { - state = state.set('unread', 0); + state = state.set('unread', state.get('pendingItems').size); } return state.set('top', top); diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js index 0b036f5fe..db45d4d40 100644 --- a/app/javascript/mastodon/reducers/timelines.js +++ b/app/javascript/mastodon/reducers/timelines.js @@ -65,7 +65,7 @@ const updateTimeline = (state, timeline, status, usePendingItems) => { 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']); @@ -128,7 +128,7 @@ const filterTimeline = (timeline, state, relationship, statuses) => { const updateTop = (state, timeline, top) => { 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); })); };