From 5a6d3f20730d52a441708cbc1e46c8f97aa21371 Mon Sep 17 00:00:00 2001 From: Marcelo Daniel Date: Thu, 24 Sep 2026 20:01:25 -0300 Subject: [PATCH 1/2] Add Brazilian Portuguese localization --- .../src-tauri/src/commands/locale_cmd.rs | 21 ++ .../credentials/ClaudeSwapAccountsSection.tsx | 1 + .../src/surfaces/settings/tabs/GeneralTab.tsx | 1 + apps/desktop-tauri/src/types/bridge.test.ts | 2 + apps/desktop-tauri/src/types/bridge.ts | 1 + rust/src/locale.rs | 2 + rust/src/locale/pt-BR.ftl | 260 ++++++++++++++++++ rust/src/locale/tests.rs | 24 ++ rust/src/settings/tests.rs | 26 +- rust/src/settings/types.rs | 13 + 10 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 rust/src/locale/pt-BR.ftl diff --git a/apps/desktop-tauri/src-tauri/src/commands/locale_cmd.rs b/apps/desktop-tauri/src-tauri/src/commands/locale_cmd.rs index a71224de8f..81c4d632e3 100644 --- a/apps/desktop-tauri/src-tauri/src/commands/locale_cmd.rs +++ b/apps/desktop-tauri/src-tauri/src/commands/locale_cmd.rs @@ -164,6 +164,17 @@ mod locale_tests { assert_eq!(bundle.entries.len(), locale::LocaleKey::ALL.len()); } + #[test] + fn locale_strings_roundtrip_brazilian_portuguese() { + let bundle = locale_strings_for(Language::PortugueseBrazil); + assert_eq!(bundle.language, "portuguesebrazil"); + assert_eq!( + bundle.entries.get("TabGeneral").map(String::as_str), + Some("Geral") + ); + assert_eq!(bundle.entries.len(), locale::LocaleKey::ALL.len()); + } + #[test] fn locale_strings_contains_every_variant() { let bundle = locale_strings_for(Language::English); @@ -190,6 +201,7 @@ mod locale_tests { "japanese", "korean", "spanish", + "portuguesebrazil", "russian", "turkish" ] @@ -203,6 +215,7 @@ mod locale_tests { "日本語", "한국어", "Español", + "Português (Brasil)", "Русский", "Türkçe" ] @@ -287,6 +300,14 @@ mod locale_tests { parse_locale_language("español"), Some(Language::Spanish) )); + assert!(matches!( + parse_locale_language("pt-BR"), + Some(Language::PortugueseBrazil) + )); + assert!(matches!( + parse_locale_language("Português (Brasil)"), + Some(Language::PortugueseBrazil) + )); assert!(matches!( parse_locale_language("tr-TR"), Some(Language::Turkish) diff --git a/apps/desktop-tauri/src/surfaces/settings/providers/sections/credentials/ClaudeSwapAccountsSection.tsx b/apps/desktop-tauri/src/surfaces/settings/providers/sections/credentials/ClaudeSwapAccountsSection.tsx index ef7509ad63..caa10309d8 100644 --- a/apps/desktop-tauri/src/surfaces/settings/providers/sections/credentials/ClaudeSwapAccountsSection.tsx +++ b/apps/desktop-tauri/src/surfaces/settings/providers/sections/credentials/ClaudeSwapAccountsSection.tsx @@ -82,6 +82,7 @@ function languageLocale(language: Language): string { japanese: "ja-JP", korean: "ko-KR", spanish: "es-MX", + portuguesebrazil: "pt-BR", russian: "ru-RU", turkish: "tr-TR", }[language]; diff --git a/apps/desktop-tauri/src/surfaces/settings/tabs/GeneralTab.tsx b/apps/desktop-tauri/src/surfaces/settings/tabs/GeneralTab.tsx index f2e700a5e3..1eb56408d9 100644 --- a/apps/desktop-tauri/src/surfaces/settings/tabs/GeneralTab.tsx +++ b/apps/desktop-tauri/src/surfaces/settings/tabs/GeneralTab.tsx @@ -23,6 +23,7 @@ const FALLBACK_LANGUAGE_OPTIONS: LanguageOption[] = [ { value: "japanese", display: "日本語" }, { value: "korean", display: "한국어" }, { value: "spanish", display: "Español" }, + { value: "portuguesebrazil", display: "Português (Brasil)" }, { value: "russian", display: "Русский" }, { value: "turkish", display: "Türkçe" }, ]; diff --git a/apps/desktop-tauri/src/types/bridge.test.ts b/apps/desktop-tauri/src/types/bridge.test.ts index 5075276d82..4fe851c9a9 100644 --- a/apps/desktop-tauri/src/types/bridge.test.ts +++ b/apps/desktop-tauri/src/types/bridge.test.ts @@ -15,7 +15,9 @@ describe("Language type", () => { const langRu: Language = "russian"; expect(langRu).toBe("russian"); const langTr: Language = "turkish"; + const langPtBr: Language = "portuguesebrazil"; expect(langTr).toBe("turkish"); + expect(langPtBr).toBe("portuguesebrazil"); }); it("allows 'spanish' in LocaleStrings payload", () => { diff --git a/apps/desktop-tauri/src/types/bridge.ts b/apps/desktop-tauri/src/types/bridge.ts index 88754baa7d..debb32bb7d 100644 --- a/apps/desktop-tauri/src/types/bridge.ts +++ b/apps/desktop-tauri/src/types/bridge.ts @@ -53,6 +53,7 @@ export type Language = | "japanese" | "korean" | "spanish" + | "portuguesebrazil" | "russian" | "turkish"; diff --git a/rust/src/locale.rs b/rust/src/locale.rs index e6ec918ac4..042f48df98 100644 --- a/rust/src/locale.rs +++ b/rust/src/locale.rs @@ -50,6 +50,7 @@ fn language_id(lang: Language) -> &'static LanguageIdentifier { static JA_JP: LazyLock = LazyLock::new(|| "ja-JP".parse().unwrap()); static KO_KR: LazyLock = LazyLock::new(|| "ko-KR".parse().unwrap()); static ES_MX: LazyLock = LazyLock::new(|| "es-MX".parse().unwrap()); + static PT_BR: LazyLock = LazyLock::new(|| "pt-BR".parse().unwrap()); static RU_RU: LazyLock = LazyLock::new(|| "ru-RU".parse().unwrap()); static TR_TR: LazyLock = LazyLock::new(|| "tr-TR".parse().unwrap()); @@ -60,6 +61,7 @@ fn language_id(lang: Language) -> &'static LanguageIdentifier { Language::Japanese => &JA_JP, Language::Korean => &KO_KR, Language::Spanish => &ES_MX, + Language::PortugueseBrazil => &PT_BR, Language::Russian => &RU_RU, Language::Turkish => &TR_TR, } diff --git a/rust/src/locale/pt-BR.ftl b/rust/src/locale/pt-BR.ftl new file mode 100644 index 0000000000..dc42392f06 --- /dev/null +++ b/rust/src/locale/pt-BR.ftl @@ -0,0 +1,260 @@ +TabGeneral = Geral +TabProviders = Provedores +TabNotifications = Notificações +TabMenuBar = Barra de menus +TabMenu = Menu +TabApiKeys = Chaves de API +TabCookies = Cookies +TabUsageSpend = Uso e gastos +TabAdvanced = Avançado +TabAbout = Sobre +TabShortcuts = Atalhos +InterfaceLanguage = Idioma da interface +StartupSettings = Sistema +StartAtLogin = Iniciar com o Windows +StartMinimized = Iniciar minimizado +StartAtLoginHelper = Entrar automaticamente após a inicialização do sistema +StartMinimizedHelper = Iniciar minimizado na bandeja do sistema +ShowNotificationsHelper = Alertar quando os limites de uso forem atingidos +SoundEnabledHelper = Reproduzir um som quando os limites forem atingidos +HighUsageThresholdHelper = Exibir um aviso neste nível de uso +CriticalUsageThresholdHelper = Exibir um alerta crítico neste nível +ShowNotifications = Mostrar notificações +SoundEnabled = Alertas sonoros +NotificationSoundTheme = Conjunto de sons padrão +NotificationSoundThemeHelper = Usado quando nenhum arquivo WAV personalizado está definido. +NotificationSoundThemeWindows = Sons do sistema Windows +NotificationSoundThemeCodexBar = Sons exclusivos do CodexBar +NotificationSoundChooseFile = Escolher WAV +NotificationSoundClearFile = Limpar +NotificationSoundUsesTheme = Usa o conjunto de sons selecionado +NotificationSoundWaveFile = Áudio WAV +NotificationSoundEventPredictiveWarning = Aviso preditivo de ritmo +NotificationSoundEventPredictiveWarningHelper = A cota pode acabar antes da renovação. +NotificationSoundEventHighUsage = Uso alto +NotificationSoundEventHighUsageHelper = O limite de uso alto foi atingido. +NotificationSoundEventCriticalUsage = Uso crítico +NotificationSoundEventCriticalUsageHelper = O limite de uso crítico foi atingido. +NotificationSoundEventExhausted = Uso esgotado +NotificationSoundEventExhaustedHelper = O uso atingiu 100%. +NotificationSoundEventStatusIssue = Problema de status do provedor +NotificationSoundEventStatusIssueHelper = Um provedor informou uma interrupção ou erro. +NotificationSoundEventSessionDepleted = Sessão esgotada +NotificationSoundEventSessionDepletedHelper = A cota de uma sessão atingiu 100%. +NotificationSoundEventSessionRestored = Sessão restaurada +NotificationSoundEventSessionRestoredHelper = Uma sessão esgotada voltou a ficar disponível. +HighUsageThreshold = Limite de uso alto +HighUsageAlert = Alerta de uso alto +CriticalUsageThreshold = Limite de uso crítico +CriticalUsageAlert = Alerta crítico +PredictivePaceWarnings = Avisos preditivos de ritmo +PredictivePaceWarningsHelper = Alertar quando o uso do Codex ou Claude puder acabar antes da renovação +PredictivePaceWarningTitle = Aviso de ritmo de { "{}" } { "{}" } +PredictivePaceWarningBody = A cota pode acabar em { "{}" } +UsageDisplay = Exibição de uso +ShowUsageAsUsed = Mostrar uso consumido +ShowUsageAsUsedHelper = Exibir o percentual usado em vez do restante +ResetTimeRelative = Horário de renovação relativo +ResetTimeRelativeHelper = Mostrar "2h 30min" em vez de "15:00" +ShowResetWhenExhausted = Mostrar renovação quando esgotado +ShowResetWhenExhaustedHelper = Substituir o percentual esgotado pela contagem regressiva da renovação +ShowPace = Mostrar ritmo +ShowPaceHelper = Mostrar ritmo de uso, orçamentos e previsões nos cartões dos provedores +TrayIcon = Ícone da bandeja +MergeTrayIcons = Unir ícones da bandeja +MergeTrayIconsHelper = Mostrar todos os provedores em um único ícone da bandeja +PerProviderTrayIcons = Ícones por provedor +PerProviderTrayIconsHelper = Mostrar um ícone separado para cada provedor ativado +ProviderEnabled = Ativado +ProviderDisabled = Desativado +ProviderInfo = Informações +ProviderUsage = Uso +PanelUsageDetails = Detalhes do uso +AuthType = Autenticação +DataSource = Fonte de dados +ProviderNotDetected = não detectado +ProviderLastFetchFailed = falha na última consulta +ProviderUsageNotFetchedYet = uso ainda não consultado +ProviderNotFetchedYetTitle = Ainda não consultado +ProviderDisabledNoRecentData = Desativado — sem dados recentes +ProviderSourceAutoShort = automático +ProviderSourceWebShort = web +ProviderSourceCliShort = cli +ProviderSourceOauthShort = oauth +ProviderSourceApiShort = api +ProviderSourceGithubApiShort = api do github +ProviderSourceLocalShort = local +ProviderSourceKiroEnvShort = ambiente kiro +WayfinderGatewayTitle = Gateway Wayfinder +WayfinderGatewayLabel = URL do gateway +WayfinderGatewayHelp = Use HTTP apenas para localhost ou endereços de loopback. HTTPS é permitido para hosts remotos. +WayfinderGatewayStatus = Gateway +WayfinderModels = Modelos +WayfinderRequests = Solicitações +WayfinderTokens = Tokens +WayfinderSaved = Salvo +WayfinderOffline = Gateway offline +WayfinderDryRun = Simulação +WayfinderMissingKeys = Chaves ausentes +TrackingItem = Item monitorado +MainWindowLiveUsageData = Dados de uso em tempo real na janela principal +StartTrackingUsage = Ative para começar a monitorar o uso +ClickTrayIconForMetrics = Clique no ícone da bandeja para ver as métricas ao vivo +BrowserCookieImport = Importação de cookies do navegador +ImportFromBrowser = Importar cookies de { "{}" } do navegador +NoCookiesFoundInBrowser = Nenhum cookie encontrado no { "{}" }. Entre na sua conta primeiro. +SelectBrowser = Selecione o navegador... +ImportCookies = Importar cookies +ImportSuccess = Cookies de { "{}" } importados +ImportFailed = Falha na importação: { "{}" } +SaveFailed = Falha ao salvar: { "{}" } +CookiesAutoImport = Os cookies são importados automaticamente do Chrome, Edge, Brave e Firefox +QuickActions = Ações rápidas +OpenProviderDashboard = Abrir painel do { "{}" } +OllamaNoDashboard = O Ollama é executado localmente e não possui painel +ApiKeysTitle = Chaves de API +ApiKeysDescription = Configure os tokens de acesso dos provedores que exigem autenticação. +AddKey = + Adicionar chave +KeySet = Definida +KeyRequired = Chave obrigatória +Remove = Remover +GetKey = Obter chave → +SavedCookies = Cookies salvos +AddManualCookie = Adicionar cookie manual +CookieHeader = Cabeçalho do cookie +PasteHere = Cole aqui... +DeleteCookie = Excluir +CookieSaved = Cookies de { "{}" } salvos +CookieDeleted = Cookies de { "{}" } excluídos +RefreshSettings = Atualização +Animations = Animações +MenuBar = Barra de menus +Fun = Diversão +GlobalShortcut = Atalho global +Privacy = Privacidade +Updates = Atualizações +UpdateChannel = Canal de atualização +UpdateChannelStable = Estável +UpdateChannelBeta = Beta +Never = Nunca +LastUpdated = Atualizado +NeverUpdated = Nunca atualizado +MinutesAgo = há { "{}" } minutos +HoursAgo = há { "{}" } horas +DaysAgo = há { "{}" } dias +BuiltWithRust = Criado com Rust + egui +OriginalMacOSVersion = Versão original para macOS +Links = Links +BuildInfo = Informações da compilação +EnabledProviders = Provedores ativados +Appearance = Aparência +ThemeSelection = Tema +LightMode = Claro +DarkMode = Escuro +AboutTitle = Sobre o CodexBar +Version = Versão +ActionRefreshAll = Atualizar tudo +ActionSettings = Configurações +ActionClose = ✕ +ProviderAccount = Conta +ProviderSession = Sessão +ProviderWeekly = Semanal +ProviderMonthly = 30 dias +ProviderModel = Modelo +ProviderPlan = Plano +ProviderNextReset = Próxima renovação +ProviderNoRecentUsage = Sem uso recente +ProviderNotSignedIn = Não conectado +SummaryTab = Resumo +StateLoadingProviders = Carregando provedores... +StateNoProviderData = Nenhum dado de provedor. +StateNoProviderSelected = Nenhum provedor selecionado. +StateSummaryRefreshPending = Atualizando após a conclusão de todas as consultas +StateError = Erro +StateRetry = Tentar novamente +StateDownload = Baixar +StateRestartAndUpdate = Reiniciar e atualizar +CreditsTitle = Créditos +UpdateRestartAndUpdate = Reiniciar e atualizar +UpdateRetry = Tentar novamente +UpdateDownload = Baixar +UpdateDownloading = Baixando +UpdateReady = Pronto para instalar +UpdateFailed = Falha na atualização +ButtonOpenProviderSettings = Abrir configurações do provedor +MenuSettings = Configurações... +MenuAbout = Sobre o CodexBar +MenuQuit = Sair +StatusJustUpdated = Atualizado agora +StatusUnableToGetUsage = Não foi possível obter o uso +ActionRefresh = Atualizar +ActionSwitchAccount = Trocar de conta... +ActionUsageDashboard = Painel de uso +ActionStatusPage = Página de status +ActionCopyError = Copiar erro +ActionBuyCredits = Comprar créditos... +PaceOnTrack = Dentro do ritmo +PaceBehind = Atrasado +MetricResetsIn = Renova em +SectionUsageBreakdown = Detalhamento do uso +SectionCost = Custo +ResetInProgress = Renovando... +TomorrowAt = Amanhã às { "{}" } +UsedPercent = { "{:.0}" }% usado +RemainingPercent = { "{:.0}" }% restante +RemainingAmount = { "{:.2}" } restante +Tokens1K = 1 mil tokens +TodayCost = Hoje: ${ "{:.2}" } +Last30DaysCost = Últimos 30 dias: ${ "{:.2}" } +StatusLabel = Status: { "{}" } +TrayOpenCodexBar = Abrir painel destacado +TrayPopOutDashboard = Abrir painel destacado +TrayShowWindow = Mostrar janela +TrayShowFloatBar = Mostrar barra flutuante +TrayRefreshAll = Atualizar tudo +TrayProviders = Provedores +TraySettings = Configurações... +TrayCheckForUpdates = Verificar atualizações +TrayQuit = Sair +TrayLoading = CodexBar - Carregando... +TrayNoProviders = CodexBar - Nenhum provedor disponível +TraySessionPercent = Sessão { "{}" }% +TrayWeeklyPercent = Semanal { "{}" }% +TrayStatusError = { " (Erro)" } +TrayStatusStale = { " (Dados desatualizados)" } +TrayStatusIncident = { " (Incidente)" } +TrayStatusPartial = { " (Interrupção parcial)" } +TrayWeeklyExhausted = Cota semanal esgotada +TrayCreditsRemaining = Créditos restantes { "{}" }% +TrayStatusRowLoading = Carregando... +TrayStatusRowError = Erro +TrayCreditsRow = Créditos { "{}" }% +TrayProviderPopOut = Abrir painel destacado +TrayProviderRefresh = Atualizar +TrayProviderSettings = Configurações... +TrayProviderQuit = Sair +State = Estado +Source = Fonte +Updated = Atualizado +UpdatedJustNow = Atualizado agora +UpdatedMinutesAgo = Atualizado há { "{}" } minutos +UpdatedHoursAgo = Atualizado há { "{}" } horas +UpdatedDaysAgo = Atualizado há { "{}" } dias +Status = Status +AllSystemsOperational = Todos os sistemas operacionais +Plan = Plano +Account = Conta +ProviderSessionLabel = Sessão +ProviderWeeklyLabel = Semanal +ClaudeScopedWeeklyLabel = Semanal de { "{}" } +ProviderCodeReviewLabel = Revisão de código +ResetsInShort = Renova em +ResetsInDaysHours = Renova em { "{}" }d { "{}" }h +ResetsInHoursMinutes = Renova em { "{}" }h { "{}" }min +ResetsInMinutes = Renova em { "{}" }min +NextExpiresInDaysHours = O próximo expira em { "{}" }d { "{}" }h +NextExpiresInHoursMinutes = O próximo expira em { "{}" }h { "{}" }min +NextExpiresInMinutes = O próximo expira em { "{}" }min +NextExpiresDueNow = Expira agora +InventoryAvailableCount = { "{}" } disponíveis +FloatBarShowCost = Mostrar custo local diff --git a/rust/src/locale/tests.rs b/rust/src/locale/tests.rs index 9daf93d809..576cb660b7 100644 --- a/rust/src/locale/tests.rs +++ b/rust/src/locale/tests.rs @@ -370,6 +370,10 @@ fn test_locale_respects_language_setting() { let lang = Language::Spanish; assert_eq!(get_text(lang, LocaleKey::TabAbout), "Acerca de"); + // Test that Brazilian Portuguese returns Portuguese strings + let lang = Language::PortugueseBrazil; + assert_eq!(get_text(lang, LocaleKey::TabAbout), "Sobre"); + // Test that Russian language returns Russian strings let lang = Language::Russian; assert_eq!(get_text(lang, LocaleKey::TabAbout), "О программе"); @@ -388,6 +392,7 @@ fn test_english_is_complete_and_other_languages_can_fallback() { ("ja-JP", include_str!("ja-JP.ftl")), ("ko-KR", include_str!("ko-KR.ftl")), ("es-MX", include_str!("es-MX.ftl")), + ("pt-BR", include_str!("pt-BR.ftl")), ("ru-RU", include_str!("ru-RU.ftl")), ("tr-TR", include_str!("tr-TR.ftl")), ]; @@ -447,6 +452,25 @@ fn test_fluent_preserves_literal_placeholders_and_status_spacing() { ); } +#[test] +fn test_brazilian_portuguese_preserves_placeholders_and_status_spacing() { + assert_eq!( + get_text(Language::PortugueseBrazil, LocaleKey::TrayStatusError), + " (Erro)" + ); + assert_eq!( + get_text( + Language::PortugueseBrazil, + LocaleKey::TrayCreditsRemaining + ), + "Créditos restantes {}%" + ); + assert_eq!( + get_text(Language::PortugueseBrazil, LocaleKey::UsedPercent), + "{:.0}% usado" + ); +} + fn resource_key_names(resource: &str) -> HashSet<&str> { resource .lines() diff --git a/rust/src/settings/tests.rs b/rust/src/settings/tests.rs index a6db4aa05b..6e7f99ee2a 100644 --- a/rust/src/settings/tests.rs +++ b/rust/src/settings/tests.rs @@ -684,13 +684,14 @@ fn test_language_defaults_to_english() { #[test] fn test_language_all_variants_available() { let languages = Language::all(); - assert_eq!(languages.len(), 8); + assert_eq!(languages.len(), 9); assert!(languages.contains(&Language::English)); assert!(languages.contains(&Language::Chinese)); assert!(languages.contains(&Language::ChineseTraditional)); assert!(languages.contains(&Language::Japanese)); assert!(languages.contains(&Language::Korean)); assert!(languages.contains(&Language::Spanish)); + assert!(languages.contains(&Language::PortugueseBrazil)); assert!(languages.contains(&Language::Russian)); assert!(languages.contains(&Language::Turkish)); } @@ -703,6 +704,29 @@ fn test_language_display_names() { assert_eq!(Language::Japanese.display_name(), "日本語"); assert_eq!(Language::Russian.display_name(), "Русский"); assert_eq!(Language::Turkish.display_name(), "Türkçe"); + assert_eq!( + Language::PortugueseBrazil.display_name(), + "Português (Brasil)" + ); +} + +#[test] +fn test_language_resolves_brazilian_portuguese_aliases() { + for alias in [ + "portuguesebrazil", + "pt", + "pt-BR", + "Portuguese", + "Português", + "portugues", + "Português (Brasil)", + ] { + assert_eq!( + Language::resolve(alias), + Some(Language::PortugueseBrazil), + "failed to resolve {alias}" + ); + } } #[test] diff --git a/rust/src/settings/types.rs b/rust/src/settings/types.rs index 6113969b15..fd1785600b 100644 --- a/rust/src/settings/types.rs +++ b/rust/src/settings/types.rs @@ -96,6 +96,8 @@ pub enum Language { Korean, /// Spanish (Mexican) Spanish, + /// Portuguese (Brazil) + PortugueseBrazil, /// Russian Russian, /// Turkish @@ -112,6 +114,7 @@ impl Language { Language::Japanese => "日本語", Language::Korean => "한국어", Language::Spanish => "Español", + Language::PortugueseBrazil => "Português (Brasil)", Language::Russian => "Русский", Language::Turkish => "Türkçe", } @@ -126,6 +129,7 @@ impl Language { Language::Japanese, Language::Korean, Language::Spanish, + Language::PortugueseBrazil, Language::Russian, Language::Turkish, ] @@ -141,6 +145,7 @@ impl Language { Language::Japanese => "japanese", Language::Korean => "korean", Language::Spanish => "spanish", + Language::PortugueseBrazil => "portuguesebrazil", Language::Russian => "russian", Language::Turkish => "turkish", } @@ -156,6 +161,14 @@ impl Language { Language::Japanese => &["ja", "ja-jp", "日本語"], Language::Korean => &["ko", "ko-kr", "한국어"], Language::Spanish => &["es", "es-mx", "español"], + Language::PortugueseBrazil => &[ + "pt", + "pt-br", + "portuguese", + "português", + "portugues", + "português (brasil)", + ], Language::Russian => &["ru", "ru-ru", "русский"], Language::Turkish => &["tr", "tr-tr", "türkçe", "turkce"], } From 4f0f08247e30a98e0e9f419f4877b439554c2154 Mon Sep 17 00:00:00 2001 From: Marcelo Daniel Date: Fri, 25 Sep 2026 08:33:16 -0300 Subject: [PATCH 2/2] Fix Brazilian Portuguese status copy --- rust/src/locale/pt-BR.ftl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/src/locale/pt-BR.ftl b/rust/src/locale/pt-BR.ftl index dc42392f06..6503d0dee9 100644 --- a/rust/src/locale/pt-BR.ftl +++ b/rust/src/locale/pt-BR.ftl @@ -13,7 +13,7 @@ InterfaceLanguage = Idioma da interface StartupSettings = Sistema StartAtLogin = Iniciar com o Windows StartMinimized = Iniciar minimizado -StartAtLoginHelper = Entrar automaticamente após a inicialização do sistema +StartAtLoginHelper = Iniciar o CodexBar automaticamente ao entrar no sistema StartMinimizedHelper = Iniciar minimizado na bandeja do sistema ShowNotificationsHelper = Alertar quando os limites de uso forem atingidos SoundEnabledHelper = Reproduzir um som quando os limites forem atingidos @@ -241,7 +241,7 @@ UpdatedMinutesAgo = Atualizado há { "{}" } minutos UpdatedHoursAgo = Atualizado há { "{}" } horas UpdatedDaysAgo = Atualizado há { "{}" } dias Status = Status -AllSystemsOperational = Todos os sistemas operacionais +AllSystemsOperational = Todos os sistemas estão operacionais Plan = Plano Account = Conta ProviderSessionLabel = Sessão