From 8567ce585b0ccc339d569e20fbb41a183b7018aa Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 16 Aug 2018 13:31:17 +0100 Subject: [PATCH] Factor out duplication of resource limit i18n --- src/components/structures/RoomStatusBar.js | 39 +++++------ src/components/structures/login/Login.js | 38 +++++----- .../structures/login/Registration.js | 36 ++++++---- .../views/globals/ServerLimitBar.js | 69 +++++++++---------- src/i18n/strings/en_EN.json | 1 - src/utils/ErrorUtils.js | 50 ++++++++++++++ 6 files changed, 143 insertions(+), 90 deletions(-) create mode 100644 src/utils/ErrorUtils.js diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index 260aec81ea..fec59aadd5 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -18,7 +18,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import Matrix from 'matrix-js-sdk'; -import { _t } from '../../languageHandler'; +import { _t, _td } from '../../languageHandler'; import sdk from '../../index'; import WhoIsTyping from '../../WhoIsTyping'; import MatrixClientPeg from '../../MatrixClientPeg'; @@ -26,6 +26,7 @@ import MemberAvatar from '../views/avatars/MemberAvatar'; import Resend from '../../Resend'; import * as cryptodevices from '../../cryptodevices'; import dis from '../../dispatcher'; +import { messageForResourceLimitError } from '../../utils/ErrorUtils'; const STATUS_BAR_HIDDEN = 0; const STATUS_BAR_EXPANDED = 1; @@ -326,20 +327,13 @@ module.exports = React.createClass({ ); } else { let consentError = null; - let mauError = null; - const translateMauError = sub => { - if (mauError.data.admin_contact) { - return {sub}; - } else { - return sub; - } - }; + let resourceLimitError = null; for (const m of unsentMessages) { if (m.error && m.error.errcode === 'M_CONSENT_NOT_GIVEN') { consentError = m.error; break; } else if (m.error && m.error.errcode === 'M_RESOURCE_LIMIT_EXCEEDED') { - mauError = m.error; + resourceLimitError = m.error; break; } } @@ -355,18 +349,19 @@ module.exports = React.createClass({ , }, ); - } else if (mauError && mauError.data.limit_type === 'monthly_active_user') { - title = _t( - "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. " + - "Please contact your service administrator to continue using the service.", - {}, { 'a' : translateMauError }, - ); - } else if (mauError) { - title = _t( - "Your message wasn't sent because this homeserver has exceeded a resource limit. " + - "Please contact your service administrator to continue using the service.", - {}, { 'a' : translateMauError }, - ); + } else if (resourceLimitError) { + title = messageForResourceLimitError( + resourceLimitError.data.limit_type, + resourceLimitError.data.admin_contact, { + 'monthly_active_user': _td( + "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. " + + "Please contact your service administrator to continue using the service.", + ), + '': _td( + "Your message wasn't sent because this homeserver has exceeded a resource limit. " + + "Please contact your service administrator to continue using the service.", + ), + }); } else if ( unsentMessages.length === 1 && unsentMessages[0].error && diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index 77db6ea444..45f523f141 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -20,11 +20,12 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import { _t } from '../../../languageHandler'; +import { _t, _td } from '../../../languageHandler'; import sdk from '../../../index'; import Login from '../../../Login'; import SdkConfig from '../../../SdkConfig'; import SettingsStore from "../../../settings/SettingsStore"; +import { messageForResourceLimitError } from '../../../utils/ErrorUtils'; // For validating phone numbers without country codes const PHONE_NUMBER_REGEX = /^[0-9()\-\s]*$/; @@ -122,24 +123,27 @@ module.exports = React.createClass({ if (error.httpStatus === 400 && usingEmail) { errorText = _t('This Home Server does not support login using email address.'); } else if (error.errcode == 'M_RESOURCE_LIMIT_EXCEEDED') { + const errorTop = messageForResourceLimitError( + error.data.limit_type, + error.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 errorDetail = messageForResourceLimitError( + error.data.limit_type, + error.data.admin_contact, { + '': _td( + "Please contact your service administrator to continue using this service.", + ), + }); errorText = (
-
{error.data.error ? error.data.error : _t("This server has exceeded its available resources")}
-
- {_t( - "Please contact your service administrator to continue using this service.", - {}, - { - a: (sub) => { - if (error.data.admin_contact) { - return {sub}; - } else { - return sub; - } - }, - }, - )} -
+
{errorTop}
+
{errorDetail}
); } else if (error.httpStatus === 401 || error.httpStatus === 403) { diff --git a/src/components/structures/login/Registration.js b/src/components/structures/login/Registration.js index 3e2b3c2bdc..1131218311 100644 --- a/src/components/structures/login/Registration.js +++ b/src/components/structures/login/Registration.js @@ -26,9 +26,10 @@ import sdk from '../../../index'; import MatrixClientPeg from '../../../MatrixClientPeg'; import RegistrationForm from '../../views/login/RegistrationForm'; import RtsClient from '../../../RtsClient'; -import { _t } from '../../../languageHandler'; +import { _t, _td } from '../../../languageHandler'; import SdkConfig from '../../../SdkConfig'; import SettingsStore from "../../../settings/SettingsStore"; +import { messageForResourceLimitError } from '../../../utils/ErrorUtils'; const MIN_PASSWORD_LENGTH = 6; @@ -165,21 +166,26 @@ module.exports = React.createClass({ let msg = response.message || response.toString(); // can we give a better error message? if (response.errcode == 'M_RESOURCE_LIMIT_EXCEEDED') { - msg =
-

{response.data.error ? response.data.error : _t("This server has exceeded its available resources")}

-

{_t( + const errorTop = messageForResourceLimitError( + response.data.limit_type, + response.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 errorDetail = messageForResourceLimitError( + response.data.limit_type, + response.data.admin_contact, { + '': _td( "Please contact your service administrator to continue using this service.", - {}, - { - a: (sub) => { - if (response.data.admin_contact) { - return {sub}; - } else { - return sub; - } - }, - }, - )}

+ ), + }); + msg =
+

{errorTop}

+

{errorDetail}

; } else if (response.required_stages && response.required_stages.indexOf('m.login.msisdn') > -1) { let msisdnAvailable = false; diff --git a/src/components/views/globals/ServerLimitBar.js b/src/components/views/globals/ServerLimitBar.js index 375d52bbe4..0b924fd2e2 100644 --- a/src/components/views/globals/ServerLimitBar.js +++ b/src/components/views/globals/ServerLimitBar.js @@ -17,7 +17,8 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -import { _t } from '../../../languageHandler'; +import { _td } from '../../../languageHandler'; +import { messageForResourceLimitError } from '../../../utils/ErrorUtils'; export default React.createClass({ propTypes: { @@ -39,52 +40,50 @@ export default React.createClass({ 'mx_MatrixToolbar': true, }; - const translateLink = (sub) => { - if (this.props.adminContact) { - return {sub}; - } else { - return sub; - } - }; - let adminContact; let limitError; if (this.props.kind === 'hard') { toolbarClasses['mx_MatrixToolbar_error'] = true; - adminContact = _t( - "Please contact your service administrator to continue using the service.", - {}, + + adminContact = messageForResourceLimitError( + this.props.limitType, + this.props.adminContact, { - 'a': translateLink, + '': _td("Please contact your service administrator to continue using the service."), + }, + ); + limitError = messageForResourceLimitError( + this.props.limitType, + this.props.adminContact, + { + 'monthly_active_user': _td("This homeserver has hit its Monthly Active User limit."), + '': _td("This homeserver has exceeded one of its resource limits."), }, ); - if (this.props.limitType === 'monthly_active_user') { - limitError = _t("This homeserver has hit its Monthly Active User limit."); - } else { - limitError = _t("This homeserver has exceeded one of its resource limits."); - } } else { toolbarClasses['mx_MatrixToolbar_info'] = true; - adminContact = _t( - "Please contact your service administrator to get this limit increased.", - {}, + adminContact = messageForResourceLimitError( + this.props.limitType, + this.props.adminContact, { - 'a': translateLink, + '': _td("Please contact your service administrator to get this limit increased."), }, ); - if (this.props.limitType === 'monthly_active_user') { - limitError = _t( - "This homeserver has hit its Monthly Active User limit so " + - "some users will not be able to log in.", {}, - {'b': sub => {sub}}, - ); - } else { - limitError = _t( - "This homeserver has exceeded one of its resource limits so " + - "some users will not be able to log in.", {}, - {'b': sub => {sub}}, - ); - } + limitError = messageForResourceLimitError( + this.props.limitType, + this.props.adminContact, + { + 'monthly_active_user': _td( + "This homeserver has hit its Monthly Active User limit so " + + "some users will not be able to log in.", + ), + '': _td( + "This homeserver has exceeded one of its resource limits so " + + "some users will not be able to log in.", + ), + }, + {'b': sub => {sub}}, + ); } return (
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 68a4ce1508..1afa35d8fd 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1171,7 +1171,6 @@ "Send Reset Email": "Send Reset Email", "Create an account": "Create an account", "This Home Server does not support login using email address.": "This Home Server does not support login using email address.", - "This server has exceeded its available resources": "This server has exceeded its available resources", "Please contact your service administrator to continue using this service.": "Please contact your service administrator to continue using this service.", "Incorrect username and/or password.": "Incorrect username and/or password.", "Please note you are logging into the %(hs)s server, not matrix.org.": "Please note you are logging into the %(hs)s server, not matrix.org.", diff --git a/src/utils/ErrorUtils.js b/src/utils/ErrorUtils.js new file mode 100644 index 0000000000..97a29a3572 --- /dev/null +++ b/src/utils/ErrorUtils.js @@ -0,0 +1,50 @@ +/* +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. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { _t } from '../languageHandler'; + +/** + * Produce a translated error message for a + * M_RESOURCE_LIMIT_EXCEEDED error + * + * @param {string} limitType The limit_type from the error + * @param {string} adminContact The admin_contact from the error + * @param {Object} strings Translateable string for different + * limit_type. Must include at least the empty string key + * which is the default. Strings may include an 'a' tag + * for the admin contact link. + * @param {Object} extraTranslations Extra translation substitution functions + * for any tags in the strings apart from 'a' + * @returns {*} Translated string or react component + */ +export function messageForResourceLimitError(limitType, adminContact, strings, extraTranslations) { + let errString = strings[limitType]; + if (errString === undefined) errString = strings['']; + + const linkSub = sub => { + if (adminContact) { + return {sub}; + } else { + return sub; + } + }; + + if (errString.includes('')) { + return _t(errString, {}, Object.assign({ 'a': linkSub }, extraTranslations)); + } else { + return _t(errString, {}, extraTranslations); + } +}