Skip to content

fix(i18n): localize Android Explore window names - #2784

Open
jvascopf wants to merge 1 commit into
ryanbr:mainfrom
jvascopf:fix/explore-window-name-l10n
Open

jvascopf wants to merge 1 commit into
ryanbr:mainfrom
jvascopf:fix/explore-window-name-l10n

Conversation

@jvascopf

Copy link
Copy Markdown

What

Localizes the window name ("week", "month", ...) used in the Android Explore comparison captions. It was passed as hard-coded English into the translated sentence.

Why

Code half of the "sem week anterior" report. The Apple side only lacked pt-PT values (fixed in #2781), so there are no Apple changes here. Refs #2781.

Scope

  • TrendsExploreScreen.kt: adds @StringRes windowNameRes to ExploreRange, used by the two captions.
  • New explore_window_week/month/quarter/half/year/all strings in 9 strings.xml files (de, es, fr, it, pl, pt-rPT, ru, zh, default), taken from the Apple catalogue.
  • The English windowName stays for the hard-coded "Trailing ..." captions (out of scope).

Verification

  • ./gradlew compileFullDebugKotlin succeeds
  • GermanLocalizationTest passes
  • i18n audit Android section clean
  • Resources only; no design-token impact; Apple and analytics untouched, so parity is unaffected

Notes

values-pt-rPT/strings.xml sits next to lines edited by #2781; will rebase if they conflict.

@ryanbr

ryanbr commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Thanks for this. The mechanical side is correct: six keys, present in all nine locale directories plus the default, every template still carries its %1$s, and nothing else reads windowNameRes. But I do not think the template approach can reach the goal, and I would rather say so now than after it lands.

The problem

Inserting a nominative noun into a sentence that inflects produces broken grammar in four of the locales:

  • pl: "w porównaniu do poprzedniego" + "tydzień" gives "poprzedniego tydzień". Polish needs the genitive, "tygodnia". Likewise "miesiąc" to "miesiąca" and "rok" to "roku", and "brak wcześniejszego tydzień" has the same issue.
  • ru: "против пред." + "неделя" gives "против пред. неделя". "против" governs the genitive, so "недели". And "нет предыдущего неделя" is wrong in both gender and case; it wants "нет предыдущей недели".
  • it: "vs %1$s precedenti" + "settimana" gives "vs settimana precedenti", a plural adjective against a singular noun. Only "6 mesi" happens to agree. "nessun dato nei settimana precedenti" also needs "nella settimana precedente".
  • pt-PT: "versus anterior semana" has the word order inverted; it wants "semana anterior".
  • zh: "对比上个 周" is not idiomatic, and the space before the placeholder reads oddly in Chinese. "上周" is the usual form.

This is not a regression. Before the change the inserted word was English, so ru read "против пред. week", which is also wrong. The point is that the change swaps one kind of wrong for another in these locales rather than arriving at correct output.

Separately, two of the templates are themselves still untranslated: explore_vs_prev_window is the English "vs prev %1$s" in both values-es and values-fr, so Spanish lands on "vs prev semana" and French on "vs prev semaine" even after this change.

What would work

Whole-phrase keys, one per window per locale (explore_vs_prev_week, explore_vs_prev_month and so on), with the enum mapping to the complete string instead of a noun. More keys, but each translator writes a natural phrase and no agreement has to survive concatenation.

That is the pattern your weekly digest change uses on the Swift side, and the comment there states the reasoning: whole-phrase variants per direction, then a whole-key wrapper, so a stitched fragment is never produced. That one is now on main. Refs #2783.

One more thing, whichever way this goes

Four readers of the English windowName survive, and they are visible copy: "Trailing ${...}" at TrendsExploreScreen.kt:619 and :621, and the sparse caption at :883 and :884. So a German user would see "vs. vorher Woche" sitting next to "Trailing week". Those are whole English literals, and the one at :883 is in a non-composable function where the i18n audit does not see it, so they each need their own string resource. Happy for that to be a separate change if you would rather keep this one narrow.

The Explore captions spliced a window-name noun into a translated
sentence ("vs prev %1$s", "no prior %1$s"). That cannot agree in case,
gender or number in inflected languages (pl, ru, it), and the English
windowName still leaked into the "Trailing ..." hero subtitle and the
"N readings · sparse" caption.

ExploreRange now maps each window to whole-phrase string resources
(vs prev, no prior, trailing, sparse-widened) and the caption uses a
readings plural, so no fragment is assembled in code. rangeCaption is
now @composable so it can resolve resources. The old
explore_vs_prev_window / explore_no_prior_window templates are removed,
which also replaces the untranslated English es and fr ones. Strings
are added for de, es, fr, it, pl, pt-rPT, ru and zh.
@jvascopf
jvascopf force-pushed the fix/explore-window-name-l10n branch from f2a3c08 to a77c3c8 Compare October 15, 2026 23:18
@jvascopf

Copy link
Copy Markdown
Author

Thanks, you're right. Stitching a nominative noun into an inflected sentence can't work, so I've reworked the PR along the lines you suggested:

  • ExploreRange now maps to whole-phrase resources: explore_vs_prev_* and explore_no_prior_* (5 windows), explore_trailing_* (6) and explore_sparse_widened_* (5), the same pattern as fix(i18n): localize weekly digest metric names #2783.
  • The old explore_vs_prev_window / explore_no_prior_window templates are removed, so the English es and fr ones are replaced by translated phrases.
  • I also covered the four remaining English readers you listed. The "Trailing …" hero subtitle (:619, :621) now uses trailingRes. rangeCaption (:883, :884) is now @Composable, using a new explore_n_readings plural plus the whole-phrase keys, so the audit sees it.

Verified: compileFullDebugKotlin and the localization unit tests pass, and the i18n audit's Android section is clean, including "no localized Android string is assembled by concatenation".

Notes: the new phrases for pl, ru, it, zh and de are mine, so a native check would be welcome. AppleHealthScreen.kt has the same windowName pattern; I left it out to keep this PR on one concern and can follow up. The branch was reset onto current main and force-pushed, so #2781's explore_vs_prev_window edit in pt-rPT becomes obsolete; I'll reconcile whichever lands second.

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.

2 participants