diff --git a/src/lib/i18n.js b/src/lib/i18n.js index c6ff9ae1..04a825e0 100644 --- a/src/lib/i18n.js +++ b/src/lib/i18n.js @@ -1,5 +1,82 @@ import { defaultLanguage, allLanguages } from '../locales/index.js' +const validatorErrorCode = 200000; +const parameterizedErrors = [ + { + localeKey: 'parameter invalid', + regex: /^parameter "(\w+)" is invalid$/, + parameters: [{ + field: 'parameter', + localized: true + }] + }, + { + localeKey: 'parameter required', + regex: /^parameter "(\w+)" is required$/, + parameters: [{ + field: 'parameter', + localized: true + }] + }, + { + localeKey: 'parameter too long', + regex: /^parameter "(\w+)" must be less than (\d+)$/, + parameters: [{ + field: 'parameter', + localized: true + }, { + field: 'length', + localized: false + }] + }, + { + localeKey: 'parameter too short', + regex: /^parameter "(\w+)" must be more than (\d+)$/, + parameters: [{ + field: 'parameter', + localized: true + }, { + field: 'length', + localized: false + }] + }, + { + localeKey: 'parameter length not equal', + regex: /^parameter "(\w+)" length is not equal to (\d+)$/, + parameters: [{ + field: 'parameter', + localized: true + }, { + field: 'length', + localized: false + }] + }, + { + localeKey: 'parameter cannot be blank', + regex: /^parameter "(\w+)" cannot be blank$/, + parameters: [{ + field: 'parameter', + localized: true + }] + }, + { + localeKey: 'parameter invalid username format', + regex: /^parameter "(\w+)" is invalid username format$/, + parameters: [{ + field: 'parameter', + localized: true + }] + }, + { + localeKey: 'parameter invalid email format', + regex: /^parameter "(\w+)" is invalid email format$/, + parameters: [{ + field: 'parameter', + localized: true + }] + } +]; + export function getAllLanguages() { return allLanguages; } @@ -56,6 +133,36 @@ export function getI18nOptions() { }; } +export function getLocalizedError(error) { + if (error.errorCode !== validatorErrorCode) { + return { + message: `error.${error.errorMessage}` + }; + } + + for (let i = 0; i < parameterizedErrors.length; i++) { + const errorInfo = parameterizedErrors[i]; + const matches = error.errorMessage.match(errorInfo.regex); + + if (matches && matches.length === errorInfo.parameters.length + 1) { + return { + message: `parameterizedError.${errorInfo.localeKey}`, + parameters: errorInfo.parameters.map((param, index) => { + return { + key: param.field, + localized: param.localized, + value: matches[index + 1] + } + }) + }; + } + } + + return { + message: error.errorMessage + }; +} + function getLocaleFromLanguageAlias(alias) { for (let locale in allLanguages) { if (!Object.prototype.hasOwnProperty.call(allLanguages, locale)) { diff --git a/src/locales/en.js b/src/locales/en.js index f93f964b..0f76d861 100644 --- a/src/locales/en.js +++ b/src/locales/en.js @@ -6,6 +6,9 @@ export default { }, 'error': { 'system error': 'System Error', + 'incomplete or incorrect submission': 'Incomplete or incorrect submission', + 'operation failed': 'Operation failed', + 'nothing will be updated': 'Nothing will be updated', 'unauthorized access': 'Unauthorized access', 'token is expired': 'Token is expired', 'token is invalid': 'Token is invalid', @@ -32,6 +35,22 @@ export default { 'two factor has already been enabled': 'Two factor has already been enabled', 'two factor backup code does not exist': 'Two factor backup code does not exist', }, + 'parameter': { + 'username': 'Username', + 'password': 'Password', + 'email': 'Email', + 'nickname': 'Nickname', + }, + 'parameterizedError': { + 'parameter invalid': '{parameter} is invalid', + 'parameter required': '{parameter} is required', + 'parameter too long': '{parameter} must be at most {length} characters', + 'parameter too short': '{parameter} must be at least {length} characters', + 'parameter length not equal': '{parameter} must be {length} characters', + 'parameter cannot be blank': '{parameter} cannot be blank', + 'parameter invalid username format': '{parameter} is invalid format', + 'parameter invalid email format': '{parameter} is invalid format', + }, 'OK': 'OK', 'Cancel': 'Cancel', 'Done': 'Done', diff --git a/src/locales/zh_Hans.js b/src/locales/zh_Hans.js index 29136e38..71b4e966 100644 --- a/src/locales/zh_Hans.js +++ b/src/locales/zh_Hans.js @@ -6,6 +6,9 @@ export default { }, 'error': { 'system error': '系统错误', + 'incomplete or incorrect submission': '提交不完整或不正确', + 'operation failed': '操作失败', + 'nothing will be updated': '没有内容更新', 'unauthorized access': '未授权的登录', 'token is expired': '认证令牌已过期', 'token is invalid': '认证令牌无效', @@ -32,6 +35,22 @@ export default { 'two factor has already been enabled': '两步验证已经启用', 'two factor backup code does not exist': '两步验证备用码不存在', }, + 'parameter': { + 'username': '用户名', + 'password': '密码', + 'email': '电子邮箱', + 'nickname': '昵称', + }, + 'parameterizedError': { + 'parameter invalid': '{parameter}无效', + 'parameter required': '{parameter}为必填项', + 'parameter too long': '{parameter}必须小于{length}个字符', + 'parameter too short': '{parameter}必须大于{length}个字符', + 'parameter length not equal': '{parameter}必须等于{length}个字符', + 'parameter cannot be blank': '{parameter}不能为空', + 'parameter invalid username format': '{parameter}格式错误', + 'parameter invalid email format': '{parameter}格式错误', + }, 'OK': '确定', 'Cancel': '取消', 'Done': '完成', diff --git a/src/mobile-main.js b/src/mobile-main.js index 4c2bc3c1..84ea4aaf 100644 --- a/src/mobile-main.js +++ b/src/mobile-main.js @@ -6,7 +6,7 @@ import Framework7Vue from 'framework7-vue/framework7-vue.esm.bundle.js'; import 'framework7/css/framework7.bundle.css'; import 'framework7-icons'; -import { getAllLanguages, getLanguage, getDefaultLanguage, getI18nOptions } from './lib/i18n.js'; +import { getAllLanguages, getLanguage, getDefaultLanguage, getI18nOptions, getLocalizedError } from './lib/i18n.js'; import settings from './lib/settings.js'; import services from './lib/services.js'; import userstate from './lib/userstate.js'; @@ -32,9 +32,28 @@ Vue.prototype.$setLanguage = function (locale) { return locale; }; Vue.prototype.$alert = function (message, confirmCallback) { + let parameters = {}; + + if (message && message.error) { + const localizedError = getLocalizedError(message.error); + message = localizedError.message; + + if (localizedError.parameters) { + for (let i = 0; i < localizedError.parameters.length; i++) { + const parameter = localizedError.parameters[i]; + + if (parameter.localized) { + parameters[parameter.key] = i18n.t(`parameter.${parameter.value}`); + } else { + parameters[parameter.key] = parameter.value; + } + } + } + } + this.$f7.dialog.create({ title: i18n.t('global.app.title'), - text: i18n.t(message), + text: i18n.t(message, parameters), buttons: [ { text: i18n.t('OK'), diff --git a/src/views/mobile/Login.vue b/src/views/mobile/Login.vue index 4200b71c..9b24c154 100644 --- a/src/views/mobile/Login.vue +++ b/src/views/mobile/Login.vue @@ -178,7 +178,7 @@ export default { } if (error.response && error.response.data && error.response.data.errorMessage) { - self.$alert(`error.${error.response.data.errorMessage}`); + self.$alert({ error: error.response.data }); } else { self.$alert('Unable to login'); } @@ -229,7 +229,7 @@ export default { app.preloader.hide(); if (error.response && error.response.data && error.response.data.errorMessage) { - self.$alert(`error.${error.response.data.errorMessage}`); + self.$alert({ error: error.response.data }); } else { self.$alert('Unable to verify'); } diff --git a/src/views/mobile/Settings.vue b/src/views/mobile/Settings.vue index 95e3124b..ec09f116 100644 --- a/src/views/mobile/Settings.vue +++ b/src/views/mobile/Settings.vue @@ -71,7 +71,7 @@ export default { } if (error.response && error.response.data && error.response.data.errorMessage) { - self.$alert(`error.${error.response.data.errorMessage}`); + self.$alert({ error: error.response.data }); } else { self.$alert('Unable to logout'); }