mirror of
https://github.com/usememos/memos.git
synced 2025-03-25 15:10:17 +01:00
chore: tweak i18n locale
This commit is contained in:
parent
342f341b3d
commit
ec206104e5
@ -20,7 +20,6 @@
|
||||
"fuse.js": "^7.0.0",
|
||||
"highlight.js": "^11.9.0",
|
||||
"i18next": "^21.10.0",
|
||||
"i18next-browser-languagedetector": "^7.2.0",
|
||||
"katex": "^0.16.9",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lucide-react": "^0.309.0",
|
||||
|
9
web/pnpm-lock.yaml
generated
9
web/pnpm-lock.yaml
generated
@ -41,9 +41,6 @@ dependencies:
|
||||
i18next:
|
||||
specifier: ^21.10.0
|
||||
version: 21.10.0
|
||||
i18next-browser-languagedetector:
|
||||
specifier: ^7.2.0
|
||||
version: 7.2.0
|
||||
katex:
|
||||
specifier: ^0.16.9
|
||||
version: 0.16.9
|
||||
@ -3304,12 +3301,6 @@ packages:
|
||||
resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==}
|
||||
dev: false
|
||||
|
||||
/i18next-browser-languagedetector@7.2.0:
|
||||
resolution: {integrity: sha512-U00DbDtFIYD3wkWsr2aVGfXGAj2TgnELzOX9qv8bT0aJtvPV9CRO77h+vgmHFBMe7LAxdwvT/7VkCWGya6L3tA==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.9
|
||||
dev: false
|
||||
|
||||
/i18next@21.10.0:
|
||||
resolution: {integrity: sha512-YeuIBmFsGjUfO3qBmMOc0rQaun4mIpGKET5WDwvu8lU7gvwpcariZLNtL0Fzj+zazcHUrlXHiptcFhBMFaxzfg==}
|
||||
dependencies:
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Option, Select } from "@mui/joy";
|
||||
import { FC } from "react";
|
||||
import { availableLocales } from "@/i18n";
|
||||
import { locales } from "@/i18n";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props {
|
||||
@ -23,7 +23,7 @@ const LocaleSelect: FC<Props> = (props: Props) => {
|
||||
value={value}
|
||||
onChange={(_, value) => handleSelectChange(value as Locale)}
|
||||
>
|
||||
{availableLocales.map((locale) => {
|
||||
{locales.map((locale) => {
|
||||
try {
|
||||
const languageName = new Intl.DisplayNames([locale], { type: "language" }).of(locale);
|
||||
if (languageName) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import i18n, { BackendModule, FallbackLng, FallbackLngObjList } from "i18next";
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
import { findNearestMatchedLanguage } from "./utils/i18n";
|
||||
|
||||
export const availableLocales = [
|
||||
export const locales = [
|
||||
"ar",
|
||||
"de",
|
||||
"en",
|
||||
@ -38,10 +38,8 @@ const LazyImportPlugin: BackendModule = {
|
||||
type: "backend",
|
||||
init: function () {},
|
||||
read: function (language, _, callback) {
|
||||
if (fallbacks[language]) {
|
||||
language = fallbacks[language][0];
|
||||
}
|
||||
import(`./locales/${language}.json`)
|
||||
const matchedLanguage = findNearestMatchedLanguage(language);
|
||||
import(`./locales/${matchedLanguage}.json`)
|
||||
.then((translation: any) => {
|
||||
callback(null, translation);
|
||||
})
|
||||
@ -53,7 +51,6 @@ const LazyImportPlugin: BackendModule = {
|
||||
|
||||
i18n
|
||||
.use(LazyImportPlugin)
|
||||
.use(LanguageDetector)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
detection: {
|
||||
@ -66,4 +63,4 @@ i18n
|
||||
});
|
||||
|
||||
export default i18n;
|
||||
export type TLocale = (typeof availableLocales)[number];
|
||||
export type TLocale = (typeof locales)[number];
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as api from "@/helpers/api";
|
||||
import storage from "@/helpers/storage";
|
||||
import i18n from "@/i18n";
|
||||
import { findNearestLanguageMatch } from "@/utils/i18n";
|
||||
import { findNearestMatchedLanguage } from "@/utils/i18n";
|
||||
import store, { useAppSelector } from "../";
|
||||
import { setAppearance, setGlobalState, setLocale } from "../reducer/global";
|
||||
|
||||
@ -44,7 +44,7 @@ export const initialGlobalState = async () => {
|
||||
// Otherwise, use server's default locale, set to storageLocale.
|
||||
const { locale: storageLocale, appearance: storageAppearance } = storage.get(["locale", "appearance"]);
|
||||
defaultGlobalState.locale =
|
||||
storageLocale || defaultGlobalState.systemStatus.customizedProfile.locale || findNearestLanguageMatch(i18n.language);
|
||||
storageLocale || defaultGlobalState.systemStatus.customizedProfile.locale || findNearestMatchedLanguage(i18n.language);
|
||||
defaultGlobalState.appearance = storageAppearance || defaultGlobalState.systemStatus.customizedProfile.appearance;
|
||||
}
|
||||
store.dispatch(setGlobalState(defaultGlobalState));
|
||||
|
@ -1,33 +1,29 @@
|
||||
import { FallbackLngObjList } from "i18next";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import i18n, { availableLocales, TLocale } from "@/i18n";
|
||||
import locales from "@/locales/en.json";
|
||||
import i18n, { locales, TLocale } from "@/i18n";
|
||||
import enTranslation from "@/locales/en.json";
|
||||
import type { NestedKeyOf } from "@/types/utils/nestedKeyOf.types";
|
||||
|
||||
export const findNearestLanguageMatch = (codename: string): Locale => {
|
||||
// Find existing translations for full codes (e.g. "en-US", "zh-Hant")
|
||||
if (codename.length > 2 && availableLocales.includes(codename as TLocale)) {
|
||||
return codename as Locale;
|
||||
export const findNearestMatchedLanguage = (language: string): Locale => {
|
||||
if (locales.includes(language as TLocale)) {
|
||||
return language as Locale;
|
||||
}
|
||||
|
||||
// Find fallback in src/i18n.ts
|
||||
const i18nfallbacks = Object.entries(i18n.store.options.fallbackLng as FallbackLngObjList);
|
||||
for (const [main, fallbacks] of i18nfallbacks) {
|
||||
if (codename === main) {
|
||||
const i18nFallbacks = Object.entries(i18n.store.options.fallbackLng as FallbackLngObjList);
|
||||
for (const [main, fallbacks] of i18nFallbacks) {
|
||||
if (language === main) {
|
||||
return fallbacks[0] as Locale;
|
||||
}
|
||||
}
|
||||
|
||||
const shortCode = codename.substring(0, 2);
|
||||
|
||||
// Match existing short code translation
|
||||
if (availableLocales.includes(shortCode as TLocale)) {
|
||||
const shortCode = language.substring(0, 2);
|
||||
if (locales.includes(shortCode as TLocale)) {
|
||||
return shortCode as Locale;
|
||||
}
|
||||
|
||||
// Try to match "xx-YY" to existing translation for "xx-ZZ" as a last resort
|
||||
// If some match is undesired, it can be overriden in src/i18n.ts `fallbacks` option
|
||||
for (const existing of availableLocales) {
|
||||
for (const existing of locales) {
|
||||
if (shortCode == existing.substring(0, 2)) {
|
||||
return existing as Locale;
|
||||
}
|
||||
@ -38,7 +34,7 @@ export const findNearestLanguageMatch = (codename: string): Locale => {
|
||||
};
|
||||
|
||||
// Represents the keys of nested translation objects.
|
||||
export type Translations = NestedKeyOf<typeof locales>;
|
||||
export type Translations = NestedKeyOf<typeof enTranslation>;
|
||||
|
||||
// Represents a typed translation function.
|
||||
type TypedT = (key: Translations, params?: Record<string, any>) => string;
|
||||
|
Loading…
x
Reference in New Issue
Block a user