Add success dialog after key backup (#10177)

This commit is contained in:
Michael Weimann 2023-02-17 13:35:13 +01:00 committed by GitHub
parent a854e941cc
commit 9b267e7bc4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 144 additions and 2 deletions

View file

@ -23,6 +23,7 @@ import { TrustInfo } from "matrix-js-sdk/src/crypto/backup";
import { CrossSigningKeys, UIAFlow } from "matrix-js-sdk/src/matrix";
import { IRecoveryKey } from "matrix-js-sdk/src/crypto/api";
import { CryptoEvent } from "matrix-js-sdk/src/crypto";
import classNames from "classnames";
import { MatrixClientPeg } from "../../../../MatrixClientPeg";
import { _t, _td } from "../../../../languageHandler";
@ -48,6 +49,7 @@ import BaseDialog from "../../../../components/views/dialogs/BaseDialog";
import Spinner from "../../../../components/views/elements/Spinner";
import InteractiveAuthDialog from "../../../../components/views/dialogs/InteractiveAuthDialog";
import { IValidationResult } from "../../../../components/views/elements/Validation";
import { Icon as CheckmarkIcon } from "../../../../../res/img/element-icons/check.svg";
// I made a mistake while converting this and it has to be fixed!
enum Phase {
@ -59,6 +61,7 @@ enum Phase {
PassphraseConfirm = "passphrase_confirm",
ShowKey = "show_key",
Storing = "storing",
Stored = "stored",
ConfirmSkip = "confirm_skip",
}
@ -361,7 +364,10 @@ export default class CreateSecretStorageDialog extends React.PureComponent<IProp
},
});
}
this.props.onFinished(true);
this.setState({
phase: Phase.Stored,
});
} catch (e) {
if (this.state.canUploadKeysWithPasswordOnly && e.httpStatus === 401 && e.data.flows) {
this.setState({
@ -785,6 +791,19 @@ export default class CreateSecretStorageDialog extends React.PureComponent<IProp
);
}
private renderStoredPhase(): JSX.Element {
return (
<>
<p className="mx_Dialog_content">{_t("Your keys are now being backed up from this device.")}</p>
<DialogButtons
primaryButton={_t("Done")}
onPrimaryButtonClick={() => this.props.onFinished(true)}
hasCancel={false}
/>
</>
);
}
private renderPhaseLoadError(): JSX.Element {
return (
<div>
@ -837,11 +856,27 @@ export default class CreateSecretStorageDialog extends React.PureComponent<IProp
return _t("Save your Security Key");
case Phase.Storing:
return _t("Setting up keys");
case Phase.Stored:
return _t("Secure Backup successful");
default:
return "";
}
}
private get topComponent(): React.ReactNode | null {
if (this.state.phase === Phase.Stored) {
return <CheckmarkIcon className="mx_Icon mx_Icon_circle-40 mx_Icon_accent mx_Icon_bg-accent-light" />;
}
return null;
}
private get classNames(): string {
return classNames("mx_CreateSecretStorageDialog", {
mx_SuccessDialog: this.state.phase === Phase.Stored,
});
}
public render(): React.ReactNode {
let content;
if (this.state.error) {
@ -884,6 +919,9 @@ export default class CreateSecretStorageDialog extends React.PureComponent<IProp
case Phase.Storing:
content = this.renderBusyPhase();
break;
case Phase.Stored:
content = this.renderStoredPhase();
break;
case Phase.ConfirmSkip:
content = this.renderPhaseSkipConfirm();
break;
@ -912,8 +950,9 @@ export default class CreateSecretStorageDialog extends React.PureComponent<IProp
return (
<BaseDialog
className="mx_CreateSecretStorageDialog"
className={this.classNames}
onFinished={this.props.onFinished}
top={this.topComponent}
title={this.titleForPhase(this.state.phase)}
titleClass={titleClass}
hasCancel={this.props.hasCancel && [Phase.Passphrase].includes(this.state.phase)}

View file

@ -50,6 +50,9 @@ interface IProps extends IDialogProps {
// determine its size. Default: true.
"fixedWidth"?: boolean;
// To be displayed at the top of the dialog. Even above the title.
"top"?: React.ReactNode;
// Title for the dialog.
"title"?: JSX.Element | string;
// Specific aria label to use, if not provided will set aria-labelledBy to mx_Dialog_title
@ -161,6 +164,7 @@ export default class BaseDialog extends React.Component<IProps> {
mx_Dialog_fixedWidth: this.props.fixedWidth,
})}
>
{this.props.top}
<div
className={classNames("mx_Dialog_header", {
mx_Dialog_headerWithButton: !!this.props.headerButton,

View file

@ -24,6 +24,7 @@ import BaseDialog from "./BaseDialog";
import DialogButtons from "../elements/DialogButtons";
interface IProps extends IDialogProps {
top?: ReactNode;
title?: string;
description?: ReactNode;
className?: string;
@ -49,6 +50,7 @@ export default class InfoDialog extends React.Component<IProps> {
<BaseDialog
className="mx_InfoDialog"
onFinished={this.props.onFinished}
top={this.props.top}
title={this.props.title}
contentId="mx_Dialog_content"
hasCancel={this.props.hasCloseButton}

View file

@ -3632,6 +3632,7 @@
"Enter a Security Phrase only you know, as it's used to safeguard your data. To be secure, you shouldn't re-use your account password.": "Enter a Security Phrase only you know, as it's used to safeguard your data. To be secure, you shouldn't re-use your account password.",
"Store your Security Key somewhere safe, like a password manager or a safe, as it's used to safeguard your encrypted data.": "Store your Security Key somewhere safe, like a password manager or a safe, as it's used to safeguard your encrypted data.",
"%(downloadButton)s or %(copyButton)s": "%(downloadButton)s or %(copyButton)s",
"Your keys are now being backed up from this device.": "Your keys are now being backed up from this device.",
"Unable to query secret storage status": "Unable to query secret storage status",
"If you cancel now, you may lose encrypted messages & data if you lose access to your logins.": "If you cancel now, you may lose encrypted messages & data if you lose access to your logins.",
"You can also set up Secure Backup & manage your keys in Settings.": "You can also set up Secure Backup & manage your keys in Settings.",
@ -3639,6 +3640,7 @@
"Set a Security Phrase": "Set a Security Phrase",
"Confirm Security Phrase": "Confirm Security Phrase",
"Save your Security Key": "Save your Security Key",
"Secure Backup successful": "Secure Backup successful",
"Unable to set up secret storage": "Unable to set up secret storage",
"Passphrases must match": "Passphrases must match",
"Passphrase must not be empty": "Passphrase must not be empty",