diff --git a/components/post_view/post_list.jsx b/components/post_view/post_list.jsx
index 09214ce68287..512041e1f999 100644
--- a/components/post_view/post_list.jsx
+++ b/components/post_view/post_list.jsx
@@ -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';
@@ -25,6 +26,18 @@ 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 postListHeightChangeForPadding = 21;
+
+const virtListStyles = {
+ position: 'absolute',
+ bottom: '0',
+ maxHeight: '100%',
+};
+
+const postListStyle = {
+ padding: '14px 0px 7px', //21px of height difference from autosized list below at DynamicSizeList height change postListHeightChangeForPadding accordingly
+};
+
export default class PostList extends React.PureComponent {
static propTypes = {
@@ -101,6 +114,7 @@ export default class PostList extends React.PureComponent {
};
this.listRef = React.createRef();
+ this.postlistRef = React.createRef();
if (isMobile) {
this.scrollStopAction = new DelayedAction(this.handleScrollStop);
}
@@ -116,10 +130,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() {
@@ -196,7 +241,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});
}
@@ -317,8 +364,8 @@ export default class PostList extends React.PureComponent {
visibleStartIndex,
visibleStopIndex,
}) => {
- this.updateFloatingTimestamp(visibleStopIndex);
- this.checkBottom(visibleStartIndex);
+ this.updateFloatingTimestamp(visibleStartIndex);
+ this.checkBottom(visibleStopIndex);
}
initScrollToIndex = () => {
@@ -443,7 +490,7 @@ export default class PostList extends React.PureComponent {
{({height, width}) => (
{this.renderRow}
diff --git a/components/post_view/post_list.test.jsx b/components/post_view/post_list.test.jsx
index ccd36dd2b0db..dab20ab07cb8 100644
--- a/components/post_view/post_list.test.jsx
+++ b/components/post_view/post_list.test.jsx
@@ -116,6 +116,7 @@ describe('PostList', () => {
describe('initScrollToIndex', () => {
test('should return index of start of new messages and call increasePostVisibility when all posts are unread', () => {
+ baseProps.actions.increasePostVisibility.mockResolvedValue({moreToLoad: false});
const postListIds = [];
for (let i = 0; i < 30; i++) {
postListIds.push(`post${i}`);
@@ -152,4 +153,33 @@ describe('PostList', () => {
expect(wrapper.state('atEnd')).toEqual(true);
});
});
+
+ describe('onItemsRendered', () => {
+ test('should set state atBottom when not visibleStopIndex is not 0', async () => {
+ const wrapper = shallow();
+ wrapper.setState({atBottom: true});
+ wrapper.instance().onItemsRendered({visibleStartIndex: 4, visibleStopIndex: 1});
+ expect(wrapper.state('atBottom')).toEqual(false);
+ });
+ });
+
+ describe('store snapshot values on change of props for correcting scroll', () => {
+ test('Should call scrollTo when posts are added at the top', async () => {
+ const wrapper = shallow();
+ wrapper.instance().postlistRef = {
+ current: {
+ scrollTop: 1000,
+ scrollHeight: 4000,
+ },
+ };
+ wrapper.setProps({postListIds: [
+ 'post1',
+ 'post2',
+ 'post3',
+ 'post4',
+ DATE_LINE + 1551711600000,
+ ]});
+ wrapper.update();
+ });
+ });
});
diff --git a/components/post_view/show_more/show_more.jsx b/components/post_view/show_more/show_more.jsx
index 8de53a5058d8..3a04d3914647 100644
--- a/components/post_view/show_more/show_more.jsx
+++ b/components/post_view/show_more/show_more.jsx
@@ -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) => {
@@ -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 = () => {
diff --git a/package-lock.json b/package-lock.json
index ee54f3916a3b..8029a86197ec 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13059,8 +13059,8 @@
"integrity": "sha512-MYXhTY1BZpdJFjUovvYHVBmkq79szK/k7V3MO+36gJkWGkrXKtyr4vCPtpphaTLRAdDNoYEYFZWE8LjN+PIHNg=="
},
"react-window": {
- "version": "github:mattermost/react-window#22cab3a8a0f4e3793ba778a990f1c0723b4c8129",
- "from": "github:mattermost/react-window#22cab3a8a0f4e3793ba778a990f1c0723b4c8129",
+ "version": "github:mattermost/react-window#aa71079c988be134735060d890fecff1479ede2a",
+ "from": "github:mattermost/react-window#aa71079c988be134735060d890fecff1479ede2a",
"requires": {
"@babel/runtime": "^7.0.0",
"memoize-one": "^3.1.1"
diff --git a/package.json b/package.json
index 93c6d7839ceb..504c2906694b 100644
--- a/package.json
+++ b/package.json
@@ -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#aa71079c988be134735060d890fecff1479ede2a",
"rebound": "0.1.0",
"redux": "4.0.1",
"redux-batched-actions": "0.4.1",
diff --git a/sass/layout/_post.scss b/sass/layout/_post.scss
index c9bd90b1db70..d7ee1b117d93 100644
--- a/sass/layout/_post.scss
+++ b/sass/layout/_post.scss
@@ -284,7 +284,6 @@
}
.post-list-holder-by-time {
- -webkit-overflow-scrolling: touch;
height: 100%;
width: 100%;
position: absolute;
@@ -413,14 +412,6 @@
padding: 15px;
}
-.post-list__dynamic {
- > div {
- > div {
- margin-bottom: 8px;
- }
- }
-}
-
.post-create__container {
@include flex(0 0 auto);
width: 100%;
@@ -700,13 +691,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 {