mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-28 14:30:59 -05:00
refactor(i18n): use browser api to determine display names for languages
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
53a3c92fdb
commit
07a28824d3
3 changed files with 73 additions and 43 deletions
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export const availableLanguages = () => [
|
||||
'en',
|
||||
'zh-CN',
|
||||
'zh-TW',
|
||||
'fr',
|
||||
'de',
|
||||
'ja',
|
||||
'es',
|
||||
'ca',
|
||||
'el',
|
||||
'pt',
|
||||
'it',
|
||||
'tr',
|
||||
'ru',
|
||||
'nl',
|
||||
'hr',
|
||||
'pl',
|
||||
'uk',
|
||||
'hi',
|
||||
'sv',
|
||||
'eo',
|
||||
'da',
|
||||
'ko',
|
||||
'id',
|
||||
'sr',
|
||||
'vi',
|
||||
'ar',
|
||||
'cs',
|
||||
'sk'
|
||||
]
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import React, { useMemo } from 'react'
|
||||
|
||||
interface LanguageOptionProps {
|
||||
languageCode: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a select option for a language. The display name is determined using the browser API.
|
||||
*
|
||||
* @param languageCode the language code to display
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl
|
||||
*/
|
||||
export const LanguageOption: React.FC<LanguageOptionProps> = ({ languageCode }) => {
|
||||
const displayName = useMemo(
|
||||
() => new Intl.DisplayNames([languageCode], { type: 'language' }).of(languageCode),
|
||||
[languageCode]
|
||||
)
|
||||
|
||||
return <option value={languageCode}>{displayName}</option>
|
||||
}
|
|
@ -1,46 +1,17 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
import { Logger } from '../../../../utils/logger'
|
||||
import { Settings } from 'luxon'
|
||||
import { availableLanguages } from './available-languages'
|
||||
import { LanguageOption } from './language-option'
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import { Form } from 'react-bootstrap'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const log = new Logger('LanguagePicker')
|
||||
const languages = {
|
||||
en: 'English',
|
||||
'zh-CN': '简体中文',
|
||||
'zh-TW': '繁體中文',
|
||||
fr: 'Français',
|
||||
de: 'Deutsch',
|
||||
ja: '日本語',
|
||||
es: 'Español',
|
||||
ca: 'Català',
|
||||
el: 'Ελληνικά',
|
||||
pt: 'Português',
|
||||
it: 'Italiano',
|
||||
tr: 'Türkçe',
|
||||
ru: 'Русский',
|
||||
nl: 'Nederlands',
|
||||
hr: 'Hrvatski',
|
||||
pl: 'Polski',
|
||||
uk: 'Українська',
|
||||
hi: 'हिन्दी',
|
||||
sv: 'Svenska',
|
||||
eo: 'Esperanto',
|
||||
da: 'Dansk',
|
||||
ko: '한국어',
|
||||
id: 'Bahasa Indonesia',
|
||||
sr: 'Cрпски',
|
||||
vi: 'Tiếng Việt',
|
||||
ar: 'العربية',
|
||||
cs: 'Česky',
|
||||
sk: 'Slovensky'
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks if the wanted language code is supported by our translations.
|
||||
|
@ -49,12 +20,13 @@ const languages = {
|
|||
* Therefore, we first need to check if the complete wanted language code is supported by our translations.
|
||||
* If not, then we look if we at least have a region independent translation.
|
||||
*
|
||||
* @param allLanguages all available languages as ISO-639-1 codes
|
||||
* @param wantedLanguage an ISO 639-1 standard language code
|
||||
* @return The supported language code
|
||||
*/
|
||||
const findLanguageCode = (wantedLanguage: string): string =>
|
||||
Object.keys(languages).find((supportedLanguage) => wantedLanguage === supportedLanguage) ??
|
||||
Object.keys(languages).find((supportedLanguage) => wantedLanguage.slice(0, 2) === supportedLanguage) ??
|
||||
const findLanguageCode = (allLanguages: string[], wantedLanguage: string): string =>
|
||||
allLanguages.find((supportedLanguage) => wantedLanguage === supportedLanguage) ??
|
||||
allLanguages.find((supportedLanguage) => wantedLanguage.slice(0, 2) === supportedLanguage) ??
|
||||
''
|
||||
|
||||
/**
|
||||
|
@ -72,16 +44,13 @@ export const LanguagePicker: React.FC = () => {
|
|||
[i18n]
|
||||
)
|
||||
|
||||
const languageCode = useMemo(() => findLanguageCode(i18n.language), [i18n.language])
|
||||
const allLanguages = useMemo(() => availableLanguages(), [])
|
||||
|
||||
const languageCode = useMemo(() => findLanguageCode(allLanguages, i18n.language), [allLanguages, i18n.language])
|
||||
|
||||
const languageOptions = useMemo(
|
||||
() =>
|
||||
Object.entries(languages).map(([language, languageName]) => (
|
||||
<option key={language} value={language}>
|
||||
{languageName}
|
||||
</option>
|
||||
)),
|
||||
[]
|
||||
() => allLanguages.map((language) => <LanguageOption languageCode={language} key={language} />),
|
||||
[allLanguages]
|
||||
)
|
||||
|
||||
return (
|
||||
|
|
Loading…
Reference in a new issue