feat: Flutter client localisation (12 languages)

Add flutter_localizations + intl, 12 ARB files (en/ru/es/de/fr/it/pt/zh/ja/ko/ar/hi),
replace all hardcoded Russian UI strings with AppLocalizations, detect system locale
on first launch, localise bottom nav bar labels, document rule in CLAUDE.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
dbastrikin
2026-03-19 22:22:52 +02:00
parent 9357c194eb
commit 54b10d51e2
40 changed files with 5919 additions and 267 deletions

View File

@@ -1,24 +1,24 @@
import 'package:food_ai/l10n/app_localizations.dart';
/// A configurable meal type that the user tracks throughout the day.
class MealTypeOption {
final String id;
final String label;
final String emoji;
const MealTypeOption({
required this.id,
required this.label,
required this.emoji,
});
}
/// All meal types available for selection.
const kAllMealTypes = [
MealTypeOption(id: 'breakfast', label: 'Завтрак', emoji: '🌅'),
MealTypeOption(id: 'second_breakfast', label: 'Второй завтрак', emoji: ''),
MealTypeOption(id: 'lunch', label: 'Обед', emoji: '🍽️'),
MealTypeOption(id: 'afternoon_snack', label: 'Полдник', emoji: '🥗'),
MealTypeOption(id: 'dinner', label: 'Ужин', emoji: '🌙'),
MealTypeOption(id: 'snack', label: 'Перекус', emoji: '🍎'),
MealTypeOption(id: 'breakfast', emoji: '🌅'),
MealTypeOption(id: 'second_breakfast', emoji: ''),
MealTypeOption(id: 'lunch', emoji: '🍽️'),
MealTypeOption(id: 'afternoon_snack', emoji: '🥗'),
MealTypeOption(id: 'dinner', emoji: '🌙'),
MealTypeOption(id: 'snack', emoji: '🍎'),
];
/// Default meal type IDs assigned to new users.
@@ -27,3 +27,14 @@ const kDefaultMealTypeIds = ['breakfast', 'lunch', 'dinner'];
/// Returns the [MealTypeOption] for the given [id], or null if not found.
MealTypeOption? mealTypeById(String id) =>
kAllMealTypes.where((option) => option.id == id).firstOrNull;
/// Returns the localised label for the given meal type [id].
String mealTypeLabel(String id, AppLocalizations l10n) => switch (id) {
'breakfast' => l10n.mealTypeBreakfast,
'second_breakfast' => l10n.mealTypeSecondBreakfast,
'lunch' => l10n.mealTypeLunch,
'afternoon_snack' => l10n.mealTypeAfternoonSnack,
'dinner' => l10n.mealTypeDinner,
'snack' => l10n.mealTypeSnack,
_ => id,
};