Skip to content

Add pt-BR + localize redesigned views + locale parity guard (supersedes #76)#101

Open
edufalcao wants to merge 1 commit into
momenbasel:mainfrom
edufalcao:feature/localization-pt-br
Open

Add pt-BR + localize redesigned views + locale parity guard (supersedes #76)#101
edufalcao wants to merge 1 commit into
momenbasel:mainfrom
edufalcao:feature/localization-pt-br

Conversation

@edufalcao
Copy link
Copy Markdown

Summary

Supersedes #76. Rebased onto current main to pick up #70 (Arabic), #75 (FDA TCC), #80 (dashboard redesign + appearance toggle), and #83 (AI history). Retargets the localization work to the new view structure and brings every bundled locale to key parity, enforced by a new XCTest case.

Replaces #76 — the previous branch shared no history with current main and SmartScanView (which the old PR localized) has been deleted, so a fresh PR was clearer than continuing the closed thread. See #76's review comments for the full original context.

What's in this PR

New languages and infrastructure

  • Brazilian Portuguese (pt-BR) added alongside the existing en / es / ja / ar / zh-Hans / zh-Hant locales. Registered in knownRegions via xcodegen.
  • Settings → General → Language picker with System Default, English, Spanish, Japanese, Arabic, Portuguese (Brazil), Chinese (Simplified), Chinese (Traditional). Persists the choice to settings.general.appLanguage and toggles AppleLanguages (the macOS bundle-localization mechanism).
  • AppLanguage + AppLanguagePreferences extracted to PureMac/Models/AppLanguage.swift. apply(_:defaults:) only mutates AppleLanguages and never touches AppleLocale, so the user's locale-derived formatting (dates, numbers, currency) stays intact regardless of UI language choice.
  • Relaunch prompt + button after changing the language, because AppleLanguages is consumed on app startup. The relaunch uses /usr/bin/open -n so the relaunched instance picks up the new bundle.

View-level localization (retargeted to current main)

  • DashboardView (replaces the old SmartScanView): hero / scanning / completed / cleaning / cleaned states; StatCard, Suggestion, LegendDot, StorageGauge, ScanningGauge, CategoryToggleRow. Dynamic strings use String(format: String(localized: ...)) so locale-specific number formatting stays correct.
  • MainWindow: section labels (Overview / Applications / Cleanup), nav rows (Dashboard, Installed Apps, Orphaned Files), FDA toast, error alert, footer status, empty-state fallback.
  • CategoryDetailView: navigation title, toolbar buttons, sort labels, confirmation dialog, file-list header, and the new hero card.
  • AppListView / AppFilesView / OrphanListView: searchable prompts, navigation titles with counts, refresh / uninstall / remove flows, empty / loading states, context-menu actions, alert dialogs.
  • OnboardingView: intro / instructions / granted / diagnostics sub-views, including featureCard and stepRow helpers (now LocalizedStringKey-typed) and ProtectedPath labels.
  • SettingsView: tab labels, section titles, search-sensitivity options + descriptions, language picker, scheduling settings.
  • AppearancePill: .help(...) tooltip routed through LocalizedStringKey so the appearance segments are translated.

AppState test injection points

AppState's init now accepts performStartupTasks, locationsProvider, and appFileScanner so the scan-for-app-files path can be exercised by a unit test without touching the filesystem. appFileScanLocationCount / currentAppFileSearchLocationCount were added so the in-progress scan UI shows the location count instead of the placeholder discovered-files count.

Tests

  • LocalizationFilesTests — parses every PureMac/*.lproj/Localizable.strings and fails if any locale drifts from en. This is the guard the maintainer asked for; with the dashboard surface now localized, it also catches any future drift in the new strings.
  • AppLanguagePreferencesTests — verifies apply(.english, defaults:) sets AppleLanguages = ["en"] and apply(.system, defaults:) removes the override, both while preserving AppleLocale.
  • AppStateTests — verifies scanForAppFiles reports the location count while results are pending and then resolves to the sorted discovered files via the injected scanner.

Build infrastructure

  • project.yml now registers the PureMacTests target and a shared PureMac scheme that builds both targets and runs the tests, so xcodebuild test -scheme PureMac works from a clean checkout.
  • PureMac.xcodeproj/xcshareddata/xcschemes/PureMac.xcscheme checked in.

Locale key counts

en       227 keys
es       227 keys
ja       227 keys
ar       227 keys
pt-BR    227 keys
zh-Hans  227 keys
zh-Hant  227 keys

The zh-Hant drift from #76's review was resolved by rebuilding the file from the canonical en key set during this rebase.

Verification

plutil -lint PureMac/{en,es,ja,ar,pt-BR,zh-Hans,zh-Hant}.lproj/Localizable.strings
# → OK for every file

xcodebuild test -project PureMac.xcodeproj -scheme PureMac \
  -destination 'platform=macOS' \
  -only-testing:PureMacTests \
  CODE_SIGNING_ALLOWED=NO CODE_SIGN_IDENTITY=''
# → Executed 4 tests, with 0 failures
#   AppLanguagePreferencesTests: 2 / 2 passed
#   AppStateTests:               1 / 1 passed
#   LocalizationFilesTests:      1 / 1 passed

xcodebuild -project PureMac.xcodeproj -scheme PureMac \
  -configuration Debug -destination 'platform=macOS' build \
  CODE_SIGNING_ALLOWED=NO CODE_SIGN_IDENTITY=''
# → BUILD SUCCEEDED

Test plan

  • xcodegen generate (matches the committed .xcodeproj)
  • xcodebuild -scheme PureMac -configuration Debug build succeeds
  • xcodebuild test -scheme PureMac -only-testing:PureMacTests reports 4 tests, 0 failures
  • Launch the app, walk through onboarding in English to confirm no regression
  • Open Settings → General → Language, switch to Portuguese (Brazil), relaunch via the button, and spot-check that:
    • Sidebar reads Visão geral / Aplicativos / Limpeza
    • Dashboard hero reads Armazenamento / livres de %@
    • Switching to Sistema (padrão) after relaunch falls back to the system language
  • Spot-check ar for RTL safety: section headers and toolbar buttons should mirror correctly under the new dashboard
  • Run a smart scan and a category clean to confirm no localized string references a missing key (would surface as the English fallback)

AI Assistance Disclosure

This PR was prepared with Claude Code (Anthropic) under human direction. The maintainer's review comment on #76 was the spec; the human reviewed and approved the rebase scope, the choice to retarget rather than reapply, and the final translations before publication.

🤖 Generated with Claude Code

…y guard

Rebases PR momenbasel#76 onto upstream/main (post momenbasel#70 Arabic, momenbasel#75 FDA TCC, momenbasel#80
dashboard redesign, momenbasel#83 AI history). Adds pt-BR alongside the existing
locales and brings every bundled locale (en/es/ja/ar/pt-BR/zh-Hans/
zh-Hant) to key parity, then enforces that parity in CI via a new
XCTest case.

UI changes
- Localize the full user-facing surface across the redesigned views
  (DashboardView replacing SmartScanView; MainWindow's Overview/
  Applications/Cleanup sidebar; CategoryDetailView's hero card;
  AppListView/AppFilesView/OrphanListView; the new OnboardingView
  flow; AppearancePill; SettingsView tabs).
- Wrap dynamic strings with String(format: String(localized: ...))
  so locale-specific number/format substitutions stay correct.
- Add a Settings > General Language picker covering System Default
  plus every bundled language, with a relaunch prompt because
  AppleLanguages is consumed at app startup.

Infrastructure
- Extract AppLanguage + AppLanguagePreferences into Models/.
  AppLanguagePreferences.apply only touches AppleLanguages and
  preserves AppleLocale.
- Wire AppState with injection points (performStartupTasks,
  locationsProvider, appFileScanner) so the scan-for-app-files path
  is exercised by a unit test without touching the real filesystem,
  and expose appFileScanLocationCount /
  currentAppFileSearchLocationCount so the in-progress scan UI
  shows the location count instead of the placeholder discovered-files
  count.

Tests
- LocalizationFilesTests: parses every PureMac/*.lproj/
  Localizable.strings and fails if any locale drifts from en.
- AppLanguagePreferencesTests: verify apply(.english) and
  apply(.system) modify only AppleLanguages.
- AppStateTests: verifies scanForAppFiles publishes the location
  count while results are pending, then resolves to the sorted
  discovered files.

Build
- project.yml registers PureMacTests and a shared scheme so
  `xcodebuild test` works from a clean checkout. xcodeproj
  regenerated via xcodegen.

Verification
- plutil -lint OK for all 7 .strings files (227 keys each).
- xcodebuild test -only-testing:PureMacTests: 4 tests, 0 failures.
- xcodebuild build -configuration Debug: SUCCEEDED.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant