mirror of
https://github.com/element-hq/element-web
synced 2024-11-22 09:15:41 +03:00
Conform more of the codebase to strictNullChecks
(#10504
* Conform more of the codebase to `strictNullChecks` * Iterate
This commit is contained in:
parent
6db0c7a1a6
commit
bc60a9b594
18 changed files with 60 additions and 54 deletions
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
|
|
@ -29,7 +29,7 @@ interface IProps {
|
|||
|
||||
interface IState {
|
||||
isRedacting: boolean;
|
||||
redactionErrorCode: string | number;
|
||||
redactionErrorCode: string | number | null;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
@ -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);
|
||||
|
@ -93,7 +93,7 @@ export default class IncomingSasDialog extends React.Component<IProps, IState> {
|
|||
});
|
||||
} catch (e) {
|
||||
this.setState({
|
||||
opponentProfileError: e,
|
||||
opponentProfileError: e as Error,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
});
|
||||
|
@ -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;
|
||||
|
@ -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}
|
||||
|
@ -239,7 +240,7 @@ export default class IncomingSasDialog extends React.Component<IProps, IState> {
|
|||
);
|
||||
}
|
||||
|
||||
private renderPhaseWaitForPartnerToConfirm(): JSX.Element {
|
||||
private renderPhaseWaitForPartnerToConfirm(): ReactNode {
|
||||
return (
|
||||
<div>
|
||||
<Spinner />
|
||||
|
@ -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:
|
||||
|
|
|
@ -23,6 +23,7 @@ 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;
|
||||
|
@ -30,8 +31,8 @@ interface IProps {
|
|||
}
|
||||
|
||||
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) => {
|
||||
|
@ -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]);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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[] {
|
||||
|
|
|
@ -57,7 +57,7 @@ export interface IRightPanelCard {
|
|||
}
|
||||
|
||||
export interface IRightPanelCardStored {
|
||||
phase: RightPanelPhases;
|
||||
phase: RightPanelPhases | null;
|
||||
state?: IRightPanelCardStateStored;
|
||||
}
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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 ?? [];
|
||||
};
|
||||
|
|
|
@ -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 }) => {
|
||||
|
|
|
@ -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({
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
|
|
@ -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 () => {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -163,8 +163,9 @@ describe("DMRoomMap", () => {
|
|||
|
||||
beforeEach(() => {
|
||||
client.getAccountData.mockReturnValue(mkMDirectEvent(mDirectContent));
|
||||
client.getRoom.mockImplementation((roomId: string) =>
|
||||
[bigRoom, smallRoom, dmWithCharlie, dmWithBob].find((room) => room.roomId === roomId),
|
||||
client.getRoom.mockImplementation(
|
||||
(roomId: string) =>
|
||||
[bigRoom, smallRoom, dmWithCharlie, dmWithBob].find((room) => room.roomId === roomId) ?? null,
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -183,7 +184,7 @@ describe("DMRoomMap", () => {
|
|||
});
|
||||
|
||||
it("excludes rooms that are not found by matrixClient", () => {
|
||||
client.getRoom.mockReset().mockReturnValue(undefined);
|
||||
client.getRoom.mockReset().mockReturnValue(null);
|
||||
const dmRoomMap = new DMRoomMap(client);
|
||||
dmRoomMap.start();
|
||||
expect(dmRoomMap.getUniqueRoomsWithIndividuals()).toEqual({});
|
||||
|
|
Loading…
Reference in a new issue