diff --git a/res/css/_common.scss b/res/css/_common.scss index e81c228430..c4cda6821e 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -250,6 +250,7 @@ textarea { .mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger { background-color: $warning-color; border: solid 1px $warning-color; + color: $accent-fg-color; } .mx_Dialog button:disabled, .mx_Dialog input[type="submit"]:disabled { diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 7959e7cb10..fb116cdffe 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.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,6 +42,13 @@ export default React.createClass({ // cancelled (from BaseDialog, this is always false). onFinished: PropTypes.func.isRequired, + // Whether the dialog should have a 'close' button that will + // cause the dialog to be cancelled. This should only be set + // to true if there is nothing the app can sensibly do if the + // dialog is cancelled, eg. "We can't restore your session and + // the app cannot work". + hasCancel: PropTypes.bool, + // called when a key is pressed onKeyDown: PropTypes.func, @@ -59,6 +67,12 @@ export default React.createClass({ contentId: React.PropTypes.string, }, + getDefaultProps: function() { + return { + hasCancel: true, + }; + }, + childContextTypes: { matrixClient: PropTypes.instanceOf(MatrixClient), }, @@ -77,7 +91,7 @@ export default React.createClass({ if (this.props.onKeyDown) { this.props.onKeyDown(e); } - if (e.keyCode === KeyCode.ESCAPE) { + if (this.props.hasCancel && e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); e.preventDefault(); this.props.onFinished(false); @@ -104,11 +118,11 @@ export default React.createClass({ // AT users can skip its presentation. aria-describedby={this.props.contentId} > - - + : null }
{ this.props.title }
diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index f101381ebf..2e152df4b0 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -31,63 +31,73 @@ export default React.createClass({ onFinished: PropTypes.func.isRequired, }, - componentDidMount: function() { - if (this.refs.bugreportLink) { - this.refs.bugreportLink.focus(); - } - }, - _sendBugReport: function() { const BugReportDialog = sdk.getComponent("dialogs.BugReportDialog"); Modal.createTrackedDialog('Session Restore Error', 'Send Bug Report Dialog', BugReportDialog, {}); }, - _onContinueClick: function() { - this.props.onFinished(true); + _onClearStorageClick: function() { + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + Modal.createTrackedDialog('Session Restore Confirm Logout', '', QuestionDialog, { + title: _t("Sign out"), + description: +
{ _t("Log out and remove encryption keys?") }
, + button: _t("Sign out"), + danger: true, + onFinished: this.props.onFinished, + }); }, - _onCancelClick: function() { - this.props.onFinished(false); + _onRefreshClick: function() { + // Is this likely to help? Probably not, but giving only one button + // that clears your storage seems awful. + window.location.reload(true); }, render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); - let bugreport; + let dialogButtons; if (SdkConfig.get().bug_report_endpoint_url) { - bugreport = ( -

- { _t( - "Otherwise, click here to send a bug report.", - {}, - { 'a': (sub) => { sub } }, - ) } -

- ); + dialogButtons = + + + } else { + dialogButtons = + + } - const shouldFocusContinueButton =!(bugreport==true); return (
-

{ _t("We encountered an error trying to restore your previous session. If " + - "you continue, you will need to log in again, and encrypted chat " + - "history will be unreadable.") }

+

{ _t("We encountered an error trying to restore your previous session.") }

{ _t("If you have previously used a more recent version of Riot, your session " + "may be incompatible with this version. Close this window and return " + "to the more recent version.") }

- { bugreport } +

{ _t("Clearing your browser's storage may fix the problem, but will sign you " + + "out and cause any encrypted chat history to become unreadable.") }

- + { dialogButtons }
); }, diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 537f906a74..73e47cbde2 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -1,5 +1,6 @@ /* Copyright 2017 Aidan Gauland +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. @@ -14,8 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; - import React from "react"; import PropTypes from "prop-types"; import { _t } from '../../../languageHandler'; @@ -33,12 +32,21 @@ module.exports = React.createClass({ // onClick handler for the primary button. onPrimaryButtonClick: PropTypes.func.isRequired, + // should there be a cancel button? default: true + hasCancel: PropTypes.bool, + // onClick handler for the cancel button. - onCancel: PropTypes.func.isRequired, + onCancel: PropTypes.func, focus: PropTypes.bool, }, + getDefaultProps: function() { + return { + hasCancel: true, + } + }, + _onCancelClick: function() { this.props.onCancel(); }, @@ -57,9 +65,9 @@ module.exports = React.createClass({ { this.props.primaryButton } { this.props.children } - + : null } ); }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 33f18e47a4..3c8dd5b66f 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -103,7 +103,6 @@ "You need to be logged in.": "You need to be logged in.", "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", "Unable to create widget.": "Unable to create widget.", - "Popout widget": "Popout widget", "Missing roomId.": "Missing roomId.", "Failed to send request.": "Failed to send request.", "This room is not recognised.": "This room is not recognised.", @@ -655,6 +654,7 @@ "Delete widget": "Delete widget", "Revoke widget access": "Revoke widget access", "Minimize apps": "Minimize apps", + "Popout widget": "Popout widget", "Picture": "Picture", "Edit": "Edit", "Create new room": "Create new room", @@ -807,11 +807,15 @@ "Ignore request": "Ignore request", "Loading device info...": "Loading device info...", "Encryption key request": "Encryption key request", - "Otherwise, click here to send a bug report.": "Otherwise, click here to send a bug report.", + "Sign out": "Sign out", + "Log out and remove encryption keys?": "Log out and remove encryption keys?", + "Send Logs": "Send Logs", + "Clear Storage and Sign Out": "Clear Storage and Sign Out", + "Refresh": "Refresh", "Unable to restore session": "Unable to restore session", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.", + "We encountered an error trying to restore your previous session.": "We encountered an error trying to restore your previous session.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.", - "Continue anyway": "Continue anyway", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.", "Invalid Email Address": "Invalid Email Address", "This doesn't appear to be a valid email address": "This doesn't appear to be a valid email address", "Verification Pending": "Verification Pending", @@ -1015,7 +1019,6 @@ "Status.im theme": "Status.im theme", "Can't load user settings": "Can't load user settings", "Server may be unavailable or overloaded": "Server may be unavailable or overloaded", - "Sign out": "Sign out", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.", "Success": "Success", "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them",