Skip to content

5.5.2 — Localize onboarding, and fix the crash that translating it would cause - #1

Open
aditya-I0063 wants to merge 1 commit into
aditya-190:masterfrom
aditya-I0063:release/5.5.2-localization
Open

aditya-I0063 wants to merge 1 commit into
aditya-190:masterfrom
aditya-I0063:release/5.5.2-localization

Conversation

@aditya-I0063

Copy link
Copy Markdown

First of three stacked PRs. Merge this one first — 5.6.0 and 5.7.0 build directly on it.

The smallest change set that makes the app correct for end users. No toolchain, architecture, schema or key changes, so it is reviewable in one sitting.

The reported bug

Onboarding titles and descriptions rendered in English in all 16 locales. Root cause: 14 strings were marked translatable="false" in values/strings.xml, which both excluded them from every values-*/ folder and suppressed the MissingTranslation lint check that would have caught it. The Kotlin was already using stringResource() correctly.

The trap this hid

Translating the headings alone would have crashed the app on first launch in every locale. TextHighlighter located the emphasised word with fullText.indexOf("Secure") and passed the result straight to AnnotatedString.addStyle. For any translated heading indexOf returns -1, and addStyle(start = -1, …) throws.

The highlight is now marked up as [[word]] inside each string resource, so translators choose the emphasised word in their own language, and a pure-Kotlin parser strips the markers. Unbalanced or absent markers degrade to unstyled text instead of throwing. Headings auto-size 36–64sp so longer languages do not clip.

Also in this PR

  • Arabic was offered by the in-app picker but missing from locales_config.xml, so selecting it silently did nothing. The picker, locales_config and the values-*/ folders now agree on all 17 locales.
  • Saving a preview without renaming it matched itself in the duplicate-heading check, reported "heading exists" and discarded the edit.
  • DetailViewModel trimmed on create but not on edit, so trailing whitespace crept into stored passwords.
  • The bottom navigation announced the raw enum name (BANKS) in every locale, and the alpha-0 FAB spacer was reachable by TalkBack.
  • The details screen's empty state read "No Previews Found".
  • PasswordGenerator used kotlin.random.Random rather than SecureRandom, and did not guarantee a character from each selected class.
  • Removed 10 string resources unused in code (170 entries across all locales), so they are not translated needlessly.
  • proguard-rules.pro kept net.sqlcipher.**, but the shipped artifact is net.zetetic:sqlcipher-android. Those rules matched nothing. The library supplies its own consumer rules — verified against mapping.txt that all 59 net.zetetic classes are kept unrenamed without any app-side rule — so the dead rules were removed rather than replaced.

MissingTranslation, ExtraTranslation, ImpliedQuantity and the string-format checks are now build-breaking errors, which is what stops this recurring.

Verification

Clean assembleRelease installed and checked, 16 unit tests, lint green. Onboarding launches without crashing in hi, ar, de, ta, ja and en on an API 36 emulator, with markers stripped and text localized.

🤖 Generated with Claude Code

Onboarding titles/descriptions, Skip/Next and the splash tagline rendered in
English in all 16 locales. Root cause: 14 strings were marked
translatable="false" in values/strings.xml, which both excluded them from every
values-*/ folder and suppressed the MissingTranslation lint check that would
have caught it. The Kotlin was already using stringResource() correctly.

Translating the headings alone would have crashed the app on first launch:
TextHighlighter located the emphasised word with fullText.indexOf("Secure") and
passed the result straight to AnnotatedString.addStyle. For any translated
heading indexOf returns -1, and addStyle(start = -1, ...) throws. The highlight
is now marked up as [[word]] inside each string resource, so translators choose
the emphasised word in their own language, and a pure-Kotlin parser strips the
markers. Unbalanced or absent markers degrade to unstyled text instead of
throwing. Headings auto-size 36-64sp so longer languages do not clip.

Also in this release:

- Arabic was offered by the in-app picker but missing from locales_config.xml,
  so selecting it silently did nothing. locales_config, values-*/ and the picker
  now agree on all 17 locales.
- Saving a preview without renaming it matched itself in the duplicate-heading
  check, reported "heading exists" and discarded the edit.
- DetailViewModel trimmed on create but not on edit, so trailing whitespace
  crept into stored passwords.
- The bottom navigation announced the raw enum name ("BANKS") in every locale,
  and the alpha-0 FAB spacer was reachable by TalkBack.
- The details screen's empty state read "No Previews Found".
- PasswordGenerator used kotlin.random.Random rather than SecureRandom, and did
  not guarantee a character from each selected class.
- Removed 10 string resources that were unused in code (170 entries across all
  locales), so they are not translated needlessly.
- proguard-rules.pro kept net.sqlcipher.**, but the shipped artifact is
  net.zetetic:sqlcipher-android. Those rules matched nothing. The library
  supplies its own consumer rules; verified against mapping.txt that all 59
  net.zetetic classes are kept unrenamed without any app-side rule, so the dead
  rules were removed rather than replaced.

MissingTranslation, ExtraTranslation, ImpliedQuantity and the string-format
checks are now build-breaking errors, which is what stops this recurring.

Verified on an API 36 emulator: onboarding launches without crashing in hi, ar,
de, ta, ja and en, with markers stripped and text localized. 16 unit tests pass,
lint passes, release build is green and the Room schema is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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