Fix notification panel infinite scroll (#2524)

Improves calculations for determining whether we are at the bottom of the notifications panel (which would trigger infinite scroll). This should be particularly effective in fixing issues on smaller screens.
This commit is contained in:
Alexander Skvortsov 2021-01-24 12:12:42 -05:00 committed by GitHub
parent 4432bce771
commit f4da9319ea

View File

@ -99,7 +99,9 @@ export default class NotificationList extends Component {
super.oncreate(vnode);
this.$notifications = this.$('.NotificationList-content');
this.$scrollParent = this.$notifications.css('overflow') === 'auto' ? this.$notifications : $(window);
// If we are on the notifications page, the window will be scrolling and not the $notifications element.
this.$scrollParent = this.inPanel() ? this.$notifications : $(window);
this.boundScrollHandler = this.scrollHandler.bind(this);
this.$scrollParent.on('scroll', this.boundScrollHandler);
@ -112,14 +114,22 @@ export default class NotificationList extends Component {
scrollHandler() {
const state = this.attrs.state;
const scrollTop = this.$scrollParent.scrollTop();
const viewportHeight = this.$scrollParent.height();
const notificationsElement = this.inPanel() ? this.$scrollParent[0] : document.querySelector('body');
const contentTop = this.$scrollParent === this.$notifications ? 0 : this.$notifications.offset().top;
const contentHeight = this.$notifications[0].scrollHeight;
// On very short screens, the scrollHeight + scrollTop might not reach the clientHeight
// by a fraction of a pixel, so we compensate for that.
const atBottom = Math.abs(notificationsElement.scrollHeight - notificationsElement.scrollTop - notificationsElement.clientHeight) <= 1;
if (state.hasMoreResults() && !state.isLoading() && scrollTop + viewportHeight >= contentTop + contentHeight) {
if (state.hasMoreResults() && !state.isLoading() && atBottom) {
state.loadMore();
}
}
/**
* If the NotificationList component isn't in a panel (e.g. on NotificationPage when mobile),
* we need to listen to scroll events on the window, and get scroll state from the body.
*/
inPanel() {
return this.$notifications.css('overflow') === 'auto';
}
}