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

Commit acb7dd8

Browse files
authored
Support dynamic room predecessors in SpaceStore (#10332)
1 parent 01d7b79 commit acb7dd8

File tree

2 files changed

+136
-9
lines changed

2 files changed

+136
-9
lines changed

src/stores/spaces/SpaceStore.ts

+38-9
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,16 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
144144
// The following properties are set by onReady as they live in account_data
145145
private _allRoomsInHome = false;
146146
private _enabledMetaSpaces: MetaSpace[] = [];
147+
/** Whether the feature flag is set for MSC3946 */
148+
private _msc3946ProcessDynamicPredecessor: boolean = SettingsStore.getValue("feature_dynamic_room_predecessors");
147149

148150
public constructor() {
149151
super(defaultDispatcher, {});
150152

151153
SettingsStore.monitorSetting("Spaces.allRoomsInHome", null);
152154
SettingsStore.monitorSetting("Spaces.enabledMetaSpaces", null);
153155
SettingsStore.monitorSetting("Spaces.showPeopleInSpace", null);
156+
SettingsStore.monitorSetting("feature_dynamic_room_predecessors", null);
154157
}
155158

156159
public get invitedSpaces(): Room[] {
@@ -352,7 +355,11 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
352355
return getChildOrder(ev.getContent().order, ev.getTs(), ev.getStateKey()!);
353356
})
354357
.map((ev) => {
355-
const history = this.matrixClient.getRoomUpgradeHistory(ev.getStateKey()!, true);
358+
const history = this.matrixClient.getRoomUpgradeHistory(
359+
ev.getStateKey()!,
360+
true,
361+
this._msc3946ProcessDynamicPredecessor,
362+
);
356363
return history[history.length - 1];
357364
})
358365
.filter((room) => {
@@ -450,7 +457,9 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
450457
useCache = true,
451458
): Set<string> => {
452459
if (space === MetaSpace.Home && this.allRoomsInHome) {
453-
return new Set(this.matrixClient.getVisibleRooms().map((r) => r.roomId));
460+
return new Set(
461+
this.matrixClient.getVisibleRooms(this._msc3946ProcessDynamicPredecessor).map((r) => r.roomId),
462+
);
454463
}
455464

456465
// meta spaces never have descendants
@@ -539,7 +548,9 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
539548
};
540549

541550
private rebuildSpaceHierarchy = (): void => {
542-
const visibleSpaces = this.matrixClient.getVisibleRooms().filter((r) => r.isSpaceRoom());
551+
const visibleSpaces = this.matrixClient
552+
.getVisibleRooms(this._msc3946ProcessDynamicPredecessor)
553+
.filter((r) => r.isSpaceRoom());
543554
const [joinedSpaces, invitedSpaces] = visibleSpaces.reduce(
544555
([joined, invited], s) => {
545556
switch (getEffectiveMembership(s.getMyMembership())) {
@@ -573,7 +584,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
573584
};
574585

575586
private rebuildParentMap = (): void => {
576-
const joinedSpaces = this.matrixClient.getVisibleRooms().filter((r) => {
587+
const joinedSpaces = this.matrixClient.getVisibleRooms(this._msc3946ProcessDynamicPredecessor).filter((r) => {
577588
return r.isSpaceRoom() && r.getMyMembership() === "join";
578589
});
579590

@@ -595,7 +606,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
595606
} else {
596607
const rooms = new Set(
597608
this.matrixClient
598-
.getVisibleRooms()
609+
.getVisibleRooms(this._msc3946ProcessDynamicPredecessor)
599610
.filter(this.showInHomeSpace)
600611
.map((r) => r.roomId),
601612
);
@@ -609,7 +620,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
609620

610621
private rebuildMetaSpaces = (): void => {
611622
const enabledMetaSpaces = new Set(this.enabledMetaSpaces);
612-
const visibleRooms = this.matrixClient.getVisibleRooms();
623+
const visibleRooms = this.matrixClient.getVisibleRooms(this._msc3946ProcessDynamicPredecessor);
613624

614625
if (enabledMetaSpaces.has(MetaSpace.Home)) {
615626
this.rebuildHomeSpace();
@@ -643,7 +654,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
643654

644655
private updateNotificationStates = (spaces?: SpaceKey[]): void => {
645656
const enabledMetaSpaces = new Set(this.enabledMetaSpaces);
646-
const visibleRooms = this.matrixClient.getVisibleRooms();
657+
const visibleRooms = this.matrixClient.getVisibleRooms(this._msc3946ProcessDynamicPredecessor);
647658

648659
let dmBadgeSpace: MetaSpace | undefined;
649660
// only show badges on dms on the most relevant space if such exists
@@ -729,7 +740,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
729740
};
730741

731742
private onRoomsUpdate = (): void => {
732-
const visibleRooms = this.matrixClient.getVisibleRooms();
743+
const visibleRooms = this.matrixClient.getVisibleRooms(this._msc3946ProcessDynamicPredecessor);
733744

734745
const prevRoomsBySpace = this.roomIdsBySpace;
735746
const prevUsersBySpace = this.userIdsBySpace;
@@ -792,7 +803,9 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
792803
// Expand room IDs to all known versions of the given rooms
793804
const expandedRoomIds = new Set(
794805
Array.from(roomIds).flatMap((roomId) => {
795-
return this.matrixClient.getRoomUpgradeHistory(roomId, true).map((r) => r.roomId);
806+
return this.matrixClient
807+
.getRoomUpgradeHistory(roomId, true, this._msc3946ProcessDynamicPredecessor)
808+
.map((r) => r.roomId);
796809
}),
797810
);
798811

@@ -1275,6 +1288,13 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
12751288
this.updateNotificationStates([payload.roomId]);
12761289
}
12771290
break;
1291+
1292+
case "feature_dynamic_room_predecessors":
1293+
this._msc3946ProcessDynamicPredecessor = SettingsStore.getValue(
1294+
"feature_dynamic_room_predecessors",
1295+
);
1296+
this.rebuildSpaceHierarchy();
1297+
break;
12781298
}
12791299
}
12801300
}
@@ -1355,6 +1375,15 @@ export default class SpaceStore {
13551375
public static get instance(): SpaceStoreClass {
13561376
return SpaceStore.internalInstance;
13571377
}
1378+
1379+
/**
1380+
* @internal for test only
1381+
*/
1382+
public static testInstance(): SpaceStoreClass {
1383+
const store = new SpaceStoreClass();
1384+
store.start();
1385+
return store;
1386+
}
13581387
}
13591388

13601389
window.mxSpaceStore = SpaceStore.instance;

test/stores/SpaceStore-test.ts

+98
Original file line numberDiff line numberDiff line change
@@ -1331,4 +1331,102 @@ describe("SpaceStore", () => {
13311331
expect(metaSpaces).toEqual(store.enabledMetaSpaces);
13321332
removeListener();
13331333
});
1334+
1335+
describe("when feature_dynamic_room_predecessors is not enabled", () => {
1336+
beforeAll(() => {
1337+
jest.spyOn(SettingsStore, "getValue").mockImplementation(
1338+
(settingName) => settingName === "Spaces.allRoomsInHome",
1339+
);
1340+
// @ts-ignore calling a private function
1341+
SpaceStore.instance.onAction({
1342+
action: Action.SettingUpdated,
1343+
settingName: "feature_dynamic_room_predecessors",
1344+
roomId: null,
1345+
level: SettingLevel.ACCOUNT,
1346+
newValueAtLevel: SettingLevel.ACCOUNT,
1347+
newValue: false,
1348+
});
1349+
});
1350+
1351+
beforeEach(() => {
1352+
jest.clearAllMocks();
1353+
});
1354+
1355+
it("passes that value in calls to getVisibleRooms and getRoomUpgradeHistory during startup", async () => {
1356+
// When we create an instance, which calls onReady and rebuildSpaceHierarchy
1357+
mkSpace("!dynspace:example.com", [mkRoom("!dynroom:example.com").roomId]);
1358+
await run();
1359+
1360+
// Then we pass through the correct value of the feature flag to
1361+
// everywhere that needs it.
1362+
expect(client.getVisibleRooms).toHaveBeenCalledWith(false);
1363+
expect(client.getVisibleRooms).not.toHaveBeenCalledWith(true);
1364+
expect(client.getVisibleRooms).not.toHaveBeenCalledWith();
1365+
expect(client.getRoomUpgradeHistory).toHaveBeenCalledWith(expect.anything(), expect.anything(), false);
1366+
expect(client.getRoomUpgradeHistory).not.toHaveBeenCalledWith(expect.anything(), expect.anything(), true);
1367+
expect(client.getRoomUpgradeHistory).not.toHaveBeenCalledWith(expect.anything(), expect.anything());
1368+
});
1369+
1370+
it("passes that value in calls to getVisibleRooms during getSpaceFilteredRoomIds", () => {
1371+
// Given a store
1372+
const store = SpaceStore.testInstance();
1373+
1374+
// When we ask for filtered room ids
1375+
store.getSpaceFilteredRoomIds(MetaSpace.Home);
1376+
1377+
// Then we pass the correct feature flag
1378+
expect(client.getVisibleRooms).toHaveBeenCalledWith(false);
1379+
expect(client.getVisibleRooms).not.toHaveBeenCalledWith(true);
1380+
expect(client.getVisibleRooms).not.toHaveBeenCalledWith();
1381+
});
1382+
});
1383+
1384+
describe("when feature_dynamic_room_predecessors is enabled", () => {
1385+
beforeAll(() => {
1386+
jest.spyOn(SettingsStore, "getValue").mockImplementation(
1387+
(settingName) =>
1388+
settingName === "Spaces.allRoomsInHome" || settingName === "feature_dynamic_room_predecessors",
1389+
);
1390+
// @ts-ignore calling a private function
1391+
SpaceStore.instance.onAction({
1392+
action: Action.SettingUpdated,
1393+
settingName: "feature_dynamic_room_predecessors",
1394+
roomId: null,
1395+
level: SettingLevel.ACCOUNT,
1396+
newValueAtLevel: SettingLevel.ACCOUNT,
1397+
newValue: true,
1398+
});
1399+
});
1400+
1401+
beforeEach(() => {
1402+
jest.clearAllMocks();
1403+
});
1404+
1405+
it("passes that value in calls to getVisibleRooms and getRoomUpgradeHistory during startup", async () => {
1406+
// When we create an instance, which calls onReady and rebuildSpaceHierarchy
1407+
mkSpace("!dynspace:example.com", [mkRoom("!dynroom:example.com").roomId]);
1408+
await run();
1409+
1410+
// Then we pass through the correct value of the feature flag to
1411+
// everywhere that needs it.
1412+
expect(client.getVisibleRooms).toHaveBeenCalledWith(true);
1413+
expect(client.getVisibleRooms).not.toHaveBeenCalledWith(false);
1414+
expect(client.getVisibleRooms).not.toHaveBeenCalledWith();
1415+
expect(client.getRoomUpgradeHistory).toHaveBeenCalledWith(expect.anything(), expect.anything(), true);
1416+
expect(client.getRoomUpgradeHistory).not.toHaveBeenCalledWith(expect.anything(), expect.anything(), false);
1417+
expect(client.getRoomUpgradeHistory).not.toHaveBeenCalledWith(expect.anything(), expect.anything());
1418+
});
1419+
1420+
it("passes that value in calls to getVisibleRooms during getSpaceFilteredRoomIds", () => {
1421+
// Given a store
1422+
const store = SpaceStore.testInstance();
1423+
// When we ask for filtered room ids
1424+
store.getSpaceFilteredRoomIds(MetaSpace.Home);
1425+
1426+
// Then we pass the correct feature flag
1427+
expect(client.getVisibleRooms).toHaveBeenCalledWith(true);
1428+
expect(client.getVisibleRooms).not.toHaveBeenCalledWith(false);
1429+
expect(client.getVisibleRooms).not.toHaveBeenCalledWith();
1430+
});
1431+
});
13341432
});

0 commit comments

Comments
 (0)