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

Commit b8f37a4

Browse files
authored
Fix bug with some space selections not being applied (#7971)
1 parent d98a73b commit b8f37a4

File tree

3 files changed

+29
-26
lines changed

3 files changed

+29
-26
lines changed

src/stores/room-list/SpaceWatcher.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ limitations under the License.
1717
import { RoomListStoreClass } from "./RoomListStore";
1818
import { SpaceFilterCondition } from "./filters/SpaceFilterCondition";
1919
import SpaceStore from "../spaces/SpaceStore";
20-
import { isMetaSpace, MetaSpace, SpaceKey, UPDATE_HOME_BEHAVIOUR, UPDATE_SELECTED_SPACE } from "../spaces";
20+
import { MetaSpace, SpaceKey, UPDATE_HOME_BEHAVIOUR, UPDATE_SELECTED_SPACE } from "../spaces";
2121

2222
/**
2323
* Watches for changes in spaces to manage the filter on the provided RoomListStore
@@ -66,11 +66,6 @@ export class SpaceWatcher {
6666
};
6767

6868
private updateFilter = () => {
69-
if (!isMetaSpace(this.activeSpace)) {
70-
SpaceStore.instance.traverseSpace(this.activeSpace, roomId => {
71-
this.store.matrixClient?.getRoom(roomId)?.loadMembersIfNeeded();
72-
}, false);
73-
}
7469
this.filter.updateSpace(this.activeSpace);
7570
};
7671
}

src/stores/spaces/SpaceStore.ts

+18-16
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import { ListIteratee, Many, sortBy, throttle } from "lodash";
17+
import { ListIteratee, Many, sortBy } from "lodash";
1818
import { EventType, RoomType } from "matrix-js-sdk/src/@types/event";
1919
import { Room, RoomEvent } from "matrix-js-sdk/src/models/room";
2020
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
@@ -235,6 +235,8 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
235235
return;
236236
}
237237

238+
window.localStorage.setItem(ACTIVE_SPACE_LS_KEY, this._activeSpace = space); // Update & persist selected space
239+
238240
if (contextSwitch) {
239241
// view last selected room from space
240242
const roomId = window.localStorage.getItem(getSpaceContextKey(space));
@@ -251,36 +253,33 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
251253
room_id: roomId,
252254
context_switch: true,
253255
metricsTrigger: "WebSpaceContextSwitch",
254-
}, true);
256+
});
255257
} else if (cliSpace) {
256258
defaultDispatcher.dispatch<ViewRoomPayload>({
257259
action: Action.ViewRoom,
258260
room_id: space,
259261
context_switch: true,
260262
metricsTrigger: "WebSpaceContextSwitch",
261-
}, true);
263+
});
262264
} else {
263265
defaultDispatcher.dispatch<ViewHomePagePayload>({
264266
action: Action.ViewHomePage,
265267
context_switch: true,
266-
}, true);
268+
});
267269
}
268270
}
269271

270-
// We can set the space after context switching as the dispatch handler which stores the last viewed room
271-
// specifically no-ops on context_switch=true.
272-
this._activeSpace = space;
273-
// Emit after a synchronous dispatch for context switching to prevent racing with SpaceWatcher calling
274-
// Room::loadMembersIfNeeded which could (via onMemberUpdate) call upon switchSpaceIfNeeded causing the
275-
// space to wrongly bounce.
276272
this.emit(UPDATE_SELECTED_SPACE, this.activeSpace);
277273
this.emit(UPDATE_SUGGESTED_ROOMS, this._suggestedRooms = []);
278274

279-
// persist space selected
280-
window.localStorage.setItem(ACTIVE_SPACE_LS_KEY, space);
281-
282275
if (cliSpace) {
283276
this.loadSuggestedRooms(cliSpace);
277+
278+
// Load all members for the selected space and its subspaces,
279+
// so we can correctly show DMs we have with members of this space.
280+
SpaceStore.instance.traverseSpace(space, roomId => {
281+
this.matrixClient.getRoom(roomId)?.loadMembersIfNeeded();
282+
}, false);
284283
}
285284
}
286285

@@ -683,7 +682,10 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
683682
this.emit(space.roomId);
684683
affectedParentSpaceIds.forEach(spaceId => this.emit(spaceId));
685684

686-
this.switchSpaceIfNeeded();
685+
if (!inSpace) {
686+
// switch space if the DM is no longer considered part of the space
687+
this.switchSpaceIfNeeded();
688+
}
687689
};
688690

689691
private onRoomsUpdate = () => {
@@ -804,12 +806,12 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
804806
this.updateNotificationStates(notificationStatesToUpdate);
805807
};
806808

807-
private switchSpaceIfNeeded = throttle(() => {
809+
private switchSpaceIfNeeded = () => {
808810
const roomId = RoomViewStore.getRoomId();
809811
if (!this.isRoomInSpace(this.activeSpace, roomId) && !this.matrixClient.getRoom(roomId)?.isSpaceRoom()) {
810812
this.switchToRelatedSpace(roomId);
811813
}
812-
}, 100, { leading: true, trailing: true });
814+
};
813815

814816
private switchToRelatedSpace = (roomId: string) => {
815817
if (this.suggestedRooms.find(r => r.room_id === roomId)) return;

test/stores/SpaceStore-test.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,13 @@ describe("SpaceStore", () => {
867867
user: dm1Partner.userId,
868868
room: space1,
869869
});
870+
space.getMember.mockImplementation(userId => {
871+
if (userId === dm1Partner.userId) {
872+
const member = new RoomMember(space1, dm1Partner.userId);
873+
member.membership = "join";
874+
return member;
875+
}
876+
});
870877

871878
client.emit(RoomStateEvent.Members, event, null, null);
872879
deferred.resolve();
@@ -885,10 +892,9 @@ describe("SpaceStore", () => {
885892
expect(space.loadMembersIfNeeded).not.toHaveBeenCalled();
886893

887894
store.setActiveSpace(space1, true);
888-
// traverse the space and call loadMembersIfNeeded, similarly to SpaceWatcher's behaviour
889-
store.traverseSpace(space1, roomId => {
890-
client.getRoom(roomId)?.loadMembersIfNeeded();
891-
}, false);
895+
jest.runOnlyPendingTimers();
896+
expect(space.loadMembersIfNeeded).toHaveBeenCalled();
897+
jest.runAllTimers();
892898

893899
expect(store.activeSpace).toBe(space1);
894900
expect(getCurrentRoom()).toBe(room1);

0 commit comments

Comments
 (0)