Merge pull request #5899 from matrix-org/t3chguy/spaces-stability
Improve edge cases with spaces context switchingpull/21833/head
						commit
						3fb4b6258a
					
				|  | @ -51,11 +51,7 @@ export const UPDATE_SELECTED_SPACE = Symbol("selected-space"); | |||
| 
 | ||||
| const MAX_SUGGESTED_ROOMS = 20; | ||||
| 
 | ||||
| const getLastViewedRoomsStorageKey = (space?: Room) => { | ||||
|     const lastViewRooms = "mx_last_viewed_rooms"; | ||||
|     const homeSpace = "home_space"; | ||||
|     return `${lastViewRooms}_${space?.roomId || homeSpace}`; | ||||
| } | ||||
| const getSpaceContextKey = (space?: Room) => `mx_space_context_${space?.roomId || "home_space"}`; | ||||
| 
 | ||||
| const partitionSpacesAndRooms = (arr: Room[]): [Room[], Room[]] => { // [spaces, rooms]
 | ||||
|     return arr.reduce((result, room: Room) => { | ||||
|  | @ -110,32 +106,34 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> { | |||
|         return this._suggestedRooms; | ||||
|     } | ||||
| 
 | ||||
|     public async setActiveSpace(space: Room | null) { | ||||
|     public async setActiveSpace(space: Room | null, contextSwitch = true) { | ||||
|         if (space === this.activeSpace) return; | ||||
| 
 | ||||
|         this._activeSpace = space; | ||||
|         this.emit(UPDATE_SELECTED_SPACE, this.activeSpace); | ||||
|         this.emit(SUGGESTED_ROOMS, this._suggestedRooms = []); | ||||
| 
 | ||||
|         // view last selected room from space
 | ||||
|         const roomId = window.localStorage.getItem(getLastViewedRoomsStorageKey(this.activeSpace)); | ||||
|         if (contextSwitch) { | ||||
|             // view last selected room from space
 | ||||
|             const roomId = window.localStorage.getItem(getSpaceContextKey(this.activeSpace)); | ||||
| 
 | ||||
|         if (roomId && this.matrixClient?.getRoom(roomId)?.getMyMembership() === "join") { | ||||
|             defaultDispatcher.dispatch({ | ||||
|                 action: "view_room", | ||||
|                 room_id: roomId, | ||||
|                 context_switch: true, | ||||
|             }); | ||||
|         } else if (space) { | ||||
|             defaultDispatcher.dispatch({ | ||||
|                 action: "view_room", | ||||
|                 room_id: space.roomId, | ||||
|                 context_switch: true, | ||||
|             }); | ||||
|         } else { | ||||
|             defaultDispatcher.dispatch({ | ||||
|                 action: "view_home_page", | ||||
|             }); | ||||
|             if (roomId && this.matrixClient?.getRoom(roomId)?.getMyMembership() === "join") { | ||||
|                 defaultDispatcher.dispatch({ | ||||
|                     action: "view_room", | ||||
|                     room_id: roomId, | ||||
|                     context_switch: true, | ||||
|                 }); | ||||
|             } else if (space) { | ||||
|                 defaultDispatcher.dispatch({ | ||||
|                     action: "view_room", | ||||
|                     room_id: space.roomId, | ||||
|                     context_switch: true, | ||||
|                 }); | ||||
|             } else { | ||||
|                 defaultDispatcher.dispatch({ | ||||
|                     action: "view_home_page", | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // persist space selected
 | ||||
|  | @ -516,37 +514,30 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> { | |||
| 
 | ||||
|                 // Don't auto-switch rooms when reacting to a context-switch
 | ||||
|                 // 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
 | ||||
| 
 | ||||
|                 // 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.isSpaceRoom()) { | ||||
|                     this.setActiveSpace(room); | ||||
|                 } else if (!this.getSpaceFilteredRoomIds(this.activeSpace).has(room.roomId)) { | ||||
|                     // 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)); | ||||
|                     if (!parent) { | ||||
|                         parent = this.getCanonicalParent(room.roomId); | ||||
|                     } | ||||
|                     if (!parent) { | ||||
|                         const parents = Array.from(this.parentMap.get(room.roomId) || []); | ||||
|                         parent = parents.find(p => this.matrixClient.getRoom(p)); | ||||
|                     } | ||||
|                     // don't trigger a context switch when we are switching a space to match the chosen room
 | ||||
|                     this.setActiveSpace(parent || null, false); | ||||
|                 } | ||||
| 
 | ||||
|                 if (room?.getMyMembership() === "join") { | ||||
|                     if (room.isSpaceRoom()) { | ||||
|                         this.setActiveSpace(room); | ||||
|                     } else if (!this.spaceFilteredRooms.get(this._activeSpace?.roomId || HOME_SPACE).has(room.roomId)) { | ||||
|                         // 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)); | ||||
|                         if (!parent) { | ||||
|                             parent = this.getCanonicalParent(room.roomId); | ||||
|                         } | ||||
|                         if (!parent) { | ||||
|                             const parents = Array.from(this.parentMap.get(room.roomId) || []); | ||||
|                             parent = parents.find(p => this.matrixClient.getRoom(p)); | ||||
|                         } | ||||
|                         if (parent) { | ||||
|                             this.setActiveSpace(parent); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 // 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; | ||||
|             } | ||||
|             case "after_leave_room": | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Michael Telatynski
						Michael Telatynski