Cleanup pre MSC3773 thread unread notif logic (#10023)

This commit is contained in:
Germain 2023-01-31 16:59:24 +00:00 committed by GitHub
parent eaf152ceef
commit 703587b8e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 23 additions and 367 deletions

View file

@ -22,7 +22,6 @@ import React from "react";
import classNames from "classnames";
import { NotificationCountType, Room, RoomEvent } from "matrix-js-sdk/src/models/room";
import { ThreadEvent } from "matrix-js-sdk/src/models/thread";
import { Feature, ServerSupport } from "matrix-js-sdk/src/feature";
import { _t } from "../../../languageHandler";
import HeaderButton from "./HeaderButton";
@ -39,12 +38,9 @@ import {
UPDATE_STATUS_INDICATOR,
} from "../../../stores/notifications/RoomNotificationStateStore";
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
import { ThreadsRoomNotificationState } from "../../../stores/notifications/ThreadsRoomNotificationState";
import { SummarizedNotificationState } from "../../../stores/notifications/SummarizedNotificationState";
import { NotificationStateEvents } from "../../../stores/notifications/NotificationState";
import PosthogTrackers from "../../../PosthogTrackers";
import { ButtonEvent } from "../elements/AccessibleButton";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import { doesRoomOrThreadHaveUnreadMessages } from "../../../Unread";
const ROOM_INFO_PHASES = [
@ -133,74 +129,48 @@ interface IProps {
export default class RoomHeaderButtons extends HeaderButtons<IProps> {
private static readonly THREAD_PHASES = [RightPanelPhases.ThreadPanel, RightPanelPhases.ThreadView];
private threadNotificationState: ThreadsRoomNotificationState | null;
private globalNotificationState: SummarizedNotificationState;
private get supportsThreadNotifications(): boolean {
const client = MatrixClientPeg.get();
return client.canSupport.get(Feature.ThreadUnreadNotifications) !== ServerSupport.Unsupported;
}
public constructor(props: IProps) {
super(props, HeaderKind.Room);
this.threadNotificationState =
!this.supportsThreadNotifications && this.props.room
? RoomNotificationStateStore.instance.getThreadsRoomState(this.props.room)
: null;
this.globalNotificationState = RoomNotificationStateStore.instance.globalState;
}
public componentDidMount(): void {
super.componentDidMount();
if (!this.supportsThreadNotifications) {
this.threadNotificationState?.on(NotificationStateEvents.Update, this.onNotificationUpdate);
} else {
// Notification badge may change if the notification counts from the
// server change, if a new thread is created or updated, or if a
// receipt is sent in the thread.
this.props.room?.on(RoomEvent.UnreadNotifications, this.onNotificationUpdate);
this.props.room?.on(RoomEvent.Receipt, this.onNotificationUpdate);
this.props.room?.on(RoomEvent.Timeline, this.onNotificationUpdate);
this.props.room?.on(RoomEvent.Redaction, this.onNotificationUpdate);
this.props.room?.on(RoomEvent.LocalEchoUpdated, this.onNotificationUpdate);
this.props.room?.on(RoomEvent.MyMembership, this.onNotificationUpdate);
this.props.room?.on(ThreadEvent.New, this.onNotificationUpdate);
this.props.room?.on(ThreadEvent.Update, this.onNotificationUpdate);
}
// Notification badge may change if the notification counts from the
// server change, if a new thread is created or updated, or if a
// receipt is sent in the thread.
this.props.room?.on(RoomEvent.UnreadNotifications, this.onNotificationUpdate);
this.props.room?.on(RoomEvent.Receipt, this.onNotificationUpdate);
this.props.room?.on(RoomEvent.Timeline, this.onNotificationUpdate);
this.props.room?.on(RoomEvent.Redaction, this.onNotificationUpdate);
this.props.room?.on(RoomEvent.LocalEchoUpdated, this.onNotificationUpdate);
this.props.room?.on(RoomEvent.MyMembership, this.onNotificationUpdate);
this.props.room?.on(ThreadEvent.New, this.onNotificationUpdate);
this.props.room?.on(ThreadEvent.Update, this.onNotificationUpdate);
this.onNotificationUpdate();
RoomNotificationStateStore.instance.on(UPDATE_STATUS_INDICATOR, this.onUpdateStatus);
}
public componentWillUnmount(): void {
super.componentWillUnmount();
if (!this.supportsThreadNotifications) {
this.threadNotificationState?.off(NotificationStateEvents.Update, this.onNotificationUpdate);
} else {
this.props.room?.off(RoomEvent.UnreadNotifications, this.onNotificationUpdate);
this.props.room?.off(RoomEvent.Receipt, this.onNotificationUpdate);
this.props.room?.off(RoomEvent.Timeline, this.onNotificationUpdate);
this.props.room?.off(RoomEvent.Redaction, this.onNotificationUpdate);
this.props.room?.off(RoomEvent.LocalEchoUpdated, this.onNotificationUpdate);
this.props.room?.off(RoomEvent.MyMembership, this.onNotificationUpdate);
this.props.room?.off(ThreadEvent.New, this.onNotificationUpdate);
this.props.room?.off(ThreadEvent.Update, this.onNotificationUpdate);
}
this.props.room?.off(RoomEvent.UnreadNotifications, this.onNotificationUpdate);
this.props.room?.off(RoomEvent.Receipt, this.onNotificationUpdate);
this.props.room?.off(RoomEvent.Timeline, this.onNotificationUpdate);
this.props.room?.off(RoomEvent.Redaction, this.onNotificationUpdate);
this.props.room?.off(RoomEvent.LocalEchoUpdated, this.onNotificationUpdate);
this.props.room?.off(RoomEvent.MyMembership, this.onNotificationUpdate);
this.props.room?.off(ThreadEvent.New, this.onNotificationUpdate);
this.props.room?.off(ThreadEvent.Update, this.onNotificationUpdate);
RoomNotificationStateStore.instance.off(UPDATE_STATUS_INDICATOR, this.onUpdateStatus);
}
private onNotificationUpdate = (): void => {
let threadNotificationColor: NotificationColor;
if (!this.supportsThreadNotifications) {
threadNotificationColor = this.threadNotificationState?.color ?? NotificationColor.None;
} else {
threadNotificationColor = this.notificationColor;
}
// console.log
// XXX: why don't we read from this.state.threadNotificationColor in the render methods?
this.setState({
threadNotificationColor,
threadNotificationColor: this.notificationColor,
});
};

View file

@ -27,7 +27,6 @@ import { NotificationCountType, Room, RoomEvent } from "matrix-js-sdk/src/models
import { CallErrorCode } from "matrix-js-sdk/src/webrtc/call";
import { CryptoEvent } from "matrix-js-sdk/src/crypto";
import { UserTrustLevel } from "matrix-js-sdk/src/crypto/CrossSigning";
import { Feature, ServerSupport } from "matrix-js-sdk/src/feature";
import ReplyChain from "../elements/ReplyChain";
import { _t } from "../../../languageHandler";
@ -62,10 +61,6 @@ import SettingsStore from "../../../settings/SettingsStore";
import { MessagePreviewStore } from "../../../stores/room-list/MessagePreviewStore";
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
import { MediaEventHelper } from "../../../utils/MediaEventHelper";
import { ThreadNotificationState } from "../../../stores/notifications/ThreadNotificationState";
import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore";
import { NotificationStateEvents } from "../../../stores/notifications/NotificationState";
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
import { ButtonEvent } from "../elements/AccessibleButton";
import { copyPlaintext, getSelectedText } from "../../../utils/strings";
import { DecryptionFailureTracker } from "../../../DecryptionFailureTracker";
@ -254,7 +249,6 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
private isListeningForReceipts: boolean;
private tile = React.createRef<IEventTileType>();
private replyChain = React.createRef<ReplyChain>();
private threadState: ThreadNotificationState;
public readonly ref = createRef<HTMLElement>();
@ -389,10 +383,6 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
if (SettingsStore.getValue("feature_threadenabled")) {
this.props.mxEvent.on(ThreadEvent.Update, this.updateThread);
if (this.thread && !this.supportsThreadNotifications) {
this.setupNotificationListener(this.thread);
}
}
client.decryptEventIfNeeded(this.props.mxEvent);
@ -403,47 +393,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
this.verifyEvent();
}
private get supportsThreadNotifications(): boolean {
const client = MatrixClientPeg.get();
return client.canSupport.get(Feature.ThreadUnreadNotifications) !== ServerSupport.Unsupported;
}
private setupNotificationListener(thread: Thread): void {
if (!this.supportsThreadNotifications) {
const notifications = RoomNotificationStateStore.instance.getThreadsRoomState(thread.room);
this.threadState = notifications.getThreadRoomState(thread);
this.threadState.on(NotificationStateEvents.Update, this.onThreadStateUpdate);
this.onThreadStateUpdate();
}
}
private onThreadStateUpdate = (): void => {
if (!this.supportsThreadNotifications) {
let threadNotification = null;
switch (this.threadState?.color) {
case NotificationColor.Grey:
threadNotification = NotificationCountType.Total;
break;
case NotificationColor.Red:
threadNotification = NotificationCountType.Highlight;
break;
}
this.setState({
threadNotification,
});
}
};
private updateThread = (thread: Thread): void => {
if (thread !== this.state.thread && !this.supportsThreadNotifications) {
if (this.threadState) {
this.threadState.off(NotificationStateEvents.Update, this.onThreadStateUpdate);
}
this.setupNotificationListener(thread);
}
this.setState({ thread });
};
@ -473,7 +423,6 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
if (SettingsStore.getValue("feature_threadenabled")) {
this.props.mxEvent.off(ThreadEvent.Update, this.updateThread);
}
this.threadState?.off(NotificationStateEvents.Update, this.onThreadStateUpdate);
}
public componentDidUpdate(prevProps: Readonly<EventTileProps>, prevState: Readonly<IState>): void {
@ -1280,9 +1229,6 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
"data-shape": this.context.timelineRenderingType,
"data-self": isOwnEvent,
"data-has-reply": !!replyChain,
"data-notification": !this.supportsThreadNotifications
? this.state.threadNotification
: undefined,
"onMouseEnter": () => this.setState({ hover: true }),
"onMouseLeave": () => this.setState({ hover: false }),
"onClick": (ev: MouseEvent) => {