Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Spaces.includeSubSpaceRoomsInRoomList settings #7682

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,7 @@
"Show chat effects (animations when receiving e.g. confetti)": "Show chat effects (animations when receiving e.g. confetti)",
"Show all rooms in Home": "Show all rooms in Home",
"All rooms you're in will appear in Home.": "All rooms you're in will appear in Home.",
"Display all people and rooms from nested spaces in the room list for a space": "Display all people and rooms from nested spaces in the room list for a space",
"Display Communities instead of Spaces": "Display Communities instead of Spaces",
"Temporarily show communities instead of Spaces for this session. Support for this will be removed in the near future. This will reload Element.": "Temporarily show communities instead of Spaces for this session. Support for this will be removed in the near future. This will reload Element.",
"Developer mode": "Developer mode",
Expand Down
5 changes: 5 additions & 0 deletions src/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,11 @@ export const SETTINGS: {[setting: string]: ISetting} = {
default: true,
controller: new IncompatibleController("showCommunitiesInsteadOfSpaces", null),
},
"Spaces.includeSubSpaceRoomsInRoomList": {
displayName: _td("Display all people and rooms from nested spaces in the room list for a space"),
supportedLevels: LEVELS_ROOM_SETTINGS,
default: true,
},
"showCommunitiesInsteadOfSpaces": {
displayName: _td("Display Communities instead of Spaces"),
description: _td("Temporarily show communities instead of Spaces for this session. " +
Expand Down
15 changes: 12 additions & 3 deletions src/stores/room-list/filters/SpaceFilterCondition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,40 @@ export class SpaceFilterCondition extends EventEmitter implements IFilterConditi
private roomIds = new Set<string>();
private userIds = new Set<string>();
private showPeopleInSpace = true;
private showSubSpaceRoomsInSpace = true;
private space: SpaceKey = MetaSpace.Home;

public get kind(): FilterKind {
return FilterKind.Prefilter;
}

public isVisible(room: Room): boolean {
return SpaceStore.instance.isRoomInSpace(this.space, room.roomId);
return SpaceStore.instance.isRoomInSpace(this.space, room.roomId, this.showSubSpaceRoomsInSpace);
}

private onStoreUpdate = async (forceUpdate = false): Promise<void> => {
const beforeShowSubSpaceRoomsInSpace = this.showSubSpaceRoomsInSpace;
this.showSubSpaceRoomsInSpace = SettingsStore.getValue("Spaces.includeSubSpaceRoomsInRoomList", this.space);

const beforeRoomIds = this.roomIds;
// clone the set as it may be mutated by the space store internally
this.roomIds = new Set(SpaceStore.instance.getSpaceFilteredRoomIds(this.space));
this.roomIds = new Set(
SpaceStore.instance.getSpaceFilteredRoomIds(this.space, this.showSubSpaceRoomsInSpace, true),
);

const beforeUserIds = this.userIds;
// clone the set as it may be mutated by the space store internally
this.userIds = new Set(SpaceStore.instance.getSpaceFilteredUserIds(this.space));
this.userIds = new Set(
SpaceStore.instance.getSpaceFilteredUserIds(this.space, this.showSubSpaceRoomsInSpace, true),
);

const beforeShowPeopleInSpace = this.showPeopleInSpace;
this.showPeopleInSpace = isMetaSpace(this.space[0]) ||
SettingsStore.getValue("Spaces.showPeopleInSpace", this.space);

if (forceUpdate ||
beforeShowPeopleInSpace !== this.showPeopleInSpace ||
beforeShowSubSpaceRoomsInSpace !== this.showSubSpaceRoomsInSpace ||
setHasDiff(beforeRoomIds, this.roomIds) ||
setHasDiff(beforeUserIds, this.userIds)
) {
Expand Down
1 change: 1 addition & 0 deletions src/stores/spaces/SpaceStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
SettingsStore.monitorSetting("Spaces.allRoomsInHome", null);
SettingsStore.monitorSetting("Spaces.enabledMetaSpaces", null);
SettingsStore.monitorSetting("Spaces.showPeopleInSpace", null);
SettingsStore.monitorSetting("Spaces.includeSubSpaceRoomsInRoomList", null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this monitoring a setting which it doesn't react to changes of?

}

public get invitedSpaces(): Room[] {
Expand Down
61 changes: 58 additions & 3 deletions test/stores/room-list/filters/SpaceFilterCondition-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ describe('SpaceFilterCondition', () => {
beforeEach(() => {
jest.resetAllMocks();
SettingsStoreMock.getValue.mockClear().mockImplementation(makeMockGetValue());
SpaceStoreInstanceMock.getSpaceFilteredRoomIds.mockReturnValue(new Set([]));
SpaceStoreInstanceMock.getSpaceFilteredUserIds.mockReturnValue(new Set([]));
SpaceStoreInstanceMock.isRoomInSpace.mockReturnValue(true);
});
Expand All @@ -66,11 +67,26 @@ describe('SpaceFilterCondition', () => {

describe('isVisible', () => {
const room1 = { roomId: room1Id } as unknown as Room;
it('calls isRoomInSpace correctly', () => {
it('calls isRoomInSpace correctly when showSubSpaceRoomsInSpace is truthy', () => {
SettingsStoreMock.getValue.mockImplementation(makeMockGetValue({
["Spaces.includeSubSpaceRoomsInRoomList"]: { [space1]: true },
}));

const filter = initFilter(space1);

expect(filter.isVisible(room1)).toEqual(true);
expect(SpaceStoreInstanceMock.isRoomInSpace).toHaveBeenCalledWith(space1, room1Id, true);
});

it('calls isRoomInSpace correctly when showSubSpaceRoomsInSpace is truthy', () => {
SettingsStoreMock.getValue.mockImplementation(makeMockGetValue({
["Spaces.includeSubSpaceRoomsInRoomList"]: { [space1]: false },
}));

const filter = initFilter(space1);

expect(filter.isVisible(room1)).toEqual(true);
expect(SpaceStoreInstanceMock.isRoomInSpace).toHaveBeenCalledWith(space1, room1Id);
expect(SpaceStoreInstanceMock.isRoomInSpace).toHaveBeenCalledWith(space1, room1Id, false);
});
});

Expand All @@ -83,6 +99,45 @@ describe('SpaceFilterCondition', () => {
expect(emitSpy).toHaveBeenCalledWith(FILTER_CHANGED);
});

it('compares sub space rooms and dms when Spaces.includeSubSpaceRoomsInRoomList enabled', async () => {
SettingsStoreMock.getValue.mockImplementation(makeMockGetValue({
["Spaces.includeSubSpaceRoomsInRoomList"]: { [space1]: true },
}));
const filter = new SpaceFilterCondition();
filter.updateSpace(space1);
jest.runOnlyPendingTimers();
expect(SpaceStoreInstanceMock.getSpaceFilteredRoomIds).toHaveBeenCalledWith(space1, true, true);
expect(SpaceStoreInstanceMock.getSpaceFilteredUserIds).toHaveBeenCalledWith(space1, true, true);
});

it('compares only direct child rooms and dms when Spaces.includeSubSpaceRoomsInRoomList disabled', async () => {
SettingsStoreMock.getValue.mockImplementation(makeMockGetValue({
["Spaces.includeSubSpaceRoomsInRoomList"]: { [space1]: false },
}));
const filter = new SpaceFilterCondition();
filter.updateSpace(space1);
jest.runOnlyPendingTimers();
expect(SpaceStoreInstanceMock.getSpaceFilteredRoomIds).toHaveBeenCalledWith(space1, false, true);
expect(SpaceStoreInstanceMock.getSpaceFilteredUserIds).toHaveBeenCalledWith(space1, false, true);
});

it('emits filter changed event when Spaces.includeSubSpaceRoomsInRoomList setting changes', async () => {
// init filter with setting true for space1
SettingsStoreMock.getValue.mockImplementation(makeMockGetValue({
["Spaces.includeSubSpaceRoomsInRoomList"]: { [space1]: true },
}));
const filter = initFilter(space1);
const emitSpy = jest.spyOn(filter, 'emit');

SettingsStoreMock.getValue.mockImplementation(makeMockGetValue({
["Spaces.includeSubSpaceRoomsInRoomList"]: { [space1]: false },
}));

SpaceStoreInstanceMock.emit(space1);
jest.runOnlyPendingTimers();
expect(emitSpy).toHaveBeenCalledWith(FILTER_CHANGED);
});

describe('showPeopleInSpace setting', () => {
it('emits filter changed event when setting changes', async () => {
// init filter with setting true for space1
Expand Down Expand Up @@ -151,7 +206,7 @@ describe('SpaceFilterCondition', () => {
expect(emitSpy).not.toHaveBeenCalledWith(FILTER_CHANGED);
});

describe('when directChildRoomIds change', () => {
describe('when spaceFilteredRoomIds change', () => {
beforeEach(() => {
SpaceStoreInstanceMock.getSpaceFilteredRoomIds.mockReturnValue(new Set([room1Id, room2Id]));
});
Expand Down