Add thread notification with server assistance (MSC3773) (#9400)

Co-authored-by: Janne Mareike Koschinski <janne@kuschku.de>
This commit is contained in:
Germain 2022-10-24 07:50:21 +01:00 committed by GitHub
parent d4f1c573ad
commit 9eb4f8d723
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 1014 additions and 142 deletions

View file

@ -20,7 +20,8 @@ limitations under the License.
import React from "react";
import classNames from "classnames";
import { Room } from "matrix-js-sdk/src/models/room";
import { NotificationCountType, Room, RoomEvent } from "matrix-js-sdk/src/models/room";
import { Feature, ServerSupport } from "matrix-js-sdk/src/feature";
import { _t } from '../../../languageHandler';
import HeaderButton from './HeaderButton';
@ -43,6 +44,7 @@ import { SummarizedNotificationState } from "../../../stores/notifications/Summa
import { NotificationStateEvents } from "../../../stores/notifications/NotificationState";
import PosthogTrackers from "../../../PosthogTrackers";
import { ButtonEvent } from "../elements/AccessibleButton";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
const ROOM_INFO_PHASES = [
RightPanelPhases.RoomSummary,
@ -136,32 +138,67 @@ export default class RoomHeaderButtons extends HeaderButtons<IProps> {
private threadNotificationState: ThreadsRoomNotificationState;
private globalNotificationState: SummarizedNotificationState;
private get supportsThreadNotifications(): boolean {
const client = MatrixClientPeg.get();
return client.canSupport.get(Feature.ThreadUnreadNotifications) !== ServerSupport.Unsupported;
}
constructor(props: IProps) {
super(props, HeaderKind.Room);
this.threadNotificationState = RoomNotificationStateStore.instance.getThreadsRoomState(this.props.room);
if (!this.supportsThreadNotifications) {
this.threadNotificationState = RoomNotificationStateStore.instance.getThreadsRoomState(this.props.room);
}
this.globalNotificationState = RoomNotificationStateStore.instance.globalState;
}
public componentDidMount(): void {
super.componentDidMount();
this.threadNotificationState.on(NotificationStateEvents.Update, this.onThreadNotification);
if (!this.supportsThreadNotifications) {
this.threadNotificationState?.on(NotificationStateEvents.Update, this.onNotificationUpdate);
} else {
this.props.room?.on(RoomEvent.UnreadNotifications, this.onNotificationUpdate);
}
this.onNotificationUpdate();
RoomNotificationStateStore.instance.on(UPDATE_STATUS_INDICATOR, this.onUpdateStatus);
}
public componentWillUnmount(): void {
super.componentWillUnmount();
this.threadNotificationState.off(NotificationStateEvents.Update, this.onThreadNotification);
if (!this.supportsThreadNotifications) {
this.threadNotificationState?.off(NotificationStateEvents.Update, this.onNotificationUpdate);
} else {
this.props.room?.off(RoomEvent.UnreadNotifications, this.onNotificationUpdate);
}
RoomNotificationStateStore.instance.off(UPDATE_STATUS_INDICATOR, this.onUpdateStatus);
}
private onThreadNotification = (): void => {
private onNotificationUpdate = (): void => {
let threadNotificationColor: NotificationColor;
if (!this.supportsThreadNotifications) {
threadNotificationColor = this.threadNotificationState.color;
} else {
threadNotificationColor = this.notificationColor;
}
// console.log
// XXX: why don't we read from this.state.threadNotificationColor in the render methods?
this.setState({
threadNotificationColor: this.threadNotificationState.color,
threadNotificationColor,
});
};
private get notificationColor(): NotificationColor {
switch (this.props.room.threadsAggregateNotificationType) {
case NotificationCountType.Highlight:
return NotificationColor.Red;
case NotificationCountType.Total:
return NotificationColor.Grey;
default:
return NotificationColor.None;
}
}
private onUpdateStatus = (notificationState: SummarizedNotificationState): void => {
// XXX: why don't we read from this.state.globalNotificationCount in the render methods?
this.globalNotificationState = notificationState;
@ -255,12 +292,13 @@ export default class RoomHeaderButtons extends HeaderButtons<IProps> {
? <HeaderButton
key={RightPanelPhases.ThreadPanel}
name="threadsButton"
data-testid="threadsButton"
title={_t("Threads")}
onClick={this.onThreadsPanelClicked}
isHighlighted={this.isPhase(RoomHeaderButtons.THREAD_PHASES)}
isUnread={this.threadNotificationState.color > 0}
isUnread={this.state.threadNotificationColor > 0}
>
<UnreadIndicator color={this.threadNotificationState.color} />
<UnreadIndicator color={this.state.threadNotificationColor} />
</HeaderButton>
: null,
);