Aller au contenu

Implémentation i18n

KanjiIQ utilise le framework d'internationalisation intégré de Flutter avec des fichiers ARB (Application Resource Bundle) pour la localisation de l'interface et PostgreSQL JSONB pour la localisation du contenu.

Localisation de l'interface avec ARB

Configuration

Le système de localisation est configuré dans frontend/l10n.yaml :

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart

Structure des fichiers ARB

Chaque langue dispose d'un fichier ARB suivant le format de message ICU :

// lib/l10n/app_en.arb (template)
{
  "@@locale": "en",
  "appTitle": "KanjiIQ",
  "studyButton": "Start Study",
  "selectLanguage": "Select Language",
  "selectLevel": "Select JLPT Level",
  "cardCount": "{count} cards",
  "@cardCount": {
    "placeholders": {
      "count": { "type": "int" }
    }
  },
  "noConnection": "No internet connection. Using cached data.",
  "showAllLanguages": "Show all 51 languages"
}

Génération de code

L'exécution de flutter gen-l10n génère :

  • app_localizations.dart — Classe de base abstraite avec toutes les chaînes localisées
  • app_localizations_en.dart — Implémentation anglaise
  • app_localizations_ja.dart — Implémentation japonaise
  • ... (51 fichiers générés)

Utilisation dans les widgets Flutter :

// Access localized strings
Text(AppLocalizations.of(context)!.studyButton)

// With parameters
Text(AppLocalizations.of(context)!.cardCount(10))

Enregistrement des locales prises en charge

Les locales sont enregistrées dans MaterialApp :

MaterialApp(
  localizationsDelegates: AppLocalizations.localizationsDelegates,
  supportedLocales: AppLocalizations.supportedLocales,
  locale: selectedLocale,  // From LocalePreferences
)

Localisation du contenu

Le contenu des flashcards (significations des kanji, définitions de vocabulaire) est stocké en JSONB dans PostgreSQL et servi via l'API :

graph LR
    A[API Request<br/>?lang=pt] --> B[Backend]
    B --> C[PostgreSQL<br/>JSONB lookup]
    C --> D[Return meaning<br/>in Portuguese]

Pipeline de traduction

Le nouveau contenu est traduit via l'API OpenAI :

  1. Le contenu source est rédigé en anglais
  2. Le backend envoie des requêtes de traduction à OpenAI avec le contexte du niveau JLPT et de l'usage
  3. Les traductions sont stockées dans la colonne JSONB aux côtés des traductions existantes
  4. Chaque langue peut être mise à jour indépendamment sans affecter les autres

Traduction auto-hébergée

Les manifestes Kubernetes incluent un déploiement LibreTranslate (k8s/04-libretranslate-deployment.yaml) comme alternative à OpenAI. Cela fournit une traduction entièrement auto-hébergée sans dépendances à des API externes, bien que la qualité varie selon les paires de langues.

Langue de l'interface vs langue du contenu

KanjiIQ permet de dissocier la langue de l'interface et la langue d'étude :

  • Langue de l'interface : La langue des boutons, libellés et de la navigation (ex. : français)
  • Langue d'étude : La langue des significations des flashcards (ex. : portugais)

Un utilisateur francophone étudiant le japonais peut avoir l'interface en français tout en voyant les significations des flashcards en portugais s'il le préfère.

Ajouter une nouvelle langue

Pour ajouter une nouvelle (52e) langue :

  1. Interface : Créer lib/l10n/app_XX.arb avec toutes les chaînes traduites
  2. Contenu : Ajouter les traductions aux colonnes JSONB via le pipeline de traduction
  3. Configuration de la locale : Ajouter le code de langue aux entrées locale_configs pertinentes via l'API administrateur
  4. Build : Exécuter flutter gen-l10n pour régénérer les fichiers de localisation

Aucune migration de schéma ni modification du code backend n'est nécessaire — le stockage JSONB et le système ARB sont tous deux conçus pour l'extensibilité.