From 21f27e6579af4bdadb063a4500cfe86cc5b24a1f Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Tue, 8 Jan 2019 21:21:46 +0100 Subject: [Glitch] Temporarily hold timeline if mouse moved recently Port 6a1216d2cd1c26c22baf86ae618a62aa66817239 to glitch-soc --- .../flavours/glitch/components/scrollable_list.js | 50 +++++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'app/javascript/flavours/glitch/components') diff --git a/app/javascript/flavours/glitch/components/scrollable_list.js b/app/javascript/flavours/glitch/components/scrollable_list.js index 21d717b81..006c2a899 100644 --- a/app/javascript/flavours/glitch/components/scrollable_list.js +++ b/app/javascript/flavours/glitch/components/scrollable_list.js @@ -10,6 +10,8 @@ import classNames from 'classnames'; import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from 'flavours/glitch/util/fullscreen'; import LoadingIndicator from './loading_indicator'; +const MOUSE_IDLE_DELAY = 300; + export default class ScrollableList extends PureComponent { static contextTypes = { @@ -38,6 +40,8 @@ export default class ScrollableList extends PureComponent { state = { fullscreen: null, + mouseMovedRecently: false, + scrollToTopOnMouseIdle: false, }; intersectionObserverWrapper = new IntersectionObserverWrapper(); @@ -61,6 +65,47 @@ export default class ScrollableList extends PureComponent { trailing: true, }); + mouseIdleTimer = null; + + clearMouseIdleTimer = () => { + if (this.mouseIdleTimer === null) { + return; + } + clearTimeout(this.mouseIdleTimer); + this.mouseIdleTimer = null; + }; + + handleMouseMove = throttle(() => { + // As long as the mouse keeps moving, clear and restart the idle timer. + this.clearMouseIdleTimer(); + 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), + })); + }, MOUSE_IDLE_DELAY / 2); + + handleMouseIdle = () => { + if (this.state.scrollToTopOnMouseIdle) { + this.node.scrollTop = 0; + this.props.onScrollToTop(); + } + this.setState({ + mouseMovedRecently: false, + scrollToTopOnMouseIdle: false, + }); + } + componentDidMount () { this.attachScrollListener(); this.attachIntersectionObserver(); @@ -90,7 +135,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) { + if ((someItemInserted && this.node.scrollTop > 0) || this.state.mouseMovedRecently) { return this.node.scrollHeight - this.node.scrollTop; } else { return null; @@ -104,6 +149,7 @@ export default class ScrollableList extends PureComponent { } componentWillUnmount () { + this.clearMouseIdleTimer(); this.detachScrollListener(); this.detachIntersectionObserver(); detachFullscreenListener(this.onFullScreenChange); @@ -181,7 +227,7 @@ export default class ScrollableList extends PureComponent { ); } else if (isLoading || childrenCount > 0 || hasMore || !emptyMessage) { scrollableArea = ( -
+
{prepend} -- cgit 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') 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 From 825decbf9ecfb60228cfa292a5d94d0ddc9d5998 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Tue, 8 Jan 2019 21:26:23 +0100 Subject: [Glitch] Identify manual scrolling to cancel scroll to top reset on mouse idle Port 2f86fc5e0a45eb2002d4b481ae093197ad523479 to glitch-soc --- .../flavours/glitch/components/scrollable_list.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'app/javascript/flavours/glitch/components') diff --git a/app/javascript/flavours/glitch/components/scrollable_list.js b/app/javascript/flavours/glitch/components/scrollable_list.js index 520749529..09a22f633 100644 --- a/app/javascript/flavours/glitch/components/scrollable_list.js +++ b/app/javascript/flavours/glitch/components/scrollable_list.js @@ -58,6 +58,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, @@ -65,8 +72,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; @@ -97,7 +112,7 @@ export default class ScrollableList extends PureComponent { handleMouseIdle = () => { if (this.scrollToTopOnMouseIdle) { - this.node.scrollTop = 0; + this.setScrollTop(0); } this.mouseMovedRecently = false; this.scrollToTopOnMouseIdle = false; @@ -123,9 +138,7 @@ export default class ScrollableList extends PureComponent { updateScrollBottom = (snapshot) => { const newScrollTop = this.node.scrollHeight - snapshot; - if (this.node.scrollTop !== newScrollTop) { - this.node.scrollTop = newScrollTop; - } + this.setScrollTop(newScrollTop); } getSnapshotBeforeUpdate (prevProps, prevState) { -- cgit From e8ae77236be07935c0dd03795d9de1db71d4283e Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Tue, 8 Jan 2019 21:29:49 +0100 Subject: [Glitch] Only consider mouse move in scrolling on item insertion Port cc1f13dfd0d9fee7d568918af031f1cd6d1441f4 to glitch-soc --- app/javascript/flavours/glitch/components/scrollable_list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/javascript/flavours/glitch/components') diff --git a/app/javascript/flavours/glitch/components/scrollable_list.js b/app/javascript/flavours/glitch/components/scrollable_list.js index 09a22f633..7cd0774a9 100644 --- a/app/javascript/flavours/glitch/components/scrollable_list.js +++ b/app/javascript/flavours/glitch/components/scrollable_list.js @@ -145,7 +145,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.mouseMovedRecently) { + if (someItemInserted && (this.node.scrollTop > 0 || this.mouseMovedRecently)) { return this.node.scrollHeight - this.node.scrollTop; } else { return null; -- cgit From 147f4f9fd2163a2f6ebb1e4bb12aae9146835431 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Thu, 10 Jan 2019 20:22:28 +0100 Subject: [Glitch] refactored account.js Port 57c91fbbed7fa5f44c7144194e313f003c2ef8b3 to glitch-soc --- app/javascript/flavours/glitch/components/account.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/javascript/flavours/glitch/components') diff --git a/app/javascript/flavours/glitch/components/account.js b/app/javascript/flavours/glitch/components/account.js index 80f20b8ad..072c601e0 100644 --- a/app/javascript/flavours/glitch/components/account.js +++ b/app/javascript/flavours/glitch/components/account.js @@ -67,10 +67,10 @@ export default class Account extends ImmutablePureComponent { if (hidden) { return ( -
+ {account.get('display_name')} {account.get('username')} -
+ ); } -- cgit From e03813cf0a6c4261fa97403e453a54ff051a6f87 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Thu, 10 Jan 2019 20:25:12 +0100 Subject: [Glitch] Stop gifv timeline preview explicitly when open the media gallery Port cf3c0fc38cd2650a421f46a5f221d1d645ef6c7b to glitch-soc --- app/javascript/flavours/glitch/components/media_gallery.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'app/javascript/flavours/glitch/components') diff --git a/app/javascript/flavours/glitch/components/media_gallery.js b/app/javascript/flavours/glitch/components/media_gallery.js index 10afeb2eb..d0226bbbb 100644 --- a/app/javascript/flavours/glitch/components/media_gallery.js +++ b/app/javascript/flavours/glitch/components/media_gallery.js @@ -71,6 +71,10 @@ class Item extends React.PureComponent { const { index, onClick } = this.props; if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { + if (this.hoverToPlay()) { + e.target.pause(); + e.target.currentTime = 0; + } e.preventDefault(); onClick(index); } -- cgit