From 3e5dddf617f3e7b69263ee75e5dd779124adf46c Mon Sep 17 00:00:00 2001 From: alexsparkes Date: Sat, 24 Jan 2026 17:25:53 +0000 Subject: [PATCH] feat(language): enhance language options with native and translated names --- src/components/Form/Settings/Radio/Radio.jsx | 2 +- src/features/misc/sections/Language.jsx | 51 ++++++++++++++++++-- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/components/Form/Settings/Radio/Radio.jsx b/src/components/Form/Settings/Radio/Radio.jsx index d0a503b9..cf5fa311 100644 --- a/src/components/Form/Settings/Radio/Radio.jsx +++ b/src/components/Form/Settings/Radio/Radio.jsx @@ -75,7 +75,7 @@ const Radio = memo((props) => { value={option.value} control={} label={option.name} - key={option.name} + key={option.value} /> ))} diff --git a/src/features/misc/sections/Language.jsx b/src/features/misc/sections/Language.jsx index 86cabe97..04104007 100644 --- a/src/features/misc/sections/Language.jsx +++ b/src/features/misc/sections/Language.jsx @@ -1,5 +1,5 @@ -import { useState, useEffect, useRef } from 'react'; -import { useT } from 'contexts/TranslationContext'; +import { useState, useEffect, useRef, useMemo } from 'react'; +import { useT, useTranslation } from 'contexts/TranslationContext'; import variables from 'config/variables'; import { MdOutlineOpenInNew } from 'react-icons/md'; @@ -10,11 +10,56 @@ import languages from '@/i18n/languages.json'; const LanguageOptions = () => { const t = useT(); + const { language: currentLanguage } = useTranslation(); const loadingText = t('modals.main.loading'); const offlineText = t('modals.main.marketplace.offline.description'); const languageTitle = t('modals.main.settings.sections.language.title'); const quoteTitle = t('modals.main.settings.sections.language.quote'); + // Create language options with both translated and native names + const languageOptions = useMemo(() => { + // Convert currentLanguage to ISO format (e.g., "de_DE" -> "de-DE") + const currentLanguageISO = currentLanguage.replace('_', '-'); + + // Use Intl.DisplayNames to get language names in the current language + const displayNames = new Intl.DisplayNames([currentLanguageISO], { type: 'language' }); + + return languages.map((lang) => { + const nativeName = lang.name; + + // Convert language code to ISO format for Intl.DisplayNames + // e.g., "en_GB" -> "en-GB", "zh_CN" -> "zh-CN" + const isoCode = lang.value.replace('_', '-'); + + let translatedName; + try { + translatedName = displayNames.of(isoCode); + // Simplify by removing country suffixes: "German (Germany)" → "German" + if (translatedName) { + translatedName = translatedName.split(' (')[0]; + } + } catch (e) { + // Fallback if the code isn't recognized + translatedName = nativeName; + } + + // Show native name first, then translated name in brackets (greyed and smaller) + const displayName = !translatedName || translatedName === nativeName + ? nativeName + : ( + <> + {nativeName}{' '} + ({translatedName}) + + ); + + return { + name: displayName, + value: lang.value, + }; + }); + }, [currentLanguage]); + const [quoteLanguages, setQuoteLanguages] = useState([ { name: loadingText, @@ -92,7 +137,7 @@ const LanguageOptions = () => {
- +
{quoteTitle}