Apply strictNullChecks to src/components/views/rooms/* (#10875)

* fix everything except notificationbadge

* unit test ThirdPartyMemberInfo

* fix RoomPreviewBar dm tests

* lint

* test PinnedEventTile
This commit is contained in:
Kerry 2023-05-22 11:53:23 +12:00 committed by GitHub
parent 08c0f332b3
commit 74d30187a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 326 additions and 17 deletions

View file

@ -17,7 +17,7 @@ limitations under the License.
import React from "react";
import classNames from "classnames";
import { Resizable } from "re-resizable";
import { Resizable, Size } from "re-resizable";
import { Room } from "matrix-js-sdk/src/models/room";
import { IWidget } from "matrix-widget-api";
@ -124,7 +124,7 @@ export default class AppsDrawer extends React.Component<IProps, IState> {
Container.Top,
this.topApps()
.slice(1)
.map((_, i) => this.resizer.forHandleAt(i).size),
.map((_, i) => this.resizer.forHandleAt(i)!.size),
);
this.setState({ resizingHorizontal: false });
},
@ -339,7 +339,9 @@ const PersistentVResizer: React.FC<IPersistentResizerProps> = ({
return (
<Resizable
size={{ height: Math.min(defaultHeight, maxHeight), width: undefined }}
// types do not support undefined height/width
// but resizable code checks specifically for undefined on Size prop
size={{ height: Math.min(defaultHeight, maxHeight), width: undefined } as unknown as Size}
minHeight={minHeight}
maxHeight={maxHeight}
onResizeStart={() => {

View file

@ -49,6 +49,7 @@ import { PosthogAnalytics } from "../../../PosthogAnalytics";
import { editorRoomKey, editorStateKey } from "../../../Editing";
import DocumentOffset from "../../../editor/offset";
import { attachMentions, attachRelation } from "./SendMessageComposer";
import { filterBoolean } from "../../../utils/arrays";
function getHtmlReplyFallback(mxEvent: MatrixEvent): string {
const html = mxEvent.getContent().formatted_body;
@ -149,8 +150,14 @@ class EditMessageComposer extends React.Component<IEditMessageComposerProps, ISt
this.dispatcherRef = dis.register(this.onAction);
}
private getRoom(): Room | null {
return this.props.mxClient.getRoom(this.props.editState.getEvent().getRoomId());
private getRoom(): Room {
const roomId = this.props.editState.getEvent().getRoomId();
const room = this.props.mxClient.getRoom(roomId);
// Something is very wrong if we encounter this
if (!room) {
throw new Error(`Cannot find room for event ${roomId}`);
}
return room;
}
private onKeyDown = (event: KeyboardEvent): void => {
@ -411,7 +418,8 @@ class EditMessageComposer extends React.Component<IEditMessageComposerProps, ISt
if (editState.hasEditorState()) {
// if restoring state from a previous editor,
// restore serialized parts from the state
parts = editState.getSerializedParts().map((p) => partCreator.deserializePart(p));
// (editState.hasEditorState() checks getSerializedParts is not null)
parts = filterBoolean<Part>(editState.getSerializedParts()!.map((p) => partCreator.deserializePart(p)));
} else {
// otherwise, either restore serialized parts from localStorage or parse the body of the event
const restoredParts = this.restoreStoredEditorState(partCreator);

View file

@ -71,6 +71,10 @@ export default class PinnedEventTile extends React.Component<IProps> {
public render(): React.ReactNode {
const sender = this.props.event.getSender();
if (!sender) {
throw new Error("Pinned event unexpectedly has no sender");
}
let unpinButton: JSX.Element | undefined;
if (this.props.onUnpinClicked) {
unpinButton = (

View file

@ -165,7 +165,7 @@ export default class ReadReceiptMarker extends React.PureComponent<IProps, IStat
return 0;
}
return info.top + info.parent.getBoundingClientRect().top;
return (info.top ?? 0) + info.parent.getBoundingClientRect().top;
}
private animateMarker(): void {

View file

@ -493,7 +493,9 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
const isDM = this.isDMInvite();
if (isDM) {
title = _t("Do you want to chat with %(user)s?", { user: inviteMember.name });
title = _t("Do you want to chat with %(user)s?", {
user: inviteMember?.name ?? this.props.inviterName,
});
subTitle = [avatar, _t("<userName/> wants to chat", {}, { userName: () => inviterElement })];
primaryActionLabel = _t("Start chatting");
} else {

View file

@ -53,11 +53,12 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
this.room = MatrixClientPeg.get().getRoom(this.props.event.getRoomId());
const me = this.room?.getMember(MatrixClientPeg.get().getUserId()!);
const powerLevels = this.room?.currentState.getStateEvents("m.room.power_levels", "");
const senderId = this.props.event.getSender()!;
let kickLevel = powerLevels ? powerLevels.getContent().kick : 50;
if (typeof kickLevel !== "number") kickLevel = 50;
const sender = this.room?.getMember(this.props.event.getSender());
const sender = this.room?.getMember(senderId);
this.state = {
stateKey: this.props.event.getStateKey()!,
@ -65,7 +66,7 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
displayName: this.props.event.getContent().display_name,
invited: true,
canKick: me ? me.powerLevel > kickLevel : false,
senderName: sender?.name ?? this.props.event.getSender(),
senderName: sender?.name ?? senderId,
};
}