From fa669bf09651c72b803a36a5ed6638b41f3036e4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 7 Sep 2018 12:18:25 +0100 Subject: [PATCH] Error on splash screen if sync is failing Display an error on the splash screen with the spinner if the sync request is not working, rather than just sitting there with a spinner as if nothing is wrong. Fixes https://github.com/vector-im/riot-web/issues/7148 --- res/css/structures/_MatrixChat.scss | 12 ++++++++++ src/components/structures/MatrixChat.js | 19 +++++++++++++++- src/i18n/strings/en_EN.json | 9 ++++---- src/utils/ErrorUtils.js | 30 ++++++++++++++++++++++++- 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/res/css/structures/_MatrixChat.scss b/res/css/structures/_MatrixChat.scss index 156b1709fe..eae1f56180 100644 --- a/res/css/structures/_MatrixChat.scss +++ b/res/css/structures/_MatrixChat.scss @@ -56,6 +56,18 @@ limitations under the License. flex: 1; } +.mx_MatrixChat_syncError { + color: $accent-fg-color; + background-color: $warning-bg-color; + border-radius: 5px; + display: table; + padding: 30px; + position: absolute; + top: 100px; + left: 50%; + transform: translateX(-50%); +} + .mx_MatrixChat .mx_LeftPanel { order: 1; diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 333e200e44..71e61cda22 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -46,6 +46,7 @@ import KeyRequestHandler from '../../KeyRequestHandler'; import { _t, getCurrentLanguage } from '../../languageHandler'; import SettingsStore, {SettingLevel} from "../../settings/SettingsStore"; import { startAnyRegistrationFlow } from "../../Registration.js"; +import { messageForSyncError } from '../../utils/ErrorUtils'; /** constants for MatrixChat.state.view */ const VIEWS = { @@ -179,6 +180,8 @@ export default React.createClass({ // When showing Modal dialogs we need to set aria-hidden on the root app element // and disable it when there are no dialogs hideToSRUsers: false, + + syncError: null, // If the current syncing status is ERROR, the error object, otherwise null. }; return s; }, @@ -1242,13 +1245,20 @@ export default React.createClass({ return self._loggedInView.child.canResetTimelineInRoom(roomId); }); - cli.on('sync', function(state, prevState) { + cli.on('sync', function(state, prevState, data) { // LifecycleStore and others cannot directly subscribe to matrix client for // events because flux only allows store state changes during flux dispatches. // So dispatch directly from here. Ideally we'd use a SyncStateStore that // would do this dispatch and expose the sync state itself (by listening to // its own dispatch). dis.dispatch({action: 'sync_state', prevState, state}); + + if (state === "ERROR") { + self.setState({syncError: data.error}); + } else if (self.state.syncError) { + self.setState({syncError: null}); + } + self.updateStatusIndicator(state, prevState); if (state === "SYNCING" && prevState === "SYNCING") { return; @@ -1744,8 +1754,15 @@ export default React.createClass({ } else { // we think we are logged in, but are still waiting for the /sync to complete const Spinner = sdk.getComponent('elements.Spinner'); + let errorBox; + if (this.state.syncError) { + errorBox =
+ {messageForSyncError(this.state.syncError)} +
; + } return (
+ {errorBox} { _t('Logout') } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index d06b986474..4643d4bdff 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -89,6 +89,7 @@ "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Your email address does not appear to be associated with a Matrix ID on this Homeserver.", "Registration Required": "Registration Required", "You need to register to do this. Would you like to register now?": "You need to register to do this. Would you like to register now?", + "Register": "Register", "Default": "Default", "Restricted": "Restricted", "Moderator": "Moderator", @@ -203,6 +204,10 @@ "Send anyway": "Send anyway", "Send": "Send", "Unnamed Room": "Unnamed Room", + "This homeserver has hit its Monthly Active User limit.": "This homeserver has hit its Monthly Active User limit.", + "This homeserver has exceeded one of its resource limits.": "This homeserver has exceeded one of its resource limits.", + "Please contact your service administrator to continue using the service.": "Please contact your service administrator to continue using the service.", + "Unable to connect to Homeserver. Retrying...": "Unable to connect to Homeserver. Retrying...", "Your browser does not support the required cryptography extensions": "Your browser does not support the required cryptography extensions", "Not a valid Riot keyfile": "Not a valid Riot keyfile", "Authentication check failed: incorrect password?": "Authentication check failed: incorrect password?", @@ -655,7 +660,6 @@ "Email address (optional)": "Email address (optional)", "You are registering with %(SelectedTeamName)s": "You are registering with %(SelectedTeamName)s", "Mobile phone number (optional)": "Mobile phone number (optional)", - "Register": "Register", "Default server": "Default server", "Custom server": "Custom server", "Home server URL": "Home server URL", @@ -694,9 +698,6 @@ "A new version of Riot is available.": "A new version of Riot is available.", "To return to your account in future you need to set a password": "To return to your account in future you need to set a password", "Set Password": "Set Password", - "Please contact your service administrator to continue using the service.": "Please contact your service administrator to continue using the service.", - "This homeserver has hit its Monthly Active User limit.": "This homeserver has hit its Monthly Active User limit.", - "This homeserver has exceeded one of its resource limits.": "This homeserver has exceeded one of its resource limits.", "Please contact your service administrator to get this limit increased.": "Please contact your service administrator to get this limit increased.", "This homeserver has hit its Monthly Active User limit so some users will not be able to log in.": "This homeserver has hit its Monthly Active User limit so some users will not be able to log in.", "This homeserver has exceeded one of its resource limits so some users will not be able to log in.": "This homeserver has exceeded one of its resource limits so some users will not be able to log in.", diff --git a/src/utils/ErrorUtils.js b/src/utils/ErrorUtils.js index 97a29a3572..4a56d64ef1 100644 --- a/src/utils/ErrorUtils.js +++ b/src/utils/ErrorUtils.js @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { _t } from '../languageHandler'; +import { _t, _td } from '../languageHandler'; /** * Produce a translated error message for a @@ -48,3 +48,31 @@ export function messageForResourceLimitError(limitType, adminContact, strings, e return _t(errString, {}, extraTranslations); } } + +export function messageForSyncError(err) { + if (err.errcode === 'M_RESOURCE_LIMIT_EXCEEDED') { + const limitError = messageForResourceLimitError( + err.data.limit_type, + err.data.admin_contact, + { + 'monthly_active_user': _td("This homeserver has hit its Monthly Active User limit."), + '': _td("This homeserver has exceeded one of its resource limits."), + }, + ); + const adminContact = messageForResourceLimitError( + err.data.limit_type, + err.data.admin_contact, + { + '': _td("Please contact your service administrator to continue using the service."), + }, + ); + return
+
{limitError}
+
{adminContact}
+
; + } else { + return
+ {_t("Unable to connect to Homeserver. Retrying...")} +
; + } +}