Fix bug with some space selections not being applied (#7971)

pull/21833/head
Michael Telatynski 2022-03-03 21:42:18 +00:00 committed by GitHub
parent d98a73b003
commit b8f37a46f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 26 deletions

View File

@ -17,7 +17,7 @@ limitations under the License.
import { RoomListStoreClass } from "./RoomListStore"; import { RoomListStoreClass } from "./RoomListStore";
import { SpaceFilterCondition } from "./filters/SpaceFilterCondition"; import { SpaceFilterCondition } from "./filters/SpaceFilterCondition";
import SpaceStore from "../spaces/SpaceStore"; import SpaceStore from "../spaces/SpaceStore";
import { isMetaSpace, MetaSpace, SpaceKey, UPDATE_HOME_BEHAVIOUR, UPDATE_SELECTED_SPACE } from "../spaces"; import { MetaSpace, SpaceKey, UPDATE_HOME_BEHAVIOUR, UPDATE_SELECTED_SPACE } from "../spaces";
/** /**
* Watches for changes in spaces to manage the filter on the provided RoomListStore * Watches for changes in spaces to manage the filter on the provided RoomListStore
@ -66,11 +66,6 @@ export class SpaceWatcher {
}; };
private updateFilter = () => { private updateFilter = () => {
if (!isMetaSpace(this.activeSpace)) {
SpaceStore.instance.traverseSpace(this.activeSpace, roomId => {
this.store.matrixClient?.getRoom(roomId)?.loadMembersIfNeeded();
}, false);
}
this.filter.updateSpace(this.activeSpace); this.filter.updateSpace(this.activeSpace);
}; };
} }

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { ListIteratee, Many, sortBy, throttle } from "lodash"; import { ListIteratee, Many, sortBy } from "lodash";
import { EventType, RoomType } from "matrix-js-sdk/src/@types/event"; import { EventType, RoomType } from "matrix-js-sdk/src/@types/event";
import { Room, RoomEvent } from "matrix-js-sdk/src/models/room"; import { Room, RoomEvent } from "matrix-js-sdk/src/models/room";
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
@ -235,6 +235,8 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
return; return;
} }
window.localStorage.setItem(ACTIVE_SPACE_LS_KEY, this._activeSpace = space); // Update & persist selected space
if (contextSwitch) { if (contextSwitch) {
// view last selected room from space // view last selected room from space
const roomId = window.localStorage.getItem(getSpaceContextKey(space)); const roomId = window.localStorage.getItem(getSpaceContextKey(space));
@ -251,36 +253,33 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
room_id: roomId, room_id: roomId,
context_switch: true, context_switch: true,
metricsTrigger: "WebSpaceContextSwitch", metricsTrigger: "WebSpaceContextSwitch",
}, true); });
} else if (cliSpace) { } else if (cliSpace) {
defaultDispatcher.dispatch<ViewRoomPayload>({ defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom, action: Action.ViewRoom,
room_id: space, room_id: space,
context_switch: true, context_switch: true,
metricsTrigger: "WebSpaceContextSwitch", metricsTrigger: "WebSpaceContextSwitch",
}, true); });
} else { } else {
defaultDispatcher.dispatch<ViewHomePagePayload>({ defaultDispatcher.dispatch<ViewHomePagePayload>({
action: Action.ViewHomePage, action: Action.ViewHomePage,
context_switch: true, context_switch: true,
}, true); });
} }
} }
// We can set the space after context switching as the dispatch handler which stores the last viewed room
// specifically no-ops on context_switch=true.
this._activeSpace = space;
// Emit after a synchronous dispatch for context switching to prevent racing with SpaceWatcher calling
// Room::loadMembersIfNeeded which could (via onMemberUpdate) call upon switchSpaceIfNeeded causing the
// space to wrongly bounce.
this.emit(UPDATE_SELECTED_SPACE, this.activeSpace); this.emit(UPDATE_SELECTED_SPACE, this.activeSpace);
this.emit(UPDATE_SUGGESTED_ROOMS, this._suggestedRooms = []); this.emit(UPDATE_SUGGESTED_ROOMS, this._suggestedRooms = []);
// persist space selected
window.localStorage.setItem(ACTIVE_SPACE_LS_KEY, space);
if (cliSpace) { if (cliSpace) {
this.loadSuggestedRooms(cliSpace); this.loadSuggestedRooms(cliSpace);
// Load all members for the selected space and its subspaces,
// so we can correctly show DMs we have with members of this space.
SpaceStore.instance.traverseSpace(space, roomId => {
this.matrixClient.getRoom(roomId)?.loadMembersIfNeeded();
}, false);
} }
} }
@ -683,7 +682,10 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
this.emit(space.roomId); this.emit(space.roomId);
affectedParentSpaceIds.forEach(spaceId => this.emit(spaceId)); affectedParentSpaceIds.forEach(spaceId => this.emit(spaceId));
this.switchSpaceIfNeeded(); if (!inSpace) {
// switch space if the DM is no longer considered part of the space
this.switchSpaceIfNeeded();
}
}; };
private onRoomsUpdate = () => { private onRoomsUpdate = () => {
@ -804,12 +806,12 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
this.updateNotificationStates(notificationStatesToUpdate); this.updateNotificationStates(notificationStatesToUpdate);
}; };
private switchSpaceIfNeeded = throttle(() => { private switchSpaceIfNeeded = () => {
const roomId = RoomViewStore.getRoomId(); const roomId = RoomViewStore.getRoomId();
if (!this.isRoomInSpace(this.activeSpace, roomId) && !this.matrixClient.getRoom(roomId)?.isSpaceRoom()) { if (!this.isRoomInSpace(this.activeSpace, roomId) && !this.matrixClient.getRoom(roomId)?.isSpaceRoom()) {
this.switchToRelatedSpace(roomId); this.switchToRelatedSpace(roomId);
} }
}, 100, { leading: true, trailing: true }); };
private switchToRelatedSpace = (roomId: string) => { private switchToRelatedSpace = (roomId: string) => {
if (this.suggestedRooms.find(r => r.room_id === roomId)) return; if (this.suggestedRooms.find(r => r.room_id === roomId)) return;

View File

@ -867,6 +867,13 @@ describe("SpaceStore", () => {
user: dm1Partner.userId, user: dm1Partner.userId,
room: space1, room: space1,
}); });
space.getMember.mockImplementation(userId => {
if (userId === dm1Partner.userId) {
const member = new RoomMember(space1, dm1Partner.userId);
member.membership = "join";
return member;
}
});
client.emit(RoomStateEvent.Members, event, null, null); client.emit(RoomStateEvent.Members, event, null, null);
deferred.resolve(); deferred.resolve();
@ -885,10 +892,9 @@ describe("SpaceStore", () => {
expect(space.loadMembersIfNeeded).not.toHaveBeenCalled(); expect(space.loadMembersIfNeeded).not.toHaveBeenCalled();
store.setActiveSpace(space1, true); store.setActiveSpace(space1, true);
// traverse the space and call loadMembersIfNeeded, similarly to SpaceWatcher's behaviour jest.runOnlyPendingTimers();
store.traverseSpace(space1, roomId => { expect(space.loadMembersIfNeeded).toHaveBeenCalled();
client.getRoom(roomId)?.loadMembersIfNeeded(); jest.runAllTimers();
}, false);
expect(store.activeSpace).toBe(space1); expect(store.activeSpace).toBe(space1);
expect(getCurrentRoom()).toBe(room1); expect(getCurrentRoom()).toBe(room1);