diff --git a/src/components/views/rooms/RoomList.tsx b/src/components/views/rooms/RoomList.tsx index 84521158df..9e7d9ca205 100644 --- a/src/components/views/rooms/RoomList.tsx +++ b/src/components/views/rooms/RoomList.tsx @@ -68,7 +68,7 @@ interface IState { suggestedRooms: ISuggestedRoom[]; } -const TAG_ORDER: TagID[] = [ +export const TAG_ORDER: TagID[] = [ DefaultTagID.Invite, DefaultTagID.Favourite, DefaultTagID.DM, diff --git a/src/components/views/spaces/SpacePanel.tsx b/src/components/views/spaces/SpacePanel.tsx index 60ebec0752..1c4043f150 100644 --- a/src/components/views/spaces/SpacePanel.tsx +++ b/src/components/views/spaces/SpacePanel.tsx @@ -76,7 +76,11 @@ const SpaceButton: React.FC = ({ let notifBadge; if (notificationState) { notifBadge =
- + SpaceStore.instance.setActiveRoomInSpace(space)} + forceCount={false} + notification={notificationState} + />
; } diff --git a/src/components/views/spaces/SpaceTreeLevel.tsx b/src/components/views/spaces/SpaceTreeLevel.tsx index cf48658169..c4a2a8f9d3 100644 --- a/src/components/views/spaces/SpaceTreeLevel.tsx +++ b/src/components/views/spaces/SpaceTreeLevel.tsx @@ -401,7 +401,11 @@ export class SpaceItem extends React.PureComponent { let notifBadge; if (notificationState) { notifBadge =
- + SpaceStore.instance.setActiveRoomInSpace(space)} + forceCount={false} + notification={notificationState} + />
; } diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx index 1a6b5109ec..65201134bf 100644 --- a/src/stores/SpaceStore.tsx +++ b/src/stores/SpaceStore.tsx @@ -38,6 +38,7 @@ import { arrayHasDiff } from "../utils/arrays"; import { objectDiff } from "../utils/objects"; import { arrayHasOrderChange } from "../utils/arrays"; import { reorderLexicographically } from "../utils/stringOrderField"; +import { TAG_ORDER } from "../components/views/rooms/RoomList"; type SpaceKey = string | symbol; @@ -130,6 +131,41 @@ export class SpaceStoreClass extends AsyncStoreWithClient { return this._suggestedRooms; } + public async setActiveRoomInSpace(space: Room | null) { + if (space && !space.isSpaceRoom()) return; + if (space !== this.activeSpace) await this.setActiveSpace(space); + + if (space) { + const notificationState = this.getNotificationState(space.roomId); + const roomId = notificationState.getFirstRoomWithNotifications(); + defaultDispatcher.dispatch({ + action: "view_room", + room_id: roomId, + context_switch: true, + }); + } else { + const lists = RoomListStore.instance.unfilteredLists; + for (let i = 0; i < TAG_ORDER.length; i++) { + const t = TAG_ORDER[i]; + const listRooms = lists[t]; + const unreadRoom = listRooms.find((r: Room) => { + if (this.showInHomeSpace(r)) { + const state = RoomNotificationStateStore.instance.getRoomState(r); + return state.isUnread; + } + }); + if (unreadRoom) { + defaultDispatcher.dispatch({ + action: "view_room", + room_id: unreadRoom.roomId, + context_switch: true, + }); + break; + } + } + } + } + /** * Sets the active space, updates room list filters, * optionally switches the user's room back to where they were when they last viewed that space. @@ -138,7 +174,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { * 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) { - if (space === this.activeSpace || (space && !space?.isSpaceRoom())) return; + if (space === this.activeSpace || (space && !space.isSpaceRoom())) return; this._activeSpace = space; this.emit(UPDATE_SELECTED_SPACE, this.activeSpace); diff --git a/src/stores/notifications/SpaceNotificationState.ts b/src/stores/notifications/SpaceNotificationState.ts index 61a9701a07..4c0a582f3f 100644 --- a/src/stores/notifications/SpaceNotificationState.ts +++ b/src/stores/notifications/SpaceNotificationState.ts @@ -53,6 +53,10 @@ export class SpaceNotificationState extends NotificationState { this.calculateTotalState(); } + public getFirstRoomWithNotifications() { + return this.rooms.find((room) => room.getUnreadNotificationCount() > 0).roomId; + } + public destroy() { super.destroy(); for (const state of Object.values(this.states)) {