Room list: add new settings to enable/disable the sections (#34151)

* Add new settings to enable/disable the sections

* Add `RoomList.showSections` settings to preference user settings

* Hide sections ui in room list header

- Hide the collapse/expand button and the *new section* entry in the
menu.
- Display the *start chat* button instead of the compose menu when the
only action available is to create a DM

* Hide sections ui in context menu of room item

* Listen to show section settings in room list item vm

* Listen to show sections setting in room list header vm

* Put all the rooms inside the chat section when sections are disabled

When the chat section is the only section, the room list is in "flat
list mode". Putting all the rooms inside the chat section.

The section filters (aka custom section, favourites etc) are not passed
to the skip list.

* Update preferences settings screenshot

* Add e2e test for RoomList.showSections toggle

* Hide "Chat moved" toast when a room is tagged when RoomList.showSections is disabled
This commit is contained in:
Florian Duros
2026-07-07 08:45:37 +00:00
committed by GitHub
parent 5065683658
commit 7ff6956014
25 changed files with 478 additions and 193 deletions
@@ -156,6 +156,36 @@ describe("RoomListHeaderViewModel", () => {
expect(vm.getSnapshot().isMessagePreviewEnabled).toBe(true);
});
it("should set areSectionsEnabled to true when RoomList.showSections is enabled", () => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((settingName: string) => {
if (settingName === "RoomList.showSections") return true;
return false;
});
vm = new RoomListHeaderViewModel({ matrixClient, spaceStore: SpaceStore.instance });
expect(vm.getSnapshot().areSectionsEnabled).toBe(true);
});
it("should update areSectionsEnabled when RoomList.showSections setting changes", () => {
let watchCallback: () => void = () => {};
jest.spyOn(SettingsStore, "watchSetting").mockImplementation((settingName, _roomId, callback) => {
if (settingName === "RoomList.showSections") watchCallback = callback as () => void;
return "watcher-id";
});
vm = new RoomListHeaderViewModel({ matrixClient, spaceStore: SpaceStore.instance });
expect(vm.getSnapshot().areSectionsEnabled).toBe(false);
// Enable sections
jest.spyOn(SettingsStore, "getValue").mockImplementation((settingName: string) => {
if (settingName === "RoomList.showSections") return true;
return false;
});
watchCallback();
expect(vm.getSnapshot().areSectionsEnabled).toBe(true);
});
it("should set displaySectionReleaseAnnouncement to true when sections feature is enabled and announcement is active", () => {
jest.spyOn(ReleaseAnnouncementStore.instance, "getReleaseAnnouncement").mockReturnValue(
"room_list_section",
@@ -664,6 +664,36 @@ describe("RoomListItemViewModel", () => {
expect(viewModel.getSnapshot().sections.map((s) => s.tag)).toEqual([]);
});
it("should set areSectionsEnabled to true when RoomList.showSections is enabled", () => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((setting) => {
if (setting === "RoomList.showSections") return true;
return false;
});
viewModel = new RoomListItemViewModel({ room, client: matrixClient });
expect(viewModel.getSnapshot().areSectionsEnabled).toBe(true);
});
it("should update areSectionsEnabled when RoomList.showSections setting changes", () => {
let watchCallback: CallbackFn<"RoomList.showSections"> = () => {};
jest.spyOn(SettingsStore, "watchSetting").mockImplementation((setting, _room, callback) => {
if (setting === "RoomList.showSections") watchCallback = callback;
return "watcher-id";
});
viewModel = new RoomListItemViewModel({ room, client: matrixClient });
expect(viewModel.getSnapshot().areSectionsEnabled).toBe(false);
// Enable sections
jest.spyOn(SettingsStore, "getValue").mockImplementation((setting) => {
if (setting === "RoomList.showSections") return true;
return false;
});
watchCallback("RoomList.showSections", null, null as any, null, null);
expect(viewModel.getSnapshot().areSectionsEnabled).toBe(true);
});
});
describe("Cleanup", () => {