Convert RoomStatusBar to TS

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Šimon Brandner 2021-09-12 10:01:14 +02:00
parent e48407a1d6
commit 1590fe32cf
No known key found for this signature in database
GPG key ID: 55C211A1226CB17D

View file

@ -15,7 +15,6 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { _t, _td } from '../../languageHandler'; import { _t, _td } from '../../languageHandler';
import { MatrixClientPeg } from '../../MatrixClientPeg'; import { MatrixClientPeg } from '../../MatrixClientPeg';
import Resend from '../../Resend'; import Resend from '../../Resend';
@ -23,87 +22,100 @@ import dis from '../../dispatcher/dispatcher';
import { messageForResourceLimitError } from '../../utils/ErrorUtils'; import { messageForResourceLimitError } from '../../utils/ErrorUtils';
import { Action } from "../../dispatcher/actions"; import { Action } from "../../dispatcher/actions";
import { replaceableComponent } from "../../utils/replaceableComponent"; import { replaceableComponent } from "../../utils/replaceableComponent";
import { EventStatus } from "matrix-js-sdk/src/models/event"; import { EventStatus, MatrixEvent } from "matrix-js-sdk/src/models/event";
import NotificationBadge from "../views/rooms/NotificationBadge"; import NotificationBadge from "../views/rooms/NotificationBadge";
import { StaticNotificationState } from "../../stores/notifications/StaticNotificationState"; import { StaticNotificationState } from "../../stores/notifications/StaticNotificationState";
import AccessibleButton from "../views/elements/AccessibleButton"; import AccessibleButton from "../views/elements/AccessibleButton";
import InlineSpinner from "../views/elements/InlineSpinner"; import InlineSpinner from "../views/elements/InlineSpinner";
import { SyncState } from "matrix-js-sdk/src/sync.api";
import { ISyncStateData } from "matrix-js-sdk/src/sync";
import { Room } from "matrix-js-sdk/src/models/room";
const STATUS_BAR_HIDDEN = 0; 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;
export function getUnsentMessages(room) { export function getUnsentMessages(room: Room): MatrixEvent[] {
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;
}); });
} }
interface IProps {
// the room this statusbar is representing.
room: Room;
// true if the room is being peeked at. This affects components that shouldn't
// logically be shown when peeking, such as a prompt to invite people to a room.
isPeeking?: boolean;
// callback for when the user clicks on the 'resend all' button in the
// 'unsent messages' bar
onResendAllClick?: () => void;
// callback for when the user clicks on the 'cancel all' button in the
// 'unsent messages' bar
onCancelAllClick?: () => void;
// callback for when the user clicks on the 'invite others' button in the
// 'you are alone' bar
onInviteClick?: () => void;
// callback for when we do something that changes the size of the
// status bar. This is used to trigger a re-layout in the parent
// component.
onResize?: () => void;
// callback for when the status bar can be hidden from view, as it is
// not displaying anything
onHidden?: () => void;
// callback for when the status bar is displaying something and should
// be visible
onVisible?: () => void;
}
interface IState {
syncState: SyncState;
syncStateData: ISyncStateData;
unsentMessages: MatrixEvent[];
isResending: boolean;
}
@replaceableComponent("structures.RoomStatusBar") @replaceableComponent("structures.RoomStatusBar")
export default class RoomStatusBar extends React.PureComponent { export default class RoomStatusBar extends React.PureComponent<IProps, IState> {
static propTypes = { constructor(props: IProps) {
// the room this statusbar is representing. super(props);
room: PropTypes.object.isRequired,
// true if the room is being peeked at. This affects components that shouldn't this.state = {
// logically be shown when peeking, such as a prompt to invite people to a room. syncState: MatrixClientPeg.get().getSyncState(),
isPeeking: PropTypes.bool, syncStateData: MatrixClientPeg.get().getSyncStateData(),
unsentMessages: getUnsentMessages(this.props.room),
isResending: false,
};
}
// callback for when the user clicks on the 'resend all' button in the public componentDidMount(): void {
// 'unsent messages' bar
onResendAllClick: PropTypes.func,
// callback for when the user clicks on the 'cancel all' button in the
// 'unsent messages' bar
onCancelAllClick: PropTypes.func,
// callback for when the user clicks on the 'invite others' button in the
// 'you are alone' bar
onInviteClick: PropTypes.func,
// callback for when we do something that changes the size of the
// status bar. This is used to trigger a re-layout in the parent
// component.
onResize: PropTypes.func,
// callback for when the status bar can be hidden from view, as it is
// not displaying anything
onHidden: PropTypes.func,
// callback for when the status bar is displaying something and should
// be visible
onVisible: PropTypes.func,
};
state = {
syncState: MatrixClientPeg.get().getSyncState(),
syncStateData: MatrixClientPeg.get().getSyncStateData(),
unsentMessages: getUnsentMessages(this.props.room),
isResending: false,
};
componentDidMount() {
MatrixClientPeg.get().on("sync", this.onSyncStateChange); MatrixClientPeg.get().on("sync", this.onSyncStateChange);
MatrixClientPeg.get().on("Room.localEchoUpdated", this._onRoomLocalEchoUpdated); MatrixClientPeg.get().on("Room.localEchoUpdated", this.onRoomLocalEchoUpdated);
this._checkSize(); this.checkSize();
} }
componentDidUpdate() { public componentDidUpdate(): void {
this._checkSize(); this.checkSize();
} }
componentWillUnmount() { public componentWillUnmount(): void {
// we may have entirely lost our client as we're logging out before clicking login on the guest bar... // we may have entirely lost our client as we're logging out before clicking login on the guest bar...
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
if (client) { if (client) {
client.removeListener("sync", this.onSyncStateChange); client.removeListener("sync", this.onSyncStateChange);
client.removeListener("Room.localEchoUpdated", this._onRoomLocalEchoUpdated); client.removeListener("Room.localEchoUpdated", this.onRoomLocalEchoUpdated);
} }
} }
onSyncStateChange = (state, prevState, data) => { private onSyncStateChange = (state: SyncState, prevState: SyncState, data: ISyncStateData): void => {
if (state === "SYNCING" && prevState === "SYNCING") { if (state === "SYNCING" && prevState === "SYNCING") {
return; return;
} }
@ -113,7 +125,7 @@ export default class RoomStatusBar extends React.PureComponent {
}); });
}; };
_onResendAllClick = () => { private onResendAllClick = (): void => {
Resend.resendUnsentEvents(this.props.room).then(() => { Resend.resendUnsentEvents(this.props.room).then(() => {
this.setState({ isResending: false }); this.setState({ isResending: false });
}); });
@ -121,12 +133,12 @@ export default class RoomStatusBar extends React.PureComponent {
dis.fire(Action.FocusSendMessageComposer); dis.fire(Action.FocusSendMessageComposer);
}; };
_onCancelAllClick = () => { private onCancelAllClick = (): void => {
Resend.cancelUnsentEvents(this.props.room); Resend.cancelUnsentEvents(this.props.room);
dis.fire(Action.FocusSendMessageComposer); dis.fire(Action.FocusSendMessageComposer);
}; };
_onRoomLocalEchoUpdated = (event, room, oldEventId, oldStatus) => { private onRoomLocalEchoUpdated = (ev: MatrixEvent, room: Room) => {
if (room.roomId !== this.props.room.roomId) return; if (room.roomId !== this.props.room.roomId) return;
const messages = getUnsentMessages(this.props.room); const messages = getUnsentMessages(this.props.room);
this.setState({ this.setState({
@ -136,8 +148,8 @@ export default class RoomStatusBar extends React.PureComponent {
}; };
// Check whether current size is greater than 0, if yes call props.onVisible // Check whether current size is greater than 0, if yes call props.onVisible
_checkSize() { private checkSize(): void {
if (this._getSize()) { if (this.getSize()) {
if (this.props.onVisible) this.props.onVisible(); if (this.props.onVisible) this.props.onVisible();
} else { } else {
if (this.props.onHidden) this.props.onHidden(); if (this.props.onHidden) this.props.onHidden();
@ -147,8 +159,8 @@ export default class RoomStatusBar extends React.PureComponent {
// We don't need the actual height - just whether it is likely to have // We don't need the actual height - just whether it is likely to have
// changed - so we use '0' to indicate normal size, and other values to // changed - so we use '0' to indicate normal size, and other values to
// indicate other sizes. // indicate other sizes.
_getSize() { private getSize(): number {
if (this._shouldShowConnectionError()) { if (this.shouldShowConnectionError()) {
return STATUS_BAR_EXPANDED; return STATUS_BAR_EXPANDED;
} else if (this.state.unsentMessages.length > 0 || this.state.isResending) { } else if (this.state.unsentMessages.length > 0 || this.state.isResending) {
return STATUS_BAR_EXPANDED_LARGE; return STATUS_BAR_EXPANDED_LARGE;
@ -156,7 +168,7 @@ export default class RoomStatusBar extends React.PureComponent {
return STATUS_BAR_HIDDEN; return STATUS_BAR_HIDDEN;
} }
_shouldShowConnectionError() { private shouldShowConnectionError(): boolean {
// no conn bar trumps the "some not sent" msg since you can't resend without // no conn bar trumps the "some not sent" msg since you can't resend without
// a connection! // a connection!
// There's one situation in which we don't show this 'no connection' bar, and that's // There's one situation in which we don't show this 'no connection' bar, and that's
@ -164,12 +176,12 @@ export default class RoomStatusBar extends React.PureComponent {
const errorIsMauError = Boolean( const errorIsMauError = Boolean(
this.state.syncStateData && this.state.syncStateData &&
this.state.syncStateData.error && this.state.syncStateData.error &&
this.state.syncStateData.error.errcode === 'M_RESOURCE_LIMIT_EXCEEDED', this.state.syncStateData.error.name === 'M_RESOURCE_LIMIT_EXCEEDED',
); );
return this.state.syncState === "ERROR" && !errorIsMauError; return this.state.syncState === "ERROR" && !errorIsMauError;
} }
_getUnsentMessageContent() { private getUnsentMessageContent(): JSX.Element {
const unsentMessages = this.state.unsentMessages; const unsentMessages = this.state.unsentMessages;
let title; let title;
@ -221,10 +233,10 @@ export default class RoomStatusBar extends React.PureComponent {
} }
let buttonRow = <> let buttonRow = <>
<AccessibleButton onClick={this._onCancelAllClick} className="mx_RoomStatusBar_unsentCancelAllBtn"> <AccessibleButton onClick={this.onCancelAllClick} className="mx_RoomStatusBar_unsentCancelAllBtn">
{ _t("Delete all") } { _t("Delete all") }
</AccessibleButton> </AccessibleButton>
<AccessibleButton onClick={this._onResendAllClick} className="mx_RoomStatusBar_unsentResendAllBtn"> <AccessibleButton onClick={this.onResendAllClick} className="mx_RoomStatusBar_unsentResendAllBtn">
{ _t("Retry all") } { _t("Retry all") }
</AccessibleButton> </AccessibleButton>
</>; </>;
@ -260,8 +272,8 @@ export default class RoomStatusBar extends React.PureComponent {
</>; </>;
} }
render() { public render(): JSX.Element {
if (this._shouldShowConnectionError()) { if (this.shouldShowConnectionError()) {
return ( return (
<div className="mx_RoomStatusBar"> <div className="mx_RoomStatusBar">
<div role="alert"> <div role="alert">
@ -287,7 +299,7 @@ export default class RoomStatusBar extends React.PureComponent {
} }
if (this.state.unsentMessages.length > 0 || this.state.isResending) { if (this.state.unsentMessages.length > 0 || this.state.isResending) {
return this._getUnsentMessageContent(); return this.getUnsentMessageContent();
} }
return null; return null;