Skip to content

Add multilingual support across 58 locales#79

Open
TheKalpeshPawar wants to merge 26 commits into
openMF:developmentfrom
TheKalpeshPawar:translate-strings
Open

Add multilingual support across 58 locales#79
TheKalpeshPawar wants to merge 26 commits into
openMF:developmentfrom
TheKalpeshPawar:translate-strings

Conversation

@TheKalpeshPawar
Copy link
Copy Markdown
Collaborator

@TheKalpeshPawar TheKalpeshPawar commented May 3, 2026

#78

Summary

Comprehensive localization pass across mifos-authenticator-passcode and cmp-sample-shared.

  • 58 locales bundled — full coverage of openMF/kmp-project-template's locale set plus 17 additional Mifos-priority and Google Pay-benchmark locales.
  • BiometricError sealed type — categorical error states (Lockout, LockoutPermanent, HardwareUnavailable, NotEnrolled, Timeout, NoSpace, InvalidRegistrationData, InvalidArguments(stage), Unknown) replace prose error strings; consumers map each case to localized messages via the BiometricErrorMessages mapper in the sample app.
  • Localized numeric keypad — Compose Resources digit_0..digit_9 overrides for non-Latin numeral locales (ar, fa, ur, hi, mr, bn, ta, te, gu, kn, pa, ml, th).
  • Quality fixes (P1, per l10n-review/REPORT.md):
    • af: Stawe met X (legal-attestation verb) → Verifieer met X for 4 cd_* labels.
    • ko: standardized passcode terminology on 비밀번호 (Google Pay KR convention) — replaced 7 암호 occurrences across both modules.
    • ca: DesblocaDesbloqueja (3×); plural→singular ConfigureuConfigura, Torneu-hoTorna-ho.
    • hi: ASCII period . → Devanagari purna viram in 3 newer error strings.
  • Formal-register pass (P2) — 16 locales standardized to formal "you" register; 228 substitutions: de Sie · hu Ön · ru вы · uk ви · bg вие · be вы · sr Ви · hr Vi · sl Vi · sq Ju · ro Dvs · lv Jūs · mk Вие · el εσείς · tr siz. lt was already 100% formal.
  • Sample-app accessibility — fingerprint / face-scan / iris / device-credential icons now use stringResource (cd_fingerprint_icon, cd_face_scan_icon, cd_iris_scan_icon, cd_device_credential_icon); same for passcode-keypad action keys (visibility toggle, delete).
  • Plan-of-recordL10N_FIX_PLAN.md documents prioritization, decisions, and verification commands for resumption by future contributors.

Test plan

  • ./gradlew :cmp-sample-android:assembleDebug — green
  • ./gradlew :cmp-sample-shared:compileDebugKotlinAndroid :mifos-authenticator-passcode:compileDebugKotlinAndroid :cmp-sample-shared:compileKotlinDesktop — green
  • ./gradlew :mifos-authenticator-biometrics:compileKotlinJs :compileKotlinWasmJs — green (KMP non-android targets)
  • ./gradlew :cmp-sample-android:lintDebug — 0 errors; 147 pre-existing baseline issues incidentally resolved
  • Resource integrity: grep -L "biometric_error_lockout" cmp-sample-shared/src/commonMain/composeResources/values-*/strings.xml | wc -l0 (all 58 locales have all 6 legacy biometric error keys; no English fallback at runtime).
  • On-device manual smoke test on the 15 locales below (login / keypad / home).
  • Native-speaker review recommended for low-resource P2 locales: be, mk, sq, sl, lv, sr, hr.
  • Windows-side runtime test — deferred to a follow-up since no Windows machine was available in this iteration.

Supported languages (58 bundled)

58 locale variants in values-XX/strings.xml plus the base values/strings.xml (English source). Locales selected to match the openMF/kmp-project-template benchmark plus Mifos-priority microfinance markets and Google Pay's coverage list.

Full locale list — click to expand
Code Language Native
af Afrikaans Afrikaans
am Amharic አማርኛ
ar Arabic العربية
be Belarusian беларуская
bg Bulgarian български
bn Bengali বাংলা
ca Catalan català
cs Czech čeština
da Danish dansk
de German Deutsch
el Greek Ελληνικά
en-rGB English (United Kingdom) English (UK)
es Spanish español
et Estonian eesti
fa Persian / Farsi فارسی
fi Finnish suomi
fil Filipino Filipino
fr French français
gu Gujarati ગુજરાતી
he Hebrew עברית
hi Hindi हिन्दी
hr Croatian hrvatski
hu Hungarian magyar
in Indonesian Bahasa Indonesia
it Italian italiano
iw Hebrew (legacy code) עברית
ja Japanese 日本語
kn Kannada ಕನ್ನಡ
ko Korean 한국어
lt Lithuanian lietuvių
lv Latvian latviešu
mk Macedonian македонски
ml Malayalam മലയാളം
mr Marathi मराठी
nb Norwegian Bokmål norsk bokmål
nl Dutch Nederlands
pa Punjabi ਪੰਜਾਬੀ
pl Polish polski
pt-rBR Portuguese (Brazil) português (Brasil)
pt-rPT Portuguese (Portugal) português (Portugal)
ro Romanian română
ru Russian русский
si Sinhala සිංහල
sk Slovak slovenčina
sl Slovenian slovenščina
sq Albanian shqip
sr Serbian српски
sv Swedish svenska
sw Swahili Kiswahili
ta Tamil தமிழ்
te Telugu తెలుగు
th Thai ไทย
tr Turkish Türkçe
uk Ukrainian українська
ur Urdu اردو
vi Vietnamese Tiếng Việt
zh-rCN Chinese (Simplified) 简体中文
zh-rTW Chinese (Traditional) 繁體中文

Native numeral overrides (locale-specific digit_0..digit_9 glyphs on the keypad): ar, fa, ur, hi, mr, bn, ta, te, gu, kn, pa, ml, th. All other locales fall back to base ASCII digits.

RTL locales: ar, fa, ur, he, iw.

Region-qualified locales: en-rGB, pt-rBR, pt-rPT, zh-rCN, zh-rTW. Note that the resource folder convention uses r as a region prefix (pt-rBR) while runtime BCP-47 tags drop it (pt-BR); Android's resource resolver bridges between the two.

## Screenshots — 15 locales × {login, keypad, home}

Click a thumbnail to view full-size.

Language Login Keypad Home
German (de) de_login de_keypad de_home
French (fr) fr_login fr_keypad fr_home
Spanish (es) es_login es_keypad es_home
Brazilian Portuguese (pt-rBR) pt-rBR_login pt-rBR_keypad pt-rBR_home
European Portuguese (pt-rPT) pt-rPT_login pt-rPT_keypad pt-rPT_home
Arabic — RTL (ar) ar_login ar_keypad ar_home
Hebrew — RTL (he) he_login he_keypad he_home
Hindi (hi) hi_login hi_keypad hi_home
Bengali (bn) bn_login bn_keypad bn_home
Tamil (ta) ta_01_login ta_02_keypad ta_03_home
Telugu (te) te_login te_keypad te_home
Korean (ko) ko_login ko_keypad ko_home
Japanese (ja) ja_login ja_keypad ja_home
Russian (ru) ru_login ru_keypad ru_home
Thai (th) th_login th_keypad th_home

Locale-tag note: Android resource folders use pt-rBR / pt-rPT / zh-rCN etc. (with r prefix), while runtime BCP-47 tags are pt-BR / pt-PT / zh-CN. Resolution is handled internally by Android's resource system.

…nd cleaning up dead resources

- Remove 22 unused string keys from passcode library and fix the 2 placeholder
  values for the external auth dialog.
- Replace the sample app's orphaned strings.xml with screen-organized keys and
  rewire 7 .kt files to use stringResource() instead of hardcoded English.
…benchmark

Adds values-XX/strings.xml under both mifos-authenticator-passcode and
cmp-sample-shared for: af, be, bg, ca, cs, da, de, el, en-rGB, es, et, fa,
fi, fr, hi, hr, hu, in, it, iw, ja, ko, lv, ml, nb, nl, pl, pt-rBR, pt-rPT,
ro, ru, sk, sv, th, tr, uk, vi, zh-rCN, zh-rTW.

Translations are machine-generated first drafts, audited and corrected for
clear errors (terminology overloading in pt-rBR/tr, missing postpositions in
hi, case error in et, ambiguous app_name in es/af, wrong sense in vi).
Native-speaker review still recommended before production — register
choices (T-V form, formal vs informal imperative) intentionally not
auto-corrected and need stakeholder decision per locale.
- Latin "OK" (not Cyrillic "ОК") in ru/bg/be — matches Google + Apple
- Romanian: tu-form throughout (informal imperative), removing the two
  voi-form outliers (Activați→Activează, Introduceți→Introdu) — Google
  Pay Romanian standardizes on tu
- Korean: -습니다 register for the dialog confirmation, normalizing the
  -어요/-습니다 mix — Google Pay Korean uses 합쇼체 for transactional flows
…dd LOCALIZATION.md

The biometrics module previously hardcoded English in three places: the Android
prompt subtitle, the iOS authentication-failed fallback, and the "Register
yourself" registration title. Errors were also surfaced as English-prefixed
prose ("Authentication failed: ...") which broke the platform's own locale
mapping when the message portion was already localized by the OS.

This refactor:
- Adds title/subtitle/description/negativeButtonText parameters to
  PlatformAuthenticator.authenticate() and registerUser(), threaded through
  PlatformAuthenticationProvider.
- Replaces AuthenticationResult.Error(message: String) and
  RegistrationResult.Error(message: String) with sealed BiometricError type
  carrying categorical cases (Lockout, LockoutPermanent, HardwareUnavailable,
  NotEnrolled, Timeout, NoSpace, Unknown). Consumer maps cases to localized
  strings from its own resources.
- Drops the "Authentication failed: " / "Registration failed: " English
  prefixes that previously concatenated with platform messages.
- Updates sample app to pass stringResource(...) for all prompt strings and
  introduces rememberBiometricErrorMessages() helper to map BiometricError to
  localized strings outside @composable context.
- Adds 6 new biometric_error_* keys to default English strings.xml; locale
  variants for the 39 already-bundled languages are pending follow-up.
- Adds LOCALIZATION.md documenting bundled locales, the per-app-locale
  recipe (Android), biometric-prompt string convention, and adding new
  locales/strings; README links to it.

Breaking change: Result.Error.message → Result.Error.error: BiometricError.
…p locale

Android 13+ AppCompatDelegate.setApplicationLocales(...) auto-converts the
legacy "iw" tag to the modern "he" tag when storing per-app locales. Compose
Multiplatform Resources then looks for values-he/ at runtime and falls back
to the default English bundle when only values-iw/ exists, even though the
Hebrew translation file is present.

Verified on a OnePlus device running Android 16: setting per-app locale to
"iw-IL" via adb stored as "he-IL", and Hebrew strings now render correctly
after this change. Both directories are kept (identical content) so devices
on older Android versions that still pass "iw" to Compose Resources continue
to work.
…markets

Not bundled in openMF/kmp-project-template's LanguageConfig benchmark, but
added here since Arabic-speaking markets (Egypt, Jordan, Morocco, etc.) are
core Mifos microfinance footprint. RTL layout was already verified working
via Persian/Hebrew tests.

Verified on a OnePlus device (Android 16): per-app locale ar-SA renders
"أدخل رمز المرور" / "نسيت رمز المرور؟" with mirrored RTL layout, the `?`
positioned on the visual left in the forgot-passcode link.

Note: consumers using kmp-project-template's LanguageConfig enum will need
to add ARABIC(localeName = "ar", text = "العربية") to expose this in their
in-app language picker.
…kets

New locales (all 17 with both passcode-library and sample-app strings.xml):

  South Asia (8):  bn (Bengali), ta (Tamil), te (Telugu), mr (Marathi),
                   gu (Gujarati), kn (Kannada), pa (Punjabi/Gurmukhi),
                   ur (Urdu/RTL), si (Sinhala)
  Africa (2):      sw (Swahili), am (Amharic)
  SE Asia (1):     fil (Filipino)
  Europe (5):      lt (Lithuanian), sl (Slovenian), sr (Serbian/Cyrillic),
                   mk (Macedonian), sq (Albanian)

Combined with the existing 39-locale set + ar (added previously) + he (paired
with iw), the library now ships 57 locale variants plus default English.

Audit-driven mistranslation fixes applied alongside this batch:

  sw: home_screen_title "Skrini ya Mwanzo" (Start Screen) → "Skrini ya Nyumbani"
      enable_external_auth_dialog_description: "stakabadhi" (receipts) →
        "vitambulisho" (credentials)
  mk: biometric_setup_title "Поставки за биометрија" (settings for...)
        → "Поставување на биометрија" (setting up of...)
  sq: biometric_error_hardware_unavailable: "Pajisja biometrike" (device)
        → "Hardueri biometrik" (hardware)
  am: log_out: "ውጣ" (bare imperative) → "ይውጡ" (polite, matches rest of file)
  ta/te/kn: biometric_prompt_subtitle "pattern" — replaced literal
        translations (வடிவம்/నమూనా/ಮಾದರಿ "shape/sample/model") with the
        Android-conventional transliteration (பேட்டர்ன்/ప్యాటర్న్/ಪ್ಯಾಟರ್ನ್).
        te/kn version also resolved a same-word collision with "sample" in
        app_name.
  mr/gu/pa: confirm_*_passcode genitive postposition — added missing ची/ની/ਦੀ
        markers per audit.
  gu: use_biometrics — fixed stray space ("બાયોમેટ્રિક નો" → "બાયોમેટ્રિકનો").

LOCALIZATION.md updated with the full 57-locale table and an expanded list of
languages flagged for native-speaker review (now also si and am).

Verified on a OnePlus device: per-app locale `bn-IN` renders Bengali strings
correctly. Build green across all targets.
Adds digit_0..digit_9 string keys to the passcode-library default
values/strings.xml (Western "0"-"9") and overrides them in the 13 bundled
locales whose native numeral system differs from Western:

  ar — Arabic-Indic       (٠-٩, U+0660..U+0669)
  fa — Persian            (۰-۹, U+06F0..U+06F9)
  ur — Persian (Urdu)     (۰-۹, same set as fa)
  hi — Devanagari         (०-९, U+0966..U+096F)
  mr — Devanagari         (०-९, same set as hi)
  bn — Bengali            (০-৯, U+09E6..U+09EF)
  ta — Tamil              (௦-௯, U+0BE6..U+0BEF)
  te — Telugu             (౦-౯, U+0C66..U+0C6F)
  gu — Gujarati           (૦-૯, U+0AE6..U+0AEF)
  kn — Kannada            (೦-೯, U+0CE6..U+0CEF)
  pa — Gurmukhi (Punjabi) (੦-੯, U+0A66..U+0A6F)
  ml — Malayalam          (൦-൯, U+0D66..U+0D6F)
  th — Thai               (๐-๙, U+0E50..U+0E59)

PasscodeKey gains a `keyDisplay: String = keyTitle` parameter that the
keypad uses to render the localized glyph; `keyTitle` (the storage value
emitted via onClick) continues to be ASCII "0"-"9" so PasscodeManager
stores a locale-independent passcode regardless of which glyph the user
saw on the keypad. Defaulting keyDisplay to keyTitle preserves backward
compatibility for existing call sites that don't decouple display from
storage.

Locales without overrides (am, iw/he, si, all Latin-script locales) fall
back to the Western default.

Hostile audit: Codepoint-by-codepoint check across all 14 files passed —
no transpositions, no wrong-script glyphs, no duplicates, no missing keys.

Verified on device: ar-SA renders Arabic-Indic, fa-IR renders Persian,
hi-IN renders Devanagari, plus bn-IN, ta-IN, te-IN, gu-IN, kn-IN, mr-IN
all render correctly. es-ES regression confirms Western digits unchanged.
LoginScreen + HomeScreen had no horizontal padding and the title Text
expanded to fill width without textAlign — Spanish strings ("Pantalla de
inicio de sesión", "Pantalla de inicio") wrapped to multiple lines that
appeared left-aligned and visually overlapped due to the default 48sp
font's tight line height. English wasn't affected because shorter strings
didn't force the Text to expand.

Fixes for both screens:
- Add `padding(horizontal = 24.dp)` to the Column root.
- Add `textAlign = TextAlign.Center` to the title Text so wrapped lines
  center within the Text bounds.
- Add `lineHeight = 56.sp` for proper line spacing at 48sp.

Verified on a OnePlus device with es-ES per-app locale: title now
properly wraps and centers, no edge-touching, no overlap.

Separately localizes PasscodeLengthSwitch:
- Replaces hardcoded "4 digits" / "6 digits" in PasscodeLengthSwitch.kt
  (lines 96, 118, 150, 152) with stringResource(passcode_length_4_digits)
  and (..._6_digits).
- Adds the two new keys to library default values/strings.xml plus all 57
  locale variants (Spanish: "4 dígitos"/"6 dígitos", and so on across
  ar, fa, hi, bn, mr, gu, kn, pa, ur, ml, te, ta, th, fr, de, it, ja, ko,
  ru, etc.). Verified on-device: Create Passcode toggle now reads
  "4 dígitos" / "6 dígitos" in Spanish.
…eral locales

The keypad already renders locale-native digits in non-Latin numeral system
locales (commit fe2fb0f), but the PasscodeLengthSwitch toggle below it kept
showing Western "4 अंक" / "6 अंक" — a visual inconsistency between the digit
on the toggle and the digit on the key the user actually presses.

Updates the leading numeral in passcode_length_4_digits and
passcode_length_6_digits for the 12 affected locales:

  ar  ٤ أرقام / ٦ أرقام        Arabic-Indic
  hi  ४ अंक / ६ अंक              Devanagari
  mr  ४ अंक / ६ अंक              Devanagari
  bn  ৪ অঙ্ক / ৬ অঙ্ক              Bengali
  ta  ௪ இலக்கங்கள் / ௬ இலக்கங்கள்  Tamil
  te  ౪ అంకెలు / ౬ అంకెలు          Telugu
  gu  ૪ અંક / ૬ અંક              Gujarati
  kn  ೪ ಅಂಕಿ / ೬ ಅಂಕಿ              Kannada
  pa  ੪ ਅੰਕ / ੬ ਅੰਕ              Gurmukhi
  ml  ൪ അക്ക / ൬ അക്ക              Malayalam
  th  ๔ หลัก / ๖ หลัก              Thai
  ur  ۴ ہندسے / ۶ ہندسے            Persian (Urdu adopts the set)

Persian (fa) was already correct (۴/۶) from the original commit; not modified.
All Latin-script locales (es, fr, de, ja, ko, zh-rCN, etc.) keep Western
4/6 — modern UI convention in those locales is Western digits with native
counter words ("4 dígitos", "4桁", "4자리", "4位").

Verified on a OnePlus Android 16 device: hi-IN renders "४ अंक" / "६ अंक",
ar-SA renders "٤ أرقام" / "٦ أرقام", both with their respective native-digit
keypads. Toggle and keypad are now visually consistent.
Refactor biometric error handling to provide more granular feedback for invalid registration data and invalid arguments, particularly for the desktop implementation.

*   **Biometrics Library**:
    *   Add `InvalidRegistrationData` and `InvalidArguments(stage: AuthStage)` to the `BiometricError` sealed interface.
    *   Introduce `AuthStage` enum to distinguish between failures during the Registration and Authentication phases.
    *   Update `WindowsHelloAuthenticator` and associated desktop logic to emit these specific error types instead of generic `Unknown` errors with platform-specific string messages.
    *   Simplify internal Windows authenticator responses by removing custom error strings in favor of typed objects.

*   **Sample App and Localization**:
    *   Add localized strings for `biometric_error_invalid_registration_data`, `biometric_error_invalid_arguments_auth`, and `biometric_error_invalid_arguments_registration` across all supported locales (ca, ar, zh, es, fr, hi, etc.).
    *   Update `BiometricKey.kt` in the sample project to map the new `BiometricError` variants to their respective localized string resources.
P0 of L10N_FIX_PLAN.md.

Adds biometric_error_lockout, _hardware_unavailable, _not_enrolled,
_timeout, _no_space, _unknown across 40 locales that were missing them
(would otherwise fall back to English at runtime).

Translations sourced from l10n-review/batch_*.json suggested_fix
payloads except he/iw which were translated manually using formal
masculine register matching existing Hebrew strings.

Also translates 3 untranslated English strings in values-fil/
(login_screen_title, home_screen_title, biometric_setup_title)
per l10n-review/REPORT.md:501-503.

Verified: all 58 locales now have all 6 biometric_error_* keys.
Builds green on android-debug and desktop targets.
P1a (af): cd_* TalkBack labels used "Stawe met X" — "stawe" is the
legal-attestation verb in Afrikaans, completely wrong for UI auth.
Replaced with "Verifieer met X" across 4 cd_* keys.

P1b (ko): Standardized passcode terminology on 비밀번호 (Google Pay KR
convention). The mixed 암호 / 비밀번호 split was internally inconsistent.
7 occurrences fixed across both passcode lib and sample-shared.

P1c (ca): "Desbloca" is a non-standard MT calque from Spanish/English;
normative Catalan imperative of *desbloquejar* is "Desbloqueja". Fixed
3 occurrences. Also fixed "Configureu" → "Configura" and "Torneu-ho" →
"Torna-ho" — the 2nd-person plural forms were inconsistent with the
rest of the file's singular register.

P1d (hi): 3 newer biometric_error_invalid_* strings used ASCII period
"." as sentence terminator; fixed to Devanagari purna viram "।" to
match the rest of the hi locale.

References: l10n-review/REPORT.md G-3 (af:529, ko:130, ca:654, hi:250).
Verification: all 4 grep checks in L10N_FIX_PLAN.md pass; android-debug
+ desktop builds green.
Deliberately overrides l10n-review/REPORT.md's case-by-case recommendation
(which suggested informal register for ~14 of these locales per Google Pay
convention). Per user request, applies formal "you" register everywhere
instead — uniform across all 16 locales.

Locales: de(Sie), hu(Ön), ru(вы), uk(ви), bg(вие), be(вы), sr(Ви),
hr(Vi), sl(Vi), sq(Ju), ro(Dvs), lt(unchanged - already formal),
lv(Jūs), mk(Вие), el(εσείς), tr(siz).

228 string substitutions applied. Each was a register-marker-only edit
(pronouns, possessives, polite-imperative endings); content was not
otherwise rewritten. Build green on android-debug, sample-shared compile,
passcode-lib compile, and desktop targets.

Caveat: native-speaker review still recommended before final ship,
especially for low-resource locales (be, mk, sq, sl, lv, lt, sr, hr).

References: L10N_FIX_PLAN.md P2.
In `WindowsHelloAuthenticator`, remove the `Logger.e` call when an exception occurs during the registration or verification process. The method continues to return `WindowsAuthenticatorResponse.Registration.Error` as the failure result.
@TheKalpeshPawar TheKalpeshPawar changed the title Translate strings Add multilingual support across 58 locales May 3, 2026
Refactors the component to use `IntrinsicSize.Max` for width calculation, ensuring that the container expands to fit longer localized strings while maintaining a minimum width of 150.dp for shorter labels.

* Rename the `width` parameter to `minWidth` to accurately reflect its new behavior.
* Replace absolute button positioning (`Alignment.CenterStart/End`) with a `Row` using `weight(1f)` to ensure equal space distribution between the two options.
* Add horizontal padding to the buttons to prevent text from clipping against the edges.
* Update `AnimatedContent` to `fillMaxSize` to match the new container constraints.
Refactor UI components to use a `PasscodeStrings` abstraction instead of direct resource references. This allows callers to provide custom localized strings or override default text across the passcode library.

* **API Changes**:
    * Add a `strings` parameter to `PasscodeScreen` and its internal components (`PasscodeHeader`, `PasscodeKeys`, `PasscodeLengthSwitch`, `PasscodeForgotButton`, etc.).
    * Use `defaultPasscodeStrings()` as the default value for the new `strings` parameter to maintain existing behavior.

* **UI Logic**:
    * Replace `stringResource(Res.string.*)` calls with properties from the `PasscodeStrings` instance.
    * Decouple the keypad's localized digits and accessibility content descriptions from static resources.
    * Update dialogs (`SystemAuthConfirmDialog`, `PasscodeMismatchedDialog`) to support dynamic string injection.

* **Cleanup**:
    * Remove unused imports for generated resource classes in multiple component files.
Library now exposes a `PasscodeStrings` data class so consumers supply
their own translations instead of relying on the bundled defaults.

- `PasscodeStrings.kt` (new) — 17-field data class covering every
  user-visible string + 10-element digit glyph list, plus a memoized
  `defaultPasscodeStrings()` factory wrapped in `remember(...)` keyed
  on the underlying string values (one allocation per locale change,
  not per recomposition).
- `PasscodeScreen` retains a top-level `strings: PasscodeStrings =
  defaultPasscodeStrings()` default and threads `strings = strings`
  to every leaf it composes.
- Leaf composables (`PasscodeHeader`, `PasscodeKeys`,
  `PasscodeLengthSwitch`, `PasscodeMismatchedDialog`,
  `PasscodeForgotButton`, `SystemAuthSetupConfirmDialog`) now require
  explicit `strings: PasscodeStrings` — no per-leaf default. This
  matches Stage 2's end state (when the lib stops bundling strings
  entirely, defaults won't be possible) and surfaces missing
  dependencies at compile time rather than via a hidden runtime
  fallback.

Dead-code cleanup: removed the unused `PasscodeSkipButton` composable
and its associated `skipButtonStyle()` text style. Trimmed the now-
orphaned `skipButtonTextStyle` field from `PasscodeButtonConfig`,
the commented-out construction line in `PasscodeScreen`, and the
commented `isSkipButtonVisible` placeholder. Verified zero remaining
references repo-wide before deletion.

Build green: passcode lib (android-debug + desktop) + sample-android
APK assembly all succeed.
Adds comprehensive localized string resources for the passcode library across multiple locales (including Arabic, Bengali, Chinese, French, Hindi, Spanish, and more) within the sample app.

**Key changes:**
* **Localization**: Populates `strings.xml` across 30+ language variants with `mifos_passcode_*` keys to support internationalization of the passcode UI.
* **Component Integration**: Updates `PasscodeScreenWithBiometrics` to accept a `PasscodeStrings` parameter, allowing the library to use caller-provided localized text.
* **Resource Mapping**: Introduces `rememberPasscodeStringsFromResources()`, a helper composable that resolves localized strings from the app's resources and memoizes them into the library's `PasscodeStrings` data class. This includes headers, error messages, digit labels, and accessibility content descriptions.
Stage 2.2 of the i18n migration. The library no longer ships its own
translations; consumers supply a `PasscodeStrings` instance constructed
from their app's resources.

- Deleted `mifos-authenticator-passcode/src/commonMain/composeResources/
  values-*/strings.xml` (58 locale variants + base English) — 59 files.
  The library's published artifact no longer carries embedded translation
  data. Drawables (mifos_logo) and fonts (Lato_*) stay bundled.

- Removed `defaultPasscodeStrings()` factory from `PasscodeStrings.kt`.
  The data class itself stays. With no bundled resources to read,
  the bridge factory is unimplementable; the explicit-strings contract
  is now load-bearing.

- Made `strings: PasscodeStrings` a required parameter on
  `PasscodeScreen(...)` (was a default-valued bridge previously).
  All current internal call sites already pass `strings = strings`
  explicitly so this only constrains future external consumers.

- New `l10n-templates/passcode/values-*/strings.xml` (59 files) holds
  the canonical translations consumers can copy into their own modules.
  Every key is prefixed `mifos_passcode_*` so it can be appended to
  a consumer's existing `strings.xml` without collision.

- New `l10n-templates/passcode/README.md` documents the integration
  paths (manual copy now; planned Gradle plugin later) and the
  resource-key → `PasscodeStrings`-field mapping table.

Verified: `:clean` then full multi-target compile (android-debug,
desktop, iOS-arm64, JS, wasmJS) plus sample-android APK assemble all
green. Compose Resources codegen handles the lib's no-`values/` state
cleanly — the auto-generated `Res` accessor exposes only `Res.drawable.*`
and `Res.font.*` after this commit.
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