From 255527fa9578a9da51abec086dd577af231dbd4d Mon Sep 17 00:00:00 2001 From: lawvs <18554747+lawvs@users.noreply.github.com> Date: Mon, 12 Sep 2022 21:13:40 +0800 Subject: [PATCH 1/2] fix: #398 --- apps/venus/src/app/common/Header.tsx | 10 ++-- apps/venus/src/app/i18n/index.ts | 70 +++++++++++++++++++++------- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/apps/venus/src/app/common/Header.tsx b/apps/venus/src/app/common/Header.tsx index 9a2e8d0173..2dc7c50ff0 100644 --- a/apps/venus/src/app/common/Header.tsx +++ b/apps/venus/src/app/common/Header.tsx @@ -13,7 +13,7 @@ import AFFiNETextLogo from './affine-text-logo.png'; import { HoverMenu } from './HoverMenu'; import { MobileHeader } from './MobileHeader'; -import { options } from '../i18n'; +import { LOCALES } from '../i18n'; export const AFFiNEHeader = () => { const matches = useMediaQuery('(max-width: 1024px)'); @@ -140,15 +140,15 @@ export const AFFiNEHeader = () => { }} /> diff --git a/apps/venus/src/app/i18n/index.ts b/apps/venus/src/app/i18n/index.ts index 9ddaa8330d..f4428a9b09 100644 --- a/apps/venus/src/app/i18n/index.ts +++ b/apps/venus/src/app/i18n/index.ts @@ -1,25 +1,63 @@ -import i18next from 'i18next'; -import { initReactI18next } from 'react-i18next'; -import en_US from './resources/en.json'; -import zh_CN from './resources/zh.json'; +import i18next, { Resource } from 'i18next'; +import { + I18nextProvider, + initReactI18next, + useTranslation, +} from 'react-i18next'; +import { LOCALES } from './resources'; +import type en_US from './resources/en.json'; -const resources = { - en: en_US, - zh: zh_CN, -} as const; +// See https://react.i18next.com/latest/typescript +declare module 'react-i18next' { + interface CustomTypeOptions { + // custom namespace type if you changed it + // defaultNS: 'ns1'; + // custom resources type + resources: { + en: typeof en_US; + }; + } +} + +const STORAGE_KEY = 'i18n_lng'; + +export { i18n, useTranslation, I18nProvider, LOCALES }; + +const resources = LOCALES.reduce( + (acc, { tag, res }) => ({ ...acc, [tag]: { translation: res } }), + {} +); + +const fallbackLng = LOCALES[0].tag; +const standardizeLocale = (language: string) => { + if (LOCALES.find(locale => locale.tag === language)) return language; + if ( + LOCALES.find( + locale => locale.tag === language.slice(0, 2).toLowerCase() + ) + ) + return language; + return fallbackLng; +}; + +const language = standardizeLocale( + localStorage.getItem(STORAGE_KEY) ?? navigator.language +); + +const i18n = i18next.createInstance(); +i18n.use(initReactI18next).init({ + lng: language, + fallbackLng, + debug: process.env['NODE_ENV'] === 'development', -i18next.use(initReactI18next).init({ - lng: 'en', - fallbackLng: 'en', resources, interpolation: { escapeValue: false, // not needed for react as it escapes by default }, }); -export const options = [ - { value: 'en', text: 'English' }, - { value: 'zh', text: '简体中文' }, -]; +i18n.on('languageChanged', lng => { + localStorage.setItem(STORAGE_KEY, lng); +}); -export { i18next }; +const I18nProvider = I18nextProvider; From 19ca0c77efe1c600757a4e9cb015545dbef500f2 Mon Sep 17 00:00:00 2001 From: lawvs <18554747+lawvs@users.noreply.github.com> Date: Mon, 12 Sep 2022 21:14:37 +0800 Subject: [PATCH 2/2] feat: add Spanish --- apps/venus/src/app/i18n/resources/en.json | 75 +++++++++++----------- apps/venus/src/app/i18n/resources/es.json | 32 +++++++++ apps/venus/src/app/i18n/resources/index.ts | 24 +++++++ apps/venus/src/app/i18n/resources/zh.json | 74 +++++++++++---------- 4 files changed, 129 insertions(+), 76 deletions(-) create mode 100644 apps/venus/src/app/i18n/resources/es.json create mode 100644 apps/venus/src/app/i18n/resources/index.ts diff --git a/apps/venus/src/app/i18n/resources/en.json b/apps/venus/src/app/i18n/resources/en.json index 80381df1d7..4dfc81af86 100644 --- a/apps/venus/src/app/i18n/resources/en.json +++ b/apps/venus/src/app/i18n/resources/en.json @@ -1,40 +1,39 @@ { - "translation": { - "Blog": "Blog", - "AboutUs": "About Us", - "Open Source": "Open Source", - "Docs": "Docs", - "Feedback": "Feedback", - "ContactUs": "Contact Us", - "Privacy First": "Privacy First", - "Alternative": "Alternative", - "Check GitHub": "Check GitHub", - "Try it Online": "Try it Online", - "language": "Language", - "description1": { - "part1": "Affine is the next-generation collaborative knowledge base for professionals.", - "part2": "It's not just a collection of Docs, whiteboard, and tables.", - "part3": "Transform any building block as you like.", - "part4": "Say goodbye to redundancy. Store your data once, and keep your data as you like it." - }, - "description2": { - "part1": "Shape Your Page", - "part2": "Docs, Kanbans, and Databases are all fully functional anywhere, anytime. A truly what-you-see-is-what-you-get environment for your data.", - "part3": "All pages come with a document (Paper Mode) and whiteboard (Edgeless Mode) view." - }, - "description3": { - "part1": "Plan Your Task", - "part2": "No more chaos managing multiple views.", - "part3": "Set a TODO with Markdown, and seamlessly edit it within a Kanban.", - "part4": "Managing multi-dimensional tables should be this simple - and now it is." - }, - "description4": { - "part1": "Privacy-first, and collaborative. No compromises whatsoever.", - "part2": "We don't like being locked-in, and neither should you. Privacy is at the foundation of everything we do, but it should not limit us that's why there are no compromises.", - "part3": "Your data is yours;it is always locally stored and secured - available to you always. While still being able to enjoy collaboration features such as real-time editing and sharing with others, without any cloud setup." - }, - "BuildFor": "Build for an open and semantic future", - "KeepUpdated": "Keep Updated on", - "Join": "Join Our Community" - } + "Blog": "Blog", + "AboutUs": "About Us", + "Open Source": "Open Source", + "Docs": "Docs", + "Feedback": "Feedback", + "ContactUs": "Contact Us", + "Privacy First": "Privacy First", + "Alternative": "Alternative", + "Check GitHub": "Check GitHub", + "GitHub": "GitHub", + "Try it Online": "Try it Online", + "language": "Language", + "description1": { + "part1": "Affine is the next-generation collaborative knowledge base for professionals.", + "part2": "It's not just a collection of Docs, whiteboard, and tables.", + "part3": "Transform any building block as you like.", + "part4": "Say goodbye to redundancy. Store your data once, and keep your data as you like it." + }, + "description2": { + "part1": "Shape Your Page", + "part2": "Docs, Kanbans, and Databases are all fully functional anywhere, anytime. A truly what-you-see-is-what-you-get environment for your data.", + "part3": "All pages come with a document (Paper Mode) and whiteboard (Edgeless Mode) view." + }, + "description3": { + "part1": "Plan Your Task", + "part2": "No more chaos managing multiple views.", + "part3": "Set a TODO with Markdown, and seamlessly edit it within a Kanban.", + "part4": "Managing multi-dimensional tables should be this simple - and now it is." + }, + "description4": { + "part1": "Privacy-first, and collaborative. No compromises whatsoever.", + "part2": "We don't like being locked-in, and neither should you. Privacy is at the foundation of everything we do, but it should not limit us that's why there are no compromises.", + "part3": "Your data is yours;it is always locally stored and secured - available to you always. While still being able to enjoy collaboration features such as real-time editing and sharing with others, without any cloud setup." + }, + "BuildFor": "Build for an open and semantic future", + "KeepUpdated": "Keep Updated on", + "Join": "Join Our Community" } diff --git a/apps/venus/src/app/i18n/resources/es.json b/apps/venus/src/app/i18n/resources/es.json new file mode 100644 index 0000000000..034eb54f70 --- /dev/null +++ b/apps/venus/src/app/i18n/resources/es.json @@ -0,0 +1,32 @@ +{ + "Alternative": "Alternativa", + "BuildFor": "Construir por un futuro abierto y semántico", + "Check GitHub": "Revisar en GitHub", + "Join": "Únete a nuestra comunidad", + "KeepUpdated": "Mantente actualizado", + "Open Source": "Código abierto", + "Privacy First": "La privacidad es lo primero", + "Try it Online": "Prueba Online", + "description1": { + "part1": "Affine es un base de conocimiento colaborativa de próxima generación para los profesionales.", + "part2": "Es más que una simple colección de Documentos, Pizarra y Tablas.", + "part3": "Transforma cualquier bloque como tu quieras. ", + "part4": "Dígale adios a la redundancia, Almacene sus datos una vez, y manténgalos como usted quiera." + }, + "description2": { + "part1": "Dele forma a sus páginas.", + "part2": "Los Documentos, Kanbans y Base de datos son completamente funcionales en cualquier lugar, en cualquier momento. Un verdadero entorno de lo que ves y lo que obtienes para tus datos.", + "part3": "Todas las páginas tiene una vista de documento y de pizarra. " + }, + "description3": { + "part1": "Programe sus tareas.", + "part2": "No más caos manejando múltiples vistas.", + "part3": "Establezca un TODO con Markdown, y edítelo sin problemas en un Kanban. ", + "part4": "La gestión de tablas multidimensionales debería ser así de fácil y ahora lo es." + }, + "description4": { + "part1": "Privacidad en primer lugar, y colaboración sin compromiso. ", + "part2": "\nNo nos gusta estar encerrados, y a usted tampoco debería. La privacidad está en la base de todo lo que hacemos, pero no debe limitarnos, por eso no hay compromisos.", + "part3": "Sus datos son suyos; siempre están almacenados y protegidos de forma local, siempre disponibles para usted. Sin dejar de lado el poder disfrutar de funciones de colaboración como la edición en tiempo real y el uso compartido con otros, sin ninguna configuración en la nube." + } +} diff --git a/apps/venus/src/app/i18n/resources/index.ts b/apps/venus/src/app/i18n/resources/index.ts new file mode 100644 index 0000000000..424560a398 --- /dev/null +++ b/apps/venus/src/app/i18n/resources/index.ts @@ -0,0 +1,24 @@ +import en from './en.json'; +import es from './es.json'; +import zh_Hans from './zh.json'; + +export const LOCALES = [ + { + name: 'English', + tag: 'en', + originalName: 'English', + res: en, + }, + { + name: 'Simplified Chinese', + tag: 'zh-Hans', + originalName: '简体中文', + res: zh_Hans, + }, + { + name: 'Spanish', + tag: 'es', + originalName: 'español', + res: es, + }, +] as const; diff --git a/apps/venus/src/app/i18n/resources/zh.json b/apps/venus/src/app/i18n/resources/zh.json index 545a644c28..e630e1c753 100644 --- a/apps/venus/src/app/i18n/resources/zh.json +++ b/apps/venus/src/app/i18n/resources/zh.json @@ -1,40 +1,38 @@ { - "translation": { - "Blog": "博客", - "AboutUs": "关于我们", - "Open Source": "开源", - "Privacy First": "隐私第一", - "Docs": "文档", - "Feedback": "反馈", - "ContactUs": "联系我们", - "Alternative": "的另一种选择", - "Check GitHub": "GitHub中查看", - "Try it Online": "在线试用", - "language": "语言", - "description1": { - "part1": "Affine是面向专业人士的下一代协同知识库", - "part2": "它不仅仅是一个文档、白板和表格的集合。", - "part3": "可以根据需要转换任何构建块。", - "part4": "向冗余说再见吧。将数据存储一次,并保留您喜欢的数据。" - }, - "description2": { - "part1": "塑造您的页面", - "part2": "文档、看板和数据库在任何地方、任何时候都是完全可用的,一个真正的“所见即所得”的数据环境。", - "part3": "所有页面都有一个文档(纸张模式)和白板(无边缘模式)视图。" - }, - "description3": { - "part1": "计划您的任务", - "part2": "不再混乱地管理多个视图。", - "part3": "使用 Markdown 设置 TODO,并在看板中无缝地编辑它。", - "part4": "管理多维表格本应该就这么简单——现在的它就是这么简单。" - }, - "description4": { - "part1": "隐私第一,合作无间,绝不妥协。", - "part2": "我们不喜欢被关起来,您也不应该。隐私是我们做任何事情的基础,但它不应该限制我们,这就是为什么我们决不妥协。", - "part3": "您的数据是您自己的,它总是安全的在本地存储并随时供您使用。您不需要任何云设置就可以享受协作功能,即时编辑和与他人共享。" - }, - "BuildFor": "构建一个开放和语义化的未来", - "KeepUpdated": "持续更新在", - "Join": "加入我们的社区" - } + "Blog": "博客", + "AboutUs": "关于我们", + "Open Source": "开源", + "Privacy First": "隐私第一", + "Docs": "文档", + "Feedback": "反馈", + "ContactUs": "联系我们", + "Alternative": "的另一种选择", + "Check GitHub": "GitHub中查看", + "Try it Online": "在线试用", + "language": "语言", + "description1": { + "part1": "Affine是面向专业人士的下一代协同知识库", + "part2": "它不仅仅是一个文档、白板和表格的集合。", + "part3": "可以根据需要转换任何构建块。", + "part4": "向冗余说再见吧。将数据存储一次,并保留您喜欢的数据。" + }, + "description2": { + "part1": "塑造您的页面", + "part2": "文档、看板和数据库在任何地方、任何时候都是完全可用的,一个真正的“所见即所得”的数据环境。", + "part3": "所有页面都有一个文档(纸张模式)和白板(无边缘模式)视图。" + }, + "description3": { + "part1": "计划您的任务", + "part2": "不再混乱地管理多个视图。", + "part3": "使用 Markdown 设置 TODO,并在看板中无缝地编辑它。", + "part4": "管理多维表格本应该就这么简单——现在的它就是这么简单。" + }, + "description4": { + "part1": "隐私第一,合作无间,绝不妥协。", + "part2": "我们不喜欢被关起来,您也不应该。隐私是我们做任何事情的基础,但它不应该限制我们,这就是为什么我们决不妥协。", + "part3": "您的数据是您自己的,它总是安全的在本地存储并随时供您使用。您不需要任何云设置就可以享受协作功能,即时编辑和与他人共享。" + }, + "BuildFor": "构建一个开放和语义化的未来", + "KeepUpdated": "持续更新在", + "Join": "加入我们的社区" }