Repository navigation
feat: add Brazilian Portuguese (pt) UI language - #215
Merged
chattymin merged 5 commits intoAug 23, 2026
Merged
Conversation
Add Portuguese as a fifth UI language, following the Spanish PR (chattymin#159) and the French PR (chattymin#185) as the template. - AppLanguage gains a .pt case (native label "Português"), and systemDefault maps the pt system locale to it. - L.t(...) is extended to five languages; every UI string in Localization.swift is translated to Brazilian Portuguese, using the informal "você" register to match the app's playful companion tone. - PokemonNature.name(_:) gains 25 Portuguese names. Unlike ko/en/ja/es these are NOT official: the core series has never shipped a Portuguese localisation, so there is no official set to copy. They are adjectives agreeing with the feminine "natureza", picked so all 25 stay distinct. - Pokémon species names deliberately stay English: PokéAPI has no `pt` language, and Brazilian players use the English names anyway (no localised core games), so AppLanguage.resolveName's English fallback is the expected result rather than a gap. "pt" is still listed in apiCodes/langCodes so the day PokéAPI adds it, it is picked up with no branch changes. - Alert copy (notifBody + every window label it embeds) is kept no longer than the Spanish equivalent so it keeps fitting the floating-pet speech bubble guarded by PerformanceTests. - Add LocalizationInterpolationTests: a parity guard asserting every language keeps its \(...) placeholders, since the compiler only enforces t(...)'s argument count, not that a translation kept its interpolations. chattymin#185 proposes an equivalent guard — whichever lands first, the other copy can be dropped. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SMZ2PCf9Fby5HVjZUtzEsk
Two native pt-BR reviews (franchise terminology + macOS UI copy) against the
EN source and the accepted ES translation. No ko/en/ja/es string is touched.
Franchise terminology, corrected against official pt-BR sources:
- Bag: "Mochila" -> "Bolsa". Niantic's pt-BR help centre calls the item
inventory "Bolsa"; "Mochila" has no franchise precedent. ES already used the
official term and pt had drifted from it for no reason.
- hatch: "eclodir" -> "chocar" (Niantic pt-BR: "Incubadoras e chocar Ovos de
Pokémon"). "Eclodir" is correct Portuguese but is a calque of the Spanish
"eclosionar" and is not what Brazilian players say. "Incubando" stays --
"Incubadora" is the official term.
- Natures: 7 of 25 replaced. Three were meaning errors -- notably lonely
"Solitária", which in pt-BR means preferring to be alone, the opposite of
さみしがり; it is now "Carente". The others trade bookish or low-frequency
words for the register the rest of the app uses.
- "Shiny" is kept untranslated as a deliberate choice: Pokémon GO pt-BR does
have an official "Brilhante", but "shiny" is what the Brazilian community
says, and this app's audience is Brazilian developers. Flagging it because a
reviewer will reasonably compare it against the ES decision to adopt the
official "Variocolor".
UI copy fixes:
- Four sentences did not say what the English said, or were ungrammatical:
shinyCharm's description had a transitive verb with no object, useNeedsPokemon
inverted what the item is used on, limitRefreshReauthNeeded was not idiomatic,
and notifCandyBody put a noun phrase in an English-style pre-nominal slot that
breaks in Portuguese ("limite de tokens Sessão de 5 horas do Claude").
- "Atualizar" covered both refresh and update, which sit next to each other in
the popover; updateButton is now "Instalar". checkNowButton is "Buscar agora"
to match the "Buscar atualizações" label beside it.
- macOS pt-BR conventions: quit -> "Encerrar", launchAtLogin -> "Abrir ao
iniciar sessão", statusFocus -> "modo foco" (the system feature's name).
- dexRaising "Criando" was ambiguous (raise vs. create) in an 8pt uppercase
badge -> "Treinando".
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SMZ2PCf9Fby5HVjZUtzEsk
Every comment this branch introduces now carries an English block followed by the Korean one. The repository's code comments are Korean, but CONTRIBUTING and CLAUDE.md put English first for anything a contributor reads, and these three spots explain non-obvious decisions an outside reviewer has to follow: why AppLanguage.pt maps to a PokéAPI code that does not exist yet, why the pt nature column is not official like the other four, and why "pt" is listed in PokeAPIClient.langCodes despite collecting nothing today. Assertion messages in the new test are English rather than bilingual — they are read from CI output, not from the source. No behaviour change; the test still runs the same 44 assertions. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SMZ2PCf9Fby5HVjZUtzEsk
main added six UI strings in Localization.swift while this branch changed `t(...)` from four arguments to five, so every call site conflicted. Resolved mechanically rather than by hand: the pt column was re-applied to main's file by matching each call's (ko, en, ja, es) tuple, not by line number, so none of main's edits could be dropped by a stale offset. Verified by stripping the fifth argument back off the resolved file and diffing against `upstream/main` — byte-identical. The six new strings were then translated: `limitsAccount`, `customScanProviderLabel`, `customScanRootsLabel`, `customScanRootsHint`, `customScanRootsPlaceholder`, `customScanRootsMatches`. Two of them interpolate, so `LocalizationInterpolationTests` was extended to cover `limitsAccount` and `customScanRootsMatches` — otherwise the guard would have silently stopped short of the newest strings, which is the exact failure mode it exists to prevent. Interpolation parity across all five languages re-verified after the merge. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SMZ2PCf9Fby5HVjZUtzEsk
Localization gained a French column upstream while this branch was open, so every t() call needed a sixth argument rather than a fifth. Rebuilt the file from main and appended the Portuguese column, keeping the other five verbatim; the same for the 25 nature name tuples. Verified mechanically: 221 calls, all six arguments, the first five byte-identical to main, the Portuguese identical to this branch. The two Antigravity limit-group strings that landed after this branch last took upstream had no Portuguese yet — added as Modelos Gemini and Modelos Claude e GPT. Kept this branch's LocalizationInterpolationTests, which covers the same ground as main's and adds a case proving the placeholder guard fails when a translation drops one.
Owner
|
Thank you for your contribution! |
chattymin
added a commit
that referenced
this pull request
Aug 23, 2026
Brazilian Portuguese shipped in #215 but the card still listed five languages. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
LuceteYang
added a commit
to LuceteYang/PikaTokenBar
that referenced
this pull request
Aug 24, 2026
Resolve the Localization.swift conflict: main widened `t()` to six languages (adding fr/pt in chattymin#215), while this branch added the five animation-quality keys with the old four-argument form. Keep main's six-argument signature and supply fr/pt translations for every animation key (Animation / Animação, Économie d'énergie / Economia de bateria, Équilibré / Equilibrado, Fluide / Fluido, and the battery hint).
LeeTaek
added a commit
to LeeTaek/PokeTokenBar
that referenced
this pull request
Aug 24, 2026
Resolves conflicts with three changes that landed after this branch was cut. **French (chattymin#185) and Brazilian Portuguese (chattymin#215) UI languages.** `L.t(...)` now takes six arguments, so every Pokédex-entry string here gains `fr` and `pt` values. `AppLanguage.apiCodes` keeps the new `.fr`/`.pt` cases and applies this branch's lowercase `ja-hrkt` fix to `.ja`. `PokeAPIClient.langCodes` keeps the "union of apiCodes" invariant that chattymin#215 documented — the dead `"ja-Hrkt"` entry is corrected in place rather than dropped, so the lockstep rule still holds. **Representative Pokémon (chattymin#158)** was built on the cell-selection model this branch removes: a tap selected a cell and the footer offered a pin action. With taps now opening the detail view there is no selection to hang it on, so the action moves to the detail header, next to the shiny toggle — a species-level action on the species screen. That also frees the 332pt footer row, which `RepresentativeToggleLayoutTests` documents as too tight for the pin action plus species text in longer locales. The cell keeps the representative accent background (state, not action); the selection highlight is gone with selection itself. `RepresentativeFooterButton` is renamed to `RepresentativeToggleButton` since it no longer lives in a footer. **Swift 6.3 SwiftUI isolation guard (chattymin#216).** The new views here get explicit `@MainActor`. `FlavorCacheKey` is split across lines because the guard matches `": App"` as a substring and a one-line `let language: AppLanguage` tripped it. Portuguese also motivated a behavior change agreed for this branch: PokéAPI has no `pt` language at all, so a language whose entry list comes back completely empty now falls back to English with an on-screen notice. Per-version gaps still drop out silently — only a wholly empty language falls back, and English itself never does.
7 of 10 tasks
lukemonaghan
pushed a commit
to lukemonaghan/PokeTokenBar
that referenced
this pull request
Aug 24, 2026
* feat: add Brazilian Portuguese (pt) UI language Add Portuguese as a fifth UI language, following the Spanish PR (chattymin#159) and the French PR (chattymin#185) as the template. - AppLanguage gains a .pt case (native label "Português"), and systemDefault maps the pt system locale to it. - L.t(...) is extended to five languages; every UI string in Localization.swift is translated to Brazilian Portuguese, using the informal "você" register to match the app's playful companion tone. - PokemonNature.name(_:) gains 25 Portuguese names. Unlike ko/en/ja/es these are NOT official: the core series has never shipped a Portuguese localisation, so there is no official set to copy. They are adjectives agreeing with the feminine "natureza", picked so all 25 stay distinct. - Pokémon species names deliberately stay English: PokéAPI has no `pt` language, and Brazilian players use the English names anyway (no localised core games), so AppLanguage.resolveName's English fallback is the expected result rather than a gap. "pt" is still listed in apiCodes/langCodes so the day PokéAPI adds it, it is picked up with no branch changes. - Alert copy (notifBody + every window label it embeds) is kept no longer than the Spanish equivalent so it keeps fitting the floating-pet speech bubble guarded by PerformanceTests. - Add LocalizationInterpolationTests: a parity guard asserting every language keeps its \(...) placeholders, since the compiler only enforces t(...)'s argument count, not that a translation kept its interpolations. chattymin#185 proposes an equivalent guard — whichever lands first, the other copy can be dropped. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SMZ2PCf9Fby5HVjZUtzEsk * fix(pt): apply native-reviewer feedback on the Portuguese copy Two native pt-BR reviews (franchise terminology + macOS UI copy) against the EN source and the accepted ES translation. No ko/en/ja/es string is touched. Franchise terminology, corrected against official pt-BR sources: - Bag: "Mochila" -> "Bolsa". Niantic's pt-BR help centre calls the item inventory "Bolsa"; "Mochila" has no franchise precedent. ES already used the official term and pt had drifted from it for no reason. - hatch: "eclodir" -> "chocar" (Niantic pt-BR: "Incubadoras e chocar Ovos de Pokémon"). "Eclodir" is correct Portuguese but is a calque of the Spanish "eclosionar" and is not what Brazilian players say. "Incubando" stays -- "Incubadora" is the official term. - Natures: 7 of 25 replaced. Three were meaning errors -- notably lonely "Solitária", which in pt-BR means preferring to be alone, the opposite of さみしがり; it is now "Carente". The others trade bookish or low-frequency words for the register the rest of the app uses. - "Shiny" is kept untranslated as a deliberate choice: Pokémon GO pt-BR does have an official "Brilhante", but "shiny" is what the Brazilian community says, and this app's audience is Brazilian developers. Flagging it because a reviewer will reasonably compare it against the ES decision to adopt the official "Variocolor". UI copy fixes: - Four sentences did not say what the English said, or were ungrammatical: shinyCharm's description had a transitive verb with no object, useNeedsPokemon inverted what the item is used on, limitRefreshReauthNeeded was not idiomatic, and notifCandyBody put a noun phrase in an English-style pre-nominal slot that breaks in Portuguese ("limite de tokens Sessão de 5 horas do Claude"). - "Atualizar" covered both refresh and update, which sit next to each other in the popover; updateButton is now "Instalar". checkNowButton is "Buscar agora" to match the "Buscar atualizações" label beside it. - macOS pt-BR conventions: quit -> "Encerrar", launchAtLogin -> "Abrir ao iniciar sessão", statusFocus -> "modo foco" (the system feature's name). - dexRaising "Criando" was ambiguous (raise vs. create) in an 8pt uppercase badge -> "Treinando". Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SMZ2PCf9Fby5HVjZUtzEsk * docs(pt): make the comments added by this branch bilingual Every comment this branch introduces now carries an English block followed by the Korean one. The repository's code comments are Korean, but CONTRIBUTING and CLAUDE.md put English first for anything a contributor reads, and these three spots explain non-obvious decisions an outside reviewer has to follow: why AppLanguage.pt maps to a PokéAPI code that does not exist yet, why the pt nature column is not official like the other four, and why "pt" is listed in PokeAPIClient.langCodes despite collecting nothing today. Assertion messages in the new test are English rather than bilingual — they are read from CI output, not from the source. No behaviour change; the test still runs the same 44 assertions. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SMZ2PCf9Fby5HVjZUtzEsk --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Patrick.Park <pdm001125@naver.com>
cte13
pushed a commit
to cte13/PokeTokenBar-iOS
that referenced
this pull request
Aug 25, 2026
Brings in upstream work since the last sync: - Brazilian Portuguese (pt) UI language (chattymin#215) — added pt strings to fork-only labels - Pi Agent usage tracking (chattymin#189) - Keep Antigravity automatic poll out of the Keychain (chattymin#221) - Route Antigravity session notice through the localization table (chattymin#222) - Docs for representative pin / Antigravity limits / scan folders (chattymin#223) - Release bump to v2.5.2 Conflicts resolved in Localization (added pt to fork-only OpenCode Go / phone / widget labels and re-added `monthly`) and defect-log.md (kept both new entries). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Aug 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Brazilian Portuguese (
pt) as a fifth UI language, following #159 (Spanish) and #185 (French) as templates.AppLanguagegains a.ptcase (native label "Português"), andsystemDefaultmaps theptsystem locale to it.L.t(...)is extended to five languages and all 212 UI strings inLocalization.swiftare translated, in the informal "você" register that matches the app's playful companion tone.PokemonNature.name(_:)gains 25 Portuguese names.LocalizationInterpolationTests, a parity guard asserting every language keeps its\(...)placeholders.Every
ko/en/ja/esstring is byte-for-byte unchanged: the new argument was appended mechanically and the result verified by stripping the fifth argument back off and diffing againstmain.Translation decisions worth a reviewer's attention
Pokémon species names deliberately stay English. PokéAPI has no
ptlanguage, and the core series has never shipped a Portuguese localisation, so Brazilian players use the English names anyway —AppLanguage.resolveName's English fallback is the expected result here, not a gap."pt"is still listed inapiCodes/langCodesso that if PokéAPI ever adds it, it is picked up with no branch changes.Nature names are not official, unlike the other four languages. With no Portuguese core-series localisation there is no official set to copy. They are adjectives agreeing with the feminine "natureza" (as the Spanish ones agree with "naturaleza"), picked so all 25 stay distinct.
"Shiny" is kept untranslated, on purpose. Pokémon GO's pt-BR does use an official "Brilhante", but "shiny" is overwhelmingly what the Brazilian community says and this app's audience is Brazilian developers. Flagging it explicitly because it diverges from the Spanish decision to adopt the official "Variocolor" — happy to switch the whole cluster (
Amuleto Brilhante,✨ Pokémon Brilhante!, …) if you prefer consistency withes.Elsewhere the translation does follow official pt-BR franchise terminology where it exists: "Bolsa" for Bag, "chocar" for hatch, "Incubadora"/"Incubando", "Doce Raro" for Rare Candy, "Estágio" for evolution stage, "companheiro" for companion, and the TCG's "Comum/Incomum/Raro".
Alert copy is length-bounded.
notifBodyand every window label it embeds are kept no longer than the Spanish equivalent, so the floating-pet speech bubble guard inPerformanceTestskeeps holding.Overlap with #185. That PR proposes an equivalent interpolation-parity guard under the same filename. Whichever lands first, the other copy can simply be dropped — the guard is not specific to either language.
Type of change
UI changes
No files under
Sources/PokeTokenBar/UI/are touched. The user-visible change is entirely driven byLocalization.swift:ptfalls back to English.ptsystem locale selects it on a fresh install. Selecting it renders every screen (popover, Pokédex, catch log, Bag, Shop, Settings, floating-pet bubbles, system notifications) in Brazilian Portuguese. Pokémon species names stay English, as described above.Checklist
swift buildandswift testpass locally