Conform more of the codebase to strictNullChecks (#10573)

* Conform more of the codebase to `strictNullChecks`

* Iterate
This commit is contained in:
Michael Telatynski 2023-04-13 08:52:57 +01:00 committed by GitHub
parent b4d7f6b592
commit 605ef084ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 119 additions and 104 deletions

View file

@ -45,7 +45,11 @@ interface IProps {
}
interface IState {
apps: Partial<{ [id in Container]: IApp[] }>;
apps: {
[Container.Top]: IApp[];
[Container.Center]: IApp[];
[Container.Right]?: IApp[];
};
resizingVertical: boolean; // true when changing the height of the apps drawer
resizingHorizontal: boolean; // true when changing the distribution of the width between widgets
resizing: boolean;
@ -203,12 +207,10 @@ export default class AppsDrawer extends React.Component<IProps, IState> {
}
};
private getApps = (): Partial<{ [id in Container]: IApp[] }> => {
const appsDict: Partial<{ [id in Container]: IApp[] }> = {};
appsDict[Container.Top] = WidgetLayoutStore.instance.getContainerWidgets(this.props.room, Container.Top);
appsDict[Container.Center] = WidgetLayoutStore.instance.getContainerWidgets(this.props.room, Container.Center);
return appsDict;
};
private getApps = (): IState["apps"] => ({
[Container.Top]: WidgetLayoutStore.instance.getContainerWidgets(this.props.room, Container.Top),
[Container.Center]: WidgetLayoutStore.instance.getContainerWidgets(this.props.room, Container.Center),
});
private topApps = (): IApp[] => this.state.apps[Container.Top];
private centerApps = (): IApp[] => this.state.apps[Container.Center];
@ -348,7 +350,7 @@ const PersistentVResizer: React.FC<IPersistentResizerProps> = ({
resizeNotifier.notifyTimelineHeightChanged();
}}
onResizeStop={(e, dir, ref, d) => {
let newHeight = defaultHeight + d.height;
let newHeight = defaultHeight! + d.height;
newHeight = percentageOf(newHeight, minHeight, maxHeight) * 100;
WidgetLayoutStore.instance.setContainerHeight(room, Container.Top, newHeight);

View file

@ -231,6 +231,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
}
private updateEditorState = (selection: Caret, inputType?: string, diff?: IDiff): void => {
if (!this.editorRef.current) return;
renderModel(this.editorRef.current, this.props.model);
if (selection) {
// set the caret/selection
@ -358,6 +359,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
private onPaste = (event: ClipboardEvent<HTMLDivElement>): boolean | undefined => {
event.preventDefault(); // we always handle the paste ourselves
if (!this.editorRef.current) return;
if (this.props.onPaste?.(event, this.props.model)) {
// to prevent double handling, allow props.onPaste to skip internal onPaste
return true;
@ -377,7 +379,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
}
this.modifiedFlag = true;
const range = getRangeForSelection(this.editorRef.current, model, document.getSelection());
const range = getRangeForSelection(this.editorRef.current, model, document.getSelection()!);
// If the user is pasting a link, and has a range selected which is not a link, wrap the range with the link
if (plainText && range.length > 0 && linkify.test(plainText) && !linkify.test(range.text)) {
@ -388,18 +390,20 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
};
private onInput = (event: Partial<InputEvent>): void => {
if (!this.editorRef.current) return;
// ignore any input while doing IME compositions
if (this.isIMEComposing) {
return;
}
this.modifiedFlag = true;
const sel = document.getSelection();
const sel = document.getSelection()!;
const { caret, text } = getCaretOffsetAndText(this.editorRef.current, sel);
this.props.model.update(text, event.inputType, caret);
};
private insertText(textToInsert: string, inputType = "insertText"): void {
const sel = document.getSelection();
if (!this.editorRef.current) return;
const sel = document.getSelection()!;
const { caret, text } = getCaretOffsetAndText(this.editorRef.current, sel);
const newText = text.slice(0, caret.offset) + textToInsert + text.slice(caret.offset);
caret.offset += textToInsert.length;
@ -468,6 +472,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
};
private onSelectionChange = (): void => {
if (!this.editorRef.current) return;
const { isEmpty } = this.props.model;
this.refreshLastCaretIfNeeded();
@ -486,6 +491,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
};
private onKeyDown = (event: React.KeyboardEvent): void => {
if (!this.editorRef.current) return;
const model = this.props.model;
let handled = false;
@ -497,7 +503,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
const selectionRange = getRangeForSelection(
this.editorRef.current,
this.props.model,
document.getSelection(),
document.getSelection()!,
);
// trim the range as we want it to exclude leading/trailing spaces
selectionRange.trim();
@ -745,11 +751,11 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
}
public onFormatAction = (action: Formatting): void => {
if (!this.state.useMarkdown) {
if (!this.state.useMarkdown || !this.editorRef.current) {
return;
}
const range: Range = getRangeForSelection(this.editorRef.current, this.props.model, document.getSelection());
const range: Range = getRangeForSelection(this.editorRef.current, this.props.model, document.getSelection()!);
this.historyManager.ensureLastChangesPushed(this.props.model);
this.modifiedFlag = true;

View file

@ -238,9 +238,11 @@ class EditMessageComposer extends React.Component<IEditMessageComposerProps, ISt
private get events(): MatrixEvent[] {
const liveTimelineEvents = this.context.liveTimeline?.getEvents();
const pendingEvents = this.getRoom()?.getPendingEvents();
const room = this.getRoom();
if (!liveTimelineEvents || !room) return [];
const pendingEvents = room.getPendingEvents();
const isInThread = Boolean(this.props.editState.getEvent().getThread());
return liveTimelineEvents?.concat(isInThread ? [] : pendingEvents) ?? [];
return liveTimelineEvents.concat(isInThread ? [] : pendingEvents);
}
private cancelEdit = (): void => {

View file

@ -89,15 +89,9 @@ export default class LinkPreviewWidget extends React.Component<IProps> {
image = mediaFromMxc(image).getThumbnailOfSourceHttp(imageMaxWidth, imageMaxHeight, "scale");
}
let thumbHeight = imageMaxHeight;
if (p["og:image:width"] && p["og:image:height"]) {
thumbHeight = ImageUtils.thumbHeight(
p["og:image:width"],
p["og:image:height"],
imageMaxWidth,
imageMaxHeight,
);
}
const thumbHeight =
ImageUtils.thumbHeight(p["og:image:width"], p["og:image:height"], imageMaxWidth, imageMaxHeight) ??
imageMaxHeight;
let img: JSX.Element | undefined;
if (image) {

View file

@ -276,7 +276,8 @@ export class MessageComposer extends React.Component<IProps, IState> {
if (createEvent?.getId()) createEventId = createEvent.getId();
}
const viaServers = [this.context.tombstone.getSender().split(":").slice(1).join(":")];
const sender = this.context.tombstone?.getSender();
const viaServers = sender ? [sender.split(":").slice(1).join(":")] : undefined;
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,

View file

@ -17,7 +17,7 @@ limitations under the License.
import classNames from "classnames";
import { IEventRelation } from "matrix-js-sdk/src/models/event";
import { M_POLL_START } from "matrix-js-sdk/src/@types/polls";
import React, { createContext, MouseEventHandler, ReactElement, ReactNode, useContext, useRef } from "react";
import React, { createContext, MouseEventHandler, ReactElement, ReactNode, RefObject, useContext, useRef } from "react";
import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixClient } from "matrix-js-sdk/src/client";
import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread";
@ -180,7 +180,7 @@ interface IUploadButtonProps {
const UploadButtonContextProvider: React.FC<IUploadButtonProps> = ({ roomId, relation, children }) => {
const cli = useContext(MatrixClientContext);
const roomContext = useContext(RoomContext);
const uploadInput = useRef<HTMLInputElement>();
const uploadInput = useRef() as RefObject<HTMLInputElement>;
const onUploadClick = (): void => {
if (cli?.isGuest()) {

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { useRef } from "react";
import React, { RefObject, useRef } from "react";
import { BreadcrumbsStore } from "../../../stores/BreadcrumbsStore";
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
@ -30,7 +30,7 @@ import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import RoomAvatar from "../avatars/RoomAvatar";
const RecentlyViewedButton: React.FC = () => {
const tooltipRef = useRef<InteractiveTooltip>();
const tooltipRef = useRef() as RefObject<InteractiveTooltip>;
const crumbs = useEventEmitterState(BreadcrumbsStore.instance, UPDATE_EVENT, () => BreadcrumbsStore.instance.rooms);
const content = (

View file

@ -33,7 +33,7 @@ function cancelQuoting(context: TimelineRenderingType): void {
}
interface IProps {
permalinkCreator: RoomPermalinkCreator;
permalinkCreator?: RoomPermalinkCreator;
replyToEvent?: MatrixEvent;
}