mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-07-14 18:15:56 -04:00
main
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b540a9111a
|
refactor(i18n): replace compiled .ts catalogs with direct .po imports
- Remove `lingui compile` / `i18n:compile` script — Vite and Metro LingUI plugins now compile `.po` files on the fly at dev/build time; no manual compile step needed
- Import `.po` files directly in `@sofa/i18n` (`./po/en.po` etc.) and add `po.d.ts` ambient module declaration so TypeScript accepts them
- Add `fallbackLocales: { default: "en" }` and `lineNumbers: false` to `lingui.config.ts`; prefix catalog paths with `<rootDir>` for correctness
- Derive `SupportedLocale` and `SUPPORTED_LOCALES` from `LOCALE_INFO` in `locales.ts` to eliminate the circular import between `index.ts` and `locales.ts`
- Update Crowdin config to use `project_id_env` instead of a hardcoded ID, drop `languages_mapping` (no longer needed), and add `preserve_hierarchy: true`
- Add a daily cron trigger (`0 6 * * *`) to the Crowdin GitHub Actions workflow and drop the now-redundant compile step from it
- Update docs and `AGENTS.md` to reflect that no compile step is required after `i18n:extract`
|
||
|
|
7b0c07ad3c
|
chore(i18n): add Claude-powered translation script and fill missing PO translations
- Add `packages/i18n/scripts/claude.ts` — a Bun script that translates empty PO entries via the Claude Code CLI, supporting batch mode, dry-run, optional AI context from `crowdin-context.jsonl`, and structured JSON output validation - Add `i18n:claude` root script (`bun packages/i18n/scripts/claude.ts`) as a convenience alias - Fill all previously empty msgstr entries across de, es, fr, it, pt PO catalogs and recompile `.ts` catalogs - Polish README with badges (license, CI status, release, language, Crowdin localization) and minor formatting fixes |
||
|
|
ad0497ccd6 |
feat: add i18n with LingUI, Crowdin integration, and typed error codes (#16)
* feat: add i18n with LingUI, Crowdin integration, and typed error codes - Add `@sofa/i18n` shared package with LingUI v5 (v6-ready config using `defineConfig` + `@lingui/format-po`), eager English + lazy-loaded fr/de/es/it/pt catalogs, `Intl`-based date/number format utilities, and test helpers - Wire `@lingui/vite-plugin` + babel macro plugin for web, and `@lingui/metro-transformer` + babel config for native - Add `I18nProvider` to both app roots with locale auto-detection (navigator.language / expo-localization) and persistence (localStorage / MMKV) - Wrap all ~512 user-facing strings across web and native with LingUI macros (`<Trans>`, `useLingui`/`t`, `i18n._(msg`...`)`, `plural`) - Add language switcher to Settings in both apps - Add `@sofa/api/errors` with 13 typed `AppErrorCode` values and `appErrorData()` helper for contract `.errors()` schemas - Update all oRPC contract error definitions with typed `data` fields; convert import procedure `throw new Error()` to `ORPCError` with codes - Add per-app `error-messages.ts` utilities that map error codes to localized strings; update global `QueryCache.onError` handlers to stop leaking raw `error.message` to users - Add `crowdin.yml` config and `.github/workflows/crowdin.yml` for automated source upload on merge and translation pull via dispatch - Add `lingui.config.ts` at repo root with `bun run i18n:extract` and `bun run i18n:compile` convenience scripts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: add Crowdin language mapping and ignore context file * fix(i18n): address 20 localization quality issues - Stop leaking raw error.message to users in change-password and account-section; use localized fallbacks instead - Add typed error data to discover contract's .errors() schema - Replace all manual English plural suffixes with LingUI plural() macro in episode counts, backup counts, star ratings, title/image counts - Replace date-fns formatDistanceToNow and hardcoded date patterns with locale-aware formatDate/formatRelativeTime from @sofa/i18n/format - Convert integration-configs from module-scope translations (frozen at import time) to lazy getIntegrationConfigs(i18n) function - Combine split Trans fragments into single translatable units in backup-schedule retention sentence and stats-display period labels - Localize TV media type badge and full episode accessibilityLabel - Replace Android-incompatible Alert.alert language picker (max 3 buttons) with zeego DropdownMenu - Await async locale initialization before hiding splash screen so non-English users don't see English flash on cold start - Add @lingui/core as direct native app dependency Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(i18n): add Intl polyfills for Hermes, replace DropdownMenu language picker, and remove date-fns - Add `@formatjs/intl-*` polyfills loaded at app startup in `intl-polyfills.ts` so Hermes on Android has full `Intl` support for locale-aware formatting - Alias `@formatjs/icu-messageformat-parser` to its `no-parser` variant in metro config to reduce bundle size - Replace the zeego `DropdownMenu` language picker in Settings with a new `SelectModal` component that works reliably on all platforms without the Android 3-button limit - Replace `date-fns` `format`/`parseISO` in `person/[id].tsx` with `formatDate` from `@sofa/i18n/format`; remove `date-fns` from native and web `package.json` - Refactor `StatusActionButton` to use a `StatusLabel` component with `<Trans>` rather than a `getStatusConfig(t)` factory so labels are always reactive to locale changes - Fix crowdin workflow to use root `bun run i18n:compile` script instead of `cd packages/i18n && bun run compile` - Wrap root layout `GestureHandlerRootView` in `SafeAreaProvider` and add `.catch` to locale-ready promise to prevent unhandled rejections blocking the splash screen * fix(i18n): localize integration status helpers, fix stats-display Trans wrapping, and clean up SelectModal - Localize `webhookStatus` and `listStatus` in `integration-card.tsx` using `i18n._(msg`...`)` so status strings are translated instead of always rendering in English - Wrap "Movies {select}" and "Episodes {select}" in a single `<Trans>` in `stats-display.tsx` so the period selector element is embedded inside the translatable unit rather than concatenated outside it - Fix locale activation order in Settings: close the modal first, then `activateLocale`, and only call `setPersistedLocale` on success to avoid persisting a locale that failed to load - Remove the redundant `SafeAreaProvider`/`SafeAreaView` wrapper from `SelectModal` — the root layout already provides `SafeAreaProvider` - Recompile all six `.po`/`.ts` catalogs to pick up new and updated message strings * chore(i18n): crowdin sync --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |