Conform more code to strictNullChecks
(#10368
* Conform more code to `strictNullChecks` * Iterate
This commit is contained in:
parent
05e3fb09d6
commit
8cb8cd4eb1
24 changed files with 176 additions and 157 deletions
|
@ -43,12 +43,12 @@ interface IProps {
|
|||
interface IState {
|
||||
sendLogs: boolean;
|
||||
busy: boolean;
|
||||
err: string;
|
||||
err: string | null;
|
||||
issueUrl: string;
|
||||
text: string;
|
||||
progress: string;
|
||||
progress: string | null;
|
||||
downloadBusy: boolean;
|
||||
downloadProgress: string;
|
||||
downloadProgress: string | null;
|
||||
}
|
||||
|
||||
export default class BugReportDialog extends React.Component<IProps, IState> {
|
||||
|
@ -181,12 +181,12 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
public render(): React.ReactNode {
|
||||
let error = null;
|
||||
let error: JSX.Element | undefined;
|
||||
if (this.state.err) {
|
||||
error = <div className="error">{this.state.err}</div>;
|
||||
}
|
||||
|
||||
let progress = null;
|
||||
let progress: JSX.Element | undefined;
|
||||
if (this.state.busy) {
|
||||
progress = (
|
||||
<div className="progress">
|
||||
|
@ -196,7 +196,7 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
|
|||
);
|
||||
}
|
||||
|
||||
let warning;
|
||||
let warning: JSX.Element | undefined;
|
||||
if (window.Modernizr && Object.values(window.Modernizr).some((support) => support === false)) {
|
||||
warning = (
|
||||
<p>
|
||||
|
|
|
@ -126,7 +126,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
|
||||
public componentDidMount(): void {
|
||||
// move focus to first field when showing dialog
|
||||
this.nameField.current.focus();
|
||||
this.nameField.current?.focus();
|
||||
}
|
||||
|
||||
private onKeyDown = (event: KeyboardEvent): void => {
|
||||
|
@ -141,10 +141,9 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
private onOk = async (): Promise<void> => {
|
||||
if (!this.nameField.current) return;
|
||||
const activeElement = document.activeElement as HTMLElement;
|
||||
if (activeElement) {
|
||||
activeElement.blur();
|
||||
}
|
||||
activeElement?.blur();
|
||||
await this.nameField.current.validate({ allowEmpty: false });
|
||||
if (this.aliasField.current) {
|
||||
await this.aliasField.current.validate({ allowEmpty: false });
|
||||
|
@ -155,7 +154,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
if (this.state.nameIsValid && (!this.aliasField.current || this.aliasField.current.isValid)) {
|
||||
this.props.onFinished(true, this.roomCreateOptions());
|
||||
} else {
|
||||
let field;
|
||||
let field: RoomAliasField | Field | null = null;
|
||||
if (!this.state.nameIsValid) {
|
||||
field = this.nameField.current;
|
||||
} else if (this.aliasField.current && !this.aliasField.current.isValid) {
|
||||
|
@ -163,7 +162,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
}
|
||||
if (field) {
|
||||
field.focus();
|
||||
field.validate({ allowEmpty: false, focused: true });
|
||||
await field.validate({ allowEmpty: false, focused: true });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -202,7 +201,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
|
||||
private onNameValidate = async (fieldState: IFieldState): Promise<IValidationResult> => {
|
||||
const result = await CreateRoomDialog.validateRoomName(fieldState);
|
||||
this.setState({ nameIsValid: result.valid });
|
||||
this.setState({ nameIsValid: !!result.valid });
|
||||
return result;
|
||||
};
|
||||
|
||||
|
@ -219,9 +218,9 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
public render(): React.ReactNode {
|
||||
const isVideoRoom = this.props.type === RoomType.ElementVideo;
|
||||
|
||||
let aliasField: JSX.Element;
|
||||
let aliasField: JSX.Element | undefined;
|
||||
if (this.state.joinRule === JoinRule.Public) {
|
||||
const domain = MatrixClientPeg.get().getDomain();
|
||||
const domain = MatrixClientPeg.get().getDomain()!;
|
||||
aliasField = (
|
||||
<div className="mx_CreateRoomDialog_aliasContainer">
|
||||
<RoomAliasField
|
||||
|
@ -234,7 +233,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
);
|
||||
}
|
||||
|
||||
let publicPrivateLabel: JSX.Element;
|
||||
let publicPrivateLabel: JSX.Element | undefined;
|
||||
if (this.state.joinRule === JoinRule.Restricted) {
|
||||
publicPrivateLabel = (
|
||||
<p>
|
||||
|
@ -242,7 +241,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
"Everyone in <SpaceName/> will be able to find and join this room.",
|
||||
{},
|
||||
{
|
||||
SpaceName: () => <b>{this.props.parentSpace.name}</b>,
|
||||
SpaceName: () => <b>{this.props.parentSpace?.name ?? _t("Unnamed Space")}</b>,
|
||||
},
|
||||
)}
|
||||
|
||||
|
@ -256,7 +255,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
"Anyone will be able to find and join this room, not just members of <SpaceName/>.",
|
||||
{},
|
||||
{
|
||||
SpaceName: () => <b>{this.props.parentSpace.name}</b>,
|
||||
SpaceName: () => <b>{this.props.parentSpace?.name ?? _t("Unnamed Space")}</b>,
|
||||
},
|
||||
)}
|
||||
|
||||
|
@ -281,7 +280,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
);
|
||||
}
|
||||
|
||||
let e2eeSection: JSX.Element;
|
||||
let e2eeSection: JSX.Element | undefined;
|
||||
if (this.state.joinRule !== JoinRule.Public) {
|
||||
let microcopy: string;
|
||||
if (privateShouldBeEncrypted()) {
|
||||
|
|
|
@ -44,7 +44,7 @@ const CreateSubspaceDialog: React.FC<IProps> = ({ space, onAddExistingSpaceClick
|
|||
const spaceNameField = useRef<Field>();
|
||||
const [alias, setAlias] = useState("");
|
||||
const spaceAliasField = useRef<RoomAliasField>();
|
||||
const [avatar, setAvatar] = useState<File>(null);
|
||||
const [avatar, setAvatar] = useState<File | undefined>();
|
||||
const [topic, setTopic] = useState<string>("");
|
||||
|
||||
const spaceJoinRule = space.getJoinRule();
|
||||
|
@ -56,7 +56,7 @@ const CreateSubspaceDialog: React.FC<IProps> = ({ space, onAddExistingSpaceClick
|
|||
|
||||
const onCreateSubspaceClick = async (e: ButtonEvent): Promise<void> => {
|
||||
e.preventDefault();
|
||||
if (busy) return;
|
||||
if (busy || !spaceNameField.current || !spaceAliasField.current) return;
|
||||
|
||||
setBusy(true);
|
||||
// require & validate the space name field
|
||||
|
@ -83,7 +83,7 @@ const CreateSubspaceDialog: React.FC<IProps> = ({ space, onAddExistingSpaceClick
|
|||
}
|
||||
};
|
||||
|
||||
let joinRuleMicrocopy: JSX.Element;
|
||||
let joinRuleMicrocopy: JSX.Element | undefined;
|
||||
if (joinRule === JoinRule.Restricted) {
|
||||
joinRuleMicrocopy = (
|
||||
<p>
|
||||
|
|
|
@ -73,7 +73,7 @@ const useExportFormState = (): ExportConfig => {
|
|||
const [exportType, setExportType] = useState(config.range ?? ExportType.Timeline);
|
||||
const [includeAttachments, setAttachments] = useState(config.includeAttachments ?? false);
|
||||
const [numberOfMessages, setNumberOfMessages] = useState<number>(config.numberOfMessages ?? 100);
|
||||
const [sizeLimit, setSizeLimit] = useState<number | null>(config.sizeMb ?? 8);
|
||||
const [sizeLimit, setSizeLimit] = useState<number>(config.sizeMb ?? 8);
|
||||
|
||||
return {
|
||||
exportFormat,
|
||||
|
@ -260,7 +260,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
|
|||
);
|
||||
});
|
||||
|
||||
let messageCount = null;
|
||||
let messageCount: JSX.Element | undefined;
|
||||
if (exportType === ExportType.LastNMessages && setNumberOfMessages) {
|
||||
messageCount = (
|
||||
<Field
|
||||
|
|
|
@ -96,7 +96,7 @@ export default class LogoutDialog extends React.Component<IProps, IState> {
|
|||
dis.dispatch({ action: "logout" });
|
||||
}
|
||||
// close dialog
|
||||
this.props.onFinished(confirmed);
|
||||
this.props.onFinished(!!confirmed);
|
||||
};
|
||||
|
||||
private onSetRecoveryMethodClick = (): void => {
|
||||
|
|
|
@ -70,7 +70,7 @@ export default class ModalWidgetDialog extends React.PureComponent<IProps, IStat
|
|||
|
||||
this.widget = new ElementWidget({
|
||||
...this.props.widgetDefinition,
|
||||
creatorUserId: MatrixClientPeg.get().getUserId(),
|
||||
creatorUserId: MatrixClientPeg.get().getSafeUserId(),
|
||||
id: `modal_${this.props.sourceWidgetId}`,
|
||||
});
|
||||
this.possibleButtons = (this.props.widgetDefinition.buttons || []).map((b) => b.id);
|
||||
|
@ -78,21 +78,23 @@ export default class ModalWidgetDialog extends React.PureComponent<IProps, IStat
|
|||
|
||||
public componentDidMount(): void {
|
||||
const driver = new StopGapWidgetDriver([], this.widget, WidgetKind.Modal, false);
|
||||
const messaging = new ClientWidgetApi(this.widget, this.appFrame.current, driver);
|
||||
const messaging = new ClientWidgetApi(this.widget, this.appFrame.current!, driver);
|
||||
this.setState({ messaging });
|
||||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
if (!this.state.messaging) return;
|
||||
this.state.messaging.off("ready", this.onReady);
|
||||
this.state.messaging.off(`action:${WidgetApiFromWidgetAction.CloseModalWidget}`, this.onWidgetClose);
|
||||
this.state.messaging.stop();
|
||||
}
|
||||
|
||||
private onReady = (): void => {
|
||||
this.state.messaging.sendWidgetConfig(this.props.widgetDefinition);
|
||||
this.state.messaging?.sendWidgetConfig(this.props.widgetDefinition);
|
||||
};
|
||||
|
||||
private onLoad = (): void => {
|
||||
if (!this.state.messaging) return;
|
||||
this.state.messaging.once("ready", this.onReady);
|
||||
this.state.messaging.on(`action:${WidgetApiFromWidgetAction.CloseModalWidget}`, this.onWidgetClose);
|
||||
this.state.messaging.on(`action:${WidgetApiFromWidgetAction.SetModalButtonEnabled}`, this.onButtonEnableToggle);
|
||||
|
@ -106,7 +108,7 @@ export default class ModalWidgetDialog extends React.PureComponent<IProps, IStat
|
|||
ev.preventDefault();
|
||||
const isClose = ev.detail.data.button === BuiltInModalButtonID.Close;
|
||||
if (isClose || !this.possibleButtons.includes(ev.detail.data.button)) {
|
||||
return this.state.messaging.transport.reply(ev.detail, {
|
||||
return this.state.messaging?.transport.reply(ev.detail, {
|
||||
error: { message: "Invalid button" },
|
||||
} as IWidgetApiErrorResponseData);
|
||||
}
|
||||
|
@ -121,15 +123,15 @@ export default class ModalWidgetDialog extends React.PureComponent<IProps, IStat
|
|||
buttonIds = Array.from(tempSet);
|
||||
}
|
||||
this.setState({ disabledButtonIds: buttonIds });
|
||||
this.state.messaging.transport.reply(ev.detail, {} as IWidgetApiAcknowledgeResponseData);
|
||||
this.state.messaging?.transport.reply(ev.detail, {} as IWidgetApiAcknowledgeResponseData);
|
||||
};
|
||||
|
||||
public render(): React.ReactNode {
|
||||
const templated = this.widget.getCompleteUrl({
|
||||
widgetRoomId: this.props.widgetRoomId,
|
||||
currentUserId: MatrixClientPeg.get().getUserId(),
|
||||
userDisplayName: OwnProfileStore.instance.displayName,
|
||||
userHttpAvatarUrl: OwnProfileStore.instance.getHttpAvatarUrl(),
|
||||
currentUserId: MatrixClientPeg.get().getSafeUserId(),
|
||||
userDisplayName: OwnProfileStore.instance.displayName ?? undefined,
|
||||
userHttpAvatarUrl: OwnProfileStore.instance.getHttpAvatarUrl() ?? undefined,
|
||||
clientId: ELEMENT_CLIENT_ID,
|
||||
clientTheme: SettingsStore.getValue("theme"),
|
||||
clientLanguage: getUserLanguage(),
|
||||
|
@ -168,7 +170,7 @@ export default class ModalWidgetDialog extends React.PureComponent<IProps, IStat
|
|||
}
|
||||
|
||||
const onClick = (): void => {
|
||||
this.state.messaging.notifyModalWidgetButtonClicked(def.id);
|
||||
this.state.messaging?.notifyModalWidgetButtonClicked(def.id);
|
||||
};
|
||||
|
||||
const isDisabled = this.state.disabledButtonIds.includes(def.id);
|
||||
|
@ -201,7 +203,7 @@ export default class ModalWidgetDialog extends React.PureComponent<IProps, IStat
|
|||
</div>
|
||||
<div>
|
||||
<iframe
|
||||
title={this.widget.name}
|
||||
title={this.widget.name ?? undefined}
|
||||
ref={this.appFrame}
|
||||
sandbox="allow-forms allow-scripts allow-same-origin"
|
||||
src={widgetUrl}
|
||||
|
|
|
@ -99,8 +99,8 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
let moderatedByRoomId = null;
|
||||
let moderatedByUserId = null;
|
||||
let moderatedByRoomId: string | null = null;
|
||||
let moderatedByUserId: string | null = null;
|
||||
|
||||
if (SettingsStore.getValue("feature_report_to_moderators")) {
|
||||
// The client supports reporting to moderators.
|
||||
|
@ -111,7 +111,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
const room = client.getRoom(props.mxEvent.getRoomId());
|
||||
|
||||
for (const stateEventType of MODERATED_BY_STATE_EVENT_TYPE) {
|
||||
const stateEvent = room.currentState.getStateEvents(stateEventType, stateEventType);
|
||||
const stateEvent = room?.currentState.getStateEvents(stateEventType, stateEventType);
|
||||
if (!stateEvent) {
|
||||
continue;
|
||||
}
|
||||
|
@ -177,9 +177,9 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
// A free-form text describing the abuse.
|
||||
reason: "",
|
||||
busy: false,
|
||||
err: null,
|
||||
err: undefined,
|
||||
// If specified, the nature of the abuse, as specified by MSC3215.
|
||||
nature: null,
|
||||
nature: undefined,
|
||||
ignoreUserToo: false, // default false, for now. Could easily be argued as default true
|
||||
};
|
||||
}
|
||||
|
@ -233,14 +233,14 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
|
||||
this.setState({
|
||||
busy: true,
|
||||
err: null,
|
||||
err: undefined,
|
||||
});
|
||||
|
||||
try {
|
||||
const client = MatrixClientPeg.get();
|
||||
const ev = this.props.mxEvent;
|
||||
if (this.moderation && this.state.nature !== NonStandardValue.Admin) {
|
||||
const nature: Nature = this.state.nature;
|
||||
const nature = this.state.nature;
|
||||
|
||||
// Report to moderators through to the dedicated bot,
|
||||
// as configured in the room's state events.
|
||||
|
@ -274,12 +274,12 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
public render(): React.ReactNode {
|
||||
let error = null;
|
||||
let error: JSX.Element | undefined;
|
||||
if (this.state.err) {
|
||||
error = <div className="error">{this.state.err}</div>;
|
||||
}
|
||||
|
||||
let progress = null;
|
||||
let progress: JSX.Element | undefined;
|
||||
if (this.state.busy) {
|
||||
progress = (
|
||||
<div className="progress">
|
||||
|
@ -299,7 +299,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
);
|
||||
|
||||
const adminMessageMD = SdkConfig.getObject("report_event")?.get("admin_message_md", "adminMessageMD");
|
||||
let adminMessage;
|
||||
let adminMessage: JSX.Element | undefined;
|
||||
if (adminMessageMD) {
|
||||
const html = new Markdown(adminMessageMD).toHTML({ externalLinks: true });
|
||||
adminMessage = <p dangerouslySetInnerHTML={{ __html: html }} />;
|
||||
|
|
|
@ -42,16 +42,20 @@ interface IProps {
|
|||
onFinished(opts?: IFinishedOpts): void;
|
||||
}
|
||||
|
||||
interface Progress {
|
||||
text: string;
|
||||
progress: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
inviteUsersToNewRoom: boolean;
|
||||
progressText?: string;
|
||||
progress?: number;
|
||||
total?: number;
|
||||
progress?: Progress;
|
||||
}
|
||||
|
||||
export default class RoomUpgradeWarningDialog extends React.Component<IProps, IState> {
|
||||
private readonly isPrivate: boolean;
|
||||
private readonly currentVersion: string;
|
||||
private readonly currentVersion?: string;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
@ -66,8 +70,14 @@ export default class RoomUpgradeWarningDialog extends React.Component<IProps, IS
|
|||
};
|
||||
}
|
||||
|
||||
private onProgressCallback = (progressText: string, progress: number, total: number): void => {
|
||||
this.setState({ progressText, progress, total });
|
||||
private onProgressCallback = (text: string, progress: number, total: number): void => {
|
||||
this.setState({
|
||||
progress: {
|
||||
text,
|
||||
progress,
|
||||
total,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
private onContinue = async (): Promise<void> => {
|
||||
|
@ -98,7 +108,7 @@ export default class RoomUpgradeWarningDialog extends React.Component<IProps, IS
|
|||
public render(): React.ReactNode {
|
||||
const brand = SdkConfig.get().brand;
|
||||
|
||||
let inviteToggle = null;
|
||||
let inviteToggle: JSX.Element | undefined;
|
||||
if (this.isPrivate) {
|
||||
inviteToggle = (
|
||||
<LabelledToggleSwitch
|
||||
|
@ -144,11 +154,11 @@ export default class RoomUpgradeWarningDialog extends React.Component<IProps, IS
|
|||
}
|
||||
|
||||
let footer: JSX.Element;
|
||||
if (this.state.progressText) {
|
||||
if (this.state.progress) {
|
||||
footer = (
|
||||
<span className="mx_RoomUpgradeWarningDialog_progress">
|
||||
<ProgressBar value={this.state.progress} max={this.state.total} />
|
||||
<div className="mx_RoomUpgradeWarningDialog_progressText">{this.state.progressText}</div>
|
||||
<ProgressBar value={this.state.progress.progress} max={this.state.progress.total} />
|
||||
<div className="mx_RoomUpgradeWarningDialog_progressText">{this.state.progress.text}</div>
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -96,7 +96,7 @@ export const SlidingSyncOptionsDialog: React.FC<{ onFinished(enabled: boolean):
|
|||
rules: [
|
||||
{
|
||||
key: "required",
|
||||
test: async ({ value }) => !!value || hasNativeSupport,
|
||||
test: async ({ value }) => !!value || !!hasNativeSupport,
|
||||
invalid: () => _t("Your server lacks native support, you must specify a proxy"),
|
||||
},
|
||||
{
|
||||
|
@ -104,7 +104,7 @@ export const SlidingSyncOptionsDialog: React.FC<{ onFinished(enabled: boolean):
|
|||
final: true,
|
||||
test: async (_, { error }) => !error,
|
||||
valid: () => _t("Looks good"),
|
||||
invalid: ({ error }) => error?.message,
|
||||
invalid: ({ error }) => error?.message ?? null,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
@ -23,14 +23,14 @@ import BaseDialog from "./BaseDialog";
|
|||
import DialogButtons from "../elements/DialogButtons";
|
||||
|
||||
interface IProps {
|
||||
title?: string;
|
||||
description?: React.ReactNode;
|
||||
value?: string;
|
||||
title: string;
|
||||
description: React.ReactNode;
|
||||
value: string;
|
||||
placeholder?: string;
|
||||
button?: string;
|
||||
busyMessage?: string; // pass _td string
|
||||
focus?: boolean;
|
||||
hasCancel?: boolean;
|
||||
busyMessage: string; // pass _td string
|
||||
focus: boolean;
|
||||
hasCancel: boolean;
|
||||
validator?: (fieldState: IFieldState) => Promise<IValidationResult>; // result of withValidation
|
||||
fixedWidth?: boolean;
|
||||
onFinished(ok?: boolean, text?: string): void;
|
||||
|
@ -68,12 +68,13 @@ export default class TextInputDialog extends React.Component<IProps, IState> {
|
|||
if (this.props.focus) {
|
||||
// Set the cursor at the end of the text input
|
||||
// this._field.current.value = this.props.value;
|
||||
this.field.current.focus();
|
||||
this.field.current?.focus();
|
||||
}
|
||||
}
|
||||
|
||||
private onOk = async (ev: React.FormEvent): Promise<void> => {
|
||||
ev.preventDefault();
|
||||
if (!this.field.current) return;
|
||||
if (this.props.validator) {
|
||||
this.setState({ busy: true });
|
||||
await this.field.current.validate({ allowEmpty: false });
|
||||
|
@ -101,7 +102,7 @@ export default class TextInputDialog extends React.Component<IProps, IState> {
|
|||
private onValidate = async (fieldState: IFieldState): Promise<IValidationResult> => {
|
||||
const result = await this.props.validator(fieldState);
|
||||
this.setState({
|
||||
valid: result.valid,
|
||||
valid: !!result.valid,
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
|
|
@ -26,8 +26,8 @@ import DialogButtons from "../elements/DialogButtons";
|
|||
|
||||
interface IProps {
|
||||
file: File;
|
||||
currentIndex?: number;
|
||||
totalFiles?: number;
|
||||
currentIndex: number;
|
||||
totalFiles: number;
|
||||
onFinished: (uploadConfirmed: boolean, uploadAll?: boolean) => void;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ export default class UploadConfirmDialog extends React.Component<IProps> {
|
|||
|
||||
public static defaultProps: Partial<IProps> = {
|
||||
totalFiles: 1,
|
||||
currentIndex: 0,
|
||||
};
|
||||
|
||||
public constructor(props: IProps) {
|
||||
|
@ -77,8 +78,8 @@ export default class UploadConfirmDialog extends React.Component<IProps> {
|
|||
}
|
||||
|
||||
const fileId = `mx-uploadconfirmdialog-${this.props.file.name}`;
|
||||
let preview: JSX.Element;
|
||||
let placeholder: JSX.Element;
|
||||
let preview: JSX.Element | undefined;
|
||||
let placeholder: JSX.Element | undefined;
|
||||
if (this.mimeType.startsWith("image/")) {
|
||||
preview = (
|
||||
<img className="mx_UploadConfirmDialog_imagePreview" src={this.objectUrl} aria-labelledby={fileId} />
|
||||
|
@ -96,7 +97,7 @@ export default class UploadConfirmDialog extends React.Component<IProps> {
|
|||
placeholder = <FileIcon className="mx_UploadConfirmDialog_fileIcon" height={18} width={18} />;
|
||||
}
|
||||
|
||||
let uploadAllButton;
|
||||
let uploadAllButton: JSX.Element | undefined;
|
||||
if (this.props.currentIndex + 1 < this.props.totalFiles) {
|
||||
uploadAllButton = <button onClick={this.onUploadAllClick}>{_t("Upload all")}</button>;
|
||||
}
|
||||
|
|
|
@ -52,19 +52,19 @@ interface IProps {
|
|||
}
|
||||
|
||||
interface IState {
|
||||
backupInfo: IKeyBackupInfo;
|
||||
backupKeyStored: Record<string, ISecretStorageKeyInfo>;
|
||||
backupInfo: IKeyBackupInfo | null;
|
||||
backupKeyStored: Record<string, ISecretStorageKeyInfo> | null;
|
||||
loading: boolean;
|
||||
loadError: string;
|
||||
loadError: string | null;
|
||||
restoreError: {
|
||||
errcode: string;
|
||||
};
|
||||
} | null;
|
||||
recoveryKey: string;
|
||||
recoverInfo: IKeyBackupRestoreResult;
|
||||
recoverInfo: IKeyBackupRestoreResult | null;
|
||||
recoveryKeyValid: boolean;
|
||||
forceRecoveryKey: boolean;
|
||||
passPhrase: string;
|
||||
restoreType: RestoreType;
|
||||
restoreType: RestoreType | null;
|
||||
progress: {
|
||||
stage: ProgressState;
|
||||
total?: number;
|
||||
|
@ -247,7 +247,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
}
|
||||
}
|
||||
|
||||
private async restoreWithCachedKey(backupInfo?: IKeyBackupInfo): Promise<boolean> {
|
||||
private async restoreWithCachedKey(backupInfo: IKeyBackupInfo | null): Promise<boolean> {
|
||||
if (!backupInfo) return false;
|
||||
try {
|
||||
const recoverInfo = await MatrixClientPeg.get().restoreKeyBackupWithCache(
|
||||
|
@ -275,7 +275,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
const cli = MatrixClientPeg.get();
|
||||
const backupInfo = await cli.getKeyBackupVersion();
|
||||
const has4S = await cli.hasSecretStorageKey();
|
||||
const backupKeyStored = has4S && (await cli.isKeyBackupKeyStored());
|
||||
const backupKeyStored = has4S ? await cli.isKeyBackupKeyStored() : null;
|
||||
this.setState({
|
||||
backupInfo,
|
||||
backupKeyStored,
|
||||
|
|
|
@ -685,7 +685,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
<Option
|
||||
id={`mx_SpotlightDialog_button_result_${result.name}`}
|
||||
key={`${Section[result.section]}-${result.name}`}
|
||||
onClick={result.onClick}
|
||||
onClick={result.onClick ?? null}
|
||||
>
|
||||
{result.avatar}
|
||||
{result.name}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue