0
0
Fork 0

Change single-column mode to scroll the whole page (#11359)

Fix #10840
This commit is contained in:
Eugen Rochko 2019-07-19 09:25:22 +02:00 committed by GitHub
parent 4fa6472523
commit aa22b38fdb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 162 additions and 42 deletions

View file

@ -35,6 +35,7 @@ export default class ScrollableList extends PureComponent {
alwaysPrepend: PropTypes.bool,
emptyMessage: PropTypes.node,
children: PropTypes.node,
bindToDocument: PropTypes.bool,
};
static defaultProps = {
@ -50,7 +51,9 @@ export default class ScrollableList extends PureComponent {
handleScroll = throttle(() => {
if (this.node) {
const { scrollTop, scrollHeight, clientHeight } = this.node;
const scrollTop = this.getScrollTop();
const scrollHeight = this.getScrollHeight();
const clientHeight = this.getClientHeight();
const offset = scrollHeight - scrollTop - clientHeight;
if (400 > offset && this.props.onLoadMore && this.props.hasMore && !this.props.isLoading) {
@ -80,9 +83,14 @@ export default class ScrollableList extends PureComponent {
scrollToTopOnMouseIdle = false;
setScrollTop = newScrollTop => {
if (this.node.scrollTop !== newScrollTop) {
if (this.getScrollTop() !== newScrollTop) {
this.lastScrollWasSynthetic = true;
this.node.scrollTop = newScrollTop;
if (this.props.bindToDocument) {
document.scrollingElement.scrollTop = newScrollTop;
} else {
this.node.scrollTop = newScrollTop;
}
}
};
@ -100,7 +108,7 @@ export default class ScrollableList extends PureComponent {
this.clearMouseIdleTimer();
this.mouseIdleTimer = setTimeout(this.handleMouseIdle, MOUSE_IDLE_DELAY);
if (!this.mouseMovedRecently && this.node.scrollTop === 0) {
if (!this.mouseMovedRecently && this.getScrollTop() === 0) {
// Only set if we just started moving and are scrolled to the top.
this.scrollToTopOnMouseIdle = true;
}
@ -135,15 +143,27 @@ export default class ScrollableList extends PureComponent {
}
getScrollPosition = () => {
if (this.node && (this.node.scrollTop > 0 || this.mouseMovedRecently)) {
return { height: this.node.scrollHeight, top: this.node.scrollTop };
if (this.node && (this.getScrollTop() > 0 || this.mouseMovedRecently)) {
return { height: this.getScrollHeight(), top: this.getScrollTop() };
} else {
return null;
}
}
getScrollTop = () => {
return this.props.bindToDocument ? document.scrollingElement.scrollTop : this.node.scrollTop;
}
getScrollHeight = () => {
return this.props.bindToDocument ? document.scrollingElement.scrollHeight : this.node.scrollHeight;
}
getClientHeight = () => {
return this.props.bindToDocument ? document.scrollingElement.clientHeight : this.node.clientHeight;
}
updateScrollBottom = (snapshot) => {
const newScrollTop = this.node.scrollHeight - snapshot;
const newScrollTop = this.getScrollHeight() - snapshot;
this.setScrollTop(newScrollTop);
}
@ -153,8 +173,8 @@ export default class ScrollableList extends PureComponent {
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)) {
return this.node.scrollHeight - this.node.scrollTop;
if (someItemInserted && (this.getScrollTop() > 0 || this.mouseMovedRecently)) {
return this.getScrollHeight() - this.getScrollTop();
} else {
return null;
}
@ -164,7 +184,7 @@ export default class ScrollableList extends PureComponent {
// 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 (snapshot !== null) {
this.setScrollTop(this.node.scrollHeight - snapshot);
this.setScrollTop(this.getScrollHeight() - snapshot);
}
}
@ -197,13 +217,23 @@ export default class ScrollableList extends PureComponent {
}
attachScrollListener () {
this.node.addEventListener('scroll', this.handleScroll);
this.node.addEventListener('wheel', this.handleWheel);
if (this.props.bindToDocument) {
document.addEventListener('scroll', this.handleScroll);
document.addEventListener('wheel', this.handleWheel);
} else {
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);
if (this.props.bindToDocument) {
document.removeEventListener('scroll', this.handleScroll);
document.removeEventListener('wheel', this.handleWheel);
} else {
this.node.removeEventListener('scroll', this.handleScroll);
this.node.removeEventListener('wheel', this.handleWheel);
}
}
getFirstChildKey (props) {