;
+
+ let Button: React.ComponentType> = AccessibleButton;
+ if (this.props.isMinimized) {
+ Button = AccessibleTooltipButton;
+ }
+
+ // Note: the addRoomButton conditionally gets moved around
+ // the DOM depending on whether or not the list is minimized.
+ // If we're minimized, we want it below the header so it
+ // doesn't become sticky.
+ // The same applies to the notification badge.
+ return (
+
+ );
+ }}
+
+ );
+ }
+
+ private onScrollPrevent(e: Event): void {
+ // the RoomTile calls scrollIntoView and the browser may scroll a div we do not wish to be scrollable
+ // this fixes https://github.com/vector-im/element-web/issues/14413
+ (e.target as HTMLDivElement).scrollTop = 0;
+ }
+
+ public render(): React.ReactElement {
+ const visibleTiles = this.renderVisibleTiles();
+ const hidden = !this.state.rooms.length && !this.props.extraTiles?.length && this.props.alwaysVisible !== true;
+ const classes = classNames({
+ mx_RoomSublist: true,
+ mx_RoomSublist_hasMenuOpen: !!this.state.contextMenuPosition,
+ mx_RoomSublist_minimized: this.props.isMinimized,
+ mx_RoomSublist_hidden: hidden,
+ });
+
+ let content: JSX.Element | undefined;
+ if (this.state.roomsLoading) {
+ content = ;
+ } else if (visibleTiles.length > 0 && this.props.forceExpanded) {
+ content = (
+
+
+ {visibleTiles}
+
+
+ );
+ } else if (visibleTiles.length > 0) {
+ const layout = this.layout; // to shorten calls
+
+ const minTiles = Math.min(layout.minVisibleTiles, this.numTiles);
+ const showMoreAtMinHeight = minTiles < this.numTiles;
+ const minHeightPadding = RESIZE_HANDLE_HEIGHT + (showMoreAtMinHeight ? SHOW_N_BUTTON_HEIGHT : 0);
+ const minTilesPx = layout.tilesToPixelsWithPadding(minTiles, minHeightPadding);
+ const maxTilesPx = layout.tilesToPixelsWithPadding(this.numTiles, this.padding);
+ const showMoreBtnClasses = classNames({
+ mx_RoomSublist_showNButton: true,
+ });
+
+ // If we're hiding rooms, show a 'show more' button to the user. This button
+ // floats above the resize handle, if we have one present. If the user has all
+ // tiles visible, it becomes 'show less'.
+ let showNButton: JSX.Element | undefined;
+ const hasMoreSlidingSync =
+ this.slidingSyncMode && RoomListStore.instance.getCount(this.getTagId()) > this.state.rooms.length;
+ if (maxTilesPx > this.state.height || hasMoreSlidingSync) {
+ // the height of all the tiles is greater than the section height: we need a 'show more' button
+ const nonPaddedHeight = this.state.height - RESIZE_HANDLE_HEIGHT - SHOW_N_BUTTON_HEIGHT;
+ const amountFullyShown = Math.floor(nonPaddedHeight / this.layout.tileHeight);
+ let numMissing = this.numTiles - amountFullyShown;
+ if (this.slidingSyncMode) {
+ numMissing = RoomListStore.instance.getCount(this.getTagId()) - amountFullyShown;
+ }
+ const label = _t("room_list|show_n_more", { count: numMissing });
+ let showMoreText: ReactNode = {label};
+ if (this.props.isMinimized) showMoreText = null;
+ showNButton = (
+
+
+ {/* set by CSS masking */}
+
+ {showMoreText}
+
+ );
+ } else if (this.numTiles > this.layout.defaultVisibleTiles) {
+ // we have all tiles visible - add a button to show less
+ const label = _t("room_list|show_less");
+ let showLessText: ReactNode = {label};
+ if (this.props.isMinimized) showLessText = null;
+ showNButton = (
+
+
+ {/* set by CSS masking */}
+
+ {showLessText}
+
+ );
+ }
+
+ // Figure out if we need a handle
+ const handles: Enable = {
+ bottom: true, // the only one we need, but the others must be explicitly false
+ bottomLeft: false,
+ bottomRight: false,
+ left: false,
+ right: false,
+ top: false,
+ topLeft: false,
+ topRight: false,
+ };
+ if (layout.visibleTiles >= this.numTiles && this.numTiles <= layout.minVisibleTiles) {
+ // we're at a minimum, don't have a bottom handle
+ handles.bottom = false;
+ }
+
+ // We have to account for padding so we can accommodate a 'show more' button and
+ // the resize handle, which are pinned to the bottom of the container. This is the
+ // easiest way to have a resize handle below the button as otherwise we're writing
+ // our own resize handling and that doesn't sound fun.
+ //
+ // The layout class has some helpers for dealing with padding, as we don't want to
+ // apply it in all cases. If we apply it in all cases, the resizing feels like it
+ // goes backwards and can become wildly incorrect (visibleTiles says 18 when there's
+ // only mathematically 7 possible).
+
+ const handleWrapperClasses = classNames({
+ mx_RoomSublist_resizerHandles: true,
+ mx_RoomSublist_resizerHandles_showNButton: !!showNButton,
+ });
+
+ content = (
+
+
+