diff --git a/flutter/lib/web/bridge.dart b/flutter/lib/web/bridge.dart index 087d300c1..6c2c23f57 100644 --- a/flutter/lib/web/bridge.dart +++ b/flutter/lib/web/bridge.dart @@ -901,7 +901,11 @@ class RustdeskImpl { } String mainGetLocalOption({required String key, dynamic hint}) { - return js.context.callMethod('getByName', ['option:local', key]); + final v = js.context.callMethod('getByName', ['option:local', key]); + if (key == 'lang' && (v == 'pt' || v == 'br')) { + return 'pt-br'; + } + return v; } // Do not return the real environment variables. diff --git a/src/common.rs b/src/common.rs index 23aa489a5..c98627187 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1197,6 +1197,9 @@ pub fn get_local_option(key: &str) -> String { } } } + if key == "lang" && (v == "pt" || v == "br") { + return "pt-br".to_owned(); + } v } diff --git a/src/lang.rs b/src/lang.rs index 27adcc1a5..8045dcb60 100644 --- a/src/lang.rs +++ b/src/lang.rs @@ -34,6 +34,7 @@ mod nb; mod nl; mod pl; mod ptbr; +mod pt_PT; mod ro; mod ru; mod sc; @@ -63,7 +64,8 @@ pub const LANGS: &[(&str, &str)] = &[ ("nb", "Norsk bokmål"), ("zh-cn", "简体中文"), ("zh-tw", "繁體中文"), - ("pt", "Português"), + ("pt-pt", "Português (Portugal)"), + ("pt-br", "Português (Brasil)"), ("es", "Español"), ("et", "Eesti keel"), ("eu", "Euskara"), @@ -143,6 +145,21 @@ fn resolve_lang(saved_lang: &str, locale: &str, cjk_fallback: bool) -> String { .to_owned(); } } + if lang.is_empty() { + // pt_PT on Linux, pt-PT on mac, pt_PT on Android. + // Per CLDR locale inheritance, every Portuguese-speaking locale + // besides bare "pt" and Brazil's own variants (pt-BR/pt_BR) has + // pt-PT as its parent (Angola, Mozambique, Cape Verde, etc.), + // so it should resolve to European Portuguese. + if locale.starts_with("pt") { + lang = (if locale == "pt" || locale.starts_with("pt-br") || locale.starts_with("pt_br") { + "pt-br" + } else { + "pt-pt" + }) + .to_owned(); + } + } if lang.is_empty() { lang = locale .split("-") @@ -187,6 +204,8 @@ pub fn translate_locale(name: String, locale: &str) -> String { "id" => id::T.deref(), "br" => ptbr::T.deref(), "pt" => ptbr::T.deref(), + "pt-br" => ptbr::T.deref(), + "pt-pt" => pt_PT::T.deref(), "tr" => tr::T.deref(), "cs" => cs::T.deref(), "da" => da::T.deref(), @@ -344,4 +363,24 @@ mod test { assert_eq!(f("", "zh_TW", false), "zh-tw"); assert_eq!(f("", "ja-JP", false), "ja"); } + + #[test] + fn test_resolve_lang_detects_pt_pt_and_pt_br_from_locale() { + use super::resolve_lang as f; + + assert_eq!(f("", "pt-PT", false), "pt-pt"); + assert_eq!(f("", "pt_PT", false), "pt-pt"); + assert_eq!(f("", "pt-BR", false), "pt-br"); + assert_eq!(f("", "pt_BR", false), "pt-br"); + assert_eq!(f("", "pt-AO", false), "pt-pt"); + assert_eq!(f("", "pt-MZ", false), "pt-pt"); + } + + #[test] + fn test_resolve_lang_saved_lang_takes_precedence_over_locale() { + use super::resolve_lang as f; + + assert_eq!(f("pt-br", "pt-PT", false), "pt-br"); + assert_eq!(f("pt-pt", "pt-BR", false), "pt-pt"); + } }