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 9 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
6 changes: 5 additions & 1 deletion src/components/views/spaces/SpacePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,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 @@ -326,7 +326,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
20 changes: 19 additions & 1 deletion src/stores/SpaceStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,24 @@ 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);

const notificationState = space
? this.getNotificationState(space.roomId)
: RoomNotificationStateStore.instance.globalState;

if (notificationState.count) {
const roomId = notificationState.getFirstRoomWithNotifications();
defaultDispatcher.dispatch({
action: "view_room",
room_id: roomId,
context_switch: 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 @@ -116,7 +134,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._notificationCounts.total > 0).roomId;
}

public destroy() {
super.destroy();
for (const state of Object.values(this.states)) {
Expand Down
10 changes: 9 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,18 +26,24 @@ 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();
this._symbol = null;
this._count = 0;
this.unreadRoomId = null;
this._color = NotificationColor.None;
}

public get numUnreadStates(): number {
return this.totalStatesWithUnread;
}

public getFirstRoomWithNotifications() {
return this.unreadRoomId;
}

/**
* Append a notification state to this snapshot, taking the loudest NotificationColor
* of the two. By default this will not adopt the symbol of the other notification
Expand All @@ -45,7 +52,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 All @@ -56,6 +63,7 @@ export class SummarizedNotificationState extends NotificationState {
this._color = other.color;
}
if (other.hasUnreadCount) {
this.unreadRoomId = !this.unreadRoomId ? other.room.roomId : this.unreadRoomId;
this.totalStatesWithUnread++;
}
}
Expand Down