From 19c64a49f7da7e4131e5090a24d3056eaff490db Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Tue, 8 Jan 2019 21:22:13 +0100 Subject: [Glitch] Cancel list scroll reset after mouse move on wheel scroll Port 9cfd610484541c14bcde3c368a158b9b5d2a6499 to glitch-soc --- .../flavours/glitch/components/scrollable_list.js | 41 +++++++++++----------- 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'app/javascript/flavours/glitch/components/scrollable_list.js') diff --git a/app/javascript/flavours/glitch/components/scrollable_list.js b/app/javascript/flavours/glitch/components/scrollable_list.js index 006c2a899..520749529 100644 --- a/app/javascript/flavours/glitch/components/scrollable_list.js +++ b/app/javascript/flavours/glitch/components/scrollable_list.js @@ -40,8 +40,6 @@ export default class ScrollableList extends PureComponent { state = { fullscreen: null, - mouseMovedRecently: false, - scrollToTopOnMouseIdle: false, }; intersectionObserverWrapper = new IntersectionObserverWrapper(); @@ -66,6 +64,8 @@ export default class ScrollableList extends PureComponent { }); mouseIdleTimer = null; + mouseMovedRecently = false; + scrollToTopOnMouseIdle = false; clearMouseIdleTimer = () => { if (this.mouseIdleTimer === null) { @@ -81,29 +81,26 @@ export default class ScrollableList extends PureComponent { this.mouseIdleTimer = setTimeout(this.handleMouseIdle, MOUSE_IDLE_DELAY); - this.setState(({ - mouseMovedRecently, - scrollToTopOnMouseIdle, - }) => ({ - mouseMovedRecently: true, - // Only set scrollToTopOnMouseIdle if we just started moving and were - // scrolled to the top. Otherwise, just retain the previous state. - scrollToTopOnMouseIdle: - mouseMovedRecently - ? scrollToTopOnMouseIdle - : (this.node.scrollTop === 0), - })); + if (!this.mouseMovedRecently && this.node.scrollTop === 0) { + // Only set if we just started moving and are scrolled to the top. + this.scrollToTopOnMouseIdle = true; + } + // Save setting this flag for last, so we can do the comparison above. + this.mouseMovedRecently = true; }, MOUSE_IDLE_DELAY / 2); + handleWheel = throttle(() => { + this.scrollToTopOnMouseIdle = false; + }, 150, { + trailing: true, + }); + handleMouseIdle = () => { - if (this.state.scrollToTopOnMouseIdle) { + if (this.scrollToTopOnMouseIdle) { this.node.scrollTop = 0; - this.props.onScrollToTop(); } - this.setState({ - mouseMovedRecently: false, - scrollToTopOnMouseIdle: false, - }); + this.mouseMovedRecently = false; + this.scrollToTopOnMouseIdle = false; } componentDidMount () { @@ -135,7 +132,7 @@ 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); - if ((someItemInserted && this.node.scrollTop > 0) || this.state.mouseMovedRecently) { + if ((someItemInserted && this.node.scrollTop > 0) || this.mouseMovedRecently) { return this.node.scrollHeight - this.node.scrollTop; } else { return null; @@ -172,10 +169,12 @@ export default class ScrollableList extends PureComponent { attachScrollListener () { this.node.addEventListener('scroll', this.handleScroll); + this.node.addEventListener('wheel', this.handleWheel); } detachScrollListener () { this.node.removeEventListener('scroll', this.handleScroll); + this.node.removeEventListener('wheel', this.handleWheel); } getFirstChildKey (props) { -- cgit