diff --git a/components/file_attachment/__snapshots__/file_attachment.test.jsx.snap b/components/file_attachment/__snapshots__/file_attachment.test.jsx.snap index b4f1f1b7adeb..22f39d638cad 100644 --- a/components/file_attachment/__snapshots__/file_attachment.test.jsx.snap +++ b/components/file_attachment/__snapshots__/file_attachment.test.jsx.snap @@ -9,8 +9,17 @@ exports[`component/FileAttachment should match snapshot, after change from file href="#" onClick={[Function]} > -
{ - this.updateFloatingTimestamp(visibleStopIndex); - this.checkBottom(visibleStartIndex); + this.updateFloatingTimestamp(visibleStartIndex); + this.checkBottom(visibleStopIndex); } initScrollToIndex = () => { @@ -443,7 +488,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..3ff1e6cbf297 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,43 @@ describe('PostList', () => { expect(wrapper.state('atEnd')).toEqual(true); }); }); + + describe('onItemsRendered', () => { + test('should set state atBottom false when visibleStopIndex is not 0', () => { + const wrapper = shallow(); + wrapper.setState({atBottom: true}); + wrapper.instance().onItemsRendered({visibleStartIndex: 4, visibleStopIndex: 1}); + expect(wrapper.state('atBottom')).toEqual(false); + }); + }); + describe('Scroll correction logic on mount of posts at the top', () => { + test('should return previous scroll position from getSnapshotBeforeUpdate', () => { + const wrapper = shallow(); + const instance = wrapper.instance(); + instance.componentDidUpdate = jest.fn(); + + instance.postlistRef = {current: {scrollTop: 10, scrollHeight: 100}}; + wrapper.setState({atEnd: true}); + expect(instance.componentDidUpdate).toHaveBeenCalledTimes(1); + expect(instance.componentDidUpdate.mock.calls[0][2]).toEqual({previousScrollTop: 10, previousScrollHeight: 100}); + + instance.postlistRef = {current: {scrollTop: 30, scrollHeight: 200}}; + wrapper.setState({atEnd: false}); + expect(instance.componentDidUpdate).toHaveBeenCalledTimes(2); + expect(instance.componentDidUpdate.mock.calls[1][2]).toEqual({previousScrollTop: 30, previousScrollHeight: 200}); + + instance.postlistRef = {current: {scrollTop: 40, scrollHeight: 400}}; + wrapper.setProps({postListIds: [ + 'post1', + 'post2', + 'post3', + 'post4', + 'post5', + DATE_LINE + 1551711600000, + ]}); + + expect(instance.componentDidUpdate).toHaveBeenCalledTimes(3); + expect(instance.componentDidUpdate.mock.calls[2][2]).toEqual({previousScrollTop: 40, previousScrollHeight: 400}); + }); + }); }); 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..40f12d2f3a5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2192,12 +2192,6 @@ "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, - "array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=", - "dev": true - }, "array-find": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-find/-/array-find-1.0.0.tgz", @@ -3438,13 +3432,13 @@ "dev": true }, "cheerio": { - "version": "1.0.0-rc.2", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz", - "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=", + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", + "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", "dev": true, "requires": { "css-select": "~1.2.0", - "dom-serializer": "~0.1.0", + "dom-serializer": "~0.1.1", "entities": "~1.1.1", "htmlparser2": "^3.9.1", "lodash": "^4.15.0", @@ -4984,20 +4978,18 @@ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" }, "enzyme": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.9.0.tgz", - "integrity": "sha512-JqxI2BRFHbmiP7/UFqvsjxTirWoM1HfeaJrmVSZ9a1EADKkZgdPcAuISPMpoUiHlac9J4dYt81MC5BBIrbJGMg==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.8.0.tgz", + "integrity": "sha512-bfsWo5nHyZm1O1vnIsbwdfhU989jk+squU9NKvB+Puwo5j6/Wg9pN5CO0YJelm98Dao3NPjkDZk+vvgwpMwYxw==", "dev": true, "requires": { "array.prototype.flat": "^1.2.1", "cheerio": "^1.0.0-rc.2", "function.prototype.name": "^1.1.0", "has": "^1.0.3", - "html-element-map": "^1.0.0", "is-boolean-object": "^1.0.0", "is-callable": "^1.1.4", "is-number-object": "^1.0.3", - "is-regex": "^1.0.4", "is-string": "^1.0.4", "is-subset": "^0.1.1", "lodash.escape": "^4.0.1", @@ -7729,15 +7721,6 @@ "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", "dev": true }, - "html-element-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.0.0.tgz", - "integrity": "sha512-/SP6aOiM5Ai9zALvCxDubIeez0LvG3qP7R9GcRDnJEP/HBmv0A8A9K0o8+HFudcFt46+i921ANjzKsjPjb7Enw==", - "dev": true, - "requires": { - "array-filter": "^1.0.0" - } - }, "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", @@ -13059,8 +13042,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#cfb30dc14b065c10a93f3418006408d84c31a80f", + "from": "github:mattermost/react-window#cfb30dc14b065c10a93f3418006408d84c31a80f", "requires": { "@babel/runtime": "^7.0.0", "memoize-one": "^3.1.1" diff --git a/package.json b/package.json index 93c6d7839ceb..b7edba4538e7 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#cfb30dc14b065c10a93f3418006408d84c31a80f", "rebound": "0.1.0", "redux": "4.0.1", "redux-batched-actions": "0.4.1", @@ -84,7 +84,7 @@ "cross-env": "5.2.0", "css-loader": "2.1.1", "cypress": "3.2.0", - "enzyme": "3.9.0", + "enzyme": "3.8.0", "enzyme-adapter-react-16": "1.11.2", "enzyme-to-json": "3.3.5", "eslint": "5.15.3", 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 {