Conform more of the codebase to strictNullChecks
(#10731)
This commit is contained in:
parent
9f8113eabd
commit
1281c0746b
40 changed files with 147 additions and 119 deletions
|
@ -19,7 +19,7 @@ import React from "react";
|
|||
import BaseDialog from "./BaseDialog";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import DialogButtons from "../elements/DialogButtons";
|
||||
import Modal from "../../../Modal";
|
||||
import Modal, { ComponentProps } from "../../../Modal";
|
||||
import SdkConfig from "../../../SdkConfig";
|
||||
import { getPolicyUrl } from "../../../toasts/AnalyticsToast";
|
||||
|
||||
|
@ -29,7 +29,7 @@ export enum ButtonClicked {
|
|||
}
|
||||
|
||||
interface IProps {
|
||||
onFinished?(buttonClicked?: ButtonClicked): void;
|
||||
onFinished(buttonClicked?: ButtonClicked): void;
|
||||
analyticsOwner: string;
|
||||
privacyPolicyUrl?: string;
|
||||
primaryButton?: string;
|
||||
|
@ -45,8 +45,8 @@ export const AnalyticsLearnMoreDialog: React.FC<IProps> = ({
|
|||
cancelButton,
|
||||
hasCancel,
|
||||
}) => {
|
||||
const onPrimaryButtonClick = (): void => onFinished?.(ButtonClicked.Primary);
|
||||
const onCancelButtonClick = (): void => onFinished?.(ButtonClicked.Cancel);
|
||||
const onPrimaryButtonClick = (): void => onFinished(ButtonClicked.Primary);
|
||||
const onCancelButtonClick = (): void => onFinished(ButtonClicked.Cancel);
|
||||
const privacyPolicyLink = privacyPolicyUrl ? (
|
||||
<span>
|
||||
{_t(
|
||||
|
@ -114,7 +114,9 @@ export const AnalyticsLearnMoreDialog: React.FC<IProps> = ({
|
|||
);
|
||||
};
|
||||
|
||||
export const showDialog = (props: Omit<IProps, "cookiePolicyUrl" | "analyticsOwner">): void => {
|
||||
export const showDialog = (
|
||||
props: Omit<ComponentProps<typeof AnalyticsLearnMoreDialog>, "cookiePolicyUrl" | "analyticsOwner">,
|
||||
): void => {
|
||||
const privacyPolicyUrl = getPolicyUrl();
|
||||
const analyticsOwner = SdkConfig.get("analytics_owner") ?? SdkConfig.get("brand");
|
||||
Modal.createDialog(
|
||||
|
|
|
@ -38,7 +38,7 @@ const BetaFeedbackDialog: React.FC<IProps> = ({ featureId, onFinished }) => {
|
|||
return (
|
||||
<GenericFeatureFeedbackDialog
|
||||
title={_t("%(featureName)s Beta feedback", { featureName: info.title })}
|
||||
subheading={_t(info.feedbackSubheading)}
|
||||
subheading={info.feedbackSubheading ? _t(info.feedbackSubheading) : undefined}
|
||||
onFinished={onFinished}
|
||||
rageshakeLabel={info.feedbackLabel}
|
||||
rageshakeData={Object.fromEntries(
|
||||
|
|
|
@ -48,14 +48,11 @@ const FeedbackDialog: React.FC<IProps> = (props: IProps) => {
|
|||
Modal.createDialog(BugReportDialog, {});
|
||||
};
|
||||
|
||||
const rageshakeUrl = SdkConfig.get().bug_report_endpoint_url;
|
||||
const hasFeedback = !!rageshakeUrl;
|
||||
const hasFeedback = !!SdkConfig.get().bug_report_endpoint_url;
|
||||
const onFinished = (sendFeedback: boolean): void => {
|
||||
if (hasFeedback && sendFeedback) {
|
||||
if (rageshakeUrl) {
|
||||
const label = props.feature ? `${props.feature}-feedback` : "feedback";
|
||||
submitFeedback(rageshakeUrl, label, comment, canContact);
|
||||
}
|
||||
const label = props.feature ? `${props.feature}-feedback` : "feedback";
|
||||
submitFeedback(label, comment, canContact);
|
||||
|
||||
Modal.createDialog(InfoDialog, {
|
||||
title: _t("Feedback sent"),
|
||||
|
@ -65,8 +62,8 @@ const FeedbackDialog: React.FC<IProps> = (props: IProps) => {
|
|||
props.onFinished();
|
||||
};
|
||||
|
||||
let feedbackSection;
|
||||
if (rageshakeUrl) {
|
||||
let feedbackSection: JSX.Element | undefined;
|
||||
if (hasFeedback) {
|
||||
feedbackSection = (
|
||||
<div className="mx_FeedbackDialog_section mx_FeedbackDialog_rateApp">
|
||||
<h3>{_t("Comment")}</h3>
|
||||
|
@ -93,8 +90,8 @@ const FeedbackDialog: React.FC<IProps> = (props: IProps) => {
|
|||
);
|
||||
}
|
||||
|
||||
let bugReports: JSX.Element | null = null;
|
||||
if (rageshakeUrl) {
|
||||
let bugReports: JSX.Element | undefined;
|
||||
if (hasFeedback) {
|
||||
bugReports = (
|
||||
<p className="mx_FeedbackDialog_section_microcopy">
|
||||
{_t(
|
||||
|
|
|
@ -19,7 +19,6 @@ import React, { ReactNode, useState } from "react";
|
|||
import QuestionDialog from "./QuestionDialog";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import Field from "../elements/Field";
|
||||
import SdkConfig from "../../../SdkConfig";
|
||||
import { submitFeedback } from "../../../rageshake/submit-rageshake";
|
||||
import StyledCheckbox from "../elements/StyledCheckbox";
|
||||
import Modal from "../../../Modal";
|
||||
|
@ -27,8 +26,8 @@ import InfoDialog from "./InfoDialog";
|
|||
|
||||
interface IProps {
|
||||
title: string;
|
||||
subheading: string;
|
||||
rageshakeLabel: string;
|
||||
subheading?: string;
|
||||
rageshakeLabel?: string;
|
||||
rageshakeData?: Record<string, any>;
|
||||
children?: ReactNode;
|
||||
onFinished(sendFeedback?: boolean): void;
|
||||
|
@ -48,7 +47,7 @@ const GenericFeatureFeedbackDialog: React.FC<IProps> = ({
|
|||
const sendFeedback = async (ok: boolean): Promise<void> => {
|
||||
if (!ok) return onFinished(false);
|
||||
|
||||
submitFeedback(SdkConfig.get().bug_report_endpoint_url, rageshakeLabel, comment, canContact, rageshakeData);
|
||||
submitFeedback(rageshakeLabel, comment, canContact, rageshakeData);
|
||||
onFinished(true);
|
||||
|
||||
Modal.createDialog(InfoDialog, {
|
||||
|
|
|
@ -29,7 +29,7 @@ import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
|
|||
interface IManualDeviceKeyVerificationDialogProps {
|
||||
userId: string;
|
||||
device: Device;
|
||||
onFinished?(confirm?: boolean): void;
|
||||
onFinished(confirm?: boolean): void;
|
||||
}
|
||||
|
||||
export function ManualDeviceKeyVerificationDialog({
|
||||
|
@ -44,7 +44,7 @@ export function ManualDeviceKeyVerificationDialog({
|
|||
if (confirm && mxClient) {
|
||||
mxClient.setDeviceVerified(userId, device.deviceId, true);
|
||||
}
|
||||
onFinished?.(confirm);
|
||||
onFinished(confirm);
|
||||
},
|
||||
[mxClient, userId, device, onFinished],
|
||||
);
|
||||
|
|
|
@ -47,7 +47,7 @@ export class ModuleUiDialog extends ScrollableBaseModal<IProps, IState> {
|
|||
|
||||
protected async submit(): Promise<void> {
|
||||
try {
|
||||
const model = await this.contentRef.current.trySubmit();
|
||||
const model = await this.contentRef.current!.trySubmit();
|
||||
this.props.onFinished(true, model);
|
||||
} catch (e) {
|
||||
logger.error("Error during submission of module dialog:", e);
|
||||
|
|
|
@ -120,7 +120,11 @@ export default class ServerPickerDialog extends React.PureComponent<IProps, ISta
|
|||
|
||||
// try to carry on anyway
|
||||
try {
|
||||
this.validatedConf = await AutoDiscoveryUtils.validateServerConfigWithStaticUrls(hsUrl, null, true);
|
||||
this.validatedConf = await AutoDiscoveryUtils.validateServerConfigWithStaticUrls(
|
||||
hsUrl,
|
||||
undefined,
|
||||
true,
|
||||
);
|
||||
return {};
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
|
|
|
@ -30,6 +30,7 @@ import SettingsStore from "../../../settings/SettingsStore";
|
|||
import { UIFeature } from "../../../settings/UIFeature";
|
||||
import BaseDialog from "./BaseDialog";
|
||||
import CopyableText from "../elements/CopyableText";
|
||||
import { XOR } from "../../../@types/common";
|
||||
|
||||
const socials = [
|
||||
{
|
||||
|
@ -63,19 +64,27 @@ const socials = [
|
|||
},
|
||||
];
|
||||
|
||||
interface IProps {
|
||||
target: Room | User | RoomMember | MatrixEvent;
|
||||
permalinkCreator?: RoomPermalinkCreator;
|
||||
interface BaseProps {
|
||||
onFinished(): void;
|
||||
}
|
||||
|
||||
interface Props extends BaseProps {
|
||||
target: Room | User | RoomMember;
|
||||
permalinkCreator?: RoomPermalinkCreator;
|
||||
}
|
||||
|
||||
interface EventProps extends BaseProps {
|
||||
target: MatrixEvent;
|
||||
permalinkCreator: RoomPermalinkCreator;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
linkSpecificEvent: boolean;
|
||||
permalinkCreator: RoomPermalinkCreator | null;
|
||||
}
|
||||
|
||||
export default class ShareDialog extends React.PureComponent<IProps, IState> {
|
||||
public constructor(props: IProps) {
|
||||
export default class ShareDialog extends React.PureComponent<XOR<Props, EventProps>, IState> {
|
||||
public constructor(props: XOR<Props, EventProps>) {
|
||||
super(props);
|
||||
|
||||
let permalinkCreator: RoomPermalinkCreator | null = null;
|
||||
|
@ -103,30 +112,25 @@ export default class ShareDialog extends React.PureComponent<IProps, IState> {
|
|||
};
|
||||
|
||||
private getUrl(): string {
|
||||
let matrixToUrl;
|
||||
|
||||
if (this.props.target instanceof Room) {
|
||||
if (this.state.linkSpecificEvent) {
|
||||
const events = this.props.target.getLiveTimeline().getEvents();
|
||||
matrixToUrl = this.state.permalinkCreator!.forEvent(events[events.length - 1].getId()!);
|
||||
return this.state.permalinkCreator!.forEvent(events[events.length - 1].getId()!);
|
||||
} else {
|
||||
matrixToUrl = this.state.permalinkCreator!.forShareableRoom();
|
||||
return this.state.permalinkCreator!.forShareableRoom();
|
||||
}
|
||||
} else if (this.props.target instanceof User || this.props.target instanceof RoomMember) {
|
||||
matrixToUrl = makeUserPermalink(this.props.target.userId);
|
||||
} else if (this.props.target instanceof MatrixEvent) {
|
||||
if (this.state.linkSpecificEvent) {
|
||||
matrixToUrl = this.props.permalinkCreator.forEvent(this.props.target.getId()!);
|
||||
} else {
|
||||
matrixToUrl = this.props.permalinkCreator.forShareableRoom();
|
||||
}
|
||||
return makeUserPermalink(this.props.target.userId);
|
||||
} else if (this.state.linkSpecificEvent) {
|
||||
return this.props.permalinkCreator!.forEvent(this.props.target.getId()!);
|
||||
} else {
|
||||
return this.props.permalinkCreator!.forShareableRoom();
|
||||
}
|
||||
return matrixToUrl;
|
||||
}
|
||||
|
||||
public render(): React.ReactNode {
|
||||
let title;
|
||||
let checkbox;
|
||||
let title: string | undefined;
|
||||
let checkbox: JSX.Element | undefined;
|
||||
|
||||
if (this.props.target instanceof Room) {
|
||||
title = _t("Share Room");
|
||||
|
|
|
@ -87,7 +87,7 @@ export const SlidingSyncOptionsDialog: React.FC<{ onFinished(enabled: boolean):
|
|||
const validProxy = withValidation<undefined, { error?: Error }>({
|
||||
async deriveData({ value }): Promise<{ error?: Error }> {
|
||||
try {
|
||||
await proxyHealthCheck(value, MatrixClientPeg.get().baseUrl);
|
||||
await proxyHealthCheck(value!, MatrixClientPeg.get().baseUrl);
|
||||
return {};
|
||||
} catch (error) {
|
||||
return { error };
|
||||
|
|
|
@ -42,7 +42,7 @@ const VALIDATION_THROTTLE_MS = 200;
|
|||
export type KeyParams = { passphrase?: string; recoveryKey?: string };
|
||||
|
||||
interface IProps {
|
||||
keyInfo?: ISecretStorageKeyInfo;
|
||||
keyInfo: ISecretStorageKeyInfo;
|
||||
checkPrivateKey: (k: KeyParams) => Promise<boolean>;
|
||||
onFinished(result?: false | KeyParams): void;
|
||||
}
|
||||
|
|
|
@ -136,6 +136,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
};
|
||||
|
||||
private onPassPhraseNext = async (): Promise<void> => {
|
||||
if (!this.state.backupInfo) return;
|
||||
this.setState({
|
||||
loading: true,
|
||||
restoreError: null,
|
||||
|
@ -177,7 +178,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
};
|
||||
|
||||
private onRecoveryKeyNext = async (): Promise<void> => {
|
||||
if (!this.state.recoveryKeyValid) return;
|
||||
if (!this.state.recoveryKeyValid || !this.state.backupInfo) return;
|
||||
|
||||
this.setState({
|
||||
loading: true,
|
||||
|
@ -228,6 +229,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
try {
|
||||
// `accessSecretStorage` may prompt for storage access as needed.
|
||||
await accessSecretStorage(async (): Promise<void> => {
|
||||
if (!this.state.backupInfo) return;
|
||||
await MatrixClientPeg.get().restoreKeyBackupWithSecretStorage(
|
||||
this.state.backupInfo,
|
||||
undefined,
|
||||
|
|
|
@ -748,7 +748,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
|||
}
|
||||
}
|
||||
|
||||
if (MatrixClientPeg.get().isRoomEncrypted(ev.getRoomId())) {
|
||||
if (MatrixClientPeg.get().isRoomEncrypted(ev.getRoomId()!)) {
|
||||
// else if room is encrypted
|
||||
// and event is being encrypted or is not_sent (Unknown Devices/Network Error)
|
||||
if (ev.status === EventStatus.ENCRYPTING) {
|
||||
|
@ -783,7 +783,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
|||
if (!this.props.showReactions || !this.props.getRelationsForEvent) {
|
||||
return null;
|
||||
}
|
||||
const eventId = this.props.mxEvent.getId();
|
||||
const eventId = this.props.mxEvent.getId()!;
|
||||
return this.props.getRelationsForEvent(eventId, "m.annotation", "m.reaction") ?? null;
|
||||
};
|
||||
|
||||
|
@ -801,7 +801,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
|||
};
|
||||
|
||||
private onTimestampContextMenu = (ev: React.MouseEvent): void => {
|
||||
this.showContextMenu(ev, this.props.permalinkCreator?.forEvent(this.props.mxEvent.getId()));
|
||||
this.showContextMenu(ev, this.props.permalinkCreator?.forEvent(this.props.mxEvent.getId()!));
|
||||
};
|
||||
|
||||
private showContextMenu(ev: React.MouseEvent, permalink?: string): void {
|
||||
|
@ -974,7 +974,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
|||
|
||||
let permalink = "#";
|
||||
if (this.props.permalinkCreator) {
|
||||
permalink = this.props.permalinkCreator.forEvent(this.props.mxEvent.getId());
|
||||
permalink = this.props.permalinkCreator.forEvent(this.props.mxEvent.getId()!);
|
||||
}
|
||||
|
||||
// we can't use local echoes as scroll tokens, because their event IDs change.
|
||||
|
|
|
@ -60,12 +60,12 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
|
|||
const sender = this.room?.getMember(this.props.event.getSender());
|
||||
|
||||
this.state = {
|
||||
stateKey: this.props.event.getStateKey(),
|
||||
roomId: this.props.event.getRoomId(),
|
||||
stateKey: this.props.event.getStateKey()!,
|
||||
roomId: this.props.event.getRoomId()!,
|
||||
displayName: this.props.event.getContent().display_name,
|
||||
invited: true,
|
||||
canKick: me ? me.powerLevel > kickLevel : false,
|
||||
senderName: sender ? sender.name : this.props.event.getSender(),
|
||||
senderName: sender?.name ?? this.props.event.getSender(),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
|
|||
this.getUpdatedDiagnostics();
|
||||
try {
|
||||
const backupInfo = await MatrixClientPeg.get().getKeyBackupVersion();
|
||||
const backupSigStatus = await MatrixClientPeg.get().isKeyBackupTrusted(backupInfo);
|
||||
const backupSigStatus = await MatrixClientPeg.get().isKeyBackupTrusted(backupInfo!);
|
||||
if (this.unmounted) return;
|
||||
this.setState({
|
||||
loading: false,
|
||||
|
@ -285,7 +285,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
|
|||
);
|
||||
}
|
||||
|
||||
let backupSigStatuses: React.ReactNode = backupSigStatus.sigs.map((sig, i) => {
|
||||
let backupSigStatuses: React.ReactNode = backupSigStatus?.sigs.map((sig, i) => {
|
||||
const deviceName = sig.device ? sig.device.getDisplayName() || sig.device.deviceId : null;
|
||||
const validity = (sub: string): JSX.Element => (
|
||||
<span className={sig.valid ? "mx_SecureBackupPanel_sigValid" : "mx_SecureBackupPanel_sigInvalid"}>
|
||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { IAuthData } from "matrix-js-sdk/src/interactive-auth";
|
||||
import { IAuthDict, IAuthData } from "matrix-js-sdk/src/interactive-auth";
|
||||
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import Modal from "../../../../Modal";
|
||||
|
@ -25,8 +25,8 @@ import InteractiveAuthDialog from "../../dialogs/InteractiveAuthDialog";
|
|||
|
||||
const makeDeleteRequest =
|
||||
(matrixClient: MatrixClient, deviceIds: string[]) =>
|
||||
async (auth?: IAuthData): Promise<IAuthData> => {
|
||||
return matrixClient.deleteMultipleDevices(deviceIds, auth);
|
||||
async (auth: IAuthDict | null): Promise<IAuthData> => {
|
||||
return matrixClient.deleteMultipleDevices(deviceIds, auth ?? undefined);
|
||||
};
|
||||
|
||||
export const deleteDevicesWithInteractiveAuth = async (
|
||||
|
@ -38,7 +38,7 @@ export const deleteDevicesWithInteractiveAuth = async (
|
|||
return;
|
||||
}
|
||||
try {
|
||||
await makeDeleteRequest(matrixClient, deviceIds)();
|
||||
await makeDeleteRequest(matrixClient, deviceIds)(null);
|
||||
// no interactive auth needed
|
||||
onFinished(true, undefined);
|
||||
} catch (error) {
|
||||
|
|
|
@ -161,7 +161,7 @@ const SessionManagerTab: React.FC = () => {
|
|||
const shouldShowOtherSessions = otherSessionsCount > 0;
|
||||
|
||||
const onVerifyCurrentDevice = (): void => {
|
||||
Modal.createDialog(SetupEncryptionDialog as unknown as React.ComponentType, { onFinished: refreshDevices });
|
||||
Modal.createDialog(SetupEncryptionDialog, { onFinished: refreshDevices });
|
||||
};
|
||||
|
||||
const onTriggerDeviceVerification = useCallback(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue