[MM-60792] Add support for loading experimental (e.g., in progress) languages (#29009)

* Add support for loading experimental (e.g., in progress) languages

* Fix e2e config

* Improve language labels

* Improvements
Этот коммит содержится в:
Claudio Costa
2024-11-14 15:02:00 -06:00
коммит произвёл GitHub
родитель 7403d29634
Коммит 3af3af0b25
12 изменённых файлов: 1194 добавлений и 52 удалений

Просмотреть файл

@@ -509,6 +509,7 @@ const defaultServerConfig: AdminConfig = {
DefaultServerLocale: 'en',
DefaultClientLocale: 'en',
AvailableLocales: '',
EnableExperimentalLocales: false,
},
SamlSettings: {
Enable: false,

Просмотреть файл

@@ -75,6 +75,8 @@ func GenerateClientConfig(c *model.Config, telemetryID string, license *model.Li
props["EnablePublicLink"] = strconv.FormatBool(*c.FileSettings.EnablePublicLink)
props["AvailableLocales"] = *c.LocalizationSettings.AvailableLocales
props["EnableExperimentalLocales"] = strconv.FormatBool(*c.LocalizationSettings.EnableExperimentalLocales)
props["SQLDriverName"] = *c.SqlSettings.DriverName
props["EnableEmojiPicker"] = strconv.FormatBool(*c.ServiceSettings.EnableEmojiPicker)

Просмотреть файл

@@ -2597,9 +2597,10 @@ func (s *ComplianceSettings) SetDefaults() {
}
type LocalizationSettings struct {
DefaultServerLocale *string `access:"site_localization"`
DefaultClientLocale *string `access:"site_localization"`
AvailableLocales *string `access:"site_localization"`
DefaultServerLocale *string `access:"site_localization"`
DefaultClientLocale *string `access:"site_localization"`
AvailableLocales *string `access:"site_localization"`
EnableExperimentalLocales *bool `access:"site_localization"`
}
func (s *LocalizationSettings) SetDefaults() {
@@ -2614,6 +2615,10 @@ func (s *LocalizationSettings) SetDefaults() {
if s.AvailableLocales == nil {
s.AvailableLocales = NewPointer("")
}
if s.EnableExperimentalLocales == nil {
s.EnableExperimentalLocales = NewPointer(false)
}
}
type SamlSettings struct {

Просмотреть файл

@@ -2102,6 +2102,13 @@ const AdminDefinition: AdminDefinitionType = {
no_result: defineMessage({id: 'admin.general.localization.availableLocalesNoResults', defaultMessage: 'No results found'}),
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.SITE.LOCALIZATION)),
},
{
type: 'bool',
key: 'LocalizationSettings.EnableExperimentalLocales',
label: defineMessage({id: 'admin.general.localization.enableExperimentalLocalesTitle', defaultMessage: 'Enable Experimental Locales:'}),
help_text: defineMessage({id: 'admin.general.localization.enableExperimentalLocalesDescription', defaultMessage: 'When true, it allows users to select experimental (e.g., in progress) languages.'}),
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.SITE.LOCALIZATION)),
},
],
},
},

Просмотреть файл

@@ -1021,6 +1021,8 @@
"admin.general.localization.availableLocalesTitle": "Available Languages:",
"admin.general.localization.clientLocaleDescription": "Default language for newly created users and pages where the user hasn't logged in.",
"admin.general.localization.clientLocaleTitle": "Default Client Language:",
"admin.general.localization.enableExperimentalLocalesDescription": "When true, it allows users to select experimental (e.g. in progress) languages",
"admin.general.localization.enableExperimentalLocalesTitle": "Enable Experimental Locales",
"admin.general.localization.serverLocaleDescription": "Default language for system messages.",
"admin.general.localization.serverLocaleTitle": "Default Server Language:",
"admin.general.log": "Logging",

Просмотреть файл

@@ -5,38 +5,17 @@
* @typedef {} Language
*/
/* eslint-disable import/order */
import bg from './bg.json';
import de from './de.json';
import enAU from './en-AU.json';
import es from './es.json';
import fa from './fa.json';
import fr from './fr.json';
import hu from './hu.json';
import it from './it.json';
import ja from './ja.json';
import ko from './ko.json';
import nl from './nl.json';
import pl from './pl.json';
import ptBR from './pt-BR.json';
import ro from './ro.json';
import ru from './ru.json';
import sv from './sv.json';
import vi from './vi.json';
import tr from './tr.json';
import uk from './uk.json';
import zhTW from './zh-TW.json';
import zhCN from './zh-CN.json';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {langFiles, langIDs, langLabels} from './imports';
// should match the values in server/public/shared/i18n/i18n.go
const languages = {
export const languages = {
de: {
value: 'de',
name: 'Deutsch',
order: 0,
url: de,
url: langFiles.de,
},
en: {
value: 'en',
@@ -48,125 +27,140 @@ const languages = {
value: 'en-AU',
name: 'English (Australia)',
order: 2,
url: enAU,
url: langFiles['en-AU'],
},
es: {
value: 'es',
name: 'Español (Beta)',
order: 3,
url: es,
url: langFiles.es,
},
fr: {
value: 'fr',
name: 'Français (Beta)',
order: 4,
url: fr,
url: langFiles.fr,
},
it: {
value: 'it',
name: 'Italiano (Alpha)',
order: 5,
url: it,
url: langFiles.it,
},
hu: {
value: 'hu',
name: 'Magyar (Beta)',
order: 6,
url: hu,
url: langFiles.hu,
},
nl: {
value: 'nl',
name: 'Nederlands',
order: 7,
url: nl,
url: langFiles.nl,
},
pl: {
value: 'pl',
name: 'Polski',
order: 8,
url: pl,
url: langFiles.pl,
},
'pt-BR': {
value: 'pt-BR',
name: 'Português (Brasil) (Alpha)',
order: 9,
url: ptBR,
url: langFiles['pt-BR'],
},
ro: {
value: 'ro',
name: 'Română (Alpha)',
order: 10,
url: ro,
url: langFiles.ro,
},
sv: {
value: 'sv',
name: 'Svenska',
order: 11,
url: sv,
url: langFiles.sv,
},
vi: {
value: 'vi',
name: 'Tiếng Việt (Beta)',
order: 12,
url: vi,
url: langFiles.vi,
},
tr: {
value: 'tr',
name: 'Türkçe',
order: 13,
url: tr,
url: langFiles.tr,
},
bg: {
value: 'bg',
name: 'Български (Alpha)',
order: 14,
url: bg,
url: langFiles.bg,
},
ru: {
value: 'ru',
name: 'Pусский',
order: 15,
url: ru,
url: langFiles.ru,
},
uk: {
value: 'uk',
name: 'Yкраїнська (Alpha)',
order: 16,
url: uk,
url: langFiles.uk,
},
fa: {
value: 'fa',
name: 'فارسی (Alpha)',
order: 17,
url: fa,
url: langFiles.fa,
},
ko: {
value: 'ko',
name: '한국어 (Alpha)',
order: 18,
url: ko,
url: langFiles.ko,
},
'zh-CN': {
value: 'zh-CN',
name: '中文 (简体) (Beta)',
order: 19,
url: zhCN,
url: langFiles['zh-CN'],
},
'zh-TW': {
value: 'zh-TW',
name: '中文 (繁體) (Beta)',
order: 20,
url: zhTW,
url: langFiles['zh-TW'],
},
ja: {
value: 'ja',
name: '日本語',
order: 21,
url: ja,
url: langFiles.ja,
},
};
export function getAllLanguages() {
export function getAllLanguages(includeExperimental) {
if (includeExperimental) {
let order = Object.keys(languages).length;
return {
...langIDs.reduce((out, id) => {
out[id] = {
value: id,
name: langLabels[id],
url: langFiles[id],
order: order++,
};
return out;
}, {}),
...languages,
};
}
return languages;
}
@@ -177,7 +171,7 @@ export function getAllLanguages() {
export function getLanguages(state) {
const config = getConfig(state);
if (!config.AvailableLocales) {
return getAllLanguages();
return getAllLanguages(config.EnableExperimentalLocales === 'true');
}
return config.AvailableLocales.split(',').reduce((result, l) => {
if (languages[l]) {
@@ -188,7 +182,7 @@ export function getLanguages(state) {
}
export function getLanguageInfo(locale) {
return getAllLanguages()[locale];
return getAllLanguages(true)[locale];
}
/**

94
webapp/channels/src/i18n/i18n.test.jsx Обычный файл
Просмотреть файл

@@ -0,0 +1,94 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {getAllLanguages, getLanguageInfo, getLanguages, isLanguageAvailable, languages} from './i18n';
jest.mock('./imports', () => ({
langIDs: ['cc'],
langFiles: {cc: 'cc.json'},
langLabels: {cc: 'CC Language'},
}));
describe('i18n', () => {
test('getAllLanguages', () => {
// no experimental languages
expect(getAllLanguages()).toBe(languages);
expect(getAllLanguages(false)).toBe(languages);
// with experimental languages
expect(getAllLanguages(true)).toStrictEqual({
cc: {
name: 'CC Language',
value: 'cc',
order: 22,
url: 'cc.json',
},
...languages,
});
});
test('getLanguages', () => {
const state = {
entities: {
general: {
config: {
},
},
},
};
// no experimental languages
expect(getLanguages(state)).toBe(languages);
// with experimental languages
state.entities.general.config.EnableExperimentalLocales = 'true';
expect(getLanguages(state)).toStrictEqual({
cc: {
name: 'CC Language',
value: 'cc',
order: 22,
url: 'cc.json',
},
...languages,
});
});
test('getLanguageInfo', () => {
// supported language
expect(getLanguageInfo('en')).toStrictEqual({
name: 'English (US)',
order: 1,
url: '',
value: 'en',
});
// experimental language (e.g. in progress)
expect(getLanguageInfo('cc')).toStrictEqual({
name: 'CC Language',
value: 'cc',
order: 22,
url: 'cc.json',
});
// non existant
expect(getLanguageInfo('invalid')).not.toBeDefined();
});
test('isLanguageAvailable', () => {
const state = {
entities: {
general: {
config: {
},
},
},
};
// no experimental languages
expect(isLanguageAvailable(state, 'cc')).toBe(false);
// with experimental languages
state.entities.general.config.EnableExperimentalLocales = 'true';
expect(isLanguageAvailable(state, 'cc')).toBe(true);
});
});

75
webapp/channels/src/i18n/imports.ts Обычный файл
Просмотреть файл

@@ -0,0 +1,75 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// DO NOT EDIT - This file is generated by gen_lang_imports through the gen-lang-imports script
/* eslint-disable */
import am from './am.json';
import ar from './ar.json';
import be from './be.json';
import bg from './bg.json';
import bn from './bn.json';
import br from './br.json';
import ca from './ca.json';
import cs from './cs.json';
import da from './da.json';
import de from './de.json';
import el from './el.json';
import enAU from './en-AU.json';
import es from './es.json';
import et from './et.json';
import eu from './eu.json';
import fa from './fa.json';
import fi from './fi.json';
import fil from './fil.json';
import fr from './fr.json';
import fy from './fy.json';
import gl from './gl.json';
import gu from './gu.json';
import he from './he.json';
import hi from './hi.json';
import hr from './hr.json';
import hu from './hu.json';
import id from './id.json';
import is from './is.json';
import it from './it.json';
import ja from './ja.json';
import ka from './ka.json';
import kkLatn from './kk-Latn.json';
import kk from './kk.json';
import km from './km.json';
import ko from './ko.json';
import la from './la.json';
import lo from './lo.json';
import lt from './lt.json';
import lv from './lv.json';
import mk from './mk.json';
import ml from './ml.json';
import mn from './mn.json';
import nbNO from './nb-NO.json';
import ne from './ne.json';
import nl from './nl.json';
import pl from './pl.json';
import pr from './pr.json';
import ptBR from './pt-BR.json';
import pt from './pt.json';
import ro from './ro.json';
import ru from './ru.json';
import si from './si.json';
import sl from './sl.json';
import sq from './sq.json';
import sr from './sr.json';
import sv from './sv.json';
import th from './th.json';
import tr from './tr.json';
import uk from './uk.json';
import vi from './vi.json';
import zhCN from './zh-CN.json';
import zhTW from './zh-TW.json';
export const langIDs = ["am","ar","be","bg","bn","br","ca","cs","da","de","el","en-AU","es","et","eu","fa","fi","fil","fr","fy","gl","gu","he","hi","hr","hu","id","is","it","ja","ka","kk-Latn","kk","km","ko","la","lo","lt","lv","mk","ml","mn","nb-NO","ne","nl","pl","pr","pt-BR","pt","ro","ru","si","sl","sq","sr","sv","th","tr","uk","vi","zh-CN","zh-TW"];
export const langLabels = {"am":"አማርኛ","ar":"العربية","be":"Беларуская","bg":"Български","bn":"বাংলা","br":"Brezhoneg","ca":"Català","cs":"Čeština","da":"Dansk","de":"Deutsch","el":"Ελληνικά","en-AU":"English (Australia)","es":"Español","et":"eesti keel","eu":"Euskara","fa":"فارسی","fi":"Suomi","fil":"Filipino","fr":"Français","fy":"Frysk","gl":"Galego","gu":"ગુજરાતી","he":"עברית‏","hi":"हिन्दी","hr":"Hrvatski","hu":"Magyar","id":"Bahasa Indonesia","is":"Íslenska","it":"Italiano","ja":"日本語","ka":"ქართული","kk-Latn":"Қазақша","kk":"Қазақша","km":"ភាសាខ្មែរ","ko":"한국어","la":"Latin","lo":"ພາສາລາວ","lt":"Lietuvių","lv":"Latviešu","mk":"Македонски","ml":"മലയാളം","mn":"Монгол","nb-NO":"Norsk (bokmål)","ne":"नेपाली","nl":"Nederlands","pl":"Polski","pr":"pr","pt-BR":"Português (Brasil)","pt":"Português","ro":"Română","ru":"Русский","si":"සිංහල","sl":"Slovenščina","sq":"Shqip","sr":"Српски","sv":"Svenska","th":"ภาษาไทย","tr":"Türkçe","uk":"Українська","vi":"Tiếng Việt","zh-CN":"中文(中国大陆)","zh-TW":"中文(台灣)"};
export const langFiles = {am,ar,be,bg,bn,br,ca,cs,da,de,el,'en-AU':enAU,es,et,eu,fa,fi,fil,fr,fy,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,'kk-Latn':kkLatn,kk,km,ko,la,lo,lt,lv,mk,ml,mn,'nb-NO':nbNO,ne,nl,pl,pr,'pt-BR':ptBR,pt,ro,ru,si,sl,sq,sr,sv,th,tr,uk,vi,'zh-CN':zhCN,'zh-TW':zhTW};

897
webapp/channels/src/i18n/langmap.js Обычный файл
Просмотреть файл

@@ -0,0 +1,897 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
module.exports = {
ach: {
nativeName: 'Lwo',
englishName: 'Acholi',
},
ady: {
nativeName: 'Адыгэбзэ',
englishName: 'Adyghe',
},
af: {
nativeName: 'Afrikaans',
englishName: 'Afrikaans',
},
'af-NA': {
nativeName: 'Afrikaans (Namibia)',
englishName: 'Afrikaans (Namibia)',
},
'af-ZA': {
nativeName: 'Afrikaans (South Africa)',
englishName: 'Afrikaans (South Africa)',
},
ak: {
nativeName: 'Tɕɥi',
englishName: 'Akan',
},
am: {
name: 'Amharic',
nativeName: 'አማርኛ',
},
ar: {
nativeName: 'العربية',
englishName: 'Arabic',
},
'ar-AR': {
nativeName: 'العربية',
englishName: 'Arabic',
},
'ar-MA': {
nativeName: 'العربية',
englishName: 'Arabic (Morocco)',
},
'ar-SA': {
nativeName: 'العربية (السعودية)',
englishName: 'Arabic (Saudi Arabia)',
},
'ay-BO': {
nativeName: 'Aymar aru',
englishName: 'Aymara',
},
az: {
nativeName: 'Azərbaycan dili',
englishName: 'Azerbaijani',
},
'az-AZ': {
nativeName: 'Azərbaycan dili',
englishName: 'Azerbaijani',
},
'be-BY': {
nativeName: 'Беларуская',
englishName: 'Belarusian',
},
bg: {
nativeName: 'Български',
englishName: 'Bulgarian',
},
'bg-BG': {
nativeName: 'Български',
englishName: 'Bulgarian',
},
bn: {
nativeName: 'বাংলা',
englishName: 'Bengali',
},
'bn-IN': {
nativeName: 'বাংলা (ভারত)',
englishName: 'Bengali (India)',
},
'bn-BD': {
nativeName: 'বাংলা(বাংলাদেশ)',
englishName: 'Bengali (Bangladesh)',
},
br: {
nativeName: 'Brezhoneg',
englishName: 'Breton',
},
'bs-BA': {
nativeName: 'Bosanski',
englishName: 'Bosnian',
},
ca: {
nativeName: 'Català',
englishName: 'Catalan',
},
'ca-ES': {
nativeName: 'Català',
englishName: 'Catalan',
},
cak: {
nativeName: 'Maya Kaqchikel',
englishName: 'Kaqchikel',
},
'ck-US': {
nativeName: 'ᏣᎳᎩ (tsalagi)',
englishName: 'Cherokee',
},
cs: {
nativeName: 'Čeština',
englishName: 'Czech',
},
'cs-CZ': {
nativeName: 'Čeština',
englishName: 'Czech',
},
cy: {
nativeName: 'Cymraeg',
englishName: 'Welsh',
},
'cy-GB': {
nativeName: 'Cymraeg',
englishName: 'Welsh',
},
da: {
nativeName: 'Dansk',
englishName: 'Danish',
},
'da-DK': {
nativeName: 'Dansk',
englishName: 'Danish',
},
de: {
nativeName: 'Deutsch',
englishName: 'German',
},
'de-AT': {
nativeName: 'Deutsch (Österreich)',
englishName: 'German (Austria)',
},
'de-DE': {
nativeName: 'Deutsch (Deutschland)',
englishName: 'German (Germany)',
},
'de-CH': {
nativeName: 'Deutsch (Schweiz)',
englishName: 'German (Switzerland)',
},
dsb: {
nativeName: 'Dolnoserbšćina',
englishName: 'Lower Sorbian',
},
el: {
nativeName: 'Ελληνικά',
englishName: 'Greek',
},
'el-GR': {
nativeName: 'Ελληνικά',
englishName: 'Greek (Greece)',
},
en: {
nativeName: 'English',
englishName: 'English',
},
'en-GB': {
nativeName: 'English (UK)',
englishName: 'English (UK)',
},
'en-AU': {
nativeName: 'English (Australia)',
englishName: 'English (Australia)',
},
'en-CA': {
nativeName: 'English (Canada)',
englishName: 'English (Canada)',
},
'en-IE': {
nativeName: 'English (Ireland)',
englishName: 'English (Ireland)',
},
'en-IN': {
nativeName: 'English (India)',
englishName: 'English (India)',
},
'en-PI': {
nativeName: 'English (Pirate)',
englishName: 'English (Pirate)',
},
'en-SG': {
nativeName: 'English (Singapore)',
englishName: 'English (Singapore)',
},
'en-UD': {
nativeName: 'English (Upside Down)',
englishName: 'English (Upside Down)',
},
'en-US': {
nativeName: 'English (US)',
englishName: 'English (US)',
},
'en-ZA': {
nativeName: 'English (South Africa)',
englishName: 'English (South Africa)',
},
'en@pirate': {
nativeName: 'English (Pirate)',
englishName: 'English (Pirate)',
},
eo: {
nativeName: 'Esperanto',
englishName: 'Esperanto',
},
'eo-EO': {
nativeName: 'Esperanto',
englishName: 'Esperanto',
},
es: {
nativeName: 'Español',
englishName: 'Spanish',
},
'es-AR': {
nativeName: 'Español (Argentine)',
englishName: 'Spanish (Argentina)',
},
'es-419': {
nativeName: 'Español (Latinoamérica)',
englishName: 'Spanish (Latin America)',
},
'es-CL': {
nativeName: 'Español (Chile)',
englishName: 'Spanish (Chile)',
},
'es-CO': {
nativeName: 'Español (Colombia)',
englishName: 'Spanish (Colombia)',
},
'es-EC': {
nativeName: 'Español (Ecuador)',
englishName: 'Spanish (Ecuador)',
},
'es-ES': {
nativeName: 'Español (España)',
englishName: 'Spanish (Spain)',
},
'es-LA': {
nativeName: 'Español (Latinoamérica)',
englishName: 'Spanish (Latin America)',
},
'es-NI': {
nativeName: 'Español (Nicaragua)',
englishName: 'Spanish (Nicaragua)',
},
'es-MX': {
nativeName: 'Español (México)',
englishName: 'Spanish (Mexico)',
},
'es-US': {
nativeName: 'Español (Estados Unidos)',
englishName: 'Spanish (United States)',
},
'es-VE': {
nativeName: 'Español (Venezuela)',
englishName: 'Spanish (Venezuela)',
},
et: {
nativeName: 'eesti keel',
englishName: 'Estonian',
},
'et-EE': {
nativeName: 'Eesti (Estonia)',
englishName: 'Estonian (Estonia)',
},
eu: {
nativeName: 'Euskara',
englishName: 'Basque',
},
'eu-ES': {
nativeName: 'Euskara',
englishName: 'Basque',
},
fa: {
nativeName: 'فارسی',
englishName: 'Persian',
},
'fa-IR': {
nativeName: 'فارسی',
englishName: 'Persian',
},
'fb-LT': {
nativeName: 'Leet Speak',
englishName: 'Leet',
},
ff: {
nativeName: 'Fulah',
englishName: 'Fulah',
},
fi: {
nativeName: 'Suomi',
englishName: 'Finnish',
},
'fi-FI': {
nativeName: 'Suomi',
englishName: 'Finnish',
},
fo: {
nativeName: 'Føroyskt',
englishName: 'Faroese',
},
'fo-FO': {
nativeName: 'Føroyskt (Færeyjar)',
englishName: 'Faroese (Faroe Islands)',
},
fr: {
nativeName: 'Français',
englishName: 'French',
},
'fr-CA': {
nativeName: 'Français (Canada)',
englishName: 'French (Canada)',
},
'fr-FR': {
nativeName: 'Français (France)',
englishName: 'French (France)',
},
'fr-BE': {
nativeName: 'Français (Belgique)',
englishName: 'French (Belgium)',
},
'fr-CH': {
nativeName: 'Français (Suisse)',
englishName: 'French (Switzerland)',
},
'fy-NL': {
nativeName: 'Frysk',
englishName: 'Frisian (West)',
},
ga: {
nativeName: 'Gaeilge',
englishName: 'Irish',
},
'ga-IE': {
nativeName: 'Gaeilge',
englishName: 'Irish',
},
gd: {
nativeName: 'Gàidhlig',
englishName: 'Gaelic',
},
gl: {
nativeName: 'Galego',
englishName: 'Galician',
},
'gl-ES': {
nativeName: 'Galego',
englishName: 'Galician',
},
'gn-PY': {
nativeName: "Avañe'ẽ",
englishName: 'Guarani',
},
'gu-IN': {
nativeName: 'ગુજરાતી',
englishName: 'Gujarati',
},
gv: {
nativeName: 'Gaelg',
englishName: 'Manx',
},
'gx-GR': {
nativeName: 'Ἑλληνική ἀρχαία',
englishName: 'Classical Greek',
},
he: {
nativeName: 'עברית‏',
englishName: 'Hebrew',
},
'he-IL': {
nativeName: 'עברית‏',
englishName: 'Hebrew',
},
hi: {
nativeName: 'हिन्दी',
englishName: 'Hindi',
},
'hi-IN': {
nativeName: 'हिन्दी',
englishName: 'Hindi',
},
hr: {
nativeName: 'Hrvatski',
englishName: 'Croatian',
},
'hr-HR': {
nativeName: 'Hrvatski',
englishName: 'Croatian',
},
hsb: {
nativeName: 'Hornjoserbšćina',
englishName: 'Upper Sorbian',
},
ht: {
nativeName: 'Kreyòl',
englishName: 'Haitian Creole',
},
hu: {
nativeName: 'Magyar',
englishName: 'Hungarian',
},
'hu-HU': {
nativeName: 'Magyar',
englishName: 'Hungarian',
},
hy: {
nativeName: 'Հայերեն',
englishName: 'Armenian',
},
'hy-AM': {
nativeName: 'Հայերեն (Հայաստան)',
englishName: 'Armenian (Armenia)',
},
id: {
nativeName: 'Bahasa Indonesia',
englishName: 'Indonesian',
},
'id-ID': {
nativeName: 'Bahasa Indonesia',
englishName: 'Indonesian',
},
is: {
nativeName: 'Íslenska',
englishName: 'Icelandic',
},
'is-IS': {
nativeName: 'Íslenska (Iceland)',
englishName: 'Icelandic (Iceland)',
},
it: {
nativeName: 'Italiano',
englishName: 'Italian',
},
'it-IT': {
nativeName: 'Italiano',
englishName: 'Italian',
},
ja: {
nativeName: '日本語',
englishName: 'Japanese',
},
'ja-JP': {
nativeName: '日本語 (日本)',
englishName: 'Japanese (Japan)',
},
'jv-ID': {
nativeName: 'Basa Jawa',
englishName: 'Javanese',
},
'ka-GE': {
nativeName: 'ქართული',
englishName: 'Georgian',
},
'kk-KZ': {
nativeName: 'Қазақша',
englishName: 'Kazakh',
},
km: {
nativeName: 'ភាសាខ្មែរ',
englishName: 'Khmer',
},
kl: {
nativeName: 'kalaallisut',
englishName: 'Greenlandic',
},
'km-KH': {
nativeName: 'ភាសាខ្មែរ',
englishName: 'Khmer',
},
kab: {
nativeName: 'Taqbaylit',
englishName: 'Kabyle',
},
kn: {
nativeName: 'ಕನ್ನಡ',
englishName: 'Kannada',
},
'kn-IN': {
nativeName: 'ಕನ್ನಡ (India)',
englishName: 'Kannada (India)',
},
ko: {
nativeName: '한국어',
englishName: 'Korean',
},
'ko-KR': {
nativeName: '한국어 (한국)',
englishName: 'Korean (Korea)',
},
'ku-TR': {
nativeName: 'Kurdî',
englishName: 'Kurdish',
},
kw: {
nativeName: 'Kernewek',
englishName: 'Cornish',
},
la: {
nativeName: 'Latin',
englishName: 'Latin',
},
'la-VA': {
nativeName: 'Latin',
englishName: 'Latin',
},
lb: {
nativeName: 'Lëtzebuergesch',
englishName: 'Luxembourgish',
},
'li-NL': {
nativeName: 'Lèmbörgs',
englishName: 'Limburgish',
},
lo: {
name: 'Lao',
nativeName: 'ພາສາລາວ',
},
lt: {
nativeName: 'Lietuvių',
englishName: 'Lithuanian',
},
'lt-LT': {
nativeName: 'Lietuvių',
englishName: 'Lithuanian',
},
lv: {
nativeName: 'Latviešu',
englishName: 'Latvian',
},
'lv-LV': {
nativeName: 'Latviešu',
englishName: 'Latvian',
},
mai: {
nativeName: 'मैथिली, মৈথিলী',
englishName: 'Maithili',
},
'mg-MG': {
nativeName: 'Malagasy',
englishName: 'Malagasy',
},
mk: {
nativeName: 'Македонски',
englishName: 'Macedonian',
},
'mk-MK': {
nativeName: 'Македонски (Македонски)',
englishName: 'Macedonian (Macedonian)',
},
ml: {
nativeName: 'മലയാളം',
englishName: 'Malayalam',
},
'ml-IN': {
nativeName: 'മലയാളം',
englishName: 'Malayalam',
},
'mn-MN': {
nativeName: 'Монгол',
englishName: 'Mongolian',
},
mr: {
nativeName: 'मराठी',
englishName: 'Marathi',
},
'mr-IN': {
nativeName: 'मराठी',
englishName: 'Marathi',
},
ms: {
nativeName: 'Bahasa Melayu',
englishName: 'Malay',
},
'ms-MY': {
nativeName: 'Bahasa Melayu',
englishName: 'Malay',
},
mt: {
nativeName: 'Malti',
englishName: 'Maltese',
},
'mt-MT': {
nativeName: 'Malti',
englishName: 'Maltese',
},
my: {
nativeName: 'ဗမာစကာ',
englishName: 'Burmese',
},
no: {
nativeName: 'Norsk',
englishName: 'Norwegian',
},
nb: {
nativeName: 'Norsk (bokmål)',
englishName: 'Norwegian (bokmal)',
},
'nb-NO': {
nativeName: 'Norsk (bokmål)',
englishName: 'Norwegian (bokmal)',
},
ne: {
nativeName: 'नेपाली',
englishName: 'Nepali',
},
'ne-NP': {
nativeName: 'नेपाली',
englishName: 'Nepali',
},
nl: {
nativeName: 'Nederlands',
englishName: 'Dutch',
},
'nl-BE': {
nativeName: 'Nederlands (België)',
englishName: 'Dutch (Belgium)',
},
'nl-NL': {
nativeName: 'Nederlands (Nederland)',
englishName: 'Dutch (Netherlands)',
},
'nn-NO': {
nativeName: 'Norsk (nynorsk)',
englishName: 'Norwegian (nynorsk)',
},
oc: {
nativeName: 'Occitan',
englishName: 'Occitan',
},
'or-IN': {
nativeName: 'ଓଡ଼ିଆ',
englishName: 'Oriya',
},
pa: {
nativeName: 'ਪੰਜਾਬੀ',
englishName: 'Punjabi',
},
'pa-IN': {
nativeName: 'ਪੰਜਾਬੀ (ਭਾਰਤ ਨੂੰ)',
englishName: 'Punjabi (India)',
},
pl: {
nativeName: 'Polski',
englishName: 'Polish',
},
'pl-PL': {
nativeName: 'Polski',
englishName: 'Polish',
},
'ps-AF': {
nativeName: 'پښتو',
englishName: 'Pashto',
},
pt: {
nativeName: 'Português',
englishName: 'Portuguese',
},
'pt-BR': {
nativeName: 'Português (Brasil)',
englishName: 'Portuguese (Brazil)',
},
'pt-PT': {
nativeName: 'Português (Portugal)',
englishName: 'Portuguese (Portugal)',
},
'qu-PE': {
nativeName: 'Qhichwa',
englishName: 'Quechua',
},
'rm-CH': {
nativeName: 'Rumantsch',
englishName: 'Romansh',
},
ro: {
nativeName: 'Română',
englishName: 'Romanian',
},
'ro-RO': {
nativeName: 'Română',
englishName: 'Romanian',
},
ru: {
nativeName: 'Русский',
englishName: 'Russian',
},
'ru-RU': {
nativeName: 'Русский',
englishName: 'Russian',
},
'sa-IN': {
nativeName: 'संस्कृतम्',
englishName: 'Sanskrit',
},
'se-NO': {
nativeName: 'Davvisámegiella',
englishName: 'Northern Sámi',
},
sh: {
nativeName: 'српскохрватски',
englishName: 'Serbo-Croatian',
},
'si-LK': {
nativeName: 'සිංහල',
englishName: 'Sinhala (Sri Lanka)',
},
sk: {
nativeName: 'Slovenčina',
englishName: 'Slovak',
},
'sk-SK': {
nativeName: 'Slovenčina (Slovakia)',
englishName: 'Slovak (Slovakia)',
},
sl: {
nativeName: 'Slovenščina',
englishName: 'Slovenian',
},
'sl-SI': {
nativeName: 'Slovenščina',
englishName: 'Slovenian',
},
'so-SO': {
nativeName: 'Soomaaliga',
englishName: 'Somali',
},
sq: {
nativeName: 'Shqip',
englishName: 'Albanian',
},
'sq-AL': {
nativeName: 'Shqip',
englishName: 'Albanian',
},
sr: {
nativeName: 'Српски',
englishName: 'Serbian',
},
'sr-RS': {
nativeName: 'Српски (Serbia)',
englishName: 'Serbian (Serbia)',
},
su: {
nativeName: 'Basa Sunda',
englishName: 'Sundanese',
},
sv: {
nativeName: 'Svenska',
englishName: 'Swedish',
},
'sv-SE': {
nativeName: 'Svenska',
englishName: 'Swedish',
},
sw: {
nativeName: 'Kiswahili',
englishName: 'Swahili',
},
'sw-KE': {
nativeName: 'Kiswahili',
englishName: 'Swahili (Kenya)',
},
ta: {
nativeName: 'தமிழ்',
englishName: 'Tamil',
},
'ta-IN': {
nativeName: 'தமிழ்',
englishName: 'Tamil',
},
te: {
nativeName: 'తెలుగు',
englishName: 'Telugu',
},
'te-IN': {
nativeName: 'తెలుగు',
englishName: 'Telugu',
},
tg: {
nativeName: 'забо́ни тоҷикӣ́',
englishName: 'Tajik',
},
'tg-TJ': {
nativeName: 'тоҷикӣ',
englishName: 'Tajik',
},
th: {
nativeName: 'ภาษาไทย',
englishName: 'Thai',
},
'th-TH': {
nativeName: 'ภาษาไทย (ประเทศไทย)',
englishName: 'Thai (Thailand)',
},
fil: {
nativeName: 'Filipino',
englishName: 'Filipino',
},
tlh: {
nativeName: 'tlhIngan-Hol',
englishName: 'Klingon',
},
tr: {
nativeName: 'Türkçe',
englishName: 'Turkish',
},
'tr-TR': {
nativeName: 'Türkçe',
englishName: 'Turkish',
},
'tt-RU': {
nativeName: 'татарча',
englishName: 'Tatar',
},
uk: {
nativeName: 'Українська',
englishName: 'Ukrainian',
},
'uk-UA': {
nativeName: 'Українська',
englishName: 'Ukrainian',
},
ur: {
nativeName: 'اردو',
englishName: 'Urdu',
},
'ur-PK': {
nativeName: 'اردو',
englishName: 'Urdu',
},
uz: {
nativeName: "O'zbek",
englishName: 'Uzbek',
},
'uz-UZ': {
nativeName: "O'zbek",
englishName: 'Uzbek',
},
vi: {
nativeName: 'Tiếng Việt',
englishName: 'Vietnamese',
},
'vi-VN': {
nativeName: 'Tiếng Việt',
englishName: 'Vietnamese',
},
'xh-ZA': {
nativeName: 'isiXhosa',
englishName: 'Xhosa',
},
yi: {
nativeName: 'ייִדיש',
englishName: 'Yiddish',
},
'yi-DE': {
nativeName: 'ייִדיש (German)',
englishName: 'Yiddish (German)',
},
zh: {
nativeName: '中文',
englishName: 'Chinese',
},
'zh-Hans': {
nativeName: '中文简体',
englishName: 'Chinese Simplified',
},
'zh-Hant': {
nativeName: '中文繁體',
englishName: 'Chinese Traditional',
},
'zh-CN': {
nativeName: '中文(中国大陆)',
englishName: 'Chinese Simplified (China)',
},
'zh-HK': {
nativeName: '中文(香港)',
englishName: 'Chinese Traditional (Hong Kong)',
},
'zh-SG': {
nativeName: '中文(新加坡)',
englishName: 'Chinese Simplified (Singapore)',
},
'zh-TW': {
nativeName: '中文(台灣)',
englishName: 'Chinese Traditional (Taiwan)',
},
'zu-ZA': {
nativeName: 'isiZulu',
englishName: 'Zulu',
},
};

Просмотреть файл

@@ -16,7 +16,8 @@
"check": "npm run check --workspaces --if-present",
"fix": "npm run fix --workspaces --if-present",
"check-types": "npm run check-types --workspaces --if-present",
"clean": "npm run clean --workspaces --if-present"
"clean": "npm run clean --workspaces --if-present",
"gen-lang-imports": "node scripts/gen_lang_imports.mjs"
},
"dependencies": {
"react-intl": "6.6.2",

Просмотреть файл

@@ -58,6 +58,7 @@ export type ClientConfig = {
EnableCustomEmoji: string;
EnableCustomGroups: string;
EnableCustomUserStatuses: string;
EnableExperimentalLocales: string;
EnableUserStatuses: string;
EnableLastActiveTime: string;
EnableTimedDND: string;
@@ -720,6 +721,7 @@ export type LocalizationSettings = {
DefaultServerLocale: string;
DefaultClientLocale: string;
AvailableLocales: string;
EnableExperimentalLocales: boolean;
};
export type SamlSettings = {

62
webapp/scripts/gen_lang_imports.mjs Обычный файл
Просмотреть файл

@@ -0,0 +1,62 @@
#!/bin/node
import * as fs from 'fs';
import langmap from '../channels/src/i18n/langmap.js';
let lines = '';
const langIDs = [];
const langFiles = {};
const langLabels = {};
fs.readdirSync('./channels/src/i18n').forEach(file => {
if (file.endsWith('.json')) {
const langID = file.substr(0, file.indexOf('.json'));
// Skip default language
if (langID === 'en') {
return
}
langIDs.push(langID);
lines += `import ${langID.replace('-', '')} from './${file}';\n`;
langFiles[langID] = langID.replace('-', '');
let m = langmap[langID]
if (!m) {
// We fallback to the language code prefix if we can't find a map.
const id = langID.includes('-') ? langID.substr(0, langID.indexOf('-')) : langID;
for (const k of Object.keys(langmap)) {
if (k.startsWith(id)) {
m = langmap[k];
break;
}
}
}
langLabels[langID] = m ? m["nativeName"] : langID;
}
});
lines += `\nexport const langIDs = ${JSON.stringify(langIDs)};\n`
lines += `\nexport const langLabels = ${JSON.stringify(langLabels)};\n`
// To generate the file exports we need to do a bit more work to handle ids with dashes and also output a map of literals rather than strings.
lines += '\nexport const langFiles = {' + Object.keys(langFiles).reduce((out, id, idx) => {
if (id.includes('-')) {
out += `'${id}':${langFiles[id]}`;
} else {
out += `${langFiles[id]}`;
}
if (idx !== (langIDs.length - 1)) {
out += ',';
}
return out;
}, '') + '};';
const header = `// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.\n\n// DO NOT EDIT - This file is generated by gen_lang_imports through the gen-lang-imports script\n\n/* eslint-disable */\n\n`;
fs.writeFileSync('./channels/src/i18n/imports.ts', header+lines);