mirror of
https://github.com/element-hq/element-web
synced 2024-11-24 10:15:43 +03:00
Show indicator in Room List for unsent events
This commit is contained in:
parent
cc095c85bf
commit
9227618b42
2 changed files with 43 additions and 15 deletions
|
@ -34,7 +34,7 @@ const STATUS_BAR_HIDDEN = 0;
|
||||||
const STATUS_BAR_EXPANDED = 1;
|
const STATUS_BAR_EXPANDED = 1;
|
||||||
const STATUS_BAR_EXPANDED_LARGE = 2;
|
const STATUS_BAR_EXPANDED_LARGE = 2;
|
||||||
|
|
||||||
function getUnsentMessages(room) {
|
export function getUnsentMessages(room) {
|
||||||
if (!room) { return []; }
|
if (!room) { return []; }
|
||||||
return room.getPendingEvents().filter(function(ev) {
|
return room.getPendingEvents().filter(function(ev) {
|
||||||
return ev.status === EventStatus.NOT_SENT;
|
return ev.status === EventStatus.NOT_SENT;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
|
||||||
Copyright 2017 New Vector Ltd
|
|
||||||
Copyright 2018 Michael Telatynski <7t3chguy@gmail.com>
|
Copyright 2018 Michael Telatynski <7t3chguy@gmail.com>
|
||||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
Copyright 2015-2017, 2019-2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -19,6 +17,7 @@ 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";
|
||||||
|
@ -52,6 +51,9 @@ 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";
|
||||||
|
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
room: Room;
|
room: Room;
|
||||||
|
@ -67,6 +69,7 @@ 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}`;
|
||||||
|
@ -93,6 +96,7 @@ 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: this.generatePreview(),
|
messagePreview: this.generatePreview(),
|
||||||
|
@ -101,6 +105,10 @@ 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();
|
||||||
}
|
}
|
||||||
|
@ -109,6 +117,11 @@ 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
|
||||||
|
@ -167,6 +180,7 @@ 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() {
|
||||||
|
@ -191,6 +205,7 @@ 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()?.off("Room.localEchoUpdated", this.onLocalEchoUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onAction = (payload: ActionPayload) => {
|
private onAction = (payload: ActionPayload) => {
|
||||||
|
@ -554,8 +569,20 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
let badge: React.ReactNode;
|
let badge: React.ReactNode;
|
||||||
if (!this.props.isMinimized && this.notificationState) {
|
if (!this.props.isMinimized) {
|
||||||
// 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.forSymbol("!", NotificationColor.Red)}
|
||||||
|
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
|
||||||
|
@ -566,6 +593,7 @@ 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) {
|
||||||
|
|
Loading…
Reference in a new issue