Add thread notification with server assistance (MSC3773) (#9400)
Co-authored-by: Janne Mareike Koschinski <janne@kuschku.de>
This commit is contained in:
parent
d4f1c573ad
commit
9eb4f8d723
22 changed files with 1014 additions and 142 deletions
|
@ -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,
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue