From 8de387295afec9f0f390a85f3ff8ae6a6d2adfaf Mon Sep 17 00:00:00 2001 From: JimmFly Date: Fri, 19 Aug 2022 21:49:54 +0800 Subject: [PATCH 1/3] chore: update dependencies --- apps/venus/package.json | 8 +++--- pnpm-lock.yaml | 55 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/apps/venus/package.json b/apps/venus/package.json index fe69da1b8e..321da2b80d 100644 --- a/apps/venus/package.json +++ b/apps/venus/package.json @@ -7,16 +7,18 @@ "keywords": [], "author": "DarkSky ", "dependencies": { - "@mui/joy": "^5.0.0-alpha.39", "@emotion/react": "^11.10.0", "@emotion/styled": "^11.10.0", - "lozad": "^1.16.0" + "@mui/joy": "^5.0.0-alpha.39", + "i18next": "^21.9.1", + "lozad": "^1.16.0", + "react-i18next": "^11.18.4" }, "devDependencies": { - "mini-css-extract-plugin": "^2.6.1", "image-minimizer-webpack-plugin": "^3.2.3", "imagemin": "^8.0.1", "imagemin-optipng": "^8.0.0", + "mini-css-extract-plugin": "^2.6.1", "webpack": "^5.74.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d2d0c70750..fb9b238428 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -220,17 +220,21 @@ importers: '@emotion/react': ^11.10.0 '@emotion/styled': ^11.10.0 '@mui/joy': ^5.0.0-alpha.39 + i18next: ^21.9.1 image-minimizer-webpack-plugin: ^3.2.3 imagemin: ^8.0.1 imagemin-optipng: ^8.0.0 lozad: ^1.16.0 mini-css-extract-plugin: ^2.6.1 + react-i18next: ^11.18.4 webpack: ^5.74.0 dependencies: '@emotion/react': 11.10.0 '@emotion/styled': 11.10.0_@emotion+react@11.10.0 '@mui/joy': 5.0.0-alpha.39_72v32ofbtgpmxm7mhvtx474vfu + i18next: 21.9.1 lozad: 1.16.0 + react-i18next: 11.18.4_i18next@21.9.1 devDependencies: image-minimizer-webpack-plugin: 3.2.3_5emixpjl54fjyhdvj76qjbw4py imagemin: 8.0.1 @@ -9563,20 +9567,30 @@ packages: '@typescript-eslint/parser': optional: true dependencies: + '@babel/runtime': 7.18.6 '@typescript-eslint/parser': 5.30.5_4x5o4skxv6sl53vpwefgt23khm + aria-query: 4.2.2 array-includes: 3.1.5 array.prototype.flat: 1.3.0 + ast-types-flow: 0.0.7 + axe-core: 4.4.2 + axobject-query: 2.2.0 + damerau-levenshtein: 1.0.8 debug: 2.6.9 doctrine: 2.1.0 + emoji-regex: 9.2.2 eslint: 8.19.0 eslint-import-resolver-node: 0.3.6 eslint-module-utils: 2.7.3_ea34krk32wbcqzxapvwr7rsjs4 has: 1.0.3 is-core-module: 2.9.0 is-glob: 4.0.3 + jsx-ast-utils: 3.3.1 + language-tags: 1.0.5 minimatch: 3.1.2 object.values: 1.1.5 resolve: 1.22.1 + semver: 6.3.0 tsconfig-paths: 3.14.1 transitivePeerDependencies: - eslint-import-resolver-typescript @@ -11121,6 +11135,12 @@ packages: terser: 5.14.1 dev: true + /html-parse-stringify/3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + dependencies: + void-elements: 3.1.0 + dev: false + /html-webpack-plugin/5.5.0_webpack@5.74.0: resolution: {integrity: sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==} engines: {node: '>=10.13.0'} @@ -11306,6 +11326,12 @@ packages: hasBin: true dev: true + /i18next/21.9.1: + resolution: {integrity: sha512-ITbDrAjbRR73spZAiu6+ex5WNlHRr1mY+acDi2ioTHuUiviJqSz269Le1xHAf0QaQ6GgIHResUhQNcxGwa/PhA==} + dependencies: + '@babel/runtime': 7.18.6 + dev: false + /iconv-lite/0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -15149,7 +15175,7 @@ packages: dev: true /proxy-from-env/1.0.0: - resolution: {integrity: sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=} + resolution: {integrity: sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==} dev: true /prr/1.0.1: @@ -15345,6 +15371,26 @@ packages: hotkeys-js: 3.9.3 dev: false + /react-i18next/11.18.4_i18next@21.9.1: + resolution: {integrity: sha512-gK/AylAQC5DvCD5YLNCHW4PNzpCfrWIyVAXbSMl+/5QXzlDP8VdBoqE2s2niGHB+zIXwBV9hRXbDrVuupbgHcg==} + peerDependencies: + i18next: '>= 19.0.0' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@babel/runtime': 7.18.6 + html-parse-stringify: 3.0.1 + i18next: 21.9.1 + dev: false + /react-is/16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -17592,7 +17638,7 @@ packages: dev: true /verror/1.10.0: - resolution: {integrity: sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=} + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} engines: {'0': node >=0.6.0} dependencies: assert-plus: 1.0.0 @@ -17600,6 +17646,11 @@ packages: extsprintf: 1.3.0 dev: true + /void-elements/3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + dev: false + /w3c-hr-time/1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} dependencies: From 4eb1c51be59fe718b45611a0cfa80df819c1cb2d Mon Sep 17 00:00:00 2001 From: JimmFly Date: Fri, 19 Aug 2022 21:50:24 +0800 Subject: [PATCH 2/3] feat: add i18n --- apps/venus/src/app/i18n/index.ts | 25 +++++++ apps/venus/src/app/i18n/resources/en.json | 34 ++++++++++ apps/venus/src/app/i18n/resources/zh.json | 34 ++++++++++ apps/venus/src/app/index.tsx | 80 ++++++++++++----------- apps/venus/src/index.tsx | 1 + 5 files changed, 135 insertions(+), 39 deletions(-) create mode 100644 apps/venus/src/app/i18n/index.ts create mode 100644 apps/venus/src/app/i18n/resources/en.json create mode 100644 apps/venus/src/app/i18n/resources/zh.json diff --git a/apps/venus/src/app/i18n/index.ts b/apps/venus/src/app/i18n/index.ts new file mode 100644 index 0000000000..9ddaa8330d --- /dev/null +++ b/apps/venus/src/app/i18n/index.ts @@ -0,0 +1,25 @@ +import i18next from 'i18next'; +import { initReactI18next } from 'react-i18next'; +import en_US from './resources/en.json'; +import zh_CN from './resources/zh.json'; + +const resources = { + en: en_US, + zh: zh_CN, +} as const; + +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: '简体中文' }, +]; + +export { i18next }; diff --git a/apps/venus/src/app/i18n/resources/en.json b/apps/venus/src/app/i18n/resources/en.json new file mode 100644 index 0000000000..cd7a377352 --- /dev/null +++ b/apps/venus/src/app/i18n/resources/en.json @@ -0,0 +1,34 @@ +{ + "translation": { + "Open Source": "Open Source", + "Privacy First": "Privacy First", + "Alternative": "Alternative", + "Check GitHub": "Check GitHub", + "Try it Online": "Try it Online", + "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/zh.json b/apps/venus/src/app/i18n/resources/zh.json new file mode 100644 index 0000000000..eb4cf432dd --- /dev/null +++ b/apps/venus/src/app/i18n/resources/zh.json @@ -0,0 +1,34 @@ +{ + "translation": { + "Open Source": "开源", + "Privacy First": "隐私第一", + "Alternative": "的另一种选择", + "Check GitHub": "GitHub中查看", + "Try it Online": "在线上试试", + "description1": { + "part1": "Affine是面向专业人士的下一代协同知识库", + "part2": "它不仅仅是一个文档、白板和表格的集合。", + "part3": "可以根据需要转换任何构建块。", + "part4": "向冗余说再见吧。将数据存储一次,并保留您喜欢的数据。" + }, + "description2": { + "part1": "塑造您的页面", + "part2": "文档、看板和数据库在任何地方、任何时候都是完全可用的,一个真正的“所见即所得”的数据环境。", + "part3": "所有页面都有一个文档(纸张模式)和白板(无边缘模式)视图。" + }, + "description3": { + "part1": "计划您的任务", + "part2": "不再混乱地管理多个视图。", + "part3": "使用 Markdown 设置 TODO,并在看板中无缝地编辑它。", + "part4": "管理多维表格本应该就这么简单——现在的它就是这么简单。" + }, + "description4": { + "part1": "隐私第一,合作无间,绝不妥协。", + "part2": "我们不喜欢被关起来,您也不应该。隐私是我们做任何事情的基础,但它不应该限制我们,这就是为什么我们决不妥协。", + "part3": "您的数据是您自己的,它总是安全的在本地存储并随时供您使用。您不需要任何云设置就可以享受协作功能,即时编辑和与他人共享。" + }, + "BuildFor": "构建一个开放和语义化的未来", + "KeepUpdated": "持续更新在", + "Join": "加入我们的社区" + } +} diff --git a/apps/venus/src/app/index.tsx b/apps/venus/src/app/index.tsx index 71db02985e..038da7373d 100644 --- a/apps/venus/src/app/index.tsx +++ b/apps/venus/src/app/index.tsx @@ -7,12 +7,15 @@ import GitHubIcon from '@mui/icons-material/GitHub'; import RedditIcon from '@mui/icons-material/Reddit'; import TelegramIcon from '@mui/icons-material/Telegram'; import { Box, Button, Container, Grid, SvgIcon, Typography } from '@mui/joy'; +import Option from '@mui/joy/Option'; +import Select from '@mui/joy/Select'; import { CssVarsProvider, styled } from '@mui/joy/styles'; import { LogoIcon } from '@toeverything/components/icons'; // eslint-disable-next-line no-restricted-imports import { useMediaQuery } from '@mui/material'; - +import { useTranslation } from 'react-i18next'; import CollaborationImage from './collaboration.png'; +import { options } from './i18n'; import LogoImage from './logo.png'; import PageImage from './page.png'; import ShapeImage from './shape.png'; @@ -199,6 +202,7 @@ const AffineImage = styled('img')({ const GitHub = (props: { center?: boolean; flat?: boolean }) => { const matches = useMediaQuery('(max-width: 1024px)'); + const { t } = useTranslation(); return ( ); }; const AFFiNEOnline = (props: { center?: boolean; flat?: boolean }) => { const matches = useMediaQuery('(max-width: 1024px)'); - + const { t } = useTranslation(); return ( ); }; export function App() { const matches = useMediaQuery('(max-width: 1024px)'); + const { t, i18n } = useTranslation(); + const changeLanguage = (event: any) => { + i18n.changeLanguage(event); + }; return ( Blog + - Open Source, + {t('Open Source')}, - Privacy First + {t('Privacy First')} @@ -413,7 +428,7 @@ export function App() { }, }} > - Alternative + {t('Alternative')} @@ -432,8 +447,7 @@ export function App() { fontWeight={'400'} sx={{ color: '#888' }} > - Affine is the next-generation collaborative - knowledge base for professionals. + {t('description1.part1')} @@ -488,8 +502,7 @@ export function App() { level={matches ? 'h2' : 'h1'} fontWeight={'bold'} > - It’s not just a collection of Docs, whiteboard, and - tables. + {t('description1.part2')} @@ -506,11 +519,10 @@ export function App() { }} > - Transform any building block as you like. + {t('description1.part3')} - Say goodbye to redundancy. Store your data once, and - keep your data as you like it. + {t('description1.part4')} @@ -547,23 +559,19 @@ export function App() { fontWeight={'bold'} style={{ marginBottom: '0.5em' }} > - Shape Your Page + {t('description2.part1')} - Docs, Kanbans, and Databases are all fully - functional anywhere, anytime. A truly - what-you-see-is-what-you-get environment for - your data. + {t('description2.part2')} - All pages come with a document (Paper Mode) and - whiteboard (Edgeless Mode) view. + {t('description2.part3')} @@ -625,27 +633,25 @@ export function App() { fontWeight={'bold'} style={{ marginBottom: '0.5em' }} > - Plan Your Task + {t('description3.part1')} - No more chaos managing multiple views. + {t('description3.part2')} - Set a TODO with Markdown, and seamlessly edit it - within a Kanban. + {t('description3.part3')} - Managing multi-dimensional tables should be this - simple – and now it is. + {t('description3.part4')} @@ -697,17 +703,13 @@ export function App() { fontWeight={'bold'} style={{ marginBottom: '0.5em' }} > - Privacy-first, and collaborative. No compromises - whatsoever. + {t('description4.part1')} - 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. + {t('description4.part2')} 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. + able enjoy collaboration features such as real-time + editing and sharing with others, without any cloud + setup. @@ -762,7 +764,7 @@ export function App() { }} > - Build for an open and semantic future + {t('BuildFor')} @@ -778,7 +780,7 @@ export function App() { > - Keep Updated on + {t('KeepUpdated')} @@ -795,7 +797,7 @@ export function App() { }} > - Join Our Community + {t('Join')} diff --git a/apps/venus/src/index.tsx b/apps/venus/src/index.tsx index f76f9a6f20..5fdc926e59 100644 --- a/apps/venus/src/index.tsx +++ b/apps/venus/src/index.tsx @@ -1,6 +1,7 @@ import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; +import './app/i18n'; import App from './app'; From 6846f23e7de116ce0fa21c923a5249987bd32d27 Mon Sep 17 00:00:00 2001 From: JimmFly Date: Fri, 19 Aug 2022 22:08:23 +0800 Subject: [PATCH 3/3] update i18n --- apps/venus/src/app/index.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/venus/src/app/index.tsx b/apps/venus/src/app/index.tsx index 038da7373d..e4d9c7854e 100644 --- a/apps/venus/src/app/index.tsx +++ b/apps/venus/src/app/index.tsx @@ -238,7 +238,7 @@ const GitHub = (props: { center?: boolean; flat?: boolean }) => { startIcon={} size="lg" > - {t(`${props.center ? 'Check ' : ''}GitHub`)} + {props.center ? t('Check GitHub') : t('GitHub')} ); }; @@ -715,11 +715,7 @@ export function App() { fontSize="1.2em" style={{ marginBottom: '0.25em' }} > - Your data is yours; it is always locally stored and - secured - available to you always. While still being - able enjoy collaboration features such as real-time - editing and sharing with others, without any cloud - setup. + {t('description4.part3')}