Skip to content

Commit 4186070

Browse files
committed
Support list collapsing and jumping
Fixes element-hq/element-web#14036
1 parent 8596905 commit 4186070

File tree

5 files changed

+81
-2
lines changed

5 files changed

+81
-2
lines changed

res/css/views/rooms/_RoomSublist2.scss

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,34 @@ limitations under the License.
138138
text-overflow: ellipsis;
139139
overflow: hidden;
140140
white-space: nowrap;
141+
142+
.mx_RoomSublist2_collapseBtn {
143+
display: inline-block;
144+
position: relative;
145+
146+
// Default hidden
147+
visibility: hidden;
148+
width: 0;
149+
height: 0;
150+
151+
&::before {
152+
content: '';
153+
width: 12px;
154+
height: 12px;
155+
position: absolute;
156+
top: 1px;
157+
left: 1px;
158+
mask-position: center;
159+
mask-size: contain;
160+
mask-repeat: no-repeat;
161+
background: $primary-fg-color;
162+
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
163+
}
164+
165+
&.mx_RoomSublist2_collapseBtn_collapsed::before {
166+
mask-image: url('$(res)/img/feather-customised/chevron-right.svg');
167+
}
168+
}
141169
}
142170
}
143171

@@ -251,6 +279,17 @@ limitations under the License.
251279
background-color: $roomlist2-button-bg-color;
252280
}
253281
}
282+
283+
.mx_RoomSublist2_headerContainer {
284+
.mx_RoomSublist2_headerText {
285+
.mx_RoomSublist2_collapseBtn {
286+
visibility: visible;
287+
width: 12px;
288+
height: 12px;
289+
margin-right: 4px;
290+
}
291+
}
292+
}
254293
}
255294

256295
&.mx_RoomSublist2_minimized {
Lines changed: 1 addition & 0 deletions
Loading

src/components/structures/LeftPanel2.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,11 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
105105
const header = sublist.querySelector<HTMLDivElement>(".mx_RoomSublist2_stickable");
106106

107107
if (slRect.top + headerHeight > bottom && !gotBottom) {
108-
console.log(`${header.textContent} is off the bottom`);
109108
header.classList.add("mx_RoomSublist2_headerContainer_sticky");
110109
header.classList.add("mx_RoomSublist2_headerContainer_stickyBottom");
111110
header.style.width = `${headerStickyWidth}px`;
112111
gotBottom = true;
113112
} else if (slRect.top < top) {
114-
console.log(`${header.textContent} is off the top`);
115113
header.classList.add("mx_RoomSublist2_headerContainer_sticky");
116114
header.classList.add("mx_RoomSublist2_headerContainer_stickyTop");
117115
header.style.width = `${headerStickyWidth}px`;

src/components/views/rooms/RoomSublist2.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,28 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
134134
this.forceUpdate(); // because the layout doesn't trigger a re-render
135135
};
136136

137+
private onHeaderClick = (ev: React.MouseEvent<HTMLDivElement>) => {
138+
let target = ev.target as HTMLDivElement;
139+
if (!target.classList.contains('mx_RoomSublist2_headerText')) {
140+
// If we don't have the headerText class, the user clicked the span in the headerText.
141+
target = target.parentElement as HTMLDivElement;
142+
}
143+
144+
const possibleSticky = target.parentElement;
145+
const sublist = possibleSticky.parentElement.parentElement;
146+
if (possibleSticky.classList.contains('mx_RoomSublist2_headerContainer_sticky')) {
147+
// is sticky - jump to list
148+
sublist.scrollIntoView({behavior: 'smooth'});
149+
} else {
150+
// on screen - toggle collapse
151+
this.props.layout.isCollapsed = !this.props.layout.isCollapsed;
152+
this.forceUpdate(); // because the layout doesn't trigger an update
153+
}
154+
};
155+
137156
private renderTiles(): React.ReactElement[] {
157+
if (this.props.layout && this.props.layout.isCollapsed) return []; // don't waste time on rendering
158+
138159
const tiles: React.ReactElement[] = [];
139160

140161
if (this.props.rooms) {
@@ -249,6 +270,11 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
249270
);
250271
}
251272

273+
const collapseClasses = classNames({
274+
'mx_RoomSublist2_collapseBtn': true,
275+
'mx_RoomSublist2_collapseBtn_collapsed': this.props.layout && this.props.layout.isCollapsed,
276+
});
277+
252278
const classes = classNames({
253279
'mx_RoomSublist2_headerContainer': true,
254280
'mx_RoomSublist2_headerContainer_withAux': !!addRoomButton,
@@ -264,7 +290,9 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
264290
className={"mx_RoomSublist2_headerText"}
265291
role="treeitem"
266292
aria-level={1}
293+
onClick={this.onHeaderClick}
267294
>
295+
<span className={collapseClasses} />
268296
<span>{this.props.label}</span>
269297
</AccessibleButton>
270298
{this.renderMenu()}

src/stores/room-list/ListLayout.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ const TILE_HEIGHT_PX = 44;
2121
interface ISerializedListLayout {
2222
numTiles: number;
2323
showPreviews: boolean;
24+
collapsed: boolean;
2425
}
2526

2627
export class ListLayout {
2728
private _n = 0;
2829
private _previews = false;
30+
private _collapsed = false;
2931

3032
constructor(public readonly tagId: TagID) {
3133
const serialized = localStorage.getItem(this.key);
@@ -34,9 +36,19 @@ export class ListLayout {
3436
const parsed = <ISerializedListLayout>JSON.parse(serialized);
3537
this._n = parsed.numTiles;
3638
this._previews = parsed.showPreviews;
39+
this._collapsed = parsed.collapsed;
3740
}
3841
}
3942

43+
public get isCollapsed(): boolean {
44+
return this._collapsed;
45+
}
46+
47+
public set isCollapsed(v: boolean) {
48+
this._collapsed = v;
49+
this.save();
50+
}
51+
4052
public get showPreviews(): boolean {
4153
return this._previews;
4254
}
@@ -100,6 +112,7 @@ export class ListLayout {
100112
return {
101113
numTiles: this.visibleTiles,
102114
showPreviews: this.showPreviews,
115+
collapsed: this.isCollapsed,
103116
};
104117
}
105118
}

0 commit comments

Comments
 (0)