Merge pull request #6715 from matrix-org/t3chguy/fix/18761

This commit is contained in:
Michael Telatynski 2021-09-01 14:30:17 +01:00 committed by GitHub
commit 6e7a1e2db7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 48 deletions

View file

@ -145,9 +145,9 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
return this._allRoomsInHome; return this._allRoomsInHome;
} }
public async setActiveRoomInSpace(space: Room | null): Promise<void> { public setActiveRoomInSpace(space: Room | null): void {
if (space && !space.isSpaceRoom()) return; if (space && !space.isSpaceRoom()) return;
if (space !== this.activeSpace) await this.setActiveSpace(space); if (space !== this.activeSpace) this.setActiveSpace(space);
if (space) { if (space) {
const roomId = this.getNotificationState(space.roomId).getFirstRoomWithNotifications(); const roomId = this.getNotificationState(space.roomId).getFirstRoomWithNotifications();
@ -190,7 +190,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
* @param contextSwitch whether to switch the user's context, * @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. * 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; if (space === this.activeSpace || (space && !space.isSpaceRoom())) return;
this._activeSpace = space; this._activeSpace = space;
@ -293,13 +293,17 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
} }
if (space) { if (space) {
this.loadSuggestedRooms(space);
}
}
private async loadSuggestedRooms(space) {
const suggestedRooms = await this.fetchSuggestedRooms(space); const suggestedRooms = await this.fetchSuggestedRooms(space);
if (this._activeSpace === space) { if (this._activeSpace === space) {
this._suggestedRooms = suggestedRooms; this._suggestedRooms = suggestedRooms;
this.emit(SUGGESTED_ROOMS, this._suggestedRooms); this.emit(SUGGESTED_ROOMS, this._suggestedRooms);
} }
} }
}
public fetchSuggestedRooms = async (space: Room, limit = MAX_SUGGESTED_ROOMS): Promise<ISuggestedRoom[]> => { public fetchSuggestedRooms = async (space: Room, limit = MAX_SUGGESTED_ROOMS): Promise<ISuggestedRoom[]> => {
try { try {
@ -666,6 +670,14 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
this.onSpaceUpdate(); this.onSpaceUpdate();
this.emit(room.roomId); 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; break;
case EventType.SpaceParent: case EventType.SpaceParent:

View file

@ -562,7 +562,7 @@ describe("SpaceStore", () => {
]); ]);
mkSpace(space3).getMyMembership.mockReturnValue("invite"); mkSpace(space3).getMyMembership.mockReturnValue("invite");
await run(); await run();
await store.setActiveSpace(null); store.setActiveSpace(null);
expect(store.activeSpace).toBe(null); expect(store.activeSpace).toBe(null);
}); });
afterEach(() => { afterEach(() => {
@ -570,31 +570,31 @@ describe("SpaceStore", () => {
}); });
it("switch to home space", async () => { it("switch to home space", async () => {
await store.setActiveSpace(client.getRoom(space1)); store.setActiveSpace(client.getRoom(space1));
fn.mockClear(); fn.mockClear();
await store.setActiveSpace(null); store.setActiveSpace(null);
expect(fn).toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, null); expect(fn).toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, null);
expect(store.activeSpace).toBe(null); expect(store.activeSpace).toBe(null);
}); });
it("switch to invited space", async () => { it("switch to invited space", async () => {
const space = client.getRoom(space3); const space = client.getRoom(space3);
await store.setActiveSpace(space); store.setActiveSpace(space);
expect(fn).toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, space); expect(fn).toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, space);
expect(store.activeSpace).toBe(space); expect(store.activeSpace).toBe(space);
}); });
it("switch to top level space", async () => { it("switch to top level space", async () => {
const space = client.getRoom(space1); const space = client.getRoom(space1);
await store.setActiveSpace(space); store.setActiveSpace(space);
expect(fn).toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, space); expect(fn).toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, space);
expect(store.activeSpace).toBe(space); expect(store.activeSpace).toBe(space);
}); });
it("switch to subspace", async () => { it("switch to subspace", async () => {
const space = client.getRoom(space2); const space = client.getRoom(space2);
await store.setActiveSpace(space); store.setActiveSpace(space);
expect(fn).toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, space); expect(fn).toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, space);
expect(store.activeSpace).toBe(space); expect(store.activeSpace).toBe(space);
}); });
@ -602,7 +602,7 @@ describe("SpaceStore", () => {
it("switch to unknown space is a nop", async () => { it("switch to unknown space is a nop", async () => {
expect(store.activeSpace).toBe(null); expect(store.activeSpace).toBe(null);
const space = client.getRoom(room1); // not a space const space = client.getRoom(room1); // not a space
await store.setActiveSpace(space); store.setActiveSpace(space);
expect(fn).not.toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, space); expect(fn).not.toHaveBeenCalledWith(UPDATE_SELECTED_SPACE, space);
expect(store.activeSpace).toBe(null); 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 () => { 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); viewRoom(room2);
await store.setActiveSpace(client.getRoom(space2)); store.setActiveSpace(client.getRoom(space2));
viewRoom(room2); viewRoom(room2);
await store.setActiveSpace(client.getRoom(space1)); store.setActiveSpace(client.getRoom(space1));
expect(getCurrentRoom()).toBe(room2); expect(getCurrentRoom()).toBe(room2);
}); });
it("last viewed room in target space is in the current space", async () => { 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); viewRoom(room2);
await store.setActiveSpace(client.getRoom(space2)); store.setActiveSpace(client.getRoom(space2));
expect(getCurrentRoom()).toBe(space2); expect(getCurrentRoom()).toBe(space2);
await store.setActiveSpace(client.getRoom(space1)); store.setActiveSpace(client.getRoom(space1));
expect(getCurrentRoom()).toBe(room2); expect(getCurrentRoom()).toBe(room2);
}); });
it("last viewed room in target space is not in the current space", async () => { 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); viewRoom(room1);
await store.setActiveSpace(client.getRoom(space2)); store.setActiveSpace(client.getRoom(space2));
viewRoom(room2); viewRoom(room2);
await store.setActiveSpace(client.getRoom(space1)); store.setActiveSpace(client.getRoom(space1));
expect(getCurrentRoom()).toBe(room1); expect(getCurrentRoom()).toBe(room1);
}); });
it("last viewed room is target space is not known", async () => { it("last viewed room is target space is not known", async () => {
await store.setActiveSpace(client.getRoom(space1)); store.setActiveSpace(client.getRoom(space1));
viewRoom(room1); viewRoom(room1);
localStorage.setItem(`mx_space_context_${space2}`, orphan2); localStorage.setItem(`mx_space_context_${space2}`, orphan2);
await store.setActiveSpace(client.getRoom(space2)); store.setActiveSpace(client.getRoom(space2));
expect(getCurrentRoom()).toBe(space2); expect(getCurrentRoom()).toBe(space2);
}); });
it("last viewed room is target space is no longer in that space", async () => { 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); viewRoom(room1);
localStorage.setItem(`mx_space_context_${space2}`, 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 expect(getCurrentRoom()).toBe(space2); // Space home instead of room1
}); });
it("no last viewed room in target space", async () => { it("no last viewed room in target space", async () => {
await store.setActiveSpace(client.getRoom(space1)); store.setActiveSpace(client.getRoom(space1));
viewRoom(room1); viewRoom(room1);
await store.setActiveSpace(client.getRoom(space2)); store.setActiveSpace(client.getRoom(space2));
expect(getCurrentRoom()).toBe(space2); expect(getCurrentRoom()).toBe(space2);
}); });
it("no last viewed room in home space", async () => { it("no last viewed room in home space", async () => {
await store.setActiveSpace(client.getRoom(space1)); store.setActiveSpace(client.getRoom(space1));
viewRoom(room1); viewRoom(room1);
await store.setActiveSpace(null); store.setActiveSpace(null);
expect(getCurrentRoom()).toBeNull(); // Home expect(getCurrentRoom()).toBeNull(); // Home
}); });
}); });
@ -715,28 +715,28 @@ describe("SpaceStore", () => {
it("no switch required, room is in current space", async () => { it("no switch required, room is in current space", async () => {
viewRoom(room1); viewRoom(room1);
await store.setActiveSpace(client.getRoom(space1), false); store.setActiveSpace(client.getRoom(space1), false);
viewRoom(room2); viewRoom(room2);
expect(store.activeSpace).toBe(client.getRoom(space1)); expect(store.activeSpace).toBe(client.getRoom(space1));
}); });
it("switch to canonical parent space for room", async () => { it("switch to canonical parent space for room", async () => {
viewRoom(room1); viewRoom(room1);
await store.setActiveSpace(client.getRoom(space2), false); store.setActiveSpace(client.getRoom(space2), false);
viewRoom(room2); viewRoom(room2);
expect(store.activeSpace).toBe(client.getRoom(space2)); expect(store.activeSpace).toBe(client.getRoom(space2));
}); });
it("switch to first containing space for room", async () => { it("switch to first containing space for room", async () => {
viewRoom(room2); viewRoom(room2);
await store.setActiveSpace(client.getRoom(space2), false); store.setActiveSpace(client.getRoom(space2), false);
viewRoom(room3); viewRoom(room3);
expect(store.activeSpace).toBe(client.getRoom(space1)); expect(store.activeSpace).toBe(client.getRoom(space1));
}); });
it("switch to home for orphaned room", async () => { it("switch to home for orphaned room", async () => {
viewRoom(room1); viewRoom(room1);
await store.setActiveSpace(client.getRoom(space1), false); store.setActiveSpace(client.getRoom(space1), false);
viewRoom(orphan1); viewRoom(orphan1);
expect(store.activeSpace).toBeNull(); 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 () => { it("when switching rooms in the all rooms home space don't switch to related space", async () => {
await setShowAllRooms(true); await setShowAllRooms(true);
viewRoom(room2); viewRoom(room2);
await store.setActiveSpace(null, false); store.setActiveSpace(null, false);
viewRoom(room1); viewRoom(room1);
expect(store.activeSpace).toBeNull(); expect(store.activeSpace).toBeNull();
}); });

View file

@ -57,7 +57,7 @@ describe("SpaceWatcher", () => {
beforeEach(async () => { beforeEach(async () => {
filter = null; filter = null;
store.removeAllListeners(); store.removeAllListeners();
await store.setActiveSpace(null); store.setActiveSpace(null);
client.getVisibleRooms.mockReturnValue(rooms = []); client.getVisibleRooms.mockReturnValue(rooms = []);
space1 = mkSpace(space1Id); space1 = mkSpace(space1Id);
@ -95,7 +95,7 @@ describe("SpaceWatcher", () => {
await setShowAllRooms(true); await setShowAllRooms(true);
new SpaceWatcher(mockRoomListStore); new SpaceWatcher(mockRoomListStore);
await SpaceStore.instance.setActiveSpace(space1); SpaceStore.instance.setActiveSpace(space1);
expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter).toBeInstanceOf(SpaceFilterCondition);
expect(filter["space"]).toBe(space1); expect(filter["space"]).toBe(space1);
@ -114,7 +114,7 @@ describe("SpaceWatcher", () => {
await setShowAllRooms(false); await setShowAllRooms(false);
new SpaceWatcher(mockRoomListStore); new SpaceWatcher(mockRoomListStore);
await SpaceStore.instance.setActiveSpace(space1); SpaceStore.instance.setActiveSpace(space1);
expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter).toBeInstanceOf(SpaceFilterCondition);
expect(filter["space"]).toBe(space1); expect(filter["space"]).toBe(space1);
@ -124,22 +124,22 @@ describe("SpaceWatcher", () => {
await setShowAllRooms(true); await setShowAllRooms(true);
new SpaceWatcher(mockRoomListStore); new SpaceWatcher(mockRoomListStore);
await SpaceStore.instance.setActiveSpace(space1); SpaceStore.instance.setActiveSpace(space1);
expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter).toBeInstanceOf(SpaceFilterCondition);
expect(filter["space"]).toBe(space1); expect(filter["space"]).toBe(space1);
await SpaceStore.instance.setActiveSpace(null); SpaceStore.instance.setActiveSpace(null);
expect(filter).toBeNull(); expect(filter).toBeNull();
}); });
it("updates filter correctly for space -> home transition", async () => { it("updates filter correctly for space -> home transition", async () => {
await setShowAllRooms(false); await setShowAllRooms(false);
await SpaceStore.instance.setActiveSpace(space1); SpaceStore.instance.setActiveSpace(space1);
new SpaceWatcher(mockRoomListStore); new SpaceWatcher(mockRoomListStore);
expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter).toBeInstanceOf(SpaceFilterCondition);
expect(filter["space"]).toBe(space1); expect(filter["space"]).toBe(space1);
await SpaceStore.instance.setActiveSpace(null); SpaceStore.instance.setActiveSpace(null);
expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter).toBeInstanceOf(SpaceFilterCondition);
expect(filter["space"]).toBe(null); expect(filter["space"]).toBe(null);
@ -147,12 +147,12 @@ describe("SpaceWatcher", () => {
it("updates filter correctly for space -> space transition", async () => { it("updates filter correctly for space -> space transition", async () => {
await setShowAllRooms(false); await setShowAllRooms(false);
await SpaceStore.instance.setActiveSpace(space1); SpaceStore.instance.setActiveSpace(space1);
new SpaceWatcher(mockRoomListStore); new SpaceWatcher(mockRoomListStore);
expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter).toBeInstanceOf(SpaceFilterCondition);
expect(filter["space"]).toBe(space1); expect(filter["space"]).toBe(space1);
await SpaceStore.instance.setActiveSpace(space2); SpaceStore.instance.setActiveSpace(space2);
expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter).toBeInstanceOf(SpaceFilterCondition);
expect(filter["space"]).toBe(space2); expect(filter["space"]).toBe(space2);
@ -160,7 +160,7 @@ describe("SpaceWatcher", () => {
it("doesn't change filter when changing showAllRooms mode to true", async () => { it("doesn't change filter when changing showAllRooms mode to true", async () => {
await setShowAllRooms(false); await setShowAllRooms(false);
await SpaceStore.instance.setActiveSpace(space1); SpaceStore.instance.setActiveSpace(space1);
new SpaceWatcher(mockRoomListStore); new SpaceWatcher(mockRoomListStore);
expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter).toBeInstanceOf(SpaceFilterCondition);
@ -173,7 +173,7 @@ describe("SpaceWatcher", () => {
it("doesn't change filter when changing showAllRooms mode to false", async () => { it("doesn't change filter when changing showAllRooms mode to false", async () => {
await setShowAllRooms(true); await setShowAllRooms(true);
await SpaceStore.instance.setActiveSpace(space1); SpaceStore.instance.setActiveSpace(space1);
new SpaceWatcher(mockRoomListStore); new SpaceWatcher(mockRoomListStore);
expect(filter).toBeInstanceOf(SpaceFilterCondition); expect(filter).toBeInstanceOf(SpaceFilterCondition);