diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.js index 91a895bce5e..7551d0b1fe4 100644 --- a/app/javascript/mastodon/components/scrollable_list.js +++ b/app/javascript/mastodon/components/scrollable_list.js @@ -59,6 +59,13 @@ export default class ScrollableList extends PureComponent { } else if (this.props.onScroll) { this.props.onScroll(); } + + if (!this.lastScrollWasSynthetic) { + // If the last scroll wasn't caused by setScrollTop(), assume it was + // intentional and cancel any pending scroll reset on mouse idle + this.scrollToTopOnMouseIdle = false; + } + this.lastScrollWasSynthetic = false; } }, 150, { trailing: true, @@ -66,8 +73,16 @@ export default class ScrollableList extends PureComponent { mouseIdleTimer = null; mouseMovedRecently = false; + lastScrollWasSynthetic = false; scrollToTopOnMouseIdle = false; + setScrollTop = newScrollTop => { + if (this.node.scrollTop !== newScrollTop) { + this.lastScrollWasSynthetic = true; + this.node.scrollTop = newScrollTop; + } + }; + clearMouseIdleTimer = () => { if (this.mouseIdleTimer === null) { return; @@ -99,7 +114,7 @@ export default class ScrollableList extends PureComponent { handleMouseIdle = () => { if (this.scrollToTopOnMouseIdle) { - this.node.scrollTop = 0; + this.setScrollTop(0); } this.mouseMovedRecently = false; @@ -132,11 +147,7 @@ export default class ScrollableList extends PureComponent { // Reset the scroll position when a new child comes in in order not to // jerk the scrollbar around if you're already scrolled down the page. if (snapshot !== null) { - const newScrollTop = this.node.scrollHeight - snapshot; - - if (this.node.scrollTop !== newScrollTop) { - this.node.scrollTop = newScrollTop; - } + this.setScrollTop(this.node.scrollHeight - snapshot); } }