diff --git a/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt b/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt index 26aa45191..70fb6d456 100644 --- a/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt +++ b/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt @@ -15,6 +15,7 @@ import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.translate.initialFromLanguage import mozilla.components.concept.engine.translate.initialToLanguage import mozilla.components.lib.state.helpers.AbstractBinding +import mozilla.components.support.locale.LocaleManager import org.mozilla.fenix.utils.LocaleUtils import java.util.Locale @@ -29,7 +30,7 @@ class TranslationsDialogBinding( private val getTranslatedPageTitle: (localizedFrom: String?, localizedTo: String?) -> String, ) : AbstractBinding(browserStore) { - @Suppress("LongMethod") + @Suppress("LongMethod", "CyclomaticComplexMethod") override suspend fun onState(flow: Flow) { // Browser level flows val browserFlow = flow.mapNotNull { state -> state } @@ -132,11 +133,15 @@ class TranslationsDialogBinding( // A session error may override a browser error if (sessionTranslationsState.translationError != null) { - var documentLangDisplayName: String? = null - sessionTranslationsState.translationEngineState?.detectedLanguages?.documentLangTag?.let { - val documentLanguage = Locale.forLanguageTag(it) - documentLangDisplayName = LocaleUtils.getDisplayName(documentLanguage) - } + val documentLangDisplayName = sessionTranslationsState.translationEngineState + ?.detectedLanguages?.documentLangTag?.let { docLangTag -> + val documentLocale = Locale.forLanguageTag(docLangTag) + val userLocale = state.browserState.locale ?: LocaleManager.getSystemDefault() + LocaleUtils.getLocalizedDisplayName( + userLocale = userLocale, + languageLocale = documentLocale, + ) + } translationsDialogStore.dispatch( TranslationsDialogAction.UpdateTranslationError( diff --git a/app/src/main/java/org/mozilla/fenix/utils/LocaleUtils.kt b/app/src/main/java/org/mozilla/fenix/utils/LocaleUtils.kt index ab30a6a75..f90abfb5d 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/LocaleUtils.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/LocaleUtils.kt @@ -12,7 +12,14 @@ import java.util.Locale object LocaleUtils { /** - * Returns a name for the locale that is appropriate for display to the user. + * Returns a name for the locale that is appropriate for display to the user. The display name + * will be in the language of the specified locale. + * + * For example, in an any language locale, the German language locale or "de" would be + * presented as "Deutsch". + * + * @param locale The locale to determine a language name. + * @return A default title case display name in the locale's language. */ fun getDisplayName(locale: Locale): String { val displayName = locale.getDisplayName(locale) @@ -23,6 +30,27 @@ object LocaleUtils { return displayName } + /** + * Returns a name for the locale that is appropriate for display to the user based on the user's + * specified language. + * + * For example, in an an English language locale, the German language locale or "de" would be + * presented as "German". + * + * @param userLocale The locale the user is using. + * @param languageLocale The locale to localize the language name into the user's language. + * + * @return A default language name in the specified user's locale language. + */ + fun getLocalizedDisplayName(userLocale: Locale, languageLocale: Locale): String { + val displayName = Locale.forLanguageTag(languageLocale.toLanguageTag()).getDisplayName(userLocale) + return if (userLocale == Locale.ENGLISH) { + LOCALE_TO_DISPLAY_ENGLISH_NAME_MAP[languageLocale.toString()] ?: displayName + } else { + displayName + } + } + private val LOCALE_TO_DISPLAY_NATIVE_NAME_MAP: Map = mapOf( "an" to "Aragonés", "anp" to "अंगिका", diff --git a/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogReducerTest.kt b/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogReducerTest.kt index 0fffa0a89..4abe33423 100644 --- a/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogReducerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogReducerTest.kt @@ -166,13 +166,13 @@ class TranslationsDialogReducerTest { translationError = TranslationError.LanguageNotSupportedError( null, ), - documentLangDisplayName = "Deutsch", + documentLangDisplayName = "German", ), ) assertTrue(updatedState.error is TranslationError.LanguageNotSupportedError) assertEquals(PositiveButtonType.Disabled, updatedState.positiveButtonType) - assertEquals(updatedState.documentLangDisplayName, "Deutsch") + assertEquals(updatedState.documentLangDisplayName, "German") val updatedStateTwo = TranslationsDialogReducer.reduce( translationsDialogState, diff --git a/app/src/test/java/org/mozilla/fenix/utils/LocaleUtilsTest.kt b/app/src/test/java/org/mozilla/fenix/utils/LocaleUtilsTest.kt new file mode 100644 index 000000000..0046f2927 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/utils/LocaleUtilsTest.kt @@ -0,0 +1,32 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.utils + +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner +import java.util.Locale + +@RunWith(FenixRobolectricTestRunner::class) +class LocaleUtilsTest { + + @Test + fun `WHEN using getDisplayName on a 'de' locale THEN get the expected default name`() { + val localizedLanguageName = LocaleUtils.getDisplayName( + locale = Locale("de"), + ) + assertEquals("Deutsch", localizedLanguageName) + } + + @Test + fun `WHEN using getLocalizedDisplayName with an 'en' locale on a 'de' locale THEN get the expected localized name`() { + val localizedLanguageName = LocaleUtils.getLocalizedDisplayName( + userLocale = Locale("en"), + languageLocale = Locale("de"), + ) + assertEquals("German", localizedLanguageName) + } +}