108 lines
4.8 KiB
TypeScript
108 lines
4.8 KiB
TypeScript
/*
|
|
* Copyright (C) 2026 Fluxer Contributors
|
|
*
|
|
* This file is part of Fluxer.
|
|
*
|
|
* Fluxer is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Fluxer is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import {msg} from '@lingui/core/macro';
|
|
import * as UserSettingsActionCreators from '~/actions/UserSettingsActionCreators';
|
|
import i18n, {loadLocaleCatalog} from '~/i18n';
|
|
import UserSettingsStore from '~/stores/UserSettingsStore';
|
|
|
|
interface LocaleInfo {
|
|
code: string;
|
|
name: import('@lingui/core').MessageDescriptor;
|
|
nativeName: string;
|
|
flag: string;
|
|
region?: string;
|
|
}
|
|
|
|
const SUPPORTED_LOCALES: Array<LocaleInfo> = [
|
|
{code: 'ar', name: msg`Arabic`, nativeName: 'العربية', flag: '🇸🇦'},
|
|
{code: 'bg', name: msg`Bulgarian`, nativeName: 'Български', flag: '🇧🇬'},
|
|
{code: 'cs', name: msg`Czech`, nativeName: 'Čeština', flag: '🇨🇿'},
|
|
{code: 'da', name: msg`Danish`, nativeName: 'Dansk', flag: '🇩🇰'},
|
|
{code: 'de', name: msg`German`, nativeName: 'Deutsch', flag: '🇩🇪'},
|
|
{code: 'el', name: msg`Greek`, nativeName: 'Ελληνικά', flag: '🇬🇷'},
|
|
{code: 'en-GB', name: msg`English`, nativeName: 'English', flag: '🇬🇧'},
|
|
{code: 'en-US', name: msg`English (US)`, nativeName: 'English (US)', flag: '🇺🇸'},
|
|
{code: 'es-ES', name: msg`Spanish (Spain)`, nativeName: 'Español (España)', flag: '🇪🇸'},
|
|
{code: 'es-419', name: msg`Spanish (Latin America)`, nativeName: 'Español (Latinoamérica)', flag: '🌎'},
|
|
{code: 'fi', name: msg`Finnish`, nativeName: 'Suomi', flag: '🇫🇮'},
|
|
{code: 'fr', name: msg`French`, nativeName: 'Français', flag: '🇫🇷'},
|
|
{code: 'he', name: msg`Hebrew`, nativeName: 'עברית', flag: '🇮🇱'},
|
|
{code: 'hi', name: msg`Hindi`, nativeName: 'हिन्दी', flag: '🇮🇳'},
|
|
{code: 'hr', name: msg`Croatian`, nativeName: 'Hrvatski', flag: '🇭🇷'},
|
|
{code: 'hu', name: msg`Hungarian`, nativeName: 'Magyar', flag: '🇭🇺'},
|
|
{code: 'id', name: msg`Indonesian`, nativeName: 'Bahasa Indonesia', flag: '🇮🇩'},
|
|
{code: 'it', name: msg`Italian`, nativeName: 'Italiano', flag: '🇮🇹'},
|
|
{code: 'ja', name: msg`Japanese`, nativeName: '日本語', flag: '🇯🇵'},
|
|
{code: 'ko', name: msg`Korean`, nativeName: '한국어', flag: '🇰🇷'},
|
|
{code: 'lt', name: msg`Lithuanian`, nativeName: 'Lietuvių', flag: '🇱🇹'},
|
|
{code: 'nl', name: msg`Dutch`, nativeName: 'Nederlands', flag: '🇳🇱'},
|
|
{code: 'no', name: msg`Norwegian`, nativeName: 'Norsk', flag: '🇳🇴'},
|
|
{code: 'pl', name: msg`Polish`, nativeName: 'Polski', flag: '🇵🇱'},
|
|
{code: 'pt-BR', name: msg`Portuguese (Brazil)`, nativeName: 'Português (Brasil)', flag: '🇧🇷'},
|
|
{code: 'ro', name: msg`Romanian`, nativeName: 'Română', flag: '🇷🇴'},
|
|
{code: 'ru', name: msg`Russian`, nativeName: 'Русский', flag: '🇷🇺'},
|
|
{code: 'sv-SE', name: msg`Swedish`, nativeName: 'Svenska', flag: '🇸🇪'},
|
|
{code: 'th', name: msg`Thai`, nativeName: 'ไทย', flag: '🇹🇭'},
|
|
{code: 'tr', name: msg`Turkish`, nativeName: 'Türkçe', flag: '🇹🇷'},
|
|
{code: 'uk', name: msg`Ukrainian`, nativeName: 'Українська', flag: '🇺🇦'},
|
|
{code: 'vi', name: msg`Vietnamese`, nativeName: 'Tiếng Việt', flag: '🇻🇳'},
|
|
{code: 'zh-CN', name: msg`Chinese (Simplified)`, nativeName: '中文 (简体)', flag: '🇨🇳'},
|
|
{code: 'zh-TW', name: msg`Chinese (Traditional)`, nativeName: '中文 (繁體)', flag: '🇹🇼'},
|
|
];
|
|
|
|
const DEFAULT_LOCALE = 'en-US';
|
|
|
|
export const getCurrentLocale = (): string => {
|
|
return UserSettingsStore.getLocale() || DEFAULT_LOCALE;
|
|
};
|
|
|
|
export const setLocale = (localeCode: string): void => {
|
|
if (!SUPPORTED_LOCALES.find((locale) => locale.code === localeCode)) {
|
|
console.warn(`Unsupported locale: ${localeCode}`);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const normalized = loadLocaleCatalog(localeCode);
|
|
UserSettingsActionCreators.update({
|
|
locale: normalized,
|
|
});
|
|
} catch (error) {
|
|
console.error(`Failed to load locale ${localeCode}:`, error);
|
|
}
|
|
};
|
|
|
|
interface TranslatedLocaleInfo {
|
|
code: string;
|
|
name: string;
|
|
nativeName: string;
|
|
flag: string;
|
|
region?: string;
|
|
}
|
|
|
|
export const getSortedLocales = (): Array<TranslatedLocaleInfo> => {
|
|
return [...SUPPORTED_LOCALES]
|
|
.map((locale) => ({
|
|
...locale,
|
|
name: i18n._(locale.name),
|
|
}))
|
|
.sort((a, b) => a.nativeName.localeCompare(b.nativeName));
|
|
};
|