Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Conform more of the codebase with strictNullChecks #10703

Merged
merged 1 commit into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/IdentityAuthClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export default class IdentityAuthClient {
}

private async checkToken(token: string): Promise<void> {
const identityServerUrl = this.matrixClient.getIdentityServerUrl();
const identityServerUrl = this.matrixClient.getIdentityServerUrl()!;

try {
await this.matrixClient.getIdentityAccount(token);
Expand Down
16 changes: 12 additions & 4 deletions src/LegacyCallHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -579,15 +579,15 @@ export default class LegacyCallHandler extends EventEmitter {
});
});
call.on(CallEvent.Hangup, () => {
if (!this.matchesCallForThisRoom(call)) return;
if (!mappedRoomId || !this.matchesCallForThisRoom(call)) return;

this.removeCallForRoom(mappedRoomId);
});
call.on(CallEvent.State, (newState: CallState, oldState: CallState) => {
this.onCallStateChanged(newState, oldState, call);
});
call.on(CallEvent.Replaced, (newCall: MatrixCall) => {
if (!this.matchesCallForThisRoom(call)) return;
if (!mappedRoomId || !this.matchesCallForThisRoom(call)) return;

logger.log(`Call ID ${call.callId} is being replaced by call ID ${newCall.callId}`);

Expand All @@ -603,7 +603,7 @@ export default class LegacyCallHandler extends EventEmitter {
this.setCallState(newCall, newCall.state);
});
call.on(CallEvent.AssertedIdentityChanged, async (): Promise<void> => {
if (!this.matchesCallForThisRoom(call)) return;
if (!mappedRoomId || !this.matchesCallForThisRoom(call)) return;

logger.log(`Call ID ${call.callId} got new asserted identity:`, call.getRemoteAssertedIdentity());

Expand Down Expand Up @@ -634,7 +634,7 @@ export default class LegacyCallHandler extends EventEmitter {

const newMappedRoomId = this.roomIdForCall(call);
logger.log(`Old room ID: ${mappedRoomId}, new room ID: ${newMappedRoomId}`);
if (newMappedRoomId !== mappedRoomId) {
if (newMappedRoomId && newMappedRoomId !== mappedRoomId) {
this.removeCallForRoom(mappedRoomId);
mappedRoomId = newMappedRoomId;
logger.log("Moving call to room " + mappedRoomId);
Expand Down Expand Up @@ -1116,6 +1116,14 @@ export default class LegacyCallHandler extends EventEmitter {
public async startTransferToMatrixID(call: MatrixCall, destination: string, consultFirst: boolean): Promise<void> {
if (consultFirst) {
const dmRoomId = await ensureDMExists(MatrixClientPeg.get(), destination);
if (!dmRoomId) {
logger.log("Failed to transfer call, could not ensure dm exists");
Modal.createDialog(ErrorDialog, {
title: _t("Transfer Failed"),
description: _t("Failed to transfer call"),
});
return;
}

this.placeCall(dmRoomId, call.type, call);
dis.dispatch<ViewRoomPayload>({
Expand Down
16 changes: 8 additions & 8 deletions src/Lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export async function loadSession(opts: ILoadSessionOpts = {}): Promise<boolean>
*/
export async function getStoredSessionOwner(): Promise<[string, boolean] | [null, null]> {
const { hsUrl, userId, hasAccessToken, isGuest } = await getStoredSessionVars();
return hsUrl && userId && hasAccessToken ? [userId, isGuest] : [null, null];
return hsUrl && userId && hasAccessToken ? [userId, !!isGuest] : [null, null];
}

/**
Expand Down Expand Up @@ -343,9 +343,9 @@ export interface IStoredSession {
* may not be valid, as it is not tested for consistency here.
* @returns {Object} Information about the session - see implementation for variables.
*/
export async function getStoredSessionVars(): Promise<IStoredSession> {
const hsUrl = localStorage.getItem(HOMESERVER_URL_KEY);
const isUrl = localStorage.getItem(ID_SERVER_URL_KEY);
export async function getStoredSessionVars(): Promise<Partial<IStoredSession>> {
const hsUrl = localStorage.getItem(HOMESERVER_URL_KEY) ?? undefined;
const isUrl = localStorage.getItem(ID_SERVER_URL_KEY) ?? undefined;
let accessToken: string | undefined;
try {
accessToken = await StorageManager.idbLoad("account", "mx_access_token");
Expand All @@ -367,8 +367,8 @@ export async function getStoredSessionVars(): Promise<IStoredSession> {
// if we pre-date storing "mx_has_access_token", but we retrieved an access
// token, then we should say we have an access token
const hasAccessToken = localStorage.getItem("mx_has_access_token") === "true" || !!accessToken;
const userId = localStorage.getItem("mx_user_id");
const deviceId = localStorage.getItem("mx_device_id");
const userId = localStorage.getItem("mx_user_id") ?? undefined;
const deviceId = localStorage.getItem("mx_device_id") ?? undefined;

let isGuest: boolean;
if (localStorage.getItem("mx_is_guest") !== null) {
Expand Down Expand Up @@ -447,7 +447,7 @@ export async function restoreFromLocalStorage(opts?: { ignoreGuest?: boolean }):
}

let decryptedAccessToken = accessToken;
const pickleKey = await PlatformPeg.get()?.getPickleKey(userId, deviceId);
const pickleKey = await PlatformPeg.get()?.getPickleKey(userId, deviceId ?? "");
if (pickleKey) {
logger.log("Got pickle key");
if (typeof accessToken !== "string") {
Expand Down Expand Up @@ -740,7 +740,7 @@ export function logout(): void {

_isLoggingOut = true;
const client = MatrixClientPeg.get();
PlatformPeg.get()?.destroyPickleKey(client.getSafeUserId(), client.getDeviceId());
PlatformPeg.get()?.destroyPickleKey(client.getSafeUserId(), client.getDeviceId() ?? "");
client.logout(true).then(onLoggedOut, (err) => {
// Just throwing an error here is going to be very unhelpful
// if you're trying to log out because your server's down and
Expand Down
5 changes: 3 additions & 2 deletions src/ScalarAuthClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default class ScalarAuthClient {
}

private writeTokenToStore(): void {
window.localStorage.setItem("mx_scalar_token_at_" + this.apiUrl, this.scalarToken);
window.localStorage.setItem("mx_scalar_token_at_" + this.apiUrl, this.scalarToken ?? "");
if (this.isDefaultManager) {
// We remove the old token from storage to migrate upwards. This is safe
// to do because even if the user switches to /app when this is on /develop
Expand Down Expand Up @@ -260,7 +260,7 @@ export default class ScalarAuthClient {
const roomId = room.roomId;
const roomName = room.name;
let url = this.uiUrl;
url += "?scalar_token=" + encodeURIComponent(this.scalarToken);
if (this.scalarToken) url += "?scalar_token=" + encodeURIComponent(this.scalarToken);
url += "&room_id=" + encodeURIComponent(roomId);
url += "&room_name=" + encodeURIComponent(roomName);
url += "&theme=" + encodeURIComponent(SettingsStore.getValue("theme"));
Expand All @@ -274,6 +274,7 @@ export default class ScalarAuthClient {
}

public getStarterLink(starterLinkUrl: string): string {
if (!this.scalarToken) return starterLinkUrl;
return starterLinkUrl + "?scalar_token=" + encodeURIComponent(this.scalarToken);
}
}
2 changes: 1 addition & 1 deletion src/components/views/auth/CountryDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default class CountryDropdown extends React.Component<IProps, IState> {
const locale = new Intl.Locale(navigator.language ?? navigator.languages[0]);
const code = locale.region ?? locale.language ?? locale.baseName;
const displayNames = new Intl.DisplayNames(["en"], { type: "region" });
const displayName = displayNames.of(code).toUpperCase();
const displayName = displayNames.of(code)?.toUpperCase();
defaultCountry = COUNTRIES.find(
(c) => c.iso2 === code.toUpperCase() || c.name.toUpperCase() === displayName,
);
Expand Down
8 changes: 4 additions & 4 deletions src/components/views/dialogs/ServerPickerDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default class ServerPickerDialog extends React.PureComponent<IProps, ISta
super(props);

const config = SdkConfig.get();
this.defaultServer = config["validated_server_config"];
this.defaultServer = config["validated_server_config"]!;
const { serverConfig } = this.props;

let otherHomeserver = "";
Expand Down Expand Up @@ -152,11 +152,11 @@ export default class ServerPickerDialog extends React.PureComponent<IProps, ISta
private onSubmit = async (ev: SyntheticEvent): Promise<void> => {
ev.preventDefault();

const valid = await this.fieldRef.current.validate({ allowEmpty: false });
const valid = await this.fieldRef.current?.validate({ allowEmpty: false });

if (!valid && !this.state.defaultChosen) {
this.fieldRef.current.focus();
this.fieldRef.current.validate({ allowEmpty: false, focused: true });
this.fieldRef.current?.focus();
this.fieldRef.current?.validate({ allowEmpty: false, focused: true });
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
ev.stopPropagation();
ev.preventDefault();

if (rovingContext.state.refs.length > 0) {
if (rovingContext.state.activeRef && rovingContext.state.refs.length > 0) {
let refs = rovingContext.state.refs;
if (!query && !filter !== null) {
// If the current selection is not in the recently viewed row then only include the
Expand All @@ -1112,6 +1112,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
if (
!query &&
!filter !== null &&
rovingContext.state.activeRef &&
rovingContext.state.refs.length > 0 &&
refIsForRecentlyViewed(rovingContext.state.activeRef)
) {
Expand Down
5 changes: 3 additions & 2 deletions src/components/views/elements/CopyableText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import AccessibleTooltipButton from "./AccessibleTooltipButton";

interface IProps {
children?: React.ReactNode;
getTextToCopy: () => string;
getTextToCopy: () => string | null;
border?: boolean;
className?: string;
}
Expand All @@ -35,7 +35,8 @@ const CopyableText: React.FC<IProps> = ({ children, getTextToCopy, border = true

const onCopyClickInternal = async (e: ButtonEvent): Promise<void> => {
e.preventDefault();
const successful = await copyPlaintext(getTextToCopy());
const text = getTextToCopy();
const successful = !!text && (await copyPlaintext(text));
setTooltip(successful ? _t("Copied!") : _t("Failed to copy"));
};

Expand Down
12 changes: 6 additions & 6 deletions src/components/views/emojipicker/EmojiPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ class EmojiPicker extends React.Component<IProps, IState> {
};

private keyboardNavigation(ev: React.KeyboardEvent, state: RovingState, dispatch: Dispatch<RovingAction>): void {
const node = state.activeRef.current;
const parent = node.parentElement;
if (!parent) return;
const node = state.activeRef?.current;
const parent = node?.parentElement;
if (!parent || !state.activeRef) return;
const rowIndex = Array.from(parent.children).indexOf(node);
const refIndex = state.refs.indexOf(state.activeRef);

Expand All @@ -173,12 +173,12 @@ class EmojiPicker extends React.Component<IProps, IState> {
switch (ev.key) {
case Key.ARROW_LEFT:
focusRef = state.refs[refIndex - 1];
newParent = focusRef?.current?.parentElement;
newParent = focusRef?.current?.parentElement ?? undefined;
break;

case Key.ARROW_RIGHT:
focusRef = state.refs[refIndex + 1];
newParent = focusRef?.current?.parentElement;
newParent = focusRef?.current?.parentElement ?? undefined;
break;

case Key.ARROW_UP:
Expand All @@ -188,7 +188,7 @@ class EmojiPicker extends React.Component<IProps, IState> {
ev.key === Key.ARROW_UP
? state.refs[refIndex - rowIndex - 1]
: state.refs[refIndex - rowIndex + EMOJIS_PER_ROW];
newParent = ref?.current?.parentElement;
newParent = ref?.current?.parentElement ?? undefined;
const newTarget = newParent?.children[clamp(rowIndex, 0, newParent.children.length - 1)];
focusRef = state.refs.find((r) => r.current === newTarget);
break;
Expand Down
9 changes: 6 additions & 3 deletions src/components/views/rooms/EditMessageComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,8 @@ class EditMessageComposer extends React.Component<IEditMessageComposerProps, ISt
// in case we're currently editing a pending event
const sel = document.getSelection()!;
let caret: DocumentOffset | undefined;
if (sel.focusNode) {
caret = getCaretOffsetAndText(this.editorRef.current?.editorRef.current, sel).caret;
if (sel.focusNode && this.editorRef.current?.editorRef.current) {
caret = getCaretOffsetAndText(this.editorRef.current.editorRef.current, sel).caret;
}
const parts = this.model.serializeParts();
// if caret is undefined because for some reason there isn't a valid selection,
Expand Down Expand Up @@ -458,12 +458,15 @@ class EditMessageComposer extends React.Component<IEditMessageComposerProps, ISt
};

public render(): React.ReactNode {
const room = this.getRoom();
if (!room) return null;

return (
<div className={classNames("mx_EditMessageComposer", this.props.className)} onKeyDown={this.onKeyDown}>
<BasicMessageComposer
ref={this.editorRef}
model={this.model}
room={this.getRoom()}
room={room}
threadId={this.props.editState?.getEvent()?.getThread()?.id}
initialCaret={this.props.editState.getCaret() ?? undefined}
label={_t("Edit message")}
Expand Down
15 changes: 8 additions & 7 deletions src/components/views/rooms/RoomList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

import { EventType, RoomType } from "matrix-js-sdk/src/@types/event";
import { Room } from "matrix-js-sdk/src/models/room";
import React, { ComponentType, createRef, ReactComponentElement, RefObject, SyntheticEvent } from "react";
import React, { ComponentType, createRef, ReactComponentElement, SyntheticEvent } from "react";

import { IState as IRovingTabIndexState, RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
Expand Down Expand Up @@ -106,8 +106,8 @@ type TagAestheticsMap = Partial<{
[tagId in TagID]: ITagAesthetics;
}>;

const auxButtonContextMenuPosition = (handle: RefObject<HTMLDivElement>): MenuProps => {
const rect = handle.current.getBoundingClientRect();
const auxButtonContextMenuPosition = (handle: HTMLDivElement): MenuProps => {
const rect = handle.getBoundingClientRect();
return {
chevronFace: ChevronFace.None,
left: rect.left - 7,
Expand All @@ -126,11 +126,11 @@ const DmAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex, dispatcher = default

if (activeSpace && (showCreateRooms || showInviteUsers)) {
let contextMenu: JSX.Element | undefined;
if (menuDisplayed) {
if (menuDisplayed && handle.current) {
const canInvite = shouldShowSpaceInvite(activeSpace);

contextMenu = (
<IconizedContextMenu {...auxButtonContextMenuPosition(handle)} onFinished={closeMenu} compact>
<IconizedContextMenu {...auxButtonContextMenuPosition(handle.current)} onFinished={closeMenu} compact>
<IconizedContextMenuOptionList first>
{showCreateRooms && (
<IconizedContextMenuOption
Expand Down Expand Up @@ -357,9 +357,9 @@ const UntaggedAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex }) => {
}

let contextMenu: JSX.Element | null = null;
if (menuDisplayed) {
if (menuDisplayed && handle.current) {
contextMenu = (
<IconizedContextMenu {...auxButtonContextMenuPosition(handle)} onFinished={closeMenu} compact>
<IconizedContextMenu {...auxButtonContextMenuPosition(handle.current)} onFinished={closeMenu} compact>
{contextMenuContent}
</IconizedContextMenu>
);
Expand Down Expand Up @@ -491,6 +491,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
if (payload.action === Action.ViewRoomDelta) {
const viewRoomDeltaPayload = payload as ViewRoomDeltaPayload;
const currentRoomId = SdkContextClass.instance.roomViewStore.getRoomId();
if (!currentRoomId) return;
const room = this.getRoomDelta(currentRoomId, viewRoomDeltaPayload.delta, viewRoomDeltaPayload.unread);
if (room) {
defaultDispatcher.dispatch<ViewRoomPayload>({
Expand Down
3 changes: 2 additions & 1 deletion src/components/views/rooms/RoomTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ export class RoomTile extends React.PureComponent<ClassProps, State> {
return;
}

const messagePreview = await MessagePreviewStore.instance.getPreviewForRoom(this.props.room, this.props.tag);
const messagePreview =
(await MessagePreviewStore.instance.getPreviewForRoom(this.props.room, this.props.tag)) ?? undefined;
this.setState({ messagePreview });
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function usePlainTextListeners(
onChange?: (content: string) => void,
onSend?: () => void,
): {
ref: RefObject<HTMLDivElement | null>;
ref: RefObject<HTMLDivElement>;
content?: string;
onInput(event: SyntheticEvent<HTMLDivElement, InputEvent | ClipboardEvent>): void;
onPaste(event: SyntheticEvent<HTMLDivElement, InputEvent | ClipboardEvent>): void;
Expand Down
6 changes: 3 additions & 3 deletions src/components/views/settings/SecureBackupPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
const verify = (sub: string): JSX.Element => (
<span
className={
sig.device && sig.deviceTrust.isVerified()
sig.device && sig.deviceTrust?.isVerified()
? "mx_SecureBackupPanel_deviceVerified"
: "mx_SecureBackupPanel_deviceNotVerified"
}
Expand Down Expand Up @@ -347,7 +347,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
{},
{ validity },
);
} else if (sig.valid && sig.deviceTrust.isVerified()) {
} else if (sig.valid && sig.deviceTrust?.isVerified()) {
sigStatus = _t(
"Backup has a <validity>valid</validity> signature from " +
"<verify>verified</verify> session <device></device>",
Expand All @@ -361,7 +361,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
{},
{ validity, verify, device },
);
} else if (!sig.valid && sig.deviceTrust.isVerified()) {
} else if (!sig.valid && sig.deviceTrust?.isVerified()) {
sigStatus = _t(
"Backup has an <validity>invalid</validity> signature from " +
"<verify>verified</verify> session <device></device>",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default class LabsUserSettingsTab extends React.Component<{}> {
const groups = new EnhancedMap<LabGroup, JSX.Element[]>();
this.labs.forEach((f) => {
groups
.getOrCreate(SettingsStore.getLabGroup(f), [])
.getOrCreate(SettingsStore.getLabGroup(f)!, [])
.push(<SettingsFlag level={SettingLevel.DEVICE} name={f} key={f} />);
});

Expand Down
Loading