From b740fcd254b56321951b250dc694005181695e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Mon, 18 Jun 2018 11:57:20 +0200 Subject: [PATCH 1/3] refactor GrowScroll to be performant --- package.json | 2 - src/components/StickyBackToTop.js | 34 +++--- src/components/base/GrowScroll/index.js | 139 +++++++++--------------- yarn.lock | 16 +-- 4 files changed, 71 insertions(+), 120 deletions(-) diff --git a/package.json b/package.json index 84f1a205..73a0d7c9 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,6 @@ "react-router-dom": "^4.3.1", "react-router-redux": "5.0.0-alpha.9", "react-select": "2.0.0-beta.6", - "react-smooth-scrollbar": "^8.0.6", "react-spring": "^5.3.15", "redux": "^4.0.0", "redux-actions": "^2.4.0", @@ -97,7 +96,6 @@ "secp256k1": "3.3.1", "semaphore": "^1.1.0", "semver": "^5.5.0", - "smooth-scrollbar": "^8.2.7", "source-map": "0.7.3", "source-map-support": "^0.5.4", "styled-components": "^3.3.2", diff --git a/src/components/StickyBackToTop.js b/src/components/StickyBackToTop.js index 2fce4cf1..9e106978 100644 --- a/src/components/StickyBackToTop.js +++ b/src/components/StickyBackToTop.js @@ -1,10 +1,10 @@ // @flow import React, { PureComponent } from 'react' import ReactDOM from 'react-dom' -import PropTypes from 'prop-types' import styled from 'styled-components' import Box from 'components/base/Box' import AngleUp from 'icons/AngleUp' +import { GrowScrollContext } from './base/GrowScroll' const Container = styled(Box)` position: fixed; @@ -29,6 +29,7 @@ const Container = styled(Box)` type Props = { scrollThreshold: number, + getGrowScroll: () => { scrollContainer: ?HTMLDivElement }, } type State = { @@ -36,11 +37,6 @@ type State = { } class StickyBackToTop extends PureComponent { - static contextTypes = { - // FIXME when we move to "real" scroll container, potential solution (instead of context): http://greweb.me/2016/09/relay-scrolling-connections/ - getScrollbar: PropTypes.func, - } - static defaultProps = { scrollThreshold: 800, } @@ -50,10 +46,10 @@ class StickyBackToTop extends PureComponent { } componentDidMount() { - if (!this.context.getScrollbar) return - this.context.getScrollbar(scrollbar => { + const { scrollContainer } = this.props.getGrowScroll() + if (scrollContainer) { const listener = () => { - const { scrollTop } = scrollbar + const { scrollTop } = scrollContainer const visible = scrollTop > this.props.scrollThreshold this.setState(previous => { if (previous.visible !== visible) { @@ -62,9 +58,9 @@ class StickyBackToTop extends PureComponent { return null }) } - scrollbar.addListener(listener) - this.releaseListener = () => scrollbar.removeListener(listener) - }) + scrollContainer.addEventListener('scroll', listener) + this.releaseListener = () => scrollContainer.addEventListener('scroll', listener) + } } componentWillUnmount() { @@ -72,9 +68,11 @@ class StickyBackToTop extends PureComponent { } onClick = () => { - this.context.getScrollbar(scrollbar => { - scrollbar.scrollTo(0, 0, 400) - }) + const { scrollContainer } = this.props.getGrowScroll() + if (scrollContainer) { + // $FlowFixMe seems to be missing in flow + scrollContainer.scrollTo(0, 0) + } } releaseListener = () => {} @@ -92,4 +90,8 @@ class StickyBackToTop extends PureComponent { } } -export default StickyBackToTop +export default (props: { scrollThreshold?: number }) => ( + + {getGrowScroll => } + +) diff --git a/src/components/base/GrowScroll/index.js b/src/components/base/GrowScroll/index.js index a4d154f1..a2686a07 100644 --- a/src/components/base/GrowScroll/index.js +++ b/src/components/base/GrowScroll/index.js @@ -1,116 +1,79 @@ // @flow -/* eslint-disable class-methods-use-this */ - import React, { PureComponent } from 'react' -import Scrollbar from 'react-smooth-scrollbar' -import SmoothScrollbar, { ScrollbarPlugin } from 'smooth-scrollbar' - import Box from 'components/base/Box' type Props = { children: any, full: boolean, maxHeight?: number, - onUpdate?: (*) => void, - onScroll?: () => void, } -// TODO this component is the source of junky scroll experience. need better solution ASAP +export const GrowScrollContext = React.createContext() + class GrowScroll extends PureComponent { static defaultProps = { full: false, } - componentDidMount() { - const { onUpdate, onScroll } = this.props - const { _scrollbar } = this - if (_scrollbar) { - if (onUpdate) { - onUpdate(_scrollbar) - } - if (onScroll) { - _scrollbar.addListener(this.onScroll) - } - } - } - - componentWillUnmount() { - const { onScroll } = this.props - const { _scrollbar } = this - if (_scrollbar && onScroll) { - _scrollbar.removeListener(this.onScroll) - } - } + scrollContainer: ?HTMLDivElement - componenDidUpdate() { - const { onUpdate } = this.props - const { _scrollbar } = this - if (_scrollbar && onUpdate) { - onUpdate(_scrollbar) - } + onScrollContainerRef = (scrollContainer: ?HTMLDivElement) => { + this.scrollContainer = scrollContainer } - onScroll = () => { - const { onScroll } = this.props - if (onScroll) onScroll() - } - - onRef = (ref: ?Scrollbar) => { - this._scrollbar = ref && ref.scrollbar - } - - _scrollbar: * + valueProvider = () => ({ + scrollContainer: this.scrollContainer, + }) render() { - const { onUpdate, children, maxHeight, full, ...props } = this.props + const { children, maxHeight, full, ...props } = this.props + + const rootStyles = { + overflow: 'hidden', + ...(full + ? { + top: 0, + left: 0, + right: 0, + bottom: 0, + } + : { + display: 'flex', + flex: 1, + positoin: 'relative', + }), + } + + const scrollContainerStyles = { + overflowY: 'auto', + marginRight: `-80px`, + paddingRight: `80px`, + ...(maxHeight + ? { + maxHeight, + } + : { + bottom: 0, + left: 0, + position: 'absolute', + right: 0, + top: 0, + }), + } return ( - - - {children} - - +
+
+ + + {children} + + +
+
) } } -SmoothScrollbar.use( - class DisableXScroll extends ScrollbarPlugin { - static pluginName = 'disableXScroll' - - transformDelta(delta) { - return { - x: 0, - y: delta.y, - } - } - }, -) - export default GrowScroll diff --git a/yarn.lock b/yarn.lock index 93960899..def68bad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4634,7 +4634,7 @@ core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" -core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0, core-js@^2.5.1, core-js@^2.5.3, core-js@^2.5.6: +core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0, core-js@^2.5.3, core-js@^2.5.6: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" @@ -11664,10 +11664,6 @@ react-select@2.0.0-beta.6: react-input-autosize "^2.2.1" react-transition-group "^2.2.1" -react-smooth-scrollbar@^8.0.6: - version "8.0.6" - resolved "https://registry.yarnpkg.com/react-smooth-scrollbar/-/react-smooth-scrollbar-8.0.6.tgz#179072e6a547b3af589ea303c50fd86366275edc" - react-split-pane@^0.1.77: version "0.1.77" resolved "https://registry.yarnpkg.com/react-split-pane/-/react-split-pane-0.1.77.tgz#f0c8cd18d076bbac900248dcf6dbcec02d5340db" @@ -12812,14 +12808,6 @@ smart-buffer@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.1.tgz#07ea1ca8d4db24eb4cac86537d7d18995221ace3" -smooth-scrollbar@^8.2.7: - version "8.2.7" - resolved "https://registry.yarnpkg.com/smooth-scrollbar/-/smooth-scrollbar-8.2.7.tgz#41a3f84ee4677ae7a417081e3384e1e15ebcdb86" - dependencies: - core-js "^2.5.1" - lodash-es "^4.17.4" - tslib "^1.7.1" - snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -13697,7 +13685,7 @@ tryer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.0.tgz#027b69fa823225e551cace3ef03b11f6ab37c1d7" -tslib@^1.7.1, tslib@^1.9.0: +tslib@^1.9.0: version "1.9.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.2.tgz#8be0cc9a1f6dc7727c38deb16c2ebd1a2892988e" From 68b27f290bb9a77528056d039c5ab51d99e4cc00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Mon, 18 Jun 2018 12:18:31 +0200 Subject: [PATCH 2/3] add overflow:hidden on app container to ensure there is no scrollbar --- src/components/base/Box/Box.js | 1 + src/components/layout/Default.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/base/Box/Box.js b/src/components/base/Box/Box.js index 48f6246e..5ded4f57 100644 --- a/src/components/base/Box/Box.js +++ b/src/components/base/Box/Box.js @@ -40,6 +40,7 @@ export default styled.div` flex-grow: ${p => (p.grow === true ? '1' : p.grow || '')}; flex-direction: ${p => (p.horizontal ? 'row' : 'column')}; + overflow: ${p => p.overflow}; overflow-y: ${p => (p.scroll === true ? 'auto' : '')}; position: ${p => (p.relative ? 'relative' : p.sticky ? 'absolute' : '')}; diff --git a/src/components/layout/Default.js b/src/components/layout/Default.js index 6ff41afe..a11652ab 100644 --- a/src/components/layout/Default.js +++ b/src/components/layout/Default.js @@ -74,7 +74,7 @@ class Default extends Component { - +
(this._scrollContainer = n)} tabIndex={-1}> From ee35b0b6041a09c8a9115a6feed8a090431808b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Mon, 18 Jun 2018 12:19:11 +0200 Subject: [PATCH 3/3] put back MIN_HEIGHT to 768 --- src/main/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/app.js b/src/main/app.js index 068fdfa1..116a4307 100644 --- a/src/main/app.js +++ b/src/main/app.js @@ -67,7 +67,7 @@ const defaultWindowOptions = { } function createMainWindow() { - const MIN_HEIGHT = 720 + const MIN_HEIGHT = 768 const MIN_WIDTH = 1024 const savedDimensions = db.getIn('settings', 'window.MainWindow.dimensions', {})