From f2684d3e1e3b54ab709c5ce5fc7fe2f6ece57622 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 17 Nov 2025 16:40:21 -0500 Subject: [PATCH] feat: add functionality to localize language display names --- .../chat/widgets/pangea_chat_input_row.dart | 4 +- .../choreographer/enums/span_data_type.dart | 3 +- .../course_language_filter.dart | 4 +- .../models/language_model.dart | 230 +++++++++++++++++- .../widgets/p_language_dropdown.dart | 7 +- .../login/pages/language_selection_page.dart | 6 +- .../space_analytics/space_analytics.dart | 3 +- .../space_analytics/space_analytics_view.dart | 7 +- 8 files changed, 244 insertions(+), 20 deletions(-) diff --git a/lib/pangea/chat/widgets/pangea_chat_input_row.dart b/lib/pangea/chat/widgets/pangea_chat_input_row.dart index 2419c466d..a3fe2bbb4 100644 --- a/lib/pangea/chat/widgets/pangea_chat_input_row.dart +++ b/lib/pangea/chat/widgets/pangea_chat_input_row.dart @@ -61,8 +61,8 @@ class PangeaChatInputRowState extends State { activel1!.langCode != LanguageKeys.unknownLanguage && activel2!.langCode != LanguageKeys.unknownLanguage ? L10n.of(context).writeAMessageLangCodes( - activel1!.displayName, - activel2!.displayName, + activel1!.getDisplayName(context), + activel2!.getDisplayName(context), ) : L10n.of(context).writeAMessage; } diff --git a/lib/pangea/choreographer/enums/span_data_type.dart b/lib/pangea/choreographer/enums/span_data_type.dart index 8cd58c0e2..c2481da0e 100644 --- a/lib/pangea/choreographer/enums/span_data_type.dart +++ b/lib/pangea/choreographer/enums/span_data_type.dart @@ -34,7 +34,8 @@ extension SpanDataTypeEnumExt on SpanDataTypeEnum { return L10n.of(context).correctionDefaultPrompt; case SpanDataTypeEnum.itStart: return L10n.of(context).needsItMessage( - MatrixState.pangeaController.languageController.userL2?.displayName ?? + MatrixState.pangeaController.languageController.userL2 + ?.getDisplayName(context) ?? L10n.of(context).targetLanguage, ); } diff --git a/lib/pangea/course_creation/course_language_filter.dart b/lib/pangea/course_creation/course_language_filter.dart index cbaaeae28..084818b37 100644 --- a/lib/pangea/course_creation/course_language_filter.dart +++ b/lib/pangea/course_creation/course_language_filter.dart @@ -22,12 +22,12 @@ class CourseLanguageFilter extends StatelessWidget { onChanged: onChanged, items: MatrixState.pangeaController.pLanguageStore.unlocalizedTargetOptions, - displayname: (v) => v.getDisplayName(context) ?? v.displayName, + displayname: (v) => v.getDisplayName(context), enableSearch: true, defaultName: L10n.of(context).allLanguages, searchMatchFn: (item, searchValue) { final search = searchValue.toLowerCase(); - final displayName = item.value?.displayName.toLowerCase(); + final displayName = item.value?.getDisplayName(context).toLowerCase(); final langCode = item.value?.langCode.toLowerCase(); return displayName?.startsWith(search) == true || langCode?.startsWith(search) == true; diff --git a/lib/pangea/learning_settings/models/language_model.dart b/lib/pangea/learning_settings/models/language_model.dart index 285577bfc..35fea0163 100644 --- a/lib/pangea/learning_settings/models/language_model.dart +++ b/lib/pangea/learning_settings/models/language_model.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; +import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart'; import 'package:fluffychat/pangea/learning_settings/enums/l2_support_enum.dart'; import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart'; @@ -70,8 +71,233 @@ class LanguageModel { displayName: "Unknown", ); - String? getDisplayName(BuildContext context) { - return displayName; + String getDisplayName(BuildContext context) { + final langKey = "${langCode.replaceAll("-", "")}DisplayName"; + final l10n = L10n.of(context); + + final displayNameMap = { + "aceDisplayName": l10n.aceDisplayName, + "achDisplayName": l10n.achDisplayName, + "afDisplayName": l10n.afDisplayName, + "akDisplayName": l10n.akDisplayName, + "alzDisplayName": l10n.alzDisplayName, + "amDisplayName": l10n.amDisplayName, + "arDisplayName": l10n.arDisplayName, + "asDisplayName": l10n.asDisplayName, + "awaDisplayName": l10n.awaDisplayName, + "ayDisplayName": l10n.ayDisplayName, + "azDisplayName": l10n.azDisplayName, + "baDisplayName": l10n.baDisplayName, + "banDisplayName": l10n.banDisplayName, + "bbcDisplayName": l10n.bbcDisplayName, + "beDisplayName": l10n.beDisplayName, + "bemDisplayName": l10n.bemDisplayName, + "bewDisplayName": l10n.bewDisplayName, + "bgDisplayName": l10n.bgDisplayName, + "bhoDisplayName": l10n.bhoDisplayName, + "bikDisplayName": l10n.bikDisplayName, + "bmDisplayName": l10n.bmDisplayName, + "bnDisplayName": l10n.bnDisplayName, + "bnBDDisplayName": l10n.bnBDDisplayName, + "bnINDisplayName": l10n.bnINDisplayName, + "brDisplayName": l10n.brDisplayName, + "bsDisplayName": l10n.bsDisplayName, + "btsDisplayName": l10n.btsDisplayName, + "btxDisplayName": l10n.btxDisplayName, + "buaDisplayName": l10n.buaDisplayName, + "caDisplayName": l10n.caDisplayName, + "cebDisplayName": l10n.cebDisplayName, + "cggDisplayName": l10n.cggDisplayName, + "chmDisplayName": l10n.chmDisplayName, + "ckbDisplayName": l10n.ckbDisplayName, + "cnhDisplayName": l10n.cnhDisplayName, + "coDisplayName": l10n.coDisplayName, + "crhDisplayName": l10n.crhDisplayName, + "crsDisplayName": l10n.crsDisplayName, + "csDisplayName": l10n.csDisplayName, + "cvDisplayName": l10n.cvDisplayName, + "cyDisplayName": l10n.cyDisplayName, + "daDisplayName": l10n.daDisplayName, + "deDisplayName": l10n.deDisplayName, + "dinDisplayName": l10n.dinDisplayName, + "doiDisplayName": l10n.doiDisplayName, + "dovDisplayName": l10n.dovDisplayName, + "dzDisplayName": l10n.dzDisplayName, + "eeDisplayName": l10n.eeDisplayName, + "enDisplayName": l10n.enDisplayName, + "enAUDisplayName": l10n.enAUDisplayName, + "enGBDisplayName": l10n.enGBDisplayName, + "enINDisplayName": l10n.enINDisplayName, + "enUSDisplayName": l10n.enUSDisplayName, + "eoDisplayName": l10n.eoDisplayName, + "esDisplayName": l10n.esDisplayName, + "esESDisplayName": l10n.esESDisplayName, + "esMXDisplayName": l10n.esMXDisplayName, + "euDisplayName": l10n.euDisplayName, + "faDisplayName": l10n.faDisplayName, + "ffDisplayName": l10n.ffDisplayName, + "fiDisplayName": l10n.fiDisplayName, + "filDisplayName": l10n.filDisplayName, + "fjDisplayName": l10n.fjDisplayName, + "foDisplayName": l10n.foDisplayName, + "frDisplayName": l10n.frDisplayName, + "frCADisplayName": l10n.frCADisplayName, + "frFRDisplayName": l10n.frFRDisplayName, + "fyDisplayName": l10n.fyDisplayName, + "gaDisplayName": l10n.gaDisplayName, + "gaaDisplayName": l10n.gaaDisplayName, + "gdDisplayName": l10n.gdDisplayName, + "glDisplayName": l10n.glDisplayName, + "gnDisplayName": l10n.gnDisplayName, + "gomDisplayName": l10n.gomDisplayName, + "guDisplayName": l10n.guDisplayName, + "haDisplayName": l10n.haDisplayName, + "hawDisplayName": l10n.hawDisplayName, + "heDisplayName": l10n.heDisplayName, + "hiDisplayName": l10n.hiDisplayName, + "hilDisplayName": l10n.hilDisplayName, + "hmnDisplayName": l10n.hmnDisplayName, + "hneDisplayName": l10n.hneDisplayName, + "hrDisplayName": l10n.hrDisplayName, + "hrxDisplayName": l10n.hrxDisplayName, + "htDisplayName": l10n.htDisplayName, + "huDisplayName": l10n.huDisplayName, + "hyDisplayName": l10n.hyDisplayName, + "idDisplayName": l10n.idDisplayName, + "igDisplayName": l10n.igDisplayName, + "iloDisplayName": l10n.iloDisplayName, + "isDisplayName": l10n.isDisplayName, + "itDisplayName": l10n.itDisplayName, + "jaDisplayName": l10n.jaDisplayName, + "jvDisplayName": l10n.jvDisplayName, + "kaDisplayName": l10n.kaDisplayName, + "kkDisplayName": l10n.kkDisplayName, + "kmDisplayName": l10n.kmDisplayName, + "knDisplayName": l10n.knDisplayName, + "koDisplayName": l10n.koDisplayName, + "kokDisplayName": l10n.kokDisplayName, + "kriDisplayName": l10n.kriDisplayName, + "ksDisplayName": l10n.ksDisplayName, + "ktuDisplayName": l10n.ktuDisplayName, + "kuDisplayName": l10n.kuDisplayName, + "kyDisplayName": l10n.kyDisplayName, + "laDisplayName": l10n.laDisplayName, + "lbDisplayName": l10n.lbDisplayName, + "lgDisplayName": l10n.lgDisplayName, + "liDisplayName": l10n.liDisplayName, + "lijDisplayName": l10n.lijDisplayName, + "lmoDisplayName": l10n.lmoDisplayName, + "lnDisplayName": l10n.lnDisplayName, + "loDisplayName": l10n.loDisplayName, + "ltDisplayName": l10n.ltDisplayName, + "ltgDisplayName": l10n.ltgDisplayName, + "luoDisplayName": l10n.luoDisplayName, + "lusDisplayName": l10n.lusDisplayName, + "lvDisplayName": l10n.lvDisplayName, + "maiDisplayName": l10n.maiDisplayName, + "makDisplayName": l10n.makDisplayName, + "mgDisplayName": l10n.mgDisplayName, + "miDisplayName": l10n.miDisplayName, + "minDisplayName": l10n.minDisplayName, + "mkDisplayName": l10n.mkDisplayName, + "mlDisplayName": l10n.mlDisplayName, + "mnDisplayName": l10n.mnDisplayName, + "mniDisplayName": l10n.mniDisplayName, + "mrDisplayName": l10n.mrDisplayName, + "msDisplayName": l10n.msDisplayName, + "msArabDisplayName": l10n.msArabDisplayName, + "msMYDisplayName": l10n.msMYDisplayName, + "mtDisplayName": l10n.mtDisplayName, + "mwrDisplayName": l10n.mwrDisplayName, + "myDisplayName": l10n.myDisplayName, + "nanDisplayName": l10n.nanDisplayName, + "nbDisplayName": l10n.nbDisplayName, + "neDisplayName": l10n.neDisplayName, + "newDisplayName": l10n.newDisplayName, + "nlDisplayName": l10n.nlDisplayName, + "nlBEDisplayName": l10n.nlBEDisplayName, + "noDisplayName": l10n.noDisplayName, + "nrDisplayName": l10n.nrDisplayName, + "nsoDisplayName": l10n.nsoDisplayName, + "nusDisplayName": l10n.nusDisplayName, + "nyDisplayName": l10n.nyDisplayName, + "ocDisplayName": l10n.ocDisplayName, + "omDisplayName": l10n.omDisplayName, + "orDisplayName": l10n.orDisplayName, + "paDisplayName": l10n.paDisplayName, + "paArabDisplayName": l10n.paArabDisplayName, + "paINDisplayName": l10n.paINDisplayName, + "pagDisplayName": l10n.pagDisplayName, + "pamDisplayName": l10n.pamDisplayName, + "papDisplayName": l10n.papDisplayName, + "plDisplayName": l10n.plDisplayName, + "psDisplayName": l10n.psDisplayName, + "ptDisplayName": l10n.ptDisplayName, + "ptBRDisplayName": l10n.ptBRDisplayName, + "ptPTDisplayName": l10n.ptPTDisplayName, + "quDisplayName": l10n.quDisplayName, + "rajDisplayName": l10n.rajDisplayName, + "rnDisplayName": l10n.rnDisplayName, + "roDisplayName": l10n.roDisplayName, + "roMDDisplayName": l10n.roMDDisplayName, + "romDisplayName": l10n.romDisplayName, + "ruDisplayName": l10n.ruDisplayName, + "rwDisplayName": l10n.rwDisplayName, + "saDisplayName": l10n.saDisplayName, + "satDisplayName": l10n.satDisplayName, + "scnDisplayName": l10n.scnDisplayName, + "sdDisplayName": l10n.sdDisplayName, + "sgDisplayName": l10n.sgDisplayName, + "shnDisplayName": l10n.shnDisplayName, + "siDisplayName": l10n.siDisplayName, + "skDisplayName": l10n.skDisplayName, + "slDisplayName": l10n.slDisplayName, + "smDisplayName": l10n.smDisplayName, + "snDisplayName": l10n.snDisplayName, + "soDisplayName": l10n.soDisplayName, + "sqDisplayName": l10n.sqDisplayName, + "srDisplayName": l10n.srDisplayName, + "srMEDisplayName": l10n.srMEDisplayName, + "ssDisplayName": l10n.ssDisplayName, + "stDisplayName": l10n.stDisplayName, + "suDisplayName": l10n.suDisplayName, + "svDisplayName": l10n.svDisplayName, + "swDisplayName": l10n.swDisplayName, + "szlDisplayName": l10n.szlDisplayName, + "taDisplayName": l10n.taDisplayName, + "teDisplayName": l10n.teDisplayName, + "tetDisplayName": l10n.tetDisplayName, + "tgDisplayName": l10n.tgDisplayName, + "thDisplayName": l10n.thDisplayName, + "tiDisplayName": l10n.tiDisplayName, + "tkDisplayName": l10n.tkDisplayName, + "tlDisplayName": l10n.tlDisplayName, + "tnDisplayName": l10n.tnDisplayName, + "trDisplayName": l10n.trDisplayName, + "tsDisplayName": l10n.tsDisplayName, + "ttDisplayName": l10n.ttDisplayName, + "ugDisplayName": l10n.ugDisplayName, + "ukDisplayName": l10n.ukDisplayName, + "urDisplayName": l10n.urDisplayName, + "urINDisplayName": l10n.urINDisplayName, + "urPKDisplayName": l10n.urPKDisplayName, + "uzDisplayName": l10n.uzDisplayName, + "viDisplayName": l10n.viDisplayName, + "wuuDisplayName": l10n.wuuDisplayName, + "xhDisplayName": l10n.xhDisplayName, + "yiDisplayName": l10n.yiDisplayName, + "yoDisplayName": l10n.yoDisplayName, + "yuaDisplayName": l10n.yuaDisplayName, + "yueDisplayName": l10n.yueDisplayName, + "yueCNDisplayName": l10n.yueCNDisplayName, + "yueHKDisplayName": l10n.yueHKDisplayName, + "zhDisplayName": l10n.zhDisplayName, + "zhCNDisplayName": l10n.zhCNDisplayName, + "zhTWDisplayName": l10n.zhTWDisplayName, + "zuDisplayName": l10n.zuDisplayName, + }; + + return displayNameMap[langKey] ?? displayName; } String get langCodeShort => langCode.split('-').first; diff --git a/lib/pangea/learning_settings/widgets/p_language_dropdown.dart b/lib/pangea/learning_settings/widgets/p_language_dropdown.dart index d1fca14bb..d78423898 100644 --- a/lib/pangea/learning_settings/widgets/p_language_dropdown.dart +++ b/lib/pangea/learning_settings/widgets/p_language_dropdown.dart @@ -63,7 +63,7 @@ class PLanguageDropdownState extends State { final bool aIsPriority = languagePriority.contains(a.langCode); final bool bIsPriority = languagePriority.contains(b.langCode); if (!aIsPriority && !bIsPriority) { - return a.getDisplayName(context)!.compareTo(b.getDisplayName(context)!); + return a.getDisplayName(context).compareTo(b.getDisplayName(context)); } if (aIsPriority && bIsPriority) { @@ -159,7 +159,8 @@ class PLanguageDropdownState extends State { ), ), searchMatchFn: (item, searchValue) { - final displayName = item.value?.displayName.toLowerCase(); + final displayName = + item.value?.getDisplayName(context).toLowerCase(); if (displayName == null) return false; final search = searchValue.toLowerCase(); @@ -222,7 +223,7 @@ class LanguageDropDownEntry extends StatelessWidget { children: [ Flexible( child: Text( - languageModel.getDisplayName(context) ?? "", + languageModel.getDisplayName(context), style: const TextStyle().copyWith( color: enabled ? Theme.of(context).textTheme.bodyLarge!.color diff --git a/lib/pangea/login/pages/language_selection_page.dart b/lib/pangea/login/pages/language_selection_page.dart index cda53fd87..5fba78707 100644 --- a/lib/pangea/login/pages/language_selection_page.dart +++ b/lib/pangea/login/pages/language_selection_page.dart @@ -144,7 +144,8 @@ class LanguageSelectionPageState extends State { alignment: WrapAlignment.center, children: languages .where( - (l) => l.displayName + (l) => l + .getDisplayName(context) .toLowerCase() .contains( _searchController.text @@ -163,8 +164,7 @@ class LanguageSelectionPageState extends State { vertical: 4.0, ), label: Text( - l.getDisplayName(context) ?? - l.displayName, + l.getDisplayName(context), style: theme.textTheme.bodyMedium, ), onSelected: (selected) { diff --git a/lib/pangea/space_analytics/space_analytics.dart b/lib/pangea/space_analytics/space_analytics.dart index c662d3c38..105036a1a 100644 --- a/lib/pangea/space_analytics/space_analytics.dart +++ b/lib/pangea/space_analytics/space_analytics.dart @@ -154,8 +154,7 @@ class SpaceAnalyticsState extends State { List get availableLanguages => _langsToUsers.keys.toList() ..sort( - (a, b) => (a.getDisplayName(context) ?? a.displayName) - .compareTo(b.getDisplayName(context) ?? b.displayName), + (a, b) => a.getDisplayName(context).compareTo(b.getDisplayName(context)), ); int get completedDownloads => diff --git a/lib/pangea/space_analytics/space_analytics_view.dart b/lib/pangea/space_analytics/space_analytics_view.dart index afd58d848..33f34f17d 100644 --- a/lib/pangea/space_analytics/space_analytics_view.dart +++ b/lib/pangea/space_analytics/space_analytics_view.dart @@ -109,9 +109,7 @@ class SpaceAnalyticsView extends StatelessWidget { ? controller.selectedLanguage!.langCode .toUpperCase() : controller.selectedLanguage! - .getDisplayName(context) ?? - controller - .selectedLanguage!.displayName, + .getDisplayName(context), style: TextStyle( color: theme.colorScheme.onPrimaryContainer, @@ -132,8 +130,7 @@ class SpaceAnalyticsView extends StatelessWidget { (item) => DropdownMenuItem( value: item, child: DropdownTextButton( - text: item.getDisplayName(context) ?? - item.displayName, + text: item.getDisplayName(context), isSelected: false, ), ),