Merge pull request #5899 from matrix-org/t3chguy/spaces-stability
Improve edge cases with spaces context switching
This commit is contained in:
commit
3fb4b6258a
1 changed files with 41 additions and 50 deletions
|
@ -51,11 +51,7 @@ export const UPDATE_SELECTED_SPACE = Symbol("selected-space");
|
||||||
|
|
||||||
const MAX_SUGGESTED_ROOMS = 20;
|
const MAX_SUGGESTED_ROOMS = 20;
|
||||||
|
|
||||||
const getLastViewedRoomsStorageKey = (space?: Room) => {
|
const getSpaceContextKey = (space?: Room) => `mx_space_context_${space?.roomId || "home_space"}`;
|
||||||
const lastViewRooms = "mx_last_viewed_rooms";
|
|
||||||
const homeSpace = "home_space";
|
|
||||||
return `${lastViewRooms}_${space?.roomId || homeSpace}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const partitionSpacesAndRooms = (arr: Room[]): [Room[], Room[]] => { // [spaces, rooms]
|
const partitionSpacesAndRooms = (arr: Room[]): [Room[], Room[]] => { // [spaces, rooms]
|
||||||
return arr.reduce((result, room: Room) => {
|
return arr.reduce((result, room: Room) => {
|
||||||
|
@ -110,15 +106,16 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
||||||
return this._suggestedRooms;
|
return this._suggestedRooms;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async setActiveSpace(space: Room | null) {
|
public async setActiveSpace(space: Room | null, contextSwitch = true) {
|
||||||
if (space === this.activeSpace) return;
|
if (space === this.activeSpace) return;
|
||||||
|
|
||||||
this._activeSpace = space;
|
this._activeSpace = space;
|
||||||
this.emit(UPDATE_SELECTED_SPACE, this.activeSpace);
|
this.emit(UPDATE_SELECTED_SPACE, this.activeSpace);
|
||||||
this.emit(SUGGESTED_ROOMS, this._suggestedRooms = []);
|
this.emit(SUGGESTED_ROOMS, this._suggestedRooms = []);
|
||||||
|
|
||||||
|
if (contextSwitch) {
|
||||||
// view last selected room from space
|
// view last selected room from space
|
||||||
const roomId = window.localStorage.getItem(getLastViewedRoomsStorageKey(this.activeSpace));
|
const roomId = window.localStorage.getItem(getSpaceContextKey(this.activeSpace));
|
||||||
|
|
||||||
if (roomId && this.matrixClient?.getRoom(roomId)?.getMyMembership() === "join") {
|
if (roomId && this.matrixClient?.getRoom(roomId)?.getMyMembership() === "join") {
|
||||||
defaultDispatcher.dispatch({
|
defaultDispatcher.dispatch({
|
||||||
|
@ -137,6 +134,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
||||||
action: "view_home_page",
|
action: "view_home_page",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// persist space selected
|
// persist space selected
|
||||||
if (space) {
|
if (space) {
|
||||||
|
@ -516,23 +514,13 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
||||||
|
|
||||||
// Don't auto-switch rooms when reacting to a context-switch
|
// Don't auto-switch rooms when reacting to a context-switch
|
||||||
// as this is not helpful and can create loops of rooms/space switching
|
// as this is not helpful and can create loops of rooms/space switching
|
||||||
if (payload.context_switch) break;
|
if (!room || payload.context_switch) break;
|
||||||
|
|
||||||
// persist last viewed room from a space
|
// persist last viewed room from a space
|
||||||
|
|
||||||
// Don't save if the room is a space room. This would cause a problem:
|
|
||||||
// When switching to a space home, we first view that room and
|
|
||||||
// only after that we switch to that space. This causes us to
|
|
||||||
// save the space home to be the last viewed room in the home
|
|
||||||
// space.
|
|
||||||
if (room && !room.isSpaceRoom()) {
|
|
||||||
window.localStorage.setItem(getLastViewedRoomsStorageKey(this.activeSpace), payload.room_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (room?.getMyMembership() === "join") {
|
|
||||||
if (room.isSpaceRoom()) {
|
if (room.isSpaceRoom()) {
|
||||||
this.setActiveSpace(room);
|
this.setActiveSpace(room);
|
||||||
} else if (!this.spaceFilteredRooms.get(this._activeSpace?.roomId || HOME_SPACE).has(room.roomId)) {
|
} else if (!this.getSpaceFilteredRoomIds(this.activeSpace).has(room.roomId)) {
|
||||||
// TODO maybe reverse these first 2 clauses once space panel active is fixed
|
// TODO maybe reverse these first 2 clauses once space panel active is fixed
|
||||||
let parent = this.rootSpaces.find(s => this.spaceFilteredRooms.get(s.roomId)?.has(room.roomId));
|
let parent = this.rootSpaces.find(s => this.spaceFilteredRooms.get(s.roomId)?.has(room.roomId));
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
|
@ -542,11 +530,14 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
||||||
const parents = Array.from(this.parentMap.get(room.roomId) || []);
|
const parents = Array.from(this.parentMap.get(room.roomId) || []);
|
||||||
parent = parents.find(p => this.matrixClient.getRoom(p));
|
parent = parents.find(p => this.matrixClient.getRoom(p));
|
||||||
}
|
}
|
||||||
if (parent) {
|
// don't trigger a context switch when we are switching a space to match the chosen room
|
||||||
this.setActiveSpace(parent);
|
this.setActiveSpace(parent || null, false);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Persist last viewed room from a space
|
||||||
|
// we don't await setActiveSpace above as we only care about this.activeSpace being up to date
|
||||||
|
// synchronously for the below code - everything else can and should be async.
|
||||||
|
window.localStorage.setItem(getSpaceContextKey(this.activeSpace), payload.room_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "after_leave_room":
|
case "after_leave_room":
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue