Merge pull request #2617 from matrix-org/dbkr/e2e_change_all_the_strings

Change text in e2e UX to new copy
This commit is contained in:
David Baker 2019-02-12 20:38:58 +00:00 committed by GitHub
commit 785b4d649f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 225 additions and 152 deletions

View file

@ -22,6 +22,10 @@ import { _t } from '../../../languageHandler';
import MatrixClientPeg from '../../../MatrixClientPeg';
export default class LogoutDialog extends React.Component {
defaultProps = {
onFinished: function() {},
}
constructor() {
super();
this._onSettingsLinkClick = this._onSettingsLinkClick.bind(this);
@ -29,13 +33,37 @@ export default class LogoutDialog extends React.Component {
this._onFinished = this._onFinished.bind(this);
this._onSetRecoveryMethodClick = this._onSetRecoveryMethodClick.bind(this);
this._onLogoutConfirm = this._onLogoutConfirm.bind(this);
this.state = {
loading: false,
backupInfo: null,
error: null,
};
if (!MatrixClientPeg.get().getKeyBackupEnabled()) {
this._loadBackupStatus();
}
}
async _loadBackupStatus() {
try {
const backupInfo = await MatrixClientPeg.get().getKeyBackupVersion();
this.setState({
loading: false,
backupInfo,
});
} catch (e) {
console.log("Unable to fetch key backup status", e);
this.setState({
loading: false,
error: e,
});
}
}
_onSettingsLinkClick() {
// close dialog
if (this.props.onFinished) {
this.props.onFinished();
}
this.props.onFinished();
}
_onExportE2eKeysClicked() {
@ -52,9 +80,7 @@ export default class LogoutDialog extends React.Component {
dis.dispatch({action: 'logout'});
}
// close dialog
if (this.props.onFinished) {
this.props.onFinished();
}
this.props.onFinished();
}
_onSetRecoveryMethodClick() {
@ -63,72 +89,83 @@ export default class LogoutDialog extends React.Component {
);
// close dialog
if (this.props.onFinished) {
this.props.onFinished();
}
this.props.onFinished();
}
_onLogoutConfirm() {
dis.dispatch({action: 'logout'});
// close dialog
if (this.props.onFinished) {
this.props.onFinished();
}
this.props.onFinished();
}
render() {
const description = <div>
<p>{_t(
"When you log out, you'll lose your secure message history. To prevent " +
"this, set up a recovery method.",
)}</p>
<p>{_t(
"Alternatively, advanced users can also manually export encryption keys in " +
"<a>Settings</a> before logging out.", {},
{
a: sub => <a href='#/settings' onClick={this._onSettingsLinkClick}>{sub}</a>,
},
"Encrypted messages are secured with end-to-end encryption. " +
"Only you and the recipient(s) have the keys to read these messages.",
)}</p>
<p>{_t("Back up your keys before signing out to avoid losing them.")}</p>
</div>;
if (!MatrixClientPeg.get().getKeyBackupEnabled()) {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
let dialogContent;
if (this.state.loading) {
const Spinner = sdk.getComponent('views.elements.Spinner');
dialogContent = <Spinner />;
} else {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
let setupButtonCaption;
if (this.state.backupInfo) {
setupButtonCaption = _t("Use Key Backup");
} else {
// if there's an error fetching the backup info, we'll just assume there's
// no backup for the purpose of the button caption
setupButtonCaption = _t("Start using Key Backup");
}
dialogContent = <div>
<div className="mx_Dialog_content" id='mx_Dialog_content'>
{ description }
</div>
<DialogButtons primaryButton={setupButtonCaption}
hasCancel={false}
onPrimaryButtonClick={this._onSetRecoveryMethodClick}
focus={true}
>
<button onClick={this._onLogoutConfirm}>
{_t("I don't want my encrypted messages")}
</button>
</DialogButtons>
<details>
<summary>{_t("Advanced")}</summary>
<p><button onClick={this._onExportE2eKeysClicked}>
{_t("Manually export keys")}
</button></p>
</details>
</div>;
}
// Not quite a standard question dialog as the primary button cancels
// the action and does something else instead, whilst non-default button
// confirms the action.
return (<BaseDialog
title={_t("Warning!")}
title={_t("You'll lose access to your encrypted messages")}
contentId='mx_Dialog_content'
hasCancel={false}
onFinsihed={this._onFinished}
hasCancel={true}
onFinished={this._onFinished}
>
<div className="mx_Dialog_content" id='mx_Dialog_content'>
{ description }
</div>
<DialogButtons primaryButton={_t('Set a Recovery Method')}
hasCancel={false}
onPrimaryButtonClick={this._onSetRecoveryMethodClick}
focus={true}
>
<button onClick={this._onLogoutConfirm}>
{_t("I understand, log out without")}
</button>
</DialogButtons>
{dialogContent}
</BaseDialog>);
} else {
const QuestionDialog = sdk.getComponent('views.dialogs.QuestionDialog');
return (<QuestionDialog
hasCancelButton={true}
title={_t("Sign out")}
// TODO: This is made up by me and would need to also mention verifying
// once you can restore a backup by verifying a device
description={_t(
"When signing in again, you can access encrypted chat history by " +
"restoring your key backup. You'll need your recovery passphrase " +
"or, if you didn't set a recovery passphrase, your recovery key " +
"(that you downloaded).",
"Are you sure you want to sign out?",
)}
button={_t("Sign out")}
onFinished={this._onFinished}

View file

@ -230,10 +230,15 @@ export default React.createClass({
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
title = _t("Enter Recovery Passphrase");
content = <div>
{_t(
<p>{_t(
"<b>Warning</b>: you should only set up key backup " +
"from a trusted computer.", {},
{ b: sub => <b>{sub}</b> },
)}</p>
<p>{_t(
"Access your secure message history and set up secure " +
"messaging by entering your recovery passphrase.",
)}<br />
)}</p>
<div className="mx_RestoreKeyBackupDialog_primaryContainer">
<input type="password"
@ -288,10 +293,15 @@ export default React.createClass({
}
content = <div>
{_t(
<p>{_t(
"<b>Warning</b>: you should only set up key backup " +
"from a trusted computer.", {},
{ b: sub => <b>{sub}</b> },
)}</p>
<p>{_t(
"Access your secure message history and set up secure " +
"messaging by entering your recovery key.",
)}<br />
)}</p>
<div className="mx_RestoreKeyBackupDialog_primaryContainer">
<input className="mx_RestoreKeyBackupDialog_recoveryKeyInput"

View file

@ -39,6 +39,7 @@ export default class RoomRecoveryReminder extends React.PureComponent {
loading: true,
error: null,
backupInfo: null,
notNowClicked: false,
};
}
@ -77,6 +78,10 @@ export default class RoomRecoveryReminder extends React.PureComponent {
}
}
onOnNotNowClick = () => {
this.setState({notNowClicked: true});
}
onDontAskAgainClick = () => {
// When you choose "Don't ask again" from the room reminder, we show a
// dialog to confirm the choice.
@ -104,46 +109,54 @@ export default class RoomRecoveryReminder extends React.PureComponent {
}
render() {
if (this.state.loading) {
// If there was an error loading just don't display the banner: we'll try again
// next time the user switchs to the room.
if (this.state.error || this.state.loading || this.state.notNowClicked) {
return null;
}
const AccessibleButton = sdk.getComponent("views.elements.AccessibleButton");
let body;
if (this.state.error) {
body = <div className="error">
{_t("Unable to load key backup status")}
</div>;
} else if (this.state.backupInfo) {
// A key backup exists for this account, but we're not using it.
body = <div>
<p>{_t(
"Secure Key Backup should be active on all of your devices to avoid " +
"losing access to your encrypted messages.",
)}</p>
</div>;
let setupCaption;
if (this.state.backupInfo) {
setupCaption = _t("Use Key Backup");
} else {
body = _t(
"Securely back up your decryption keys to the server to make sure " +
"you'll always be able to read your encrypted messages.",
);
setupCaption = _t("Start using Key Backup");
}
return (
<div className="mx_RoomRecoveryReminder">
<div className="mx_RoomRecoveryReminder_header">{_t(
"Don't risk losing your encrypted messages!",
"Never lose encrypted messages",
)}</div>
<div className="mx_RoomRecoveryReminder_body">{body}</div>
<div className="mx_RoomRecoveryReminder_body">
<p>{_t(
"Messages in this room are secured with end-to-end " +
"encryption. Only you and the recipient(s) have the " +
"keys to read these messages.",
)}</p>
<p>{_t(
"Securely back up your keys to avoid losing them. " +
"<a>Learn more.</a>", {},
{
// TODO: We don't have this link yet: this will prevent the translators
// having to re-translate the string when we do.
a: sub => '',
},
)}</p>
</div>
<div className="mx_RoomRecoveryReminder_buttons">
<AccessibleButton className="mx_RoomRecoveryReminder_button"
onClick={this.onSetupClick}>
{_t("Activate Secure Key Backup")}
{setupCaption}
</AccessibleButton>
<p><AccessibleButton className="mx_RoomRecoveryReminder_secondary mx_linkButton"
onClick={this.onOnNotNowClick}>
{ _t("Not now") }
</AccessibleButton></p>
<p><AccessibleButton className="mx_RoomRecoveryReminder_secondary mx_linkButton"
onClick={this.onDontAskAgainClick}>
{ _t("No thanks, I'll download a copy of my decryption keys before I log out") }
{ _t("Don't ask me again") }
</AccessibleButton></p>
</div>
</div>

View file

@ -111,10 +111,10 @@ export default class KeyBackupPanel extends React.PureComponent {
Modal.createTrackedDialog('Delete Backup', '', QuestionDialog, {
title: _t('Delete Backup'),
description: _t(
"Delete your backed up encryption keys from the server? " +
"You will no longer be able to use your recovery key to read encrypted message history",
"Are you sure? You will lose your encrypted messages if your " +
"keys are not backed up properly.",
),
button: _t('Delete backup'),
button: _t('Delete Backup'),
danger: true,
onFinished: (proceed) => {
if (!proceed) return;
@ -135,6 +135,10 @@ export default class KeyBackupPanel extends React.PureComponent {
render() {
const Spinner = sdk.getComponent("elements.Spinner");
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
const encryptedMessageAreEncrypted = _t(
"Encrypted messages are secured with end-to-end encryption. " +
"Only you and the recipient(s) have the keys to read these messages.",
);
if (this.state.error) {
return (
@ -145,14 +149,25 @@ export default class KeyBackupPanel extends React.PureComponent {
} else if (this.state.loading) {
return <Spinner />;
} else if (this.state.backupInfo) {
const EmojiText = sdk.getComponent('elements.EmojiText');
let clientBackupStatus;
let restoreButtonCaption = _t("Restore from Backup");
if (MatrixClientPeg.get().getKeyBackupEnabled()) {
clientBackupStatus = _t("This device is using key backup");
clientBackupStatus = <div>
<p>{encryptedMessageAreEncrypted}</p>
<p>{_t("This device is backing up your keys. ")}<EmojiText></EmojiText></p>
</div>;
} else {
clientBackupStatus = _t(
"This device is <b>not</b> using key backup. Restore the backup to start using it.", {},
{b: x => <b>{x}</b>},
);
clientBackupStatus = <div>
<p>{encryptedMessageAreEncrypted}</p>
<p>{_t(
"This device is <b>not backing up your keys</b>.", {},
{b: sub => <b>{sub}</b>},
)}</p>
<p>{_t("Back up your keys before signing out to avoid losing them.")}</p>
</div>;
restoreButtonCaption = _t("Use key backup");
}
let uploadStatus;
@ -243,18 +258,25 @@ export default class KeyBackupPanel extends React.PureComponent {
</details>
<p>
<AccessibleButton kind="primary" onClick={this._restoreBackup}>
{ _t("Restore backup") }
{restoreButtonCaption}
</AccessibleButton>&nbsp;&nbsp;&nbsp;
<AccessibleButton kind="danger" onClick={this._deleteBackup}>
{ _t("Delete backup") }
{ _t("Delete Backup") }
</AccessibleButton>
</p>
</div>;
} else {
return <div>
{_t("No backup is present")}<br /><br />
<div>
<p>{_t(
"Your keys are <b>not being backed up from this device</b>.", {},
{b: sub => <b>{sub}</b>},
)}</p>
<p>{encryptedMessageAreEncrypted}</p>
<p>{_t("Back up your keys before signing out to avoid losing them.")}</p>
</div>
<AccessibleButton kind="primary" onClick={this._startNewBackup}>
{ _t("Start a new backup") }
{ _t("Start using Key Backup") }
</AccessibleButton>
</div>;
}