Convert CreateKeyBackupDialog to class

This commit is contained in:
J. Ryan Stinnett 2019-11-15 13:36:59 +00:00
parent d5d2f7f936
commit af2302265a

View file

@ -1,5 +1,6 @@
/* /*
Copyright 2018, 2019 New Vector Ltd Copyright 2018, 2019 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -15,7 +16,6 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import createReactClass from 'create-react-class';
import sdk from '../../../../index'; import sdk from '../../../../index';
import MatrixClientPeg from '../../../../MatrixClientPeg'; import MatrixClientPeg from '../../../../MatrixClientPeg';
import { scorePassword } from '../../../../utils/PasswordScorer'; import { scorePassword } from '../../../../utils/PasswordScorer';
@ -49,9 +49,11 @@ function selectText(target) {
* Walks the user through the process of creating an e2e key backup * Walks the user through the process of creating an e2e key backup
* on the server. * on the server.
*/ */
export default createReactClass({ export default class CreateKeyBackupDialog extends React.PureComponent {
getInitialState: function() { constructor(props) {
return { super(props);
this.state = {
phase: PHASE_PASSPHRASE, phase: PHASE_PASSPHRASE,
passPhrase: '', passPhrase: '',
passPhraseConfirm: '', passPhraseConfirm: '',
@ -60,25 +62,25 @@ export default createReactClass({
zxcvbnResult: null, zxcvbnResult: null,
setPassPhrase: false, setPassPhrase: false,
}; };
}, }
componentWillMount: function() { componentWillMount() {
this._recoveryKeyNode = null; this._recoveryKeyNode = null;
this._keyBackupInfo = null; this._keyBackupInfo = null;
this._setZxcvbnResultTimeout = null; this._setZxcvbnResultTimeout = null;
}, }
componentWillUnmount: function() { componentWillUnmount() {
if (this._setZxcvbnResultTimeout !== null) { if (this._setZxcvbnResultTimeout !== null) {
clearTimeout(this._setZxcvbnResultTimeout); clearTimeout(this._setZxcvbnResultTimeout);
} }
}, }
_collectRecoveryKeyNode: function(n) { _collectRecoveryKeyNode = (n) => {
this._recoveryKeyNode = n; this._recoveryKeyNode = n;
}, }
_onCopyClick: function() { _onCopyClick = () => {
selectText(this._recoveryKeyNode); selectText(this._recoveryKeyNode);
const successful = document.execCommand('copy'); const successful = document.execCommand('copy');
if (successful) { if (successful) {
@ -87,9 +89,9 @@ export default createReactClass({
phase: PHASE_KEEPITSAFE, phase: PHASE_KEEPITSAFE,
}); });
} }
}, }
_onDownloadClick: function() { _onDownloadClick = () => {
const blob = new Blob([this._keyBackupInfo.recovery_key], { const blob = new Blob([this._keyBackupInfo.recovery_key], {
type: 'text/plain;charset=us-ascii', type: 'text/plain;charset=us-ascii',
}); });
@ -99,9 +101,9 @@ export default createReactClass({
downloaded: true, downloaded: true,
phase: PHASE_KEEPITSAFE, phase: PHASE_KEEPITSAFE,
}); });
}, }
_createBackup: async function() { _createBackup = async () => {
this.setState({ this.setState({
phase: PHASE_BACKINGUP, phase: PHASE_BACKINGUP,
error: null, error: null,
@ -128,38 +130,38 @@ export default createReactClass({
error: e, error: e,
}); });
} }
}, }
_onCancel: function() { _onCancel = () => {
this.props.onFinished(false); this.props.onFinished(false);
}, }
_onDone: function() { _onDone = () => {
this.props.onFinished(true); this.props.onFinished(true);
}, }
_onOptOutClick: function() { _onOptOutClick = () => {
this.setState({phase: PHASE_OPTOUT_CONFIRM}); this.setState({phase: PHASE_OPTOUT_CONFIRM});
}, }
_onSetUpClick: function() { _onSetUpClick = () => {
this.setState({phase: PHASE_PASSPHRASE}); this.setState({phase: PHASE_PASSPHRASE});
}, }
_onSkipPassPhraseClick: async function() { _onSkipPassPhraseClick = async () => {
this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion(); this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion();
this.setState({ this.setState({
copied: false, copied: false,
downloaded: false, downloaded: false,
phase: PHASE_SHOWKEY, phase: PHASE_SHOWKEY,
}); });
}, }
_onPassPhraseNextClick: function() { _onPassPhraseNextClick = () => {
this.setState({phase: PHASE_PASSPHRASE_CONFIRM}); this.setState({phase: PHASE_PASSPHRASE_CONFIRM});
}, }
_onPassPhraseKeyPress: async function(e) { _onPassPhraseKeyPress = async (e) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
// If we're waiting for the timeout before updating the result at this point, // If we're waiting for the timeout before updating the result at this point,
// skip ahead and do it now, otherwise we'll deny the attempt to proceed // skip ahead and do it now, otherwise we'll deny the attempt to proceed
@ -177,9 +179,9 @@ export default createReactClass({
this._onPassPhraseNextClick(); this._onPassPhraseNextClick();
} }
} }
}, }
_onPassPhraseConfirmNextClick: async function() { _onPassPhraseConfirmNextClick = async () => {
this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion(this.state.passPhrase); this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion(this.state.passPhrase);
this.setState({ this.setState({
setPassPhrase: true, setPassPhrase: true,
@ -187,30 +189,30 @@ export default createReactClass({
downloaded: false, downloaded: false,
phase: PHASE_SHOWKEY, phase: PHASE_SHOWKEY,
}); });
}, }
_onPassPhraseConfirmKeyPress: function(e) { _onPassPhraseConfirmKeyPress = (e) => {
if (e.key === 'Enter' && this.state.passPhrase === this.state.passPhraseConfirm) { if (e.key === 'Enter' && this.state.passPhrase === this.state.passPhraseConfirm) {
this._onPassPhraseConfirmNextClick(); this._onPassPhraseConfirmNextClick();
} }
}, }
_onSetAgainClick: function() { _onSetAgainClick = () => {
this.setState({ this.setState({
passPhrase: '', passPhrase: '',
passPhraseConfirm: '', passPhraseConfirm: '',
phase: PHASE_PASSPHRASE, phase: PHASE_PASSPHRASE,
zxcvbnResult: null, zxcvbnResult: null,
}); });
}, }
_onKeepItSafeBackClick: function() { _onKeepItSafeBackClick = () => {
this.setState({ this.setState({
phase: PHASE_SHOWKEY, phase: PHASE_SHOWKEY,
}); });
}, }
_onPassPhraseChange: function(e) { _onPassPhraseChange = (e) => {
this.setState({ this.setState({
passPhrase: e.target.value, passPhrase: e.target.value,
}); });
@ -227,19 +229,19 @@ export default createReactClass({
zxcvbnResult: scorePassword(this.state.passPhrase), zxcvbnResult: scorePassword(this.state.passPhrase),
}); });
}, PASSPHRASE_FEEDBACK_DELAY); }, PASSPHRASE_FEEDBACK_DELAY);
}, }
_onPassPhraseConfirmChange: function(e) { _onPassPhraseConfirmChange = (e) => {
this.setState({ this.setState({
passPhraseConfirm: e.target.value, passPhraseConfirm: e.target.value,
}); });
}, }
_passPhraseIsValid: function() { _passPhraseIsValid() {
return this.state.zxcvbnResult && this.state.zxcvbnResult.score >= PASSWORD_MIN_SCORE; return this.state.zxcvbnResult && this.state.zxcvbnResult.score >= PASSWORD_MIN_SCORE;
}, }
_renderPhasePassPhrase: function() { _renderPhasePassPhrase() {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
let strengthMeter; let strengthMeter;
@ -305,9 +307,9 @@ export default createReactClass({
</button></p> </button></p>
</details> </details>
</div>; </div>;
}, }
_renderPhasePassPhraseConfirm: function() { _renderPhasePassPhraseConfirm() {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
let matchText; let matchText;
@ -361,9 +363,9 @@ export default createReactClass({
disabled={this.state.passPhrase !== this.state.passPhraseConfirm} disabled={this.state.passPhrase !== this.state.passPhraseConfirm}
/> />
</div>; </div>;
}, }
_renderPhaseShowKey: function() { _renderPhaseShowKey() {
let bodyText; let bodyText;
if (this.state.setPassPhrase) { if (this.state.setPassPhrase) {
bodyText = _t( bodyText = _t(
@ -402,9 +404,9 @@ export default createReactClass({
</div> </div>
</div> </div>
</div>; </div>;
}, }
_renderPhaseKeepItSafe: function() { _renderPhaseKeepItSafe() {
let introText; let introText;
if (this.state.copied) { if (this.state.copied) {
introText = _t( introText = _t(
@ -431,16 +433,16 @@ export default createReactClass({
<button onClick={this._onKeepItSafeBackClick}>{_t("Back")}</button> <button onClick={this._onKeepItSafeBackClick}>{_t("Back")}</button>
</DialogButtons> </DialogButtons>
</div>; </div>;
}, }
_renderBusyPhase: function(text) { _renderBusyPhase(text) {
const Spinner = sdk.getComponent('views.elements.Spinner'); const Spinner = sdk.getComponent('views.elements.Spinner');
return <div> return <div>
<Spinner /> <Spinner />
</div>; </div>;
}, }
_renderPhaseDone: function() { _renderPhaseDone() {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return <div> return <div>
<p>{_t( <p>{_t(
@ -451,9 +453,9 @@ export default createReactClass({
hasCancel={false} hasCancel={false}
/> />
</div>; </div>;
}, }
_renderPhaseOptOutConfirm: function() { _renderPhaseOptOutConfirm() {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return <div> return <div>
{_t( {_t(
@ -467,9 +469,9 @@ export default createReactClass({
<button onClick={this._onCancel}>I understand, continue without</button> <button onClick={this._onCancel}>I understand, continue without</button>
</DialogButtons> </DialogButtons>
</div>; </div>;
}, }
_titleForPhase: function(phase) { _titleForPhase(phase) {
switch (phase) { switch (phase) {
case PHASE_PASSPHRASE: case PHASE_PASSPHRASE:
return _t('Secure your backup with a passphrase'); return _t('Secure your backup with a passphrase');
@ -488,9 +490,9 @@ export default createReactClass({
default: default:
return _t("Create Key Backup"); return _t("Create Key Backup");
} }
}, }
render: function() { render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
let content; let content;
@ -543,5 +545,5 @@ export default createReactClass({
</div> </div>
</BaseDialog> </BaseDialog>
); );
}, }
}); }