diff --git a/src/components/structures/RoomSubList.js b/src/components/structures/RoomSubList.js
index ba61bb5ad1..e5a96d0923 100644
--- a/src/components/structures/RoomSubList.js
+++ b/src/components/structures/RoomSubList.js
@@ -61,14 +61,14 @@ const RoomSubList = React.createClass({
getInitialState: function() {
// throttle updates to LazyRenderList
- this._onScroll = _.throttle(
- this._onScroll, 100,
- {leading: false, trailing: true},
- );
- this._updateLazyRenderHeight = _.throttle(
- this._updateLazyRenderHeight, 100,
- {leading: false, trailing: true},
- );
+ // this._onScroll = _.throttle(
+ // this._onScroll, 50,
+ // {leading: false, trailing: true},
+ // );
+ // this._updateLazyRenderHeight = _.throttle(
+ // this._updateLazyRenderHeight, 100,
+ // {leading: false, trailing: true},
+ // );
return {
hidden: this.props.startAsHidden || false,
// some values to get LazyRenderList starting
@@ -307,7 +307,7 @@ const RoomSubList = React.createClass({
{this._getHeaderJsx(isCollapsed)}
;
} else {
- const items = this.props.list.concat(this.props.extraTiles);
+ const items = this.props.list; //.concat(this.props.extraTiles);
return
{this._getHeaderJsx(isCollapsed)}
diff --git a/src/components/views/elements/LazyRenderList.js b/src/components/views/elements/LazyRenderList.js
index 69abc34128..ec56b9a532 100644
--- a/src/components/views/elements/LazyRenderList.js
+++ b/src/components/views/elements/LazyRenderList.js
@@ -14,20 +14,79 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-const OVERFLOW_ITEMS = 2;
+import React from "react";
-export default function LazyRenderList(props) {
- const {items, itemHeight, scrollTop, height, renderItem} = props;
+const OVERFLOW_ITEMS = 20;
+const OVERFLOW_MARGIN = 5;
- const firstIdx = Math.max(0, Math.floor(scrollTop / itemHeight) - OVERFLOW_ITEMS);
- const itemsAfterFirst = items.length - firstIdx;
- const amount = Math.min(Math.ceil(height / itemHeight) + OVERFLOW_ITEMS, itemsAfterFirst);
- const beforeSpace = firstIdx * itemHeight;
- const itemsAfter = itemsAfterFirst - amount;
- const afterSpace = itemsAfter * itemHeight;
- const renderedItems = items.slice(firstIdx, firstIdx + amount);
+class ItemRange {
+ constructor(topCount, renderCount, bottomCount) {
+ this.topCount = topCount;
+ this.renderCount = renderCount;
+ this.bottomCount = bottomCount;
+ }
- return (
- { renderedItems.map(renderItem) }
-
);
+ contains(range) {
+ return range.topCount >= this.topCount &&
+ (range.topCount + range.renderCount) <= (this.topCount + this.renderCount);
+ }
+
+ expand(amount) {
+ const topGrow = Math.min(amount, this.topCount);
+ const bottomGrow = Math.min(amount, this.bottomCount);
+ return new ItemRange(
+ this.topCount - topGrow,
+ this.renderCount + topGrow + bottomGrow,
+ this.bottomCount - bottomGrow,
+ );
+ }
+}
+
+export default class LazyRenderList extends React.Component {
+ constructor(props) {
+ super(props);
+ const renderRange = LazyRenderList.getVisibleRangeFromProps(props).expand(OVERFLOW_ITEMS);
+ this.state = {renderRange};
+ }
+
+ static getVisibleRangeFromProps(props) {
+ const {items, itemHeight, scrollTop, height} = props;
+ const length = items ? items.length : 0;
+ const topCount = Math.max(0, Math.floor(scrollTop / itemHeight));
+ const itemsAfterTop = length - topCount;
+ const renderCount = Math.min(Math.ceil(height / itemHeight), itemsAfterTop);
+ const bottomCount = itemsAfterTop - renderCount;
+ return new ItemRange(topCount, renderCount, bottomCount);
+ }
+
+ componentWillReceiveProps(props) {
+ const state = this.state;
+ const range = LazyRenderList.getVisibleRangeFromProps(props);
+ // only update state if the new range isn't contained by the old anymore
+ if (!state.renderRange || !state.renderRange.contains(range.expand(OVERFLOW_MARGIN))) {
+ this.setState({renderRange: range.expand(OVERFLOW_ITEMS)});
+ }
+ }
+
+ shouldComponentUpdate(nextProps, nextState) {
+ const itemsChanged = nextProps.items !== this.props.items;
+ const rangeChanged = nextState.renderRange !== this.state.renderRange;
+ return itemsChanged || rangeChanged;
+ }
+
+ render() {
+ const {itemHeight, items, renderItem} = this.props;
+
+ const {renderRange} = this.state;
+ const paddingTop = renderRange.topCount * itemHeight;
+ const paddingBottom = renderRange.bottomCount * itemHeight;
+ const renderedItems = items.slice(
+ renderRange.topCount,
+ renderRange.topCount + renderRange.renderCount,
+ );
+
+ return (
+ { renderedItems.map(renderItem) }
+
);
+ }
}