Skip to content

Commit

Permalink
Cancel list scroll reset after mouse move on wheel scroll (#9233)
Browse files Browse the repository at this point in the history
- Use object properties rather than component state for
  mouseMovedRecently and scrollToTopOnMouseIdle flags

- Remove redundant scrollToTop prop call, also fixing an attempt to call
  an undefined prop.

Fixes #9217
  • Loading branch information
lmorchard authored and Gargron committed Nov 8, 2018
1 parent b22db81 commit 9cfd610
Showing 1 changed file with 20 additions and 21 deletions.
41 changes: 20 additions & 21 deletions app/javascript/mastodon/components/scrollable_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ export default class ScrollableList extends PureComponent {

state = {
fullscreen: null,
mouseMovedRecently: false,
scrollToTopOnMouseIdle: false,
};

intersectionObserverWrapper = new IntersectionObserverWrapper();
Expand All @@ -65,6 +63,8 @@ export default class ScrollableList extends PureComponent {
});

mouseIdleTimer = null;
mouseMovedRecently = false;
scrollToTopOnMouseIdle = false;

clearMouseIdleTimer = () => {
if (this.mouseIdleTimer === null) {
Expand All @@ -80,29 +80,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 () {
Expand All @@ -118,7 +115,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;
Expand Down Expand Up @@ -161,10 +158,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) {
Expand Down

0 comments on commit 9cfd610

Please sign in to comment.