Skip to content

Commit

Permalink
feat: CORE-308 Support multi language and support zh-CN language
Browse files Browse the repository at this point in the history
  • Loading branch information
yanuar committed Jul 15, 2020
1 parent 06a3780 commit 8ab297e
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 16 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [1.1.0]
### Added
- Support multi language
- Support zh-CN language

## [1.0.1]
### Fixed
- Ecommerce error translation not showed on Admin Portal
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ test:
publish:
echo 'registry=${NEXUS_REPOSITORY_URL}\nemail=${NEXUS_EMAIL}\nalways-auth=true\n_auth=${NEXUS_AUTH}' > .npmrc
npm publish

pack:
npm pack
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "justice-js-common-utils",
"version": "1.0.1",
"version": "1.1.0",
"description": "AccelByte's Justice Common Javascript Utilities",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion scripts/i18nbuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,6 @@ function run({ files, languages, directory }) {
const tsxFiles = findFilesInDirectory(path.resolve(__dirname, "../src/lib/service-error-translator"), ".tsx");
run({
files: tsxFiles,
languages: ["en-US"],
languages: ["en-US", "zh-CN"],
directory: path.resolve(__dirname, "../src/lib/service-error-translator/translations"),
});
2 changes: 1 addition & 1 deletion src/lib/service-error-translator/config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"languageCodes": ["en-US"],
"languageCodes": ["en-US", "zh-CN"],
"defaultLanguage": "en-US",
"fallbackLanguage": "en-US"
}
32 changes: 29 additions & 3 deletions src/lib/service-error-translator/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,26 @@ import flatten from "flat";
import i18next, { Resource } from "i18next";
import { initReactI18next } from "react-i18next";
import config from "./config.json";
import enUS from "./translations/en-US.json";
import zhCN from "./translations/zh-CN.json";

const loadedLanguages: { [key: string]: string } = {
"en-US": "enUS",
function isOnBrowser() {
try {
if (window) {
return true;
}
// eslint-disable-next-line
} catch (error) {
console.error(error);
}
return false;
}

const loadedLanguages: { [key: string]: { [key: string]: string } } = {
"en-US": enUS,
"zh-CN": zhCN,
};
const languageLocalStorageKey = "i18nextLng";
const availableLanguageCodes = config.languageCodes;
const translationResource = availableLanguageCodes.reduce((resources: Resource, languageCode: string) => {
// eslint-disable-next-line no-param-reassign
Expand All @@ -22,10 +38,20 @@ const translationResource = availableLanguageCodes.reduce((resources: Resource,
return resources;
}, {});

export function getLocalStorageLanguage(): string {
if (isOnBrowser()) {
const currentLanguageCode = localStorage.getItem(languageLocalStorageKey);
if (currentLanguageCode && availableLanguageCodes.includes(currentLanguageCode)) {
return currentLanguageCode;
}
}
return config.defaultLanguage;
}

// @ts-ignore
export const i18nInstance = i18next.use(initReactI18next).createInstance(
{
lng: config.defaultLanguage,
lng: getLocalStorageLanguage(),
fallbackLng: config.fallbackLanguage,
preload: availableLanguageCodes,
resources: translationResource,
Expand Down
32 changes: 22 additions & 10 deletions src/lib/service-error-translator/service-error-translator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
*/

import * as React from "react";
import { Trans } from "react-i18next";
import { I18nextProvider, Trans } from "react-i18next";
import { BasicAdminErrorTranslationMap } from "./error-translation-map/basic-admin-error-translation-map";
import { BasicErrorTranslationMap } from "./error-translation-map/basic-error-translation-map";
import { EcommerceErrorTranslationMap } from "./error-translation-map/ecommerce-error-translation-map";
import { IAMAdminErrorTranslationMap } from "./error-translation-map/iam-admin-error-translation-map";
import { IAMErrorTranslationMap } from "./error-translation-map/iam-error-translation-map";
import {
StatisticAdminErrorTranslationMap,
} from "./error-translation-map/statistic-admin-error-translation-map";
import { StatisticAdminErrorTranslationMap } from "./error-translation-map/statistic-admin-error-translation-map";
import { getLocalStorageLanguage, i18nInstance } from "./i18n";

interface ServiceErrorProps {
errorCode: number;
Expand All @@ -31,18 +30,31 @@ export const ServiceErrorTranslator = (props: ServiceErrorProps) => {
return null;
};

export const translateServiceError = (errorCode: number) => {
export const Withi18nProvider = ({ children, lang }: { children: React.ReactNode, lang?: string }) => {
i18nInstance.changeLanguage(lang || getLocalStorageLanguage());
return <I18nextProvider i18n={i18nInstance}>{children}</I18nextProvider>;
};

export const translateServiceError = (errorCode: number, lang?: string) => {
if (isValidServiceError(errorCode) && errorCode in serviceErrorTranslationMap) {
return serviceErrorTranslationMap[errorCode];
return <Withi18nProvider lang={lang}>{serviceErrorTranslationMap[errorCode]}</Withi18nProvider>;
}
return <Trans i18nKey="serviceError.unknown">Failed to complete the request</Trans>;
return (
<Withi18nProvider lang={lang}>
<Trans i18nKey="serviceError.unknown">Failed to complete the request</Trans>
</Withi18nProvider>
);
};

export const translateServiceErrorForAdmin = (errorCode: number) => {
export const translateServiceErrorForAdmin = (errorCode: number, lang?: string) => {
if (isValidServiceError(errorCode) && errorCode in adminServiceErrorTranslationMap) {
return adminServiceErrorTranslationMap[errorCode];
return <Withi18nProvider lang={lang}>adminServiceErrorTranslationMap[errorCode]</Withi18nProvider>;
}
return <Trans i18nKey="serviceError.unknown">Failed to complete the request</Trans>;
return (
<Withi18nProvider lang={lang}>
<Trans i18nKey="serviceError.unknown">Failed to complete the request</Trans>
</Withi18nProvider>
);
};

const serviceErrorTranslationMap: { [key: string]: React.ReactNode } = Object.freeze({
Expand Down
95 changes: 95 additions & 0 deletions src/lib/service-error-translator/translations/zh-CN.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
{
"adminServiceError.10130": "年龄不符合年龄限制",
"adminServiceError.10133": "电子邮件地址已被使用",
"adminServiceError.10136": "验证码已被使用",
"adminServiceError.10137": "验证码已过期",
"adminServiceError.10138": "验证码不匹配",
"adminServiceError.10139": "平台帐户不存在",
"adminServiceError.10140": "用户已经过验证",
"adminServiceError.10145": "只有出版商管理员可以执行此操作",
"adminServiceError.10146": "用户ID不匹配",
"adminServiceError.10148": "不正确的上下文",
"adminServiceError.10149": "接触式的不匹配",
"adminServiceError.10152": "出了些问题。请与管理员联系。",
"adminServiceError.10153": "用户已存在",
"adminServiceError.10154": "国家不存在",
"adminServiceError.10156": "角色不存在",
"adminServiceError.10157": "角色不存在",
"adminServiceError.10158": "禁令并不存在",
"adminServiceError.10159": "只有角色管理器可以执行此操作",
"adminServiceError.10160": "用户已经有作用",
"adminServiceError.10161": "用户已注册为角色成员",
"adminServiceError.10169": "年龄限制不存在",
"adminServiceError.10170": "用户已经拥有平台账号",
"adminServiceError.10171": "电子邮件地址未注册",
"adminServiceError.10364": "客户端已经存在",
"adminServiceError.10365": "客户端不存在",
"adminServiceError.10456": "角色不存在",
"adminServiceError.10457": "无法添加角色成员,该角色是不是管理员角色",
"adminServiceError.10459": "只有角色管理器可以执行此操作",
"adminServiceError.10466": "无效的角色成员",
"adminServiceError.10467": "管理员角色必须拥有至少1角色管理器",
"adminServiceError.10468": "用户已注册为角色管理器",
"adminServiceError.10469": "用户已注册为角色成员",
"adminServiceError.11132": "你已经达到了最大上传限制",
"adminServiceError.11233": "区域不存在",
"adminServiceError.11234": "全国已经注册在另一区域",
"adminServiceError.11235": "地区已经存在",
"adminServiceError.11336": "命名空间已经存在",
"adminServiceError.11337": "命名空间不存在",
"adminServiceError.11440": "用户配置文件不存在",
"adminServiceError.11540": "用户配置文件不存在",
"adminServiceError.20000": "出了些问题。请与管理员联系。",
"adminServiceError.20001": "很抱歉,您不授权选定操作",
"adminServiceError.20002": "请更正表格中的错误进行",
"adminServiceError.20006": "该项目已被另一管理员更新。请刷新页面。",
"adminServiceError.20007": "您已经请求了太多的代码。请稍后再试。",
"adminServiceError.20008": "用户不存在",
"adminServiceError.20013": "对不起,您无权做这个动作或访问此页",
"adminServiceError.20019": "出了些问题。请与管理员联系。",
"adminServiceError.20022": "出了些问题。你发送一个无效的请求。",
"adminServiceError.70131": "配置中不存在",
"adminServiceError.70132": "配置已经存在",
"adminServiceError.70330": "对不起,我们无法处理此请求",
"adminServiceError.70331": "配置中不存在",
"adminServiceError.70334": "统计值不decreasable。",
"adminServiceError.70335": "用户统计项目不存在",
"adminServiceError.70336": "用户统计项目已经存在",
"adminServiceError.70337": "您已到达统计的最大值",
"serviceError.10130": "对不起,我们无法处理此请求",
"serviceError.10133": "很抱歉,您必须输入新的电子邮件地址",
"serviceError.10136": "对不起,您输入的代码已被使用。请resquest一个新的。",
"serviceError.10137": "对不起,您输入的代码已过期。请申请一个新的。",
"serviceError.10138": "对不起,您输入的代码是无效的。请再试一遍。",
"serviceError.10139": "哎呀,好像你还没有玩游戏呢。请玩游戏,用这个动作之前进行",
"serviceError.10140": "用户已经过验证",
"serviceError.10142": "对不起,您的新密码不能是相同的旧",
"serviceError.10143": "您所输入的密码不匹配。请确保你输入了正确的密码",
"serviceError.10148": "出了些问题。欲了解更多信息,请联系我们的[email protected]支持",
"serviceError.10149": "出了些问题。欲了解更多信息,请联系我们的[email protected]支持",
"serviceError.10152": "出了些问题。欲了解更多信息,请联系我们的[email protected]支持",
"serviceError.10153": "用户已存在",
"serviceError.10154": "国家不存在",
"serviceError.10170": "哎呀,你已经挂您的电子邮件地址到您的帐户。",
"serviceError.10171": "此电子邮件地址未注册",
"serviceError.10172": "对不起,您的帐户已链接。",
"serviceError.10173": "对不起,平台帐户已与其他用户账户链接。",
"serviceError.10174": "哎呀,你要连接的平台不存在。请尝试其他平台。",
"serviceError.11132": "你已经达到了最大上传限制。",
"serviceError.11233": "错误:国家组不存在。如果您看到此错误,请[email protected]立即帮助联系我们的支持",
"serviceError.11337": "错误:用户的个人资料不存在。如果您看到此错误,请[email protected]立即帮助联系我们的支持",
"serviceError.11440": "错误:用户的个人资料不存在。如果您看到此错误,请[email protected]立即帮助联系我们的支持",
"serviceError.11441": "错误:用户配置文件已经存在。如果您看到此错误,请[email protected]立即帮助联系我们的支持",
"serviceError.20000": "出了些问题。欲了解更多信息,请联系我们的[email protected]支持",
"serviceError.20001": "很抱歉,您要访问的页面不向公众提供。",
"serviceError.20002": "请更正表格中的错误进行",
"serviceError.20007": "您已经请求了太多的代码。请稍后再试。",
"serviceError.20008": "错误:用户不存在。如果您看到此错误,请[email protected]立即帮助联系我们的支持",
"serviceError.20013": "对不起,您无权做这个动作或访问此页",
"serviceError.20017": "哎呀,好像你还没有玩游戏呢。请玩游戏,用这个动作之前进行",
"serviceError.20019": "出了些问题。欲了解更多信息,请联系我们的[email protected]支持",
"serviceError.20022": "出了些问题。欲了解更多信息,请联系我们的[email protected]支持",
"serviceError.38171": "很抱歉,您已拥有这项商品",
"serviceError.30122": "商店草案应具有相同的默认语言,默认域和命名空间与公布的商店。",
"serviceError.unknown": "无法完成请求"
}

0 comments on commit 8ab297e

Please sign in to comment.