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

Navigate to the first room with notifications when clicked on space notification dot #5974

Merged
merged 15 commits into from
Jul 22, 2021
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/views/rooms/RoomList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ interface IState {
suggestedRooms: ISuggestedRoom[];
}

const TAG_ORDER: TagID[] = [
export const TAG_ORDER: TagID[] = [
DefaultTagID.Invite,
DefaultTagID.Favourite,
DefaultTagID.DM,
Expand Down
6 changes: 5 additions & 1 deletion src/components/views/spaces/SpacePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ const SpaceButton: React.FC<IButtonProps> = ({
let notifBadge;
if (notificationState) {
notifBadge = <div className="mx_SpacePanel_badgeContainer">
<NotificationBadge forceCount={false} notification={notificationState} />
<NotificationBadge
onClick={() => SpaceStore.instance.setActiveRoomInSpace(space)}
forceCount={false}
notification={notificationState}
/>
</div>;
}

Expand Down
6 changes: 5 additions & 1 deletion src/components/views/spaces/SpaceTreeLevel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,11 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
let notifBadge;
if (notificationState) {
notifBadge = <div className="mx_SpacePanel_badgeContainer">
<NotificationBadge forceCount={false} notification={notificationState} />
<NotificationBadge
onClick={() => SpaceStore.instance.setActiveRoomInSpace(space)}
forceCount={false}
notification={notificationState}
/>
</div>;
}

Expand Down
38 changes: 37 additions & 1 deletion src/stores/SpaceStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -124,6 +125,41 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
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;
TAG_ORDER.every(t => {
jaiwanth-v marked this conversation as resolved.
Show resolved Hide resolved
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,
});
return false;
}
return true;
});
}
}

/**
* 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.
Expand All @@ -132,7 +168,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
* 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);
Expand Down
4 changes: 4 additions & 0 deletions src/stores/notifications/SpaceNotificationState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
4 changes: 3 additions & 1 deletion src/stores/notifications/SummarizedNotificationState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.

import { NotificationColor } from "./NotificationColor";
import { NotificationState } from "./NotificationState";
import { RoomNotificationState } from "./RoomNotificationState";

/**
* Summarizes a number of states into a unique snapshot. To populate, call
Expand All @@ -25,6 +26,7 @@ import { NotificationState } from "./NotificationState";
*/
export class SummarizedNotificationState extends NotificationState {
private totalStatesWithUnread = 0;
private unreadRoomId: string;
jaiwanth-v marked this conversation as resolved.
Show resolved Hide resolved
jaiwanth-v marked this conversation as resolved.
Show resolved Hide resolved

constructor() {
super();
Expand All @@ -45,7 +47,7 @@ export class SummarizedNotificationState extends NotificationState {
* @param includeSymbol If true, the notification state's symbol will be taken if one
* is present.
*/
public add(other: NotificationState, includeSymbol = false) {
public add(other: RoomNotificationState, includeSymbol = false) {
if (other.symbol && includeSymbol) {
this._symbol = other.symbol;
}
Expand Down