diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index 58ebf54bf7..6682527254 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -91,6 +91,12 @@ export default class RoomSublist2 extends React.Component { return (this.props.rooms || []).length; } + private get numVisibleTiles(): number { + if (!this.props.layout) return 0; + const nVisible = Math.floor(this.props.layout.visibleTiles); + return Math.min(nVisible, this.numTiles); + } + public componentDidUpdate() { this.state.notificationState.setRooms(this.props.rooms); } @@ -107,7 +113,7 @@ export default class RoomSublist2 extends React.Component { private onResize = (e: React.MouseEvent, data: ResizeCallbackData) => { const direction = e.movementY < 0 ? -1 : +1; const tileDiff = this.props.layout.pixelsToTiles(Math.abs(e.movementY)) * direction; - this.props.layout.visibleTiles += tileDiff; + this.props.layout.setVisibleTilesWithin(tileDiff, this.numTiles); this.forceUpdate(); // because the layout doesn't trigger a re-render }; @@ -173,13 +179,17 @@ export default class RoomSublist2 extends React.Component { } }; - private renderTiles(): React.ReactElement[] { - if (this.props.layout && this.props.layout.isCollapsed) return []; // don't waste time on rendering + private renderVisibleTiles(): React.ReactElement[] { + if (this.props.layout && this.props.layout.isCollapsed) { + // don't waste time on rendering + return []; + } const tiles: React.ReactElement[] = []; if (this.props.rooms) { - for (const room of this.props.rooms) { + const visibleRooms = this.props.rooms.slice(0, this.numVisibleTiles); + for (const room of visibleRooms) { tiles.push( { public render(): React.ReactElement { // TODO: Error boundary: https://github.com/vector-im/riot-web/issues/14185 - const tiles = this.renderTiles(); + const visibleTiles = this.renderVisibleTiles(); const classes = classNames({ 'mx_RoomSublist2': true, @@ -347,13 +357,10 @@ export default class RoomSublist2 extends React.Component { }); let content = null; - if (tiles.length > 0) { + if (visibleTiles.length > 0) { const layout = this.props.layout; // to shorten calls - const nVisible = Math.floor(layout.visibleTiles); - const visibleTiles = tiles.slice(0, nVisible); - - const maxTilesFactored = layout.tilesWithResizerBoxFactor(tiles.length); + const maxTilesFactored = layout.tilesWithResizerBoxFactor(this.numTiles); const showMoreBtnClasses = classNames({ 'mx_RoomSublist2_showNButton': true, 'mx_RoomSublist2_isCutting': this.state.isResizing && layout.visibleTiles < maxTilesFactored, @@ -363,9 +370,9 @@ export default class RoomSublist2 extends React.Component { // floats above the resize handle, if we have one present. If the user has all // tiles visible, it becomes 'show less'. let showNButton = null; - if (tiles.length > nVisible) { + if (this.numTiles > this.numVisibleTiles) { // we have a cutoff condition - add the button to show all - const numMissing = tiles.length - visibleTiles.length; + const numMissing = this.numTiles - visibleTiles.length; let showMoreText = ( {_t("Show %(count)s more", {count: numMissing})} @@ -380,7 +387,7 @@ export default class RoomSublist2 extends React.Component { {showMoreText} ); - } else if (tiles.length <= nVisible && tiles.length > this.props.layout.defaultVisibleTiles) { + } else if (this.numTiles <= this.numVisibleTiles && this.numTiles > this.props.layout.defaultVisibleTiles) { // we have all tiles visible - add a button to show less let showLessText = ( @@ -400,7 +407,7 @@ export default class RoomSublist2 extends React.Component { // Figure out if we need a handle let handles = ['s']; - if (layout.visibleTiles >= tiles.length && tiles.length <= layout.minVisibleTiles) { + if (layout.visibleTiles >= this.numTiles && this.numTiles <= layout.minVisibleTiles) { handles = []; // no handles, we're at a minimum } @@ -419,9 +426,9 @@ export default class RoomSublist2 extends React.Component { if (showNButton) padding += SHOW_N_BUTTON_HEIGHT; padding += RESIZE_HANDLE_HEIGHT; // always append the handle height - const relativeTiles = layout.tilesWithPadding(tiles.length, padding); + const relativeTiles = layout.tilesWithPadding(this.numTiles, padding); const minTilesPx = layout.calculateTilesToPixelsMin(relativeTiles, layout.minVisibleTiles, padding); - const maxTilesPx = layout.tilesToPixelsWithPadding(tiles.length, padding); + const maxTilesPx = layout.tilesToPixelsWithPadding(this.numTiles, padding); const tilesWithoutPadding = Math.min(relativeTiles, layout.visibleTiles); const tilesPx = layout.calculateTilesToPixelsMin(relativeTiles, tilesWithoutPadding, padding); diff --git a/src/stores/room-list/ListLayout.ts b/src/stores/room-list/ListLayout.ts index d8564bf947..528276e801 100644 --- a/src/stores/room-list/ListLayout.ts +++ b/src/stores/room-list/ListLayout.ts @@ -89,6 +89,14 @@ export class ListLayout { return 10 + RESIZER_BOX_FACTOR; } + public setVisibleTilesWithin(diff: number, maxPossible: number) { + if (this.visibleTiles > maxPossible) { + this.visibleTiles = maxPossible + diff; + } else { + this.visibleTiles += diff; + } + } + public calculateTilesToPixelsMin(maxTiles: number, n: number, possiblePadding: number): number { // Only apply the padding if we're about to use maxTiles as we need to // plan for the padding. If we're using n, the padding is already accounted