Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
MM-14949 Correct scroll when new posts are loaded
Browse files Browse the repository at this point in the history
* Check for state change in posts instead of props
* Correct scroll when posts change at top or when header changes
* use snapshot for taking height before updating postslist
  • Loading branch information
sudheerDev committed Apr 29, 2019
1 parent 20233ab commit d65cf0f
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 32 deletions.
59 changes: 50 additions & 9 deletions components/post_view/post_list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import PropTypes from 'prop-types';
import React from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
import {DynamicSizeList} from 'react-window';
import {debounce} from 'mattermost-redux/actions/helpers';

import LoadingScreen from 'components/loading_screen.jsx';

Expand All @@ -25,6 +26,12 @@ const OVERSCAN_COUNT_BACKWARD = window.OVERSCAN_COUNT_BACKWARD || 50; // Exposin
const OVERSCAN_COUNT_FORWARD = window.OVERSCAN_COUNT_FORWARD || 100; // Exposing the value for PM to test will be removed soon
const HEIGHT_TRIGGER_FOR_MORE_POSTS = window.HEIGHT_TRIGGER_FOR_MORE_POSTS || 1000; // Exposing the value for PM to test will be removed soon

const virtListStyles = {
position: 'absolute',
bottom: '0',
maxHeight: '100%',
};

export default class PostList extends React.PureComponent {
static propTypes = {

Expand Down Expand Up @@ -96,11 +103,12 @@ export default class PostList extends React.PureComponent {
topPostId: '',
postMenuOpened: false,
dynamicListStyle: {
willChange: 'transform',
willChange: 'transform',
},
};

this.listRef = React.createRef();
this.postlistRef = React.createRef();
if (isMobile) {
this.scrollStopAction = new DelayedAction(this.handleScrollStop);
}
Expand All @@ -116,10 +124,41 @@ export default class PostList extends React.PureComponent {
window.addEventListener('resize', this.handleWindowResize);
}

componentDidUpdate(prevProps) {
getSnapshotBeforeUpdate(prevProps, prevState) {
if (this.postlistRef && this.postlistRef.current) {
const postsAddedAtTop = this.state.postListIds.length !== prevState.postListIds.length && this.state.postListIds[0] === prevState.postListIds[0];
const channelHeaderAdded = this.state.atEnd !== prevState.atEnd && this.state.postListIds.length === prevState.postListIds.length;
if (postsAddedAtTop || channelHeaderAdded) {
const previousScrollTop = this.postlistRef.current.scrollTop;
const previousScrollHeight = this.postlistRef.current.scrollHeight;

return {
previousScrollTop,
previousScrollHeight,
};
}
}
return null;
}

componentDidUpdate(prevProps, prevState, snapshot) {
if (prevProps.channelLoading && !this.props.channelLoading) {
this.loadPosts(this.props.channel.id, this.props.focusedPostId);
}

if (!this.postlistRef.current || !snapshot) {
return;
}

const postlistScrollHeight = this.postlistRef.current.scrollHeight;
const postsAddedAtTop = this.state.postListIds.length !== prevState.postListIds.length && this.state.postListIds[0] === prevState.postListIds[0];
const channelHeaderAdded = this.state.atEnd !== prevState.atEnd && this.state.postListIds.length === prevState.postListIds.length;
if (postsAddedAtTop || channelHeaderAdded) {
const scrollValue = snapshot.previousScrollTop + (postlistScrollHeight - snapshot.previousScrollHeight);
if (scrollValue !== 0 && (scrollValue - snapshot.previousScrollTop) !== 0) {
this.listRef.current.scrollTo(scrollValue, scrollValue - snapshot.previousScrollTop, !this.state.atEnd);
}
}
}

componentWillUnmount() {
Expand Down Expand Up @@ -196,7 +235,9 @@ export default class PostList extends React.PureComponent {
if (error) {
if (this.autoRetriesCount < MAX_NUMBER_OF_AUTO_RETRIES) {
this.autoRetriesCount++;
this.loadMorePosts();
debounce(() => {
this.loadMorePosts();
});
} else if (this.mounted) {
this.setState({autoRetryEnable: false});
}
Expand Down Expand Up @@ -255,11 +296,11 @@ export default class PostList extends React.PureComponent {
return postListIds[index] ? postListIds[index] : index;
}

onScroll = ({scrollDirection, scrollOffset, scrollUpdateWasRequested}) => {
onScroll = ({scrollDirection, scrollOffset, scrollUpdateWasRequested, scrollCorrectionInProgress}) => {
const isNotLoadingPosts = !this.state.loadingFirstSetOfPosts && !this.loadingMorePosts;
const didUserScrollBackwards = scrollDirection === 'backward' && !scrollUpdateWasRequested;
const isOffsetWithInRange = scrollOffset < HEIGHT_TRIGGER_FOR_MORE_POSTS;
if (isNotLoadingPosts && didUserScrollBackwards && isOffsetWithInRange && !this.state.atEnd) {
if (isNotLoadingPosts && didUserScrollBackwards && isOffsetWithInRange && !this.state.atEnd && !scrollCorrectionInProgress) {
this.loadMorePosts();
}

Expand Down Expand Up @@ -317,8 +358,8 @@ export default class PostList extends React.PureComponent {
visibleStartIndex,
visibleStopIndex,
}) => {
this.updateFloatingTimestamp(visibleStopIndex);
this.checkBottom(visibleStartIndex);
this.updateFloatingTimestamp(visibleStartIndex);
this.checkBottom(visibleStopIndex);
}

initScrollToIndex = () => {
Expand Down Expand Up @@ -454,10 +495,10 @@ export default class PostList extends React.PureComponent {
onScroll={this.onScroll}
onItemsRendered={this.onItemsRendered}
initScrollToIndex={this.initScrollToIndex}
onNewItemsMounted={this.onNewItemsMounted}
canLoadMorePosts={this.canLoadMorePosts}
skipResizeClass='col__reply'
style={dynamicListStyle}
innerRef={this.postlistRef}
style={{...virtListStyles, ...dynamicListStyle}}
>
{this.renderRow}
</DynamicSizeList>
Expand Down
28 changes: 18 additions & 10 deletions components/post_view/show_more/show_more.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ export default class ShowMore extends React.PureComponent {

componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
if (this.overflowRef) {
window.cancelAnimationFrame(this.overflowRef);
}
}

toggleCollapse = (e) => {
Expand All @@ -53,18 +56,23 @@ export default class ShowMore extends React.PureComponent {
};

checkTextOverflow = () => {
const textContainer = this.refs.textContainer;
let isOverflow = false;

if (textContainer && textContainer.scrollHeight > this.props.maxHeight) {
isOverflow = true;
if (this.overflowRef) {
window.cancelAnimationFrame(this.overflowRef);
}
this.overflowRef = window.requestAnimationFrame(() => {
const textContainer = this.refs.textContainer;
let isOverflow = false;

if (isOverflow !== this.state.isOverflow) {
this.setState({
isOverflow,
});
}
if (textContainer && textContainer.scrollHeight > this.props.maxHeight) {
isOverflow = true;
}

if (isOverflow !== this.state.isOverflow) {
this.setState({
isOverflow,
});
}
});
};

handleResize = () => {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"react-select": "2.4.2",
"react-transition-group": "2.7.1",
"react-virtualized-auto-sizer": "^1.0.2",
"react-window": "github:mattermost/react-window#22cab3a8a0f4e3793ba778a990f1c0723b4c8129",
"react-window": "github:mattermost/react-window#a0cd09a94058eec91bfe37019ac9fc3936afa50c",
"rebound": "0.1.0",
"redux": "4.0.1",
"redux-batched-actions": "0.4.1",
Expand Down
18 changes: 8 additions & 10 deletions sass/layout/_post.scss
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,6 @@
}

.post-list-holder-by-time {
-webkit-overflow-scrolling: touch;
height: 100%;
width: 100%;
position: absolute;
Expand Down Expand Up @@ -413,12 +412,12 @@
padding: 15px;
}

.post-list__dynamic {
> div {
> div {
margin-bottom: 8px;
}
}
.post-list__dynamic > div > div:last-child > div {
padding-bottom: 0.5em
}

.post-list__dynamic > div > div:first-child > div {
padding-top: 1em;
}

.post-create__container {
Expand Down Expand Up @@ -700,13 +699,12 @@

.post-list__table {
@include clearfix;
display: table;
height: 100%;
table-layout: fixed;
width: 100%;

.post-list__content {
display: table-cell;
height: 100%;
overflow: hidden;

.dropdown-menu {
&.bottom {
Expand Down

0 comments on commit d65cf0f

Please sign in to comment.