diff --git a/src/components/views/rooms/RoomList2.tsx b/src/components/views/rooms/RoomList2.tsx index 06708931a2..0eef2143dd 100644 --- a/src/components/views/rooms/RoomList2.tsx +++ b/src/components/views/rooms/RoomList2.tsx @@ -17,13 +17,16 @@ limitations under the License. */ import * as React from "react"; +import { Dispatcher } from "flux"; +import { Room } from "matrix-js-sdk/src/models/room"; + import { _t, _td } from "../../../languageHandler"; import { RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex"; import { ResizeNotifier } from "../../../utils/ResizeNotifier"; -import RoomListStore, { LISTS_UPDATE_EVENT, RoomListStore2 } from "../../../stores/room-list/RoomListStore2"; +import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore2"; +import RoomViewStore from "../../../stores/RoomViewStore"; import { ITagMap } from "../../../stores/room-list/algorithms/models"; import { DefaultTagID, TagID } from "../../../stores/room-list/models"; -import { Dispatcher } from "flux"; import dis from "../../../dispatcher/dispatcher"; import defaultDispatcher from "../../../dispatcher/dispatcher"; import RoomSublist2 from "./RoomSublist2"; @@ -35,6 +38,9 @@ import GroupAvatar from "../avatars/GroupAvatar"; import TemporaryTile from "./TemporaryTile"; import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState"; import { NotificationColor } from "../../../stores/notifications/NotificationColor"; +import { TagSpecificNotificationState } from "../../../stores/notifications/TagSpecificNotificationState"; +import { Action } from "../../../dispatcher/actions"; +import { ViewRoomDeltaPayload } from "../../../dispatcher/payloads/ViewRoomDeltaPayload"; // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231 // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231 @@ -140,6 +146,7 @@ const TAG_AESTHETICS: { export default class RoomList2 extends React.Component { private searchFilter: NameFilterCondition = new NameFilterCondition(); + private dispatcherRef; constructor(props: IProps) { super(props); @@ -148,6 +155,8 @@ export default class RoomList2 extends React.Component { sublists: {}, layouts: new Map(), }; + + this.dispatcherRef = defaultDispatcher.register(this.onAction); } public componentDidUpdate(prevProps: Readonly): void { @@ -172,8 +181,48 @@ export default class RoomList2 extends React.Component { public componentWillUnmount() { RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.updateLists); + defaultDispatcher.unregister(this.dispatcherRef); } + private onAction = (payload: ActionPayload) => { + if (payload.action === Action.ViewRoomDelta) { + const viewRoomDeltaPayload = payload as ViewRoomDeltaPayload; + const currentRoomId = RoomViewStore.getRoomId(); + const room = this.getRoomDelta(currentRoomId, viewRoomDeltaPayload.delta, viewRoomDeltaPayload.unread); + if (room) { + dis.dispatch({ + action: 'view_room', + room_id: room.roomId, + show_room_tile: true, // to make sure the room gets scrolled into view + }); + } + } + }; + + private getRoomDelta = (roomId: string, delta: number, unread = false) => { + const lists = RoomListStore.instance.orderedLists; + let rooms: Room = []; + TAG_ORDER.forEach(t => { + let listRooms = lists[t]; + + if (unread) { + const notificationStates = rooms.map(r => new TagSpecificNotificationState(r, t)); + // filter to only notification rooms (and our current active room so we can index properly) + listRooms = notificationStates.filter(state => { + return state.room.roomId === roomId || state.color >= NotificationColor.Bold; + }); + notificationStates.forEach(state => state.destroy()); + } + + rooms.push(...listRooms); + }); + + const currentIndex = rooms.findIndex(r => r.roomId === roomId); + // use slice to account for looping around the start + const [room] = rooms.slice((currentIndex + delta) % rooms.length); + return room; + }; + private updateLists = () => { const newLists = RoomListStore.instance.orderedLists; console.log("new lists", newLists); diff --git a/src/stores/notifications/RoomNotificationState.ts b/src/stores/notifications/RoomNotificationState.ts index f9b19fcbcb..51355a2d4d 100644 --- a/src/stores/notifications/RoomNotificationState.ts +++ b/src/stores/notifications/RoomNotificationState.ts @@ -31,7 +31,7 @@ export class RoomNotificationState extends EventEmitter implements IDestroyable, private _count: number; private _color: NotificationColor; - constructor(private room: Room) { + constructor(public readonly room: Room) { super(); this.room.on("Room.receipt", this.handleReadReceipt); this.room.on("Room.timeline", this.handleRoomEventUpdate);