diff --git a/src/Lifecycle.js b/src/Lifecycle.js index ec1fca2bc6..7378e982ef 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -1,6 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -64,33 +65,33 @@ import sdk from './index'; * Resolves to `true` if we ended up starting a session, or `false` if we * failed. */ -export function loadSession(opts) { - const fragmentQueryParams = opts.fragmentQueryParams || {}; - let enableGuest = opts.enableGuest || false; - const guestHsUrl = opts.guestHsUrl; - const guestIsUrl = opts.guestIsUrl; - const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; +export async function loadSession(opts) { + try { + let enableGuest = opts.enableGuest || false; + const guestHsUrl = opts.guestHsUrl; + const guestIsUrl = opts.guestIsUrl; + const fragmentQueryParams = opts.fragmentQueryParams || {}; + const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; - if (!guestHsUrl) { - console.warn("Cannot enable guest access: can't determine HS URL to use"); - enableGuest = false; - } + if (!guestHsUrl) { + console.warn("Cannot enable guest access: can't determine HS URL to use"); + enableGuest = false; + } - if (enableGuest && - fragmentQueryParams.guest_user_id && - fragmentQueryParams.guest_access_token - ) { - console.log("Using guest access credentials"); - return _doSetLoggedIn({ - userId: fragmentQueryParams.guest_user_id, - accessToken: fragmentQueryParams.guest_access_token, - homeserverUrl: guestHsUrl, - identityServerUrl: guestIsUrl, - guest: true, - }, true).then(() => true); - } - - return _restoreFromLocalStorage().then((success) => { + if (enableGuest && + fragmentQueryParams.guest_user_id && + fragmentQueryParams.guest_access_token + ) { + console.log("Using guest access credentials"); + return _doSetLoggedIn({ + userId: fragmentQueryParams.guest_user_id, + accessToken: fragmentQueryParams.guest_access_token, + homeserverUrl: guestHsUrl, + identityServerUrl: guestIsUrl, + guest: true, + }, true).then(() => true); + } + const success = await _restoreFromLocalStorage(); if (success) { return true; } @@ -101,7 +102,9 @@ export function loadSession(opts) { // fall back to login screen return false; - }); + } catch (e) { + return _handleLoadSessionFailure(e); + } } /** @@ -195,9 +198,9 @@ function _registerAsGuest(hsUrl, isUrl, defaultDeviceDisplayName) { // The plan is to gradually move the localStorage access done here into // SessionStore to avoid bugs where the view becomes out-of-sync with // localStorage (e.g. teamToken, isGuest etc.) -function _restoreFromLocalStorage() { +async function _restoreFromLocalStorage() { if (!localStorage) { - return Promise.resolve(false); + return false; } const hsUrl = localStorage.getItem("mx_hs_url"); const isUrl = localStorage.getItem("mx_is_url") || 'https://matrix.org'; @@ -215,26 +218,23 @@ function _restoreFromLocalStorage() { if (accessToken && userId && hsUrl) { console.log(`Restoring session for ${userId}`); - try { - return _doSetLoggedIn({ - userId: userId, - deviceId: deviceId, - accessToken: accessToken, - homeserverUrl: hsUrl, - identityServerUrl: isUrl, - guest: isGuest, - }, false).then(() => true); - } catch (e) { - return _handleRestoreFailure(e); - } + await _doSetLoggedIn({ + userId: userId, + deviceId: deviceId, + accessToken: accessToken, + homeserverUrl: hsUrl, + identityServerUrl: isUrl, + guest: isGuest, + }, false); + return true; } else { console.log("No previous session found."); - return Promise.resolve(false); + return false; } } -function _handleRestoreFailure(e) { - console.log("Unable to restore session", e); +function _handleLoadSessionFailure(e) { + console.log("Unable to load session", e); const def = Promise.defer(); const SessionRestoreErrorDialog = @@ -255,7 +255,7 @@ function _handleRestoreFailure(e) { } // try, try again - return _restoreFromLocalStorage(); + return loadSession(); }); } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 1eb96c9f11..8df46d2f7c 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1,7 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd -Copyright 2017 New Vector Ltd +Copyright 2017, 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -351,16 +351,16 @@ export default React.createClass({ guestIsUrl: this.getCurrentIsUrl(), defaultDeviceDisplayName: this.props.defaultDeviceDisplayName, }); - }).catch((e) => { - console.error('Error attempting to load session', e); - return false; }).then((loadedSession) => { if (!loadedSession) { // fall back to showing the login screen dis.dispatch({action: "start_login"}); } }); - }).done(); + // Note we don't catch errors from this: we catch everything within + // loadSession as there's logic there to ask the user if they want + // to try logging out. + }); }, componentWillUnmount: function() { diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 21a2477c37..51d9180885 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -36,6 +36,9 @@ export default React.createClass({ propTypes: { // onFinished callback to call when Escape is pressed + // Take a boolean which is true if the dialog was dismissed + // with a positive / confirm action or false if it was + // cancelled (BaseDialog itself only calls this with false). onFinished: PropTypes.func.isRequired, // called when a key is pressed @@ -77,12 +80,12 @@ export default React.createClass({ if (e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); e.preventDefault(); - this.props.onFinished(); + this.props.onFinished(false); } }, _onCancelClick: function(e) { - this.props.onFinished(); + this.props.onFinished(false); }, render: function() { diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 451785197e..f101381ebf 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -41,10 +42,14 @@ export default React.createClass({ Modal.createTrackedDialog('Session Restore Error', 'Send Bug Report Dialog', BugReportDialog, {}); }, - _continueClicked: function() { + _onContinueClick: function() { this.props.onFinished(true); }, + _onCancelClick: function() { + this.props.onFinished(false); + }, + render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); @@ -81,8 +86,8 @@ export default React.createClass({ { bugreport } + onPrimaryButtonClick={this._onContinueClick} focus={shouldFocusContinueButton} + onCancel={this._onCancelClick} /> ); }, diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index c159324c1d..537f906a74 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -39,6 +39,10 @@ module.exports = React.createClass({ focus: PropTypes.bool, }, + _onCancelClick: function() { + this.props.onCancel(); + }, + render: function() { let primaryButtonClassName = "mx_Dialog_primary"; if (this.props.primaryButtonClass) { @@ -53,7 +57,7 @@ module.exports = React.createClass({ { this.props.primaryButton } { this.props.children } -