diff --git a/framework/core/js/src/forum/components/NotificationList.js b/framework/core/js/src/forum/components/NotificationList.js index 4eb7fea0d..2db7bbbf3 100644 --- a/framework/core/js/src/forum/components/NotificationList.js +++ b/framework/core/js/src/forum/components/NotificationList.js @@ -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'; + } }