diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx index c08c66714ba..5c921d6ad7a 100644 --- a/src/stores/SpaceStore.tsx +++ b/src/stores/SpaceStore.tsx @@ -145,9 +145,9 @@ export class SpaceStoreClass extends AsyncStoreWithClient { return this._allRoomsInHome; } - public async setActiveRoomInSpace(space: Room | null): Promise { + public setActiveRoomInSpace(space: Room | null): void { if (space && !space.isSpaceRoom()) return; - if (space !== this.activeSpace) await this.setActiveSpace(space); + if (space !== this.activeSpace) this.setActiveSpace(space); if (space) { const roomId = this.getNotificationState(space.roomId).getFirstRoomWithNotifications(); @@ -190,7 +190,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { * @param contextSwitch whether to switch the user's context, * should not be done when the space switch is done implicitly due to another event like switching room. */ - public async setActiveSpace(space: Room | null, contextSwitch = true) { + public setActiveSpace(space: Room | null, contextSwitch = true) { if (space === this.activeSpace || (space && !space.isSpaceRoom())) return; this._activeSpace = space; @@ -293,11 +293,15 @@ export class SpaceStoreClass extends AsyncStoreWithClient { } if (space) { - const suggestedRooms = await this.fetchSuggestedRooms(space); - if (this._activeSpace === space) { - this._suggestedRooms = suggestedRooms; - this.emit(SUGGESTED_ROOMS, this._suggestedRooms); - } + this.loadSuggestedRooms(space); + } + } + + private async loadSuggestedRooms(space) { + const suggestedRooms = await this.fetchSuggestedRooms(space); + if (this._activeSpace === space) { + this._suggestedRooms = suggestedRooms; + this.emit(SUGGESTED_ROOMS, this._suggestedRooms); } } @@ -666,6 +670,14 @@ export class SpaceStoreClass extends AsyncStoreWithClient { this.onSpaceUpdate(); this.emit(room.roomId); } + + if (room === this.activeSpace && // current space + this.matrixClient.getRoom(ev.getStateKey())?.getMyMembership() !== "join" && // target not joined + ev.getPrevContent().suggested !== ev.getContent().suggested // suggested flag changed + ) { + this.loadSuggestedRooms(room); + } + break; case EventType.SpaceParent: diff --git a/test/stores/SpaceStore-test.ts b/test/stores/SpaceStore-test.ts index 2e823aa72bb..7cfd97b2345 100644 --- a/test/stores/SpaceStore-test.ts +++ b/test/stores/SpaceStore-test.ts @@ -562,7 +562,7 @@ describe("SpaceStore", () => { ]); mkSpace(space3).getMyMembership.mockReturnValue("invite"); await run(); - await store.setActiveSpace(null); + store.setActiveSpace(null); expect(store.activeSpace).toBe(null); }); afterEach(() => { @@ -570,31 +570,31 @@ describe("SpaceStore", () => { }); it("switch to home space", async () => { - await store.setActiveSpace(client.getRoom(space1)); + store.setActiveSpace(client.getRoom(space1)); fn.mockClear(); - await store.setActiveSpace(null); + store.setActiveSpace(null); expect(fn).toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, null); expect(store.activeSpace).toBe(null); }); it("switch to invited space", async () => { const space = client.getRoom(space3); - await store.setActiveSpace(space); + store.setActiveSpace(space); expect(fn).toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, space); expect(store.activeSpace).toBe(space); }); it("switch to top level space", async () => { const space = client.getRoom(space1); - await store.setActiveSpace(space); + store.setActiveSpace(space); expect(fn).toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, space); expect(store.activeSpace).toBe(space); }); it("switch to subspace", async () => { const space = client.getRoom(space2); - await store.setActiveSpace(space); + store.setActiveSpace(space); expect(fn).toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, space); expect(store.activeSpace).toBe(space); }); @@ -602,7 +602,7 @@ describe("SpaceStore", () => { it("switch to unknown space is a nop", async () => { expect(store.activeSpace).toBe(null); const space = client.getRoom(room1); // not a space - await store.setActiveSpace(space); + store.setActiveSpace(space); expect(fn).not.toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, space); expect(store.activeSpace).toBe(null); }); @@ -635,59 +635,59 @@ describe("SpaceStore", () => { }; it("last viewed room in target space is the current viewed and in both spaces", async () => { - await store.setActiveSpace(client.getRoom(space1)); + store.setActiveSpace(client.getRoom(space1)); viewRoom(room2); - await store.setActiveSpace(client.getRoom(space2)); + store.setActiveSpace(client.getRoom(space2)); viewRoom(room2); - await store.setActiveSpace(client.getRoom(space1)); + store.setActiveSpace(client.getRoom(space1)); expect(getCurrentRoom()).toBe(room2); }); it("last viewed room in target space is in the current space", async () => { - await store.setActiveSpace(client.getRoom(space1)); + store.setActiveSpace(client.getRoom(space1)); viewRoom(room2); - await store.setActiveSpace(client.getRoom(space2)); + store.setActiveSpace(client.getRoom(space2)); expect(getCurrentRoom()).toBe(space2); - await store.setActiveSpace(client.getRoom(space1)); + store.setActiveSpace(client.getRoom(space1)); expect(getCurrentRoom()).toBe(room2); }); it("last viewed room in target space is not in the current space", async () => { - await store.setActiveSpace(client.getRoom(space1)); + store.setActiveSpace(client.getRoom(space1)); viewRoom(room1); - await store.setActiveSpace(client.getRoom(space2)); + store.setActiveSpace(client.getRoom(space2)); viewRoom(room2); - await store.setActiveSpace(client.getRoom(space1)); + store.setActiveSpace(client.getRoom(space1)); expect(getCurrentRoom()).toBe(room1); }); it("last viewed room is target space is not known", async () => { - await store.setActiveSpace(client.getRoom(space1)); + store.setActiveSpace(client.getRoom(space1)); viewRoom(room1); localStorage.setItem(`mx_space_context_${space2}`, orphan2); - await store.setActiveSpace(client.getRoom(space2)); + store.setActiveSpace(client.getRoom(space2)); expect(getCurrentRoom()).toBe(space2); }); it("last viewed room is target space is no longer in that space", async () => { - await store.setActiveSpace(client.getRoom(space1)); + store.setActiveSpace(client.getRoom(space1)); viewRoom(room1); localStorage.setItem(`mx_space_context_${space2}`, room1); - await store.setActiveSpace(client.getRoom(space2)); + store.setActiveSpace(client.getRoom(space2)); expect(getCurrentRoom()).toBe(space2); // Space home instead of room1 }); it("no last viewed room in target space", async () => { - await store.setActiveSpace(client.getRoom(space1)); + store.setActiveSpace(client.getRoom(space1)); viewRoom(room1); - await store.setActiveSpace(client.getRoom(space2)); + store.setActiveSpace(client.getRoom(space2)); expect(getCurrentRoom()).toBe(space2); }); it("no last viewed room in home space", async () => { - await store.setActiveSpace(client.getRoom(space1)); + store.setActiveSpace(client.getRoom(space1)); viewRoom(room1); - await store.setActiveSpace(null); + store.setActiveSpace(null); expect(getCurrentRoom()).toBeNull(); // Home }); }); @@ -715,28 +715,28 @@ describe("SpaceStore", () => { it("no switch required, room is in current space", async () => { viewRoom(room1); - await store.setActiveSpace(client.getRoom(space1), false); + store.setActiveSpace(client.getRoom(space1), false); viewRoom(room2); expect(store.activeSpace).toBe(client.getRoom(space1)); }); it("switch to canonical parent space for room", async () => { viewRoom(room1); - await store.setActiveSpace(client.getRoom(space2), false); + store.setActiveSpace(client.getRoom(space2), false); viewRoom(room2); expect(store.activeSpace).toBe(client.getRoom(space2)); }); it("switch to first containing space for room", async () => { viewRoom(room2); - await store.setActiveSpace(client.getRoom(space2), false); + store.setActiveSpace(client.getRoom(space2), false); viewRoom(room3); expect(store.activeSpace).toBe(client.getRoom(space1)); }); it("switch to home for orphaned room", async () => { viewRoom(room1); - await store.setActiveSpace(client.getRoom(space1), false); + store.setActiveSpace(client.getRoom(space1), false); viewRoom(orphan1); expect(store.activeSpace).toBeNull(); }); @@ -744,7 +744,7 @@ describe("SpaceStore", () => { it("when switching rooms in the all rooms home space don't switch to related space", async () => { await setShowAllRooms(true); viewRoom(room2); - await store.setActiveSpace(null, false); + store.setActiveSpace(null, false); viewRoom(room1); expect(store.activeSpace).toBeNull(); }); diff --git a/test/stores/room-list/SpaceWatcher-test.ts b/test/stores/room-list/SpaceWatcher-test.ts index 85f79c75b6a..474c279fddb 100644 --- a/test/stores/room-list/SpaceWatcher-test.ts +++ b/test/stores/room-list/SpaceWatcher-test.ts @@ -57,7 +57,7 @@ describe("SpaceWatcher", () => { beforeEach(async () => { filter = null; store.removeAllListeners(); - await store.setActiveSpace(null); + store.setActiveSpace(null); client.getVisibleRooms.mockReturnValue(rooms = []); space1 = mkSpace(space1Id); @@ -95,7 +95,7 @@ describe("SpaceWatcher", () => { await setShowAllRooms(true); new SpaceWatcher(mockRoomListStore); - await SpaceStore.instance.setActiveSpace(space1); + SpaceStore.instance.setActiveSpace(space1); expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter["space"]).toBe(space1); @@ -114,7 +114,7 @@ describe("SpaceWatcher", () => { await setShowAllRooms(false); new SpaceWatcher(mockRoomListStore); - await SpaceStore.instance.setActiveSpace(space1); + SpaceStore.instance.setActiveSpace(space1); expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter["space"]).toBe(space1); @@ -124,22 +124,22 @@ describe("SpaceWatcher", () => { await setShowAllRooms(true); new SpaceWatcher(mockRoomListStore); - await SpaceStore.instance.setActiveSpace(space1); + SpaceStore.instance.setActiveSpace(space1); expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter["space"]).toBe(space1); - await SpaceStore.instance.setActiveSpace(null); + SpaceStore.instance.setActiveSpace(null); expect(filter).toBeNull(); }); it("updates filter correctly for space -> home transition", async () => { await setShowAllRooms(false); - await SpaceStore.instance.setActiveSpace(space1); + SpaceStore.instance.setActiveSpace(space1); new SpaceWatcher(mockRoomListStore); expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter["space"]).toBe(space1); - await SpaceStore.instance.setActiveSpace(null); + SpaceStore.instance.setActiveSpace(null); expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter["space"]).toBe(null); @@ -147,12 +147,12 @@ describe("SpaceWatcher", () => { it("updates filter correctly for space -> space transition", async () => { await setShowAllRooms(false); - await SpaceStore.instance.setActiveSpace(space1); + SpaceStore.instance.setActiveSpace(space1); new SpaceWatcher(mockRoomListStore); expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter["space"]).toBe(space1); - await SpaceStore.instance.setActiveSpace(space2); + SpaceStore.instance.setActiveSpace(space2); expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter["space"]).toBe(space2); @@ -160,7 +160,7 @@ describe("SpaceWatcher", () => { it("doesn't change filter when changing showAllRooms mode to true", async () => { await setShowAllRooms(false); - await SpaceStore.instance.setActiveSpace(space1); + SpaceStore.instance.setActiveSpace(space1); new SpaceWatcher(mockRoomListStore); expect(filter).toBeInstanceOf(SpaceFilterCondition); @@ -173,7 +173,7 @@ describe("SpaceWatcher", () => { it("doesn't change filter when changing showAllRooms mode to false", async () => { await setShowAllRooms(true); - await SpaceStore.instance.setActiveSpace(space1); + SpaceStore.instance.setActiveSpace(space1); new SpaceWatcher(mockRoomListStore); expect(filter).toBeInstanceOf(SpaceFilterCondition);