about summary refs log tree commit diff
path: root/app/javascript/mastodon/components/scrollable_list.js
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-09-09 02:26:41 +0200
committerGitHub <noreply@github.com>2017-09-09 02:26:41 +0200
commitbaa8b82179203a8c035dab23fbea48a0e6cfc886 (patch)
tree15089347edcb2ac67fcf209fdef37a9adf0329db /app/javascript/mastodon/components/scrollable_list.js
parent4b460bc57188c5dab31a921daed3c0012df28761 (diff)
Fix #1004 - Temporarily pause timeline if there's been recent mouse movement (#4859)
Diffstat (limited to 'app/javascript/mastodon/components/scrollable_list.js')
-rw-r--r--app/javascript/mastodon/components/scrollable_list.js21
1 files changed, 19 insertions, 2 deletions
diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.js
index e47b1e9aa..42763ddd3 100644
--- a/app/javascript/mastodon/components/scrollable_list.js
+++ b/app/javascript/mastodon/components/scrollable_list.js
@@ -27,6 +27,10 @@ export default class ScrollableList extends PureComponent {
     trackScroll: true,
   };
 
+  state = {
+    lastMouseMove: null,
+  };
+
   intersectionObserverWrapper = new IntersectionObserverWrapper();
 
   handleScroll = throttle(() => {
@@ -47,6 +51,14 @@ export default class ScrollableList extends PureComponent {
     trailing: true,
   });
 
+  handleMouseMove = throttle(() => {
+    this.setState({ lastMouseMove: new Date() });
+  }, 300);
+
+  handleMouseLeave = () => {
+    this.setState({ lastMouseMove: null });
+  }
+
   componentDidMount () {
     this.attachScrollListener();
     this.attachIntersectionObserver();
@@ -58,9 +70,10 @@ export default class ScrollableList extends PureComponent {
   componentDidUpdate (prevProps) {
     // 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 (React.Children.count(prevProps.children) < React.Children.count(this.props.children) && this._oldScrollPosition && this.node.scrollTop > 0) {
+    if (React.Children.count(prevProps.children) < React.Children.count(this.props.children) && this._oldScrollPosition && (this.node.scrollTop > 0 || this._recentlyMoved())) {
       if (this.getFirstChildKey(prevProps) !== this.getFirstChildKey(this.props)) {
         const newScrollTop = this.node.scrollHeight - this._oldScrollPosition;
+
         if (this.node.scrollTop !== newScrollTop) {
           this.node.scrollTop = newScrollTop;
         }
@@ -114,6 +127,10 @@ export default class ScrollableList extends PureComponent {
     this.props.onScrollToBottom();
   }
 
+  _recentlyMoved () {
+    return this.state.lastMouseMove === null || ((new Date()) - this.state.lastMouseMove < 600);
+  }
+
   handleKeyDown = (e) => {
     if (['PageDown', 'PageUp'].includes(e.key) || (e.ctrlKey && ['End', 'Home'].includes(e.key))) {
       const article = (() => {
@@ -149,7 +166,7 @@ export default class ScrollableList extends PureComponent {
 
     if (isLoading || childrenCount > 0 || !emptyMessage) {
       scrollableArea = (
-        <div className='scrollable' ref={this.setRef}>
+        <div className='scrollable' ref={this.setRef} onMouseMove={this.handleMouseMove} onMouseLeave={this.handleMouseLeave}>
           <div role='feed' className='item-list' onKeyDown={this.handleKeyDown}>
             {prepend}