Files
vnidrop/localization
cdricms c23f7916bb Merge origin/master into feat/apple-typed-resources-and-fixes
Brings in custom relays, relay connection policies, storage cache clearing, and
receiver-failure reporting. Apple-side conflict resolutions:
- CoreRepository: keep CoreDispatcher, adopt master's relay factory + network
  transition guard, drop the now-unused serial queue.
- TransferDetailsView: keep the toolbar-share layout; adopt master's
  invitationPresentation-based QR panel and the new .failed receiver case (typed).
- SettingsModel/SettingsScreen: typed L10n titleKey with master's .network case;
  relay controls and the Free up space / storage redesign coexist.
- Add the missing transfer_receiver_failed localization key.
- Regenerate l10n from the merged strings.json; keep the Apple catalog untracked.
- Drop the notificationsEnabled test assertion (notifications preference was
  intentionally removed on this branch).
2026-07-24 17:48:10 +02:00
..

Localization

Single source of truth for every user-facing string, in strings.json. A Bun CLI generates the platform-native files from it:

Target Output Notes
apple apple/VniDrop/Resources/Localizable.xcstrings one catalog, all languages nested
kmp shared/src/commonMain/composeResources/values[-lang]/strings.xml one file per language

Workflow

# From the repository root:
make check-localization      # structural checks (run before committing)
make localization            # regenerate .xcstrings + strings.xml from strings.json
make localization-migrate    # one-time: rebuild strings.json from platform files

Never edit the generated .xcstrings / strings.xml by hand — edit strings.json and regenerate. Regenerated output is deterministic (sorted keys), so diffs stay small.

strings.json format

{
  "sourceLanguage": "en",
  "supportedLanguages": ["en", "fr"],
  "strings": {
    "send_title": {
      "context": "Send tab — screen title.",
      "translations": { "en": "Send", "fr": "Envoyer" }
    },

    "send_selected_files_count": {
      "context": "Send flow — number of files chosen before creating a transfer.",
      "targets": ["kmp", "apple"],
      "args": [{ "name": "count", "type": "int" }],
      "plural": {
        "en": { "one": "{count} file selected", "other": "{count} files selected" },
        "fr": { "one": "{count} fichier sélectionné", "other": "{count} fichiers sélectionnés" }
      }
    }
  }
}

Fields

  • context (required) — where the string appears and its purpose. Emitted as the .xcstrings comment and an XML comment; also the note translators see.
  • targets (optional)["kmp", "apple"]. Omit to mean all targets.
  • args (optional) — ordered list of { name, type }, typestring | int | double. Referenced in text as {name}.
  • translations — flat text per language. Mutually exclusive with plural.
  • plural — per language, per CLDR category (zero, one, two, few, many, other). other is always required.

Placeholders

Write named tokens {count}, {name} in text. The generator converts them to the right positional token per platform, using the declared type:

type Apple Android/KMP
string %N$@ %N$s
int %N$d %N$d
double %N$f %N$f

A literal % in text is emitted as %% whenever the string has args.

Adding a language

Add its code to supportedLanguages, fill in translations / plural for each key, then generate. KMP gets a new values-<lang>/strings.xml; Apple gets the language inside the single catalog. validate warns about any key still missing that language.

Migration notes (from the initial import)

  • Apple keys that were literal English strings ("%@ · %@") were imported verbatim — rename them to semantic keys and update the Swift call sites.
  • Arg names default to arg1, arg2… (a lone int arg becomes count). Rename for clarity; keep the {token} in text in sync.
  • Folding transfer_file_count_one / _other into the plural key transfer_file_count requires switching the KMP call site from Res.string.transfer_file_count_one to the Compose plural API (pluralStringResource(Res.plurals.transfer_file_count, count, count)), and the Apple side to automatic plural inflection.