mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-12 15:46:29 +08:00
fix: #398
This commit is contained in:
@@ -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 = () => {
|
||||
}}
|
||||
/>
|
||||
<Select
|
||||
defaultValue="en"
|
||||
defaultValue={i18n.language}
|
||||
sx={{ display: matchesIPAD ? 'none' : 'intial' }}
|
||||
onChange={changeLanguage}
|
||||
size="md"
|
||||
variant="plain"
|
||||
>
|
||||
{options.map(option => (
|
||||
<Option key={option.value} value={option.value}>
|
||||
{option.text}
|
||||
{LOCALES.map(lang => (
|
||||
<Option key={lang.tag} value={lang.tag}>
|
||||
{lang.originalName}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
@@ -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<Resource>(
|
||||
(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;
|
||||
|
||||
Reference in New Issue
Block a user