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

@@ -0,0 +1,289 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Russian (`ru`).
class AppLocalizationsRu extends AppLocalizations {
AppLocalizationsRu([String locale = 'ru']) : super(locale);
@override
String get appTitle => 'FoodAI';
@override
String get greetingMorning => 'Доброе утро';
@override
String get greetingAfternoon => 'Добрый день';
@override
String get greetingEvening => 'Добрый вечер';
@override
String get caloriesUnit => 'ккал';
@override
String get gramsUnit => 'г';
@override
String get goalLabel => 'цель:';
@override
String get consumed => 'Потреблено';
@override
String get remaining => 'Осталось';
@override
String get exceeded => 'Превышение';
@override
String get proteinLabel => 'Белки';
@override
String get fatLabel => 'Жиры';
@override
String get carbsLabel => 'Углеводы';
@override
String get today => 'Сегодня';
@override
String get yesterday => 'Вчера';
@override
String get mealsSection => 'Приёмы пищи';
@override
String get addDish => 'Добавить блюдо';
@override
String get scanDish => 'Сканировать';
@override
String get menu => 'Меню';
@override
String get dishHistory => 'История блюд';
@override
String get recommendCook => 'Рекомендуем приготовить';
@override
String get camera => 'Камера';
@override
String get gallery => 'Галерея';
@override
String get analyzingPhoto => 'Анализируем фото...';
@override
String get inQueue => 'Вы в очереди';
@override
String queuePosition(int position) {
return 'Позиция $position';
}
@override
String get processing => 'Обрабатываем...';
@override
String get upgradePrompt => 'Хотите без очереди? Upgrade →';
@override
String get recognitionFailed => 'Не удалось распознать. Попробуйте ещё раз.';
@override
String get dishRecognition => 'Распознавание блюд';
@override
String get all => 'Все';
@override
String get dishRecognized => 'Блюдо распознано';
@override
String get recognizing => 'Распознаётся…';
@override
String get recognitionError => 'Ошибка распознавания';
@override
String get dishResultTitle => 'Распознано блюдо';
@override
String get selectDish => 'Выберите блюдо';
@override
String get dishNotRecognized => 'Блюдо не распознано';
@override
String get tryAgain => 'Попробовать снова';
@override
String get nutritionApproximate =>
'КБЖУ приблизительные — определены по фото.';
@override
String get portion => 'Порция';
@override
String get mealType => 'Приём пищи';
@override
String get dateLabel => 'Дата';
@override
String get addToJournal => 'Добавить в журнал';
@override
String get addFailed => 'Не удалось добавить. Попробуйте ещё раз.';
@override
String get historyTitle => 'История распознавания';
@override
String get historyLoadError => 'Не удалось загрузить историю';
@override
String get retry => 'Повторить';
@override
String get noHistory => 'Нет распознаваний';
@override
String get profileTitle => 'Профиль';
@override
String get edit => 'Изменить';
@override
String get bodyParams => 'ПАРАМЕТРЫ ТЕЛА';
@override
String get goalActivity => 'ЦЕЛЬ И АКТИВНОСТЬ';
@override
String get nutrition => 'ПИТАНИЕ';
@override
String get settings => 'НАСТРОЙКИ';
@override
String get height => 'Рост';
@override
String get weight => 'Вес';
@override
String get age => 'Возраст';
@override
String get gender => 'Пол';
@override
String get genderMale => 'Мужской';
@override
String get genderFemale => 'Женский';
@override
String get goalLoss => 'Похудение';
@override
String get goalMaintain => 'Поддержание';
@override
String get goalGain => 'Набор массы';
@override
String get activityLow => 'Низкая';
@override
String get activityMedium => 'Средняя';
@override
String get activityHigh => 'Высокая';
@override
String get calorieGoal => 'Норма калорий';
@override
String get mealTypes => 'Приёмы пищи';
@override
String get formulaNote => 'Рассчитано по формуле Миффлина-Сан Жеора';
@override
String get language => 'Язык';
@override
String get notSet => 'Не задано';
@override
String get calorieHint => 'Укажите параметры тела для расчёта нормы калорий';
@override
String get logout => 'Выйти из аккаунта';
@override
String get editProfile => 'Редактировать профиль';
@override
String get cancel => 'Отмена';
@override
String get save => 'Сохранить';
@override
String get nameLabel => 'Имя';
@override
String get heightCm => 'Рост (см)';
@override
String get weightKg => 'Вес (кг)';
@override
String get birthDate => 'Дата рождения';
@override
String get nameRequired => 'Введите имя';
@override
String get profileUpdated => 'Профиль обновлён';
@override
String get profileSaveFailed => 'Не удалось сохранить';
@override
String get mealTypeBreakfast => 'Завтрак';
@override
String get mealTypeSecondBreakfast => 'Второй завтрак';
@override
String get mealTypeLunch => 'Обед';
@override
String get mealTypeAfternoonSnack => 'Полдник';
@override
String get mealTypeDinner => 'Ужин';
@override
String get mealTypeSnack => 'Перекус';
@override
String get navHome => 'Главная';
@override
String get navProducts => 'Продукты';
@override
String get navRecipes => 'Рецепты';
}