### 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
| @@ -19,6 +19,3 @@ | |||
| color: white; | |||
| .darkBg(); | |||
| } | |||
| .optionContainer { | |||
| padding: 10px; | |||
| } | |||
| @@ -6,7 +6,6 @@ import { IModalProps } from '@/interfaces/common'; | |||
| import { | |||
| Card, | |||
| Checkbox, | |||
| Flex, | |||
| Form, | |||
| Modal, | |||
| Select, | |||
| @@ -14,11 +13,14 @@ import { | |||
| TabsProps, | |||
| Typography, | |||
| } from 'antd'; | |||
| import { useState } from 'react'; | |||
| import { useMemo, useState } from 'react'; | |||
| import { useIsDarkTheme } from '@/components/theme-provider'; | |||
| import { | |||
| LanguageAbbreviation, | |||
| LanguageAbbreviationMap, | |||
| } from '@/constants/common'; | |||
| import { cn } from '@/lib/utils'; | |||
| import { languageOptions } from '@/locales/config'; | |||
| import styles from './index.less'; | |||
| const { Paragraph, Link } = Typography; | |||
| @@ -42,6 +44,13 @@ const EmbedModal = ({ | |||
| const [visibleAvatar, setVisibleAvatar] = useState(false); | |||
| const [locale, setLocale] = useState(''); | |||
| const languageOptions = useMemo(() => { | |||
| return Object.values(LanguageAbbreviation).map((x) => ({ | |||
| label: LanguageAbbreviationMap[x], | |||
| value: x, | |||
| })); | |||
| }, []); | |||
| const generateIframeSrc = () => { | |||
| let src = `${location.origin}/chat/share?shared_id=${token}&from=${form}&auth=${beta}`; | |||
| if (visibleAvatar) { | |||
| @@ -76,15 +85,24 @@ const EmbedModal = ({ | |||
| extra={<CopyToClipboard text={text}></CopyToClipboard>} | |||
| 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 | |||
| checked={visibleAvatar} | |||
| onChange={(e) => setVisibleAvatar(e.target.checked)} | |||
| ></Checkbox> | |||
| </Form.Item> | |||
| <Form.Item label={t('locale')}> | |||
| <Form.Item | |||
| label={t('locale')} | |||
| labelCol={{ span: 6 }} | |||
| wrapperCol={{ span: 18 }} | |||
| > | |||
| <Select | |||
| placeholder="Select a locale" | |||
| onChange={(value) => setLocale(value)} | |||
| @@ -92,7 +110,7 @@ const EmbedModal = ({ | |||
| style={{ width: '100%' }} | |||
| /> | |||
| </Form.Item> | |||
| </Flex> | |||
| </div> | |||
| <HightLightMarkdown>{text}</HightLightMarkdown> | |||
| </Card> | |||
| ), | |||
| @@ -61,6 +61,28 @@ export const LanguageMap = { | |||
| '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 = { | |||
| English: 'en', | |||
| Chinese: 'zh', | |||
| @@ -2,6 +2,7 @@ import i18n from 'i18next'; | |||
| import LanguageDetector from 'i18next-browser-languagedetector'; | |||
| import { initReactI18next } from 'react-i18next'; | |||
| import { LanguageAbbreviation } from '@/constants/common'; | |||
| import translation_en from './en'; | |||
| import translation_es from './es'; | |||
| import translation_id from './id'; | |||
| @@ -13,14 +14,14 @@ import translation_zh from './zh'; | |||
| import translation_zh_traditional from './zh-traditional'; | |||
| 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 viFlattened = flattenObject(translation_vi); | |||
| @@ -48,16 +49,7 @@ i18n | |||
| detection: { | |||
| lookupLocalStorage: 'lng', | |||
| }, | |||
| supportedLngs: [ | |||
| 'en', | |||
| 'zh', | |||
| 'zh-TRADITIONAL', | |||
| 'id', | |||
| 'es', | |||
| 'vi', | |||
| 'ja', | |||
| 'pt-BR', | |||
| ], | |||
| supportedLngs: Object.values(LanguageAbbreviation), | |||
| resources, | |||
| fallbackLng: 'en', | |||
| interpolation: { | |||
| @@ -65,15 +57,4 @@ i18n | |||
| }, | |||
| }); | |||
| 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; | |||