Skip to content

i18n: externalize hardcoded UI strings + complete French translation#392

Open
foXaCe wants to merge 1 commit into
ProdigyV21:mainfrom
foXaCe:feat/i18n-extract-fr-full
Open

i18n: externalize hardcoded UI strings + complete French translation#392
foXaCe wants to merge 1 commit into
ProdigyV21:mainfrom
foXaCe:feat/i18n-extract-fr-full

Conversation

@foXaCe

@foXaCe foXaCe commented Jun 18, 2026

Copy link
Copy Markdown

Summary

Externalizes hardcoded user-facing strings to res/values/strings.xml and adds a complete, parity-checked French translation in res/values-fr/strings.xml.

  • strings.xml: 247 → 1038 keys
  • values-fr/strings.xml: 61 → 1038 keys (full parity, French in vouvoiement throughout)
  • Both flavors compile (compileSideloadDebugKotlin + compilePlayDebugKotlin)

What changed

  • Compose Text / contentDescription / labels, dialogs, toasts, notifications → stringResource(R.string.x)
  • ViewModels, repositories, updater, live TV and data layer → context.getString(...); @ApplicationContext injected where it was missing
  • AuthEmailValidator.validate now returns @StringRes Int? resolved at the call sites
  • Display-only localization for values that are persisted/compared in code (settings option values like Off/Any/Medium, collection & rail titles, avatar and live-TV categories): the stored English value is kept for matching/dedup/cloud-sync, and only the displayed label is translated via small @Composable helpers (localizeSettingValue, localizedCollectionTitle, avatarCategoryLabel, liveCategoryLabel). This avoids freezing the locale or breaking comparisons.

Conventions

  • Technical terms / brands kept in English (Trakt, IPTV, EPG, Xtream, M3U, addon, stream, hero, debrid, Groq, Gemini, TDLib, Stalker…)
  • French typography: typographic apostrophes ('), non-breaking spaces before : ? !, ellipsis
  • All %1$s / %1$d placeholders preserved; EN ↔ FR parity verified (0 missing / 0 orphan / 0 duplicate)

Not included (out of scope)

  • TMDB_LANGUAGES language names in the language picker (≈53 entries — UX decision on native vs. translated names)
  • AiKeyWebPage HTML page (separate sub-system)
  • A handful of stored-value fallbacks in data-model classes without a Context (stream quality/source names) that would need display-layer localization at the stream tiles

Externalize hardcoded UI strings to res/values/strings.xml (247 -> 1038
keys) and add the complete French translation in res/values-fr/strings.xml
(61 -> 1038, full parity), entirely in vouvoiement.

- Compose Text/contentDescription/labels, dialogs, toasts, notifications
  -> stringResource(R.string.x)
- ViewModels, repositories, updater, live TV and data layer -> getString;
  @ApplicationContext injected where missing
- AuthEmailValidator.validate now returns @stringres resolved at call sites
- Display-only localization for stored/compared values (settings option
  values, collection/rail titles, avatar and live-TV categories): the
  persisted English value is kept for matching/dedup, only the shown label
  is translated (localizeSettingValue / localizedCollectionTitle /
  avatarCategoryLabel / liveCategoryLabel helpers)
- Technical terms and brands kept (Trakt, IPTV, EPG, Xtream, addon, stream,
  hero, Groq, Gemini, TDLib...)
- French typography: typographic apostrophes, non-breaking spaces before
  : ? !, ellipsis; placeholders preserved
- Both flavors compile (compileSideloadDebugKotlin + compilePlayDebugKotlin)
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