### What problem does this PR solve? Feat: Add LanguageAbbreviation to simplify language resource files. #5065 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.17.0
| color: white; | color: white; | ||||
| .darkBg(); | .darkBg(); | ||||
| } | } | ||||
| .optionContainer { | |||||
| padding: 10px; | |||||
| } |
| import { | import { | ||||
| Card, | Card, | ||||
| Checkbox, | Checkbox, | ||||
| Flex, | |||||
| Form, | Form, | ||||
| Modal, | Modal, | ||||
| Select, | Select, | ||||
| TabsProps, | TabsProps, | ||||
| Typography, | Typography, | ||||
| } from 'antd'; | } from 'antd'; | ||||
| import { useState } from 'react'; | |||||
| import { useMemo, useState } from 'react'; | |||||
| import { useIsDarkTheme } from '@/components/theme-provider'; | import { useIsDarkTheme } from '@/components/theme-provider'; | ||||
| import { | |||||
| LanguageAbbreviation, | |||||
| LanguageAbbreviationMap, | |||||
| } from '@/constants/common'; | |||||
| import { cn } from '@/lib/utils'; | import { cn } from '@/lib/utils'; | ||||
| import { languageOptions } from '@/locales/config'; | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| const { Paragraph, Link } = Typography; | const { Paragraph, Link } = Typography; | ||||
| const [visibleAvatar, setVisibleAvatar] = useState(false); | const [visibleAvatar, setVisibleAvatar] = useState(false); | ||||
| const [locale, setLocale] = useState(''); | const [locale, setLocale] = useState(''); | ||||
| const languageOptions = useMemo(() => { | |||||
| return Object.values(LanguageAbbreviation).map((x) => ({ | |||||
| label: LanguageAbbreviationMap[x], | |||||
| value: x, | |||||
| })); | |||||
| }, []); | |||||
| const generateIframeSrc = () => { | const generateIframeSrc = () => { | ||||
| let src = `${location.origin}/chat/share?shared_id=${token}&from=${form}&auth=${beta}`; | let src = `${location.origin}/chat/share?shared_id=${token}&from=${form}&auth=${beta}`; | ||||
| if (visibleAvatar) { | if (visibleAvatar) { | ||||
| extra={<CopyToClipboard text={text}></CopyToClipboard>} | extra={<CopyToClipboard text={text}></CopyToClipboard>} | ||||
| className={styles.codeCard} | className={styles.codeCard} | ||||
| > | > | ||||
| <Flex vertical className={styles.optionContainer}> | |||||
| <h2>Option</h2> | |||||
| <Form.Item label={t('avatarHidden')}> | |||||
| <div className="p-2"> | |||||
| <h2 className="mb-3">Option:</h2> | |||||
| <Form.Item | |||||
| label={t('avatarHidden')} | |||||
| labelCol={{ span: 6 }} | |||||
| wrapperCol={{ span: 18 }} | |||||
| > | |||||
| <Checkbox | <Checkbox | ||||
| checked={visibleAvatar} | checked={visibleAvatar} | ||||
| onChange={(e) => setVisibleAvatar(e.target.checked)} | onChange={(e) => setVisibleAvatar(e.target.checked)} | ||||
| ></Checkbox> | ></Checkbox> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item label={t('locale')}> | |||||
| <Form.Item | |||||
| label={t('locale')} | |||||
| labelCol={{ span: 6 }} | |||||
| wrapperCol={{ span: 18 }} | |||||
| > | |||||
| <Select | <Select | ||||
| placeholder="Select a locale" | placeholder="Select a locale" | ||||
| onChange={(value) => setLocale(value)} | onChange={(value) => setLocale(value)} | ||||
| style={{ width: '100%' }} | style={{ width: '100%' }} | ||||
| /> | /> | ||||
| </Form.Item> | </Form.Item> | ||||
| </Flex> | |||||
| </div> | |||||
| <HightLightMarkdown>{text}</HightLightMarkdown> | <HightLightMarkdown>{text}</HightLightMarkdown> | ||||
| </Card> | </Card> | ||||
| ), | ), |
| 'Portuguese BR': 'Português BR', | 'Portuguese BR': 'Português BR', | ||||
| }; | }; | ||||
| export enum LanguageAbbreviation { | |||||
| En = 'en', | |||||
| Zh = 'zh', | |||||
| ZhTraditional = 'zh-TRADITIONAL', | |||||
| Id = 'id', | |||||
| Ja = 'ja', | |||||
| Es = 'es', | |||||
| Vi = 'vi', | |||||
| PtBr = 'pt-BR', | |||||
| } | |||||
| export const LanguageAbbreviationMap = { | |||||
| [LanguageAbbreviation.En]: 'English', | |||||
| [LanguageAbbreviation.Zh]: '简体中文', | |||||
| [LanguageAbbreviation.ZhTraditional]: '繁體中文', | |||||
| [LanguageAbbreviation.Id]: 'Indonesia', | |||||
| [LanguageAbbreviation.Es]: 'Español', | |||||
| [LanguageAbbreviation.Vi]: 'Tiếng việt', | |||||
| [LanguageAbbreviation.Ja]: '日本語', | |||||
| [LanguageAbbreviation.PtBr]: 'Português BR', | |||||
| }; | |||||
| export const LanguageTranslationMap = { | export const LanguageTranslationMap = { | ||||
| English: 'en', | English: 'en', | ||||
| Chinese: 'zh', | Chinese: 'zh', |
| import LanguageDetector from 'i18next-browser-languagedetector'; | import LanguageDetector from 'i18next-browser-languagedetector'; | ||||
| import { initReactI18next } from 'react-i18next'; | import { initReactI18next } from 'react-i18next'; | ||||
| import { LanguageAbbreviation } from '@/constants/common'; | |||||
| import translation_en from './en'; | import translation_en from './en'; | ||||
| import translation_es from './es'; | import translation_es from './es'; | ||||
| import translation_id from './id'; | import translation_id from './id'; | ||||
| import translation_zh_traditional from './zh-traditional'; | import translation_zh_traditional from './zh-traditional'; | ||||
| const resources = { | const resources = { | ||||
| en: translation_en, | |||||
| zh: translation_zh, | |||||
| 'zh-TRADITIONAL': translation_zh_traditional, | |||||
| id: translation_id, | |||||
| ja: translation_ja, | |||||
| es: translation_es, | |||||
| vi: translation_vi, | |||||
| 'pt-BR': translation_pt_br, | |||||
| [LanguageAbbreviation.En]: translation_en, | |||||
| [LanguageAbbreviation.Zh]: translation_zh, | |||||
| [LanguageAbbreviation.ZhTraditional]: translation_zh_traditional, | |||||
| [LanguageAbbreviation.Id]: translation_id, | |||||
| [LanguageAbbreviation.Ja]: translation_ja, | |||||
| [LanguageAbbreviation.Es]: translation_es, | |||||
| [LanguageAbbreviation.Vi]: translation_vi, | |||||
| [LanguageAbbreviation.PtBr]: translation_pt_br, | |||||
| }; | }; | ||||
| const enFlattened = flattenObject(translation_en); | const enFlattened = flattenObject(translation_en); | ||||
| const viFlattened = flattenObject(translation_vi); | const viFlattened = flattenObject(translation_vi); | ||||
| detection: { | detection: { | ||||
| lookupLocalStorage: 'lng', | lookupLocalStorage: 'lng', | ||||
| }, | }, | ||||
| supportedLngs: [ | |||||
| 'en', | |||||
| 'zh', | |||||
| 'zh-TRADITIONAL', | |||||
| 'id', | |||||
| 'es', | |||||
| 'vi', | |||||
| 'ja', | |||||
| 'pt-BR', | |||||
| ], | |||||
| supportedLngs: Object.values(LanguageAbbreviation), | |||||
| resources, | resources, | ||||
| fallbackLng: 'en', | fallbackLng: 'en', | ||||
| interpolation: { | interpolation: { | ||||
| }, | }, | ||||
| }); | }); | ||||
| export const languageOptions = [ | |||||
| { value: 'en', label: 'English' }, | |||||
| { value: 'zh', label: 'Chinese' }, | |||||
| { value: 'zh-TRADITIONAL', label: 'Traditional Chinese' }, | |||||
| { value: 'id', label: 'Indonesian' }, | |||||
| { value: 'es', label: 'Spanish' }, | |||||
| { value: 'vi', label: 'Vietnamese' }, | |||||
| { value: 'ja', label: 'Japanese' }, | |||||
| { value: 'pt-BR', label: 'Brazilian Portuguese' }, | |||||
| ]; | |||||
| export default i18n; | export default i18n; |