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

Commit

Permalink
Conform more of the codebase to strictNullChecks (#10504
Browse files Browse the repository at this point in the history
* Conform more of the codebase to `strictNullChecks`

* Iterate
  • Loading branch information
t3chguy authored Apr 4, 2023
1 parent 6db0c7a commit bc60a9b
Show file tree
Hide file tree
Showing 18 changed files with 60 additions and 54 deletions.
2 changes: 1 addition & 1 deletion src/LegacyCallHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ export default class LegacyCallHandler extends EventEmitter {

const timeUntilTurnCresExpire = MatrixClientPeg.get().getTurnServersExpiry() - Date.now();
logger.log("Current turn creds expire in " + timeUntilTurnCresExpire + " ms");
const call = MatrixClientPeg.get().createCall(mappedRoomId);
const call = MatrixClientPeg.get().createCall(mappedRoomId)!;

try {
this.addCallForRoom(roomId, call);
Expand Down
13 changes: 8 additions & 5 deletions src/components/views/dialogs/AddExistingToSpaceDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import React, { ReactElement, ReactNode, useContext, useMemo, useRef, useState } from "react";
import React, { ReactElement, ReactNode, RefObject, useContext, useMemo, useRef, useState } from "react";
import classNames from "classnames";
import { Room } from "matrix-js-sdk/src/models/room";
import { sleep } from "matrix-js-sdk/src/utils";
Expand Down Expand Up @@ -140,11 +140,12 @@ export const AddExistingToSpace: React.FC<IAddExistingToSpaceProps> = ({
const cli = useContext(MatrixClientContext);
const msc3946ProcessDynamicPredecessor = useSettingValue<boolean>("feature_dynamic_room_predecessors");
const visibleRooms = useMemo(
() => cli.getVisibleRooms(msc3946ProcessDynamicPredecessor).filter((r) => r.getMyMembership() === "join"),
() =>
cli?.getVisibleRooms(msc3946ProcessDynamicPredecessor).filter((r) => r.getMyMembership() === "join") ?? [],
[cli, msc3946ProcessDynamicPredecessor],
);

const scrollRef = useRef<AutoHideScrollbar<"div">>();
const scrollRef = useRef() as RefObject<AutoHideScrollbar<"div">>;
const [scrollState, setScrollState] = useState<IScrollState>({
// these are estimates which update as soon as it mounts
scrollTop: 0,
Expand Down Expand Up @@ -212,7 +213,7 @@ export const AddExistingToSpace: React.FC<IAddExistingToSpaceProps> = ({

throw e;
});
setProgress((i) => i + 1);
setProgress((i) => (i ?? 0) + 1);
} catch (e) {
logger.error("Failed to add rooms to space", e);
error = e;
Expand Down Expand Up @@ -305,13 +306,15 @@ export const AddExistingToSpace: React.FC<IAddExistingToSpaceProps> = ({

const onScroll = (): void => {
const body = scrollRef.current?.containerRef.current;
if (!body) return;
setScrollState({
scrollTop: body.scrollTop,
height: body.clientHeight,
});
};

const wrappedRef = (body: HTMLDivElement): void => {
const wrappedRef = (body: HTMLDivElement | null): void => {
if (!body) return;
setScrollState({
scrollTop: body.scrollTop,
height: body.clientHeight,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface IProps {

interface IState {
isRedacting: boolean;
redactionErrorCode: string | number;
redactionErrorCode: string | number | null;
}

/*
Expand Down
14 changes: 7 additions & 7 deletions src/components/views/dialogs/ExportDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import React, { useRef, useState, Dispatch, SetStateAction } from "react";
import React, { useRef, useState, Dispatch, SetStateAction, RefObject } from "react";
import { Room } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger";

Expand Down Expand Up @@ -104,8 +104,8 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
} = useExportFormState();

const [isExporting, setExporting] = useState(false);
const sizeLimitRef = useRef<Field>();
const messageCountRef = useRef<Field>();
const sizeLimitRef = useRef() as RefObject<Field>;
const messageCountRef = useRef() as RefObject<Field>;
const [exportProgressText, setExportProgressText] = useState(_t("Processing…"));
const [displayCancel, setCancelWarning] = useState(false);
const [exportCancelled, setExportCancelled] = useState(false);
Expand Down Expand Up @@ -144,18 +144,18 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
const onExportClick = async (): Promise<void> => {
const isValidSize =
!setSizeLimit ||
(await sizeLimitRef.current.validate({
(await sizeLimitRef.current?.validate({
focused: false,
}));

if (!isValidSize) {
sizeLimitRef.current.validate({ focused: true });
sizeLimitRef.current?.validate({ focused: true });
return;
}
if (exportType === ExportType.LastNMessages) {
const isValidNumberOfMessages = await messageCountRef.current.validate({ focused: false });
const isValidNumberOfMessages = await messageCountRef.current?.validate({ focused: false });
if (!isValidNumberOfMessages) {
messageCountRef.current.validate({ focused: true });
messageCountRef.current?.validate({ focused: true });
return;
}
}
Expand Down
27 changes: 14 additions & 13 deletions src/components/views/dialogs/IncomingSasDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import React from "react";
import React, { ReactNode } from "react";
import { IGeneratedSas, ISasEvent, SasEvent } from "matrix-js-sdk/src/crypto/verification/SAS";
import { VerificationBase, VerificationEvent } from "matrix-js-sdk/src/crypto/verification/Base";
import { logger } from "matrix-js-sdk/src/logger";
Expand Down Expand Up @@ -48,13 +48,13 @@ interface IState {
// eslint-disable-next-line camelcase
avatar_url?: string;
displayname?: string;
};
opponentProfileError: Error;
sas: IGeneratedSas;
} | null;
opponentProfileError: Error | null;
sas: IGeneratedSas | null;
}

export default class IncomingSasDialog extends React.Component<IProps, IState> {
private showSasEvent: ISasEvent;
private showSasEvent: ISasEvent | null;

public constructor(props: IProps) {
super(props);
Expand Down Expand Up @@ -93,7 +93,7 @@ export default class IncomingSasDialog extends React.Component<IProps, IState> {
});
} catch (e) {
this.setState({
opponentProfileError: e,
opponentProfileError: e as Error,
});
}
}
Expand Down Expand Up @@ -133,7 +133,7 @@ export default class IncomingSasDialog extends React.Component<IProps, IState> {
};

private onSasMatchesClick = (): void => {
this.showSasEvent.confirm();
this.showSasEvent?.confirm();
this.setState({
phase: PHASE_WAIT_FOR_PARTNER_TO_CONFIRM,
});
Expand All @@ -143,7 +143,7 @@ export default class IncomingSasDialog extends React.Component<IProps, IState> {
this.props.onFinished(true);
};

private renderPhaseStart(): JSX.Element {
private renderPhaseStart(): ReactNode {
const isSelf = this.props.verifier.userId === MatrixClientPeg.get().getUserId();

let profile;
Expand Down Expand Up @@ -227,7 +227,8 @@ export default class IncomingSasDialog extends React.Component<IProps, IState> {
);
}

private renderPhaseShowSas(): JSX.Element {
private renderPhaseShowSas(): ReactNode {
if (!this.showSasEvent) return null;
return (
<VerificationShowSas
sas={this.showSasEvent.sas}
Expand All @@ -239,7 +240,7 @@ export default class IncomingSasDialog extends React.Component<IProps, IState> {
);
}

private renderPhaseWaitForPartnerToConfirm(): JSX.Element {
private renderPhaseWaitForPartnerToConfirm(): ReactNode {
return (
<div>
<Spinner />
Expand All @@ -248,15 +249,15 @@ export default class IncomingSasDialog extends React.Component<IProps, IState> {
);
}

private renderPhaseVerified(): JSX.Element {
private renderPhaseVerified(): ReactNode {
return <VerificationComplete onDone={this.onVerifiedDoneClick} />;
}

private renderPhaseCancelled(): JSX.Element {
private renderPhaseCancelled(): ReactNode {
return <VerificationCancelled onDone={this.onCancelClick} />;
}

public render(): React.ReactNode {
public render(): ReactNode {
let body;
switch (this.state.phase) {
case PHASE_START:
Expand Down
9 changes: 4 additions & 5 deletions src/components/views/dialogs/LeaveSpaceDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ import DialogButtons from "../elements/DialogButtons";
import BaseDialog from "../dialogs/BaseDialog";
import SpaceStore from "../../../stores/spaces/SpaceStore";
import SpaceChildrenPicker from "../spaces/SpaceChildrenPicker";
import { filterBoolean } from "../../../utils/arrays";

interface IProps {
space: Room;
onFinished(leave: boolean, rooms?: Room[]): void;
}

const isOnlyAdmin = (room: Room): boolean => {
const userId = room.client.getUserId();
if (room.getMember(userId).powerLevelNorm !== 100) {
const userId = room.client.getSafeUserId();
if (room.getMember(userId)?.powerLevelNorm !== 100) {
return false; // user is not an admin
}
return room.getJoinedMembers().every((member) => {
Expand All @@ -51,9 +52,7 @@ const LeaveSpaceDialog: React.FC<IProps> = ({ space, onFinished }) => {
},
false,
);
return Array.from(roomSet)
.map((roomId) => space.client.getRoom(roomId))
.filter(Boolean);
return filterBoolean(Array.from(roomSet).map((roomId) => space.client.getRoom(roomId)));
}, [space]);
const [roomsToLeave, setRoomsToLeave] = useState<Room[]>([]);
const selectedRooms = useMemo(() => new Set(roomsToLeave), [roomsToLeave]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ import InteractiveAuthDialog from "../InteractiveAuthDialog";
interface IProps {
accountPassword?: string;
tokenLogin?: boolean;
onFinished?: (success?: boolean) => void;
onFinished: (success?: boolean) => void;
}

interface IState {
error: Error | null;
canUploadKeysWithPasswordOnly?: boolean;
canUploadKeysWithPasswordOnly: boolean | null;
accountPassword: string;
}

Expand Down Expand Up @@ -73,7 +73,7 @@ export default class CreateCrossSigningDialog extends React.PureComponent<IProps

private async queryKeyUploadAuth(): Promise<void> {
try {
await MatrixClientPeg.get().uploadDeviceSigningKeys(null, {} as CrossSigningKeys);
await MatrixClientPeg.get().uploadDeviceSigningKeys(undefined, {} as CrossSigningKeys);
// We should never get here: the server should always require
// UI auth to upload device signing keys. If we do, we upload
// no keys which would be a no-op.
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/messages/MPollBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
* @returns userId -> UserVote
*/
private collectUserVotes(): Map<string, UserVote> {
if (!this.state.voteRelations) {
if (!this.state.voteRelations || !this.context) {
return new Map<string, UserVote>();
}
return collectUserVotes(allVotes(this.state.voteRelations), this.context.getUserId(), this.state.selected);
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/right_panel/PinnedMessagesCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ const PinnedMessagesCard: React.FC<IProps> = ({ room, onClose, permalinkCreator
const newlyRead = pinnedEventIds.filter((id) => !readPinnedEvents.has(id));
if (newlyRead.length > 0) {
// clear out any read pinned events which no longer are pinned
cli.setRoomAccountData(room.roomId, ReadPinsEventId, {
cli?.setRoomAccountData(room.roomId, ReadPinsEventId, {
event_ids: pinnedEventIds,
});
}
Expand Down
8 changes: 5 additions & 3 deletions src/components/views/rooms/MemberList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default class MemberList extends React.Component<IProps, IState> {
public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) {
super(props);
this.state = this.getMembersState([], []);
this.showPresence = context.memberListStore.isPresenceEnabled();
this.showPresence = context?.memberListStore.isPresenceEnabled() ?? true;
this.mounted = true;
this.listenForMembersChanges();
}
Expand Down Expand Up @@ -278,7 +278,7 @@ export default class MemberList extends React.Component<IProps, IState> {
});
};

private getPending3PidInvites(): MatrixEvent[] | undefined {
private getPending3PidInvites(): MatrixEvent[] {
// include 3pid invites (m.room.third_party_invite) state events.
// The HS may have already converted these into m.room.member invites so
// we shouldn't add them if the 3pid invite state key (token) is in the
Expand All @@ -291,11 +291,13 @@ export default class MemberList extends React.Component<IProps, IState> {

// discard all invites which have a m.room.member event since we've
// already added them.
const memberEvent = room.currentState.getInviteForThreePidToken(e.getStateKey());
const memberEvent = room.currentState.getInviteForThreePidToken(e.getStateKey()!);
if (memberEvent) return false;
return true;
});
}

return [];
}

private makeMemberTiles(members: Array<RoomMember | MatrixEvent>): JSX.Element[] {
Expand Down
2 changes: 1 addition & 1 deletion src/stores/right-panel/RightPanelStoreIPanelState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export interface IRightPanelCard {
}

export interface IRightPanelCardStored {
phase: RightPanelPhases;
phase: RightPanelPhases | null;
state?: IRightPanelCardStateStored;
}

Expand Down
2 changes: 1 addition & 1 deletion src/utils/beacon/useBeacon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const useBeacon = (beaconInfoEvent: MatrixEvent): Beacon | undefined => {
const roomId = beaconInfoEvent.getRoomId();
const beaconIdentifier = getBeaconInfoIdentifier(beaconInfoEvent);

const room = matrixClient.getRoom(roomId);
const room = matrixClient?.getRoom(roomId);
const beaconInstance = room?.currentState.beacons.get(beaconIdentifier);

// TODO could this be less stupid?
Expand Down
4 changes: 2 additions & 2 deletions src/utils/permalinks/Permalinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,8 @@ function isHostnameIpAddress(hostname: string): boolean {
return isIp(hostname);
}

export const calculateRoomVia = (room: Room): string[] | undefined => {
export const calculateRoomVia = (room: Room): string[] => {
const permalinkCreator = new RoomPermalinkCreator(room);
permalinkCreator.load();
return permalinkCreator.serverCandidates;
return permalinkCreator.serverCandidates ?? [];
};
2 changes: 1 addition & 1 deletion src/voice-broadcast/hooks/useHasRoomLiveVoiceBroadcast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const useHasRoomLiveVoiceBroadcast = (room: Room): boolean => {
const [hasLiveVoiceBroadcast, setHasLiveVoiceBroadcast] = useState(false);

const update = useMemo(() => {
return sdkContext.client
return sdkContext?.client
? () => {
hasRoomLiveVoiceBroadcast(sdkContext.client!, room).then(
({ hasBroadcast }) => {
Expand Down
8 changes: 4 additions & 4 deletions test/LegacyCallHandler-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ describe("LegacyCallHandler", () => {
fakeCall!.getRemoteAssertedIdentity = jest.fn().mockReturnValue({
id: NATIVE_BOB,
});
fakeCall!.emit(CallEvent.AssertedIdentityChanged, fakeCall);
fakeCall!.emit(CallEvent.AssertedIdentityChanged, fakeCall!);

// Now set the config option
SdkConfig.add({
Expand All @@ -378,7 +378,7 @@ describe("LegacyCallHandler", () => {
fakeCall!.getRemoteAssertedIdentity = jest.fn().mockReturnValue({
id: NATIVE_CHARLIE,
});
fakeCall!.emit(CallEvent.AssertedIdentityChanged, fakeCall);
fakeCall!.emit(CallEvent.AssertedIdentityChanged, fakeCall!);

await roomChangePromise;
callHandler.removeAllListeners();
Expand Down Expand Up @@ -624,7 +624,7 @@ describe("LegacyCallHandler without third party protocols", () => {

// call added to call map
expect(callHandler.getCallForRoom(roomId)).toEqual(call);
call.emit(CallEvent.State, CallState.Ringing, CallState.Connected, fakeCall);
call.emit(CallEvent.State, CallState.Ringing, CallState.Connected, fakeCall!);

// ringer audio element started
expect(mockAudioElement.play).toHaveBeenCalled();
Expand All @@ -641,7 +641,7 @@ describe("LegacyCallHandler without third party protocols", () => {

// call added to call map
expect(callHandler.getCallForRoom(roomId)).toEqual(call);
call.emit(CallEvent.State, CallState.Ringing, CallState.Connected, fakeCall);
call.emit(CallEvent.State, CallState.Ringing, CallState.Connected, fakeCall!);

// ringer audio element started
expect(mockAudioElement.play).not.toHaveBeenCalled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ describe("NotificatinSettingsTab", () => {
const room = mkStubRoom(roomId, "test room", cli);
roomProps = EchoChamber.forRoom(room);

NotificationSettingsTab.contextType = React.createContext(cli);
NotificationSettingsTab.contextType = React.createContext<MatrixClient | undefined>(cli);
});

it("should prevent »Settings« link click from bubbling up to radio buttons", async () => {
Expand Down
2 changes: 1 addition & 1 deletion test/stores/widgets/StopGapWidgetDriver-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ describe("StopGapWidgetDriver", () => {
const aliceMobile = new DeviceInfo("aliceMobile");
const bobDesktop = new DeviceInfo("bobDesktop");

mocked(client.crypto.deviceList).downloadKeys.mockResolvedValue(
mocked(client.crypto!.deviceList).downloadKeys.mockResolvedValue(
new Map([
[
"@alice:example.org",
Expand Down
Loading

0 comments on commit bc60a9b

Please sign in to comment.