Move unsent event badge handling into RoomNotificationState
This commit is contained in:
parent
e5bd863054
commit
329bc8a89e
2 changed files with 23 additions and 40 deletions
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||||
|
|
||||||
import React, { createRef } from "react";
|
import React, { createRef } from "react";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex";
|
import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex";
|
||||||
import AccessibleButton, { ButtonEvent } from "../../views/elements/AccessibleButton";
|
import AccessibleButton, { ButtonEvent } from "../../views/elements/AccessibleButton";
|
||||||
|
@ -51,8 +50,6 @@ import IconizedContextMenu, {
|
||||||
} from "../context_menus/IconizedContextMenu";
|
} from "../context_menus/IconizedContextMenu";
|
||||||
import { CommunityPrototypeStore, IRoomProfile } from "../../../stores/CommunityPrototypeStore";
|
import { CommunityPrototypeStore, IRoomProfile } from "../../../stores/CommunityPrototypeStore";
|
||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
import { getUnsentMessages } from "../../structures/RoomStatusBar";
|
|
||||||
import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState";
|
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
room: Room;
|
room: Room;
|
||||||
|
@ -68,7 +65,6 @@ interface IState {
|
||||||
notificationsMenuPosition: PartialDOMRect;
|
notificationsMenuPosition: PartialDOMRect;
|
||||||
generalMenuPosition: PartialDOMRect;
|
generalMenuPosition: PartialDOMRect;
|
||||||
messagePreview?: string;
|
messagePreview?: string;
|
||||||
hasUnsentEvents: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const messagePreviewId = (roomId: string) => `mx_RoomTile_messagePreview_${roomId}`;
|
const messagePreviewId = (roomId: string) => `mx_RoomTile_messagePreview_${roomId}`;
|
||||||
|
@ -95,7 +91,6 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
||||||
selected: ActiveRoomObserver.activeRoomId === this.props.room.roomId,
|
selected: ActiveRoomObserver.activeRoomId === this.props.room.roomId,
|
||||||
notificationsMenuPosition: null,
|
notificationsMenuPosition: null,
|
||||||
generalMenuPosition: null,
|
generalMenuPosition: null,
|
||||||
hasUnsentEvents: this.countUnsentEvents() > 0,
|
|
||||||
|
|
||||||
// generatePreview() will return nothing if the user has previews disabled
|
// generatePreview() will return nothing if the user has previews disabled
|
||||||
messagePreview: "",
|
messagePreview: "",
|
||||||
|
@ -106,10 +101,6 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
||||||
this.roomProps = EchoChamber.forRoom(this.props.room);
|
this.roomProps = EchoChamber.forRoom(this.props.room);
|
||||||
}
|
}
|
||||||
|
|
||||||
private countUnsentEvents(): number {
|
|
||||||
return getUnsentMessages(this.props.room).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
private onRoomNameUpdate = (room) => {
|
private onRoomNameUpdate = (room) => {
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
};
|
};
|
||||||
|
@ -118,11 +109,6 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
||||||
this.forceUpdate(); // notification state changed - update
|
this.forceUpdate(); // notification state changed - update
|
||||||
};
|
};
|
||||||
|
|
||||||
private onLocalEchoUpdated = (ev: MatrixEvent, room: Room) => {
|
|
||||||
if (room?.roomId !== this.props.room.roomId) return;
|
|
||||||
this.setState({ hasUnsentEvents: this.countUnsentEvents() > 0 });
|
|
||||||
};
|
|
||||||
|
|
||||||
private onRoomPropertyUpdate = (property: CachedRoomKey) => {
|
private onRoomPropertyUpdate = (property: CachedRoomKey) => {
|
||||||
if (property === CachedRoomKey.NotificationVolume) this.onNotificationUpdate();
|
if (property === CachedRoomKey.NotificationVolume) this.onNotificationUpdate();
|
||||||
// else ignore - not important for this tile
|
// else ignore - not important for this tile
|
||||||
|
@ -183,7 +169,6 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
||||||
CommunityPrototypeStore.getUpdateEventName(this.props.room.roomId),
|
CommunityPrototypeStore.getUpdateEventName(this.props.room.roomId),
|
||||||
this.onCommunityUpdate,
|
this.onCommunityUpdate,
|
||||||
);
|
);
|
||||||
MatrixClientPeg.get().on("Room.localEchoUpdated", this.onLocalEchoUpdated);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
|
@ -208,7 +193,6 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
||||||
CommunityPrototypeStore.getUpdateEventName(this.props.room.roomId),
|
CommunityPrototypeStore.getUpdateEventName(this.props.room.roomId),
|
||||||
this.onCommunityUpdate,
|
this.onCommunityUpdate,
|
||||||
);
|
);
|
||||||
MatrixClientPeg.get()?.removeListener("Room.localEchoUpdated", this.onLocalEchoUpdated);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onAction = (payload: ActionPayload) => {
|
private onAction = (payload: ActionPayload) => {
|
||||||
|
@ -587,20 +571,8 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
let badge: React.ReactNode;
|
let badge: React.ReactNode;
|
||||||
if (!this.props.isMinimized) {
|
if (!this.props.isMinimized && this.notificationState) {
|
||||||
// aria-hidden because we summarise the unread count/highlight status in a manual aria-label below
|
// aria-hidden because we summarise the unread count/highlight status in a manual aria-label below
|
||||||
if (this.state.hasUnsentEvents) {
|
|
||||||
// hardcode the badge to a danger state when there's unsent messages
|
|
||||||
badge = (
|
|
||||||
<div className="mx_RoomTile_badgeContainer" aria-hidden="true">
|
|
||||||
<NotificationBadge
|
|
||||||
notification={StaticNotificationState.RED_EXCLAMATION}
|
|
||||||
forceCount={false}
|
|
||||||
roomId={this.props.room.roomId}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
} else if (this.notificationState) {
|
|
||||||
badge = (
|
badge = (
|
||||||
<div className="mx_RoomTile_badgeContainer" aria-hidden="true">
|
<div className="mx_RoomTile_badgeContainer" aria-hidden="true">
|
||||||
<NotificationBadge
|
<NotificationBadge
|
||||||
|
@ -611,7 +583,6 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let messagePreview = null;
|
let messagePreview = null;
|
||||||
if (this.showMessagePreview && this.state.messagePreview) {
|
if (this.showMessagePreview && this.state.messagePreview) {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import * as RoomNotifs from '../../RoomNotifs';
|
import * as RoomNotifs from '../../RoomNotifs';
|
||||||
import * as Unread from '../../Unread';
|
import * as Unread from '../../Unread';
|
||||||
import { NotificationState } from "./NotificationState";
|
import { NotificationState } from "./NotificationState";
|
||||||
|
import { getUnsentMessages } from "../../components/structures/RoomStatusBar";
|
||||||
|
|
||||||
export class RoomNotificationState extends NotificationState implements IDestroyable {
|
export class RoomNotificationState extends NotificationState implements IDestroyable {
|
||||||
constructor(public readonly room: Room) {
|
constructor(public readonly room: Room) {
|
||||||
|
@ -32,6 +33,7 @@ export class RoomNotificationState extends NotificationState implements IDestroy
|
||||||
this.room.on("Room.timeline", this.handleRoomEventUpdate);
|
this.room.on("Room.timeline", this.handleRoomEventUpdate);
|
||||||
this.room.on("Room.redaction", this.handleRoomEventUpdate);
|
this.room.on("Room.redaction", this.handleRoomEventUpdate);
|
||||||
this.room.on("Room.myMembership", this.handleMembershipUpdate);
|
this.room.on("Room.myMembership", this.handleMembershipUpdate);
|
||||||
|
this.room.on("Room.localEchoUpdated", this.handleLocalEchoUpdated);
|
||||||
MatrixClientPeg.get().on("Event.decrypted", this.handleRoomEventUpdate);
|
MatrixClientPeg.get().on("Event.decrypted", this.handleRoomEventUpdate);
|
||||||
MatrixClientPeg.get().on("accountData", this.handleAccountDataUpdate);
|
MatrixClientPeg.get().on("accountData", this.handleAccountDataUpdate);
|
||||||
this.updateNotificationState();
|
this.updateNotificationState();
|
||||||
|
@ -47,12 +49,17 @@ export class RoomNotificationState extends NotificationState implements IDestroy
|
||||||
this.room.removeListener("Room.timeline", this.handleRoomEventUpdate);
|
this.room.removeListener("Room.timeline", this.handleRoomEventUpdate);
|
||||||
this.room.removeListener("Room.redaction", this.handleRoomEventUpdate);
|
this.room.removeListener("Room.redaction", this.handleRoomEventUpdate);
|
||||||
this.room.removeListener("Room.myMembership", this.handleMembershipUpdate);
|
this.room.removeListener("Room.myMembership", this.handleMembershipUpdate);
|
||||||
|
this.room.removeListener("Room.localEchoUpdated", this.handleLocalEchoUpdated);
|
||||||
if (MatrixClientPeg.get()) {
|
if (MatrixClientPeg.get()) {
|
||||||
MatrixClientPeg.get().removeListener("Event.decrypted", this.handleRoomEventUpdate);
|
MatrixClientPeg.get().removeListener("Event.decrypted", this.handleRoomEventUpdate);
|
||||||
MatrixClientPeg.get().removeListener("accountData", this.handleAccountDataUpdate);
|
MatrixClientPeg.get().removeListener("accountData", this.handleAccountDataUpdate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleLocalEchoUpdated = () => {
|
||||||
|
this.updateNotificationState();
|
||||||
|
};
|
||||||
|
|
||||||
private handleReadReceipt = (event: MatrixEvent, room: Room) => {
|
private handleReadReceipt = (event: MatrixEvent, room: Room) => {
|
||||||
if (!readReceiptChangeIsFor(event, MatrixClientPeg.get())) return; // not our own - ignore
|
if (!readReceiptChangeIsFor(event, MatrixClientPeg.get())) return; // not our own - ignore
|
||||||
if (room.roomId !== this.room.roomId) return; // not for us - ignore
|
if (room.roomId !== this.room.roomId) return; // not for us - ignore
|
||||||
|
@ -79,7 +86,12 @@ export class RoomNotificationState extends NotificationState implements IDestroy
|
||||||
private updateNotificationState() {
|
private updateNotificationState() {
|
||||||
const snapshot = this.snapshot();
|
const snapshot = this.snapshot();
|
||||||
|
|
||||||
if (RoomNotifs.getRoomNotifsState(this.room.roomId) === RoomNotifs.MUTE) {
|
if (getUnsentMessages(this.room).length > 0) {
|
||||||
|
// When there are unsent messages we show a red `!`
|
||||||
|
this._color = NotificationColor.Red;
|
||||||
|
this._symbol = "!";
|
||||||
|
this._count = 1; // not used, technically
|
||||||
|
} else if (RoomNotifs.getRoomNotifsState(this.room.roomId) === RoomNotifs.MUTE) {
|
||||||
// When muted we suppress all notification states, even if we have context on them.
|
// When muted we suppress all notification states, even if we have context on them.
|
||||||
this._color = NotificationColor.None;
|
this._color = NotificationColor.None;
|
||||||
this._symbol = null;
|
this._symbol = null;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue