Add thread notification with server assistance (MSC3773) (#9400)
Co-authored-by: Janne Mareike Koschinski <janne@kuschku.de>
This commit is contained in:
co-authored by
Janne Mareike Koschinski
parent
d4f1c573ad
commit
9eb4f8d723
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
import { MatrixEvent, MatrixEventEvent } from "matrix-js-sdk/src/models/event";
|
||||
import { NotificationCountType, Room, RoomEvent } from "matrix-js-sdk/src/models/room";
|
||||
import { ClientEvent } from "matrix-js-sdk/src/client";
|
||||
import { Feature, ServerSupport } from "matrix-js-sdk/src/feature";
|
||||
|
||||
import { NotificationColor } from "./NotificationColor";
|
||||
import { IDestroyable } from "../../utils/IDestroyable";
|
||||
@@ -32,15 +33,16 @@ import { ThreadsRoomNotificationState } from "./ThreadsRoomNotificationState";
|
||||
export class RoomNotificationState extends NotificationState implements IDestroyable {
|
||||
constructor(public readonly room: Room, private readonly threadsState?: ThreadsRoomNotificationState) {
|
||||
super();
|
||||
this.room.on(RoomEvent.Receipt, this.handleReadReceipt); // for unread indicators
|
||||
this.room.on(RoomEvent.MyMembership, this.handleMembershipUpdate); // for redness on invites
|
||||
this.room.on(RoomEvent.LocalEchoUpdated, this.handleLocalEchoUpdated); // for redness on unsent messages
|
||||
const cli = this.room.client;
|
||||
this.room.on(RoomEvent.Receipt, this.handleReadReceipt);
|
||||
this.room.on(RoomEvent.MyMembership, this.handleMembershipUpdate);
|
||||
this.room.on(RoomEvent.LocalEchoUpdated, this.handleLocalEchoUpdated);
|
||||
this.room.on(RoomEvent.UnreadNotifications, this.handleNotificationCountUpdate); // for server-sent counts
|
||||
if (threadsState) {
|
||||
threadsState.on(NotificationStateEvents.Update, this.handleThreadsUpdate);
|
||||
if (cli.canSupport.get(Feature.ThreadUnreadNotifications) === ServerSupport.Unsupported) {
|
||||
this.threadsState?.on(NotificationStateEvents.Update, this.handleThreadsUpdate);
|
||||
}
|
||||
MatrixClientPeg.get().on(MatrixEventEvent.Decrypted, this.onEventDecrypted); // for local count calculation
|
||||
MatrixClientPeg.get().on(ClientEvent.AccountData, this.handleAccountDataUpdate); // for push rules
|
||||
cli.on(MatrixEventEvent.Decrypted, this.onEventDecrypted);
|
||||
cli.on(ClientEvent.AccountData, this.handleAccountDataUpdate);
|
||||
this.updateNotificationState();
|
||||
}
|
||||
|
||||
@@ -50,17 +52,17 @@ export class RoomNotificationState extends NotificationState implements IDestroy
|
||||
|
||||
public destroy(): void {
|
||||
super.destroy();
|
||||
const cli = this.room.client;
|
||||
this.room.removeListener(RoomEvent.Receipt, this.handleReadReceipt);
|
||||
this.room.removeListener(RoomEvent.MyMembership, this.handleMembershipUpdate);
|
||||
this.room.removeListener(RoomEvent.LocalEchoUpdated, this.handleLocalEchoUpdated);
|
||||
this.room.removeListener(RoomEvent.UnreadNotifications, this.handleNotificationCountUpdate);
|
||||
if (this.threadsState) {
|
||||
if (cli.canSupport.get(Feature.ThreadUnreadNotifications) === ServerSupport.Unsupported) {
|
||||
this.room.removeListener(RoomEvent.UnreadNotifications, this.handleNotificationCountUpdate);
|
||||
} else if (this.threadsState) {
|
||||
this.threadsState.removeListener(NotificationStateEvents.Update, this.handleThreadsUpdate);
|
||||
}
|
||||
if (MatrixClientPeg.get()) {
|
||||
MatrixClientPeg.get().removeListener(MatrixEventEvent.Decrypted, this.onEventDecrypted);
|
||||
MatrixClientPeg.get().removeListener(ClientEvent.AccountData, this.handleAccountDataUpdate);
|
||||
}
|
||||
cli.removeListener(MatrixEventEvent.Decrypted, this.onEventDecrypted);
|
||||
cli.removeListener(ClientEvent.AccountData, this.handleAccountDataUpdate);
|
||||
}
|
||||
|
||||
private handleThreadsUpdate = () => {
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { ISyncStateData, SyncState } from "matrix-js-sdk/src/sync";
|
||||
import { ClientEvent } from "matrix-js-sdk/src/client";
|
||||
import { Feature, ServerSupport } from "matrix-js-sdk/src/feature";
|
||||
|
||||
import { ActionPayload } from "../../dispatcher/payloads";
|
||||
import { AsyncStoreWithClient } from "../AsyncStoreWithClient";
|
||||
@@ -39,9 +40,9 @@ export class RoomNotificationStateStore extends AsyncStoreWithClient<IState> {
|
||||
instance.start();
|
||||
return instance;
|
||||
})();
|
||||
|
||||
private roomMap = new Map<Room, RoomNotificationState>();
|
||||
private roomThreadsMap = new Map<Room, ThreadsRoomNotificationState>();
|
||||
|
||||
private roomThreadsMap: Map<Room, ThreadsRoomNotificationState> = new Map<Room, ThreadsRoomNotificationState>();
|
||||
private listMap = new Map<TagID, ListNotificationState>();
|
||||
private _globalState = new SummarizedNotificationState();
|
||||
|
||||
@@ -86,18 +87,25 @@ export class RoomNotificationStateStore extends AsyncStoreWithClient<IState> {
|
||||
*/
|
||||
public getRoomState(room: Room): RoomNotificationState {
|
||||
if (!this.roomMap.has(room)) {
|
||||
// Not very elegant, but that way we ensure that we start tracking
|
||||
// threads notification at the same time at rooms.
|
||||
// There are multiple entry points, and it's unclear which one gets
|
||||
// called first
|
||||
const threadState = new ThreadsRoomNotificationState(room);
|
||||
this.roomThreadsMap.set(room, threadState);
|
||||
let threadState;
|
||||
if (room.client.canSupport.get(Feature.ThreadUnreadNotifications) === ServerSupport.Unsupported) {
|
||||
// Not very elegant, but that way we ensure that we start tracking
|
||||
// threads notification at the same time at rooms.
|
||||
// There are multiple entry points, and it's unclear which one gets
|
||||
// called first
|
||||
const threadState = new ThreadsRoomNotificationState(room);
|
||||
this.roomThreadsMap.set(room, threadState);
|
||||
}
|
||||
this.roomMap.set(room, new RoomNotificationState(room, threadState));
|
||||
}
|
||||
return this.roomMap.get(room);
|
||||
}
|
||||
|
||||
public getThreadsRoomState(room: Room): ThreadsRoomNotificationState {
|
||||
public getThreadsRoomState(room: Room): ThreadsRoomNotificationState | null {
|
||||
if (room.client.canSupport.get(Feature.ThreadUnreadNotifications) !== ServerSupport.Unsupported) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!this.roomThreadsMap.has(room)) {
|
||||
this.roomThreadsMap.set(room, new ThreadsRoomNotificationState(room));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user