feat: localise scan screen (12 languages)

Replace all hardcoded Russian strings in ScanScreen and _LoadingDialog
with AppLocalizations keys; add addFromReceiptOrPhoto, chooseMethod,
photoReceipt, photoReceiptSubtitle, photoProducts, photoProductsSubtitle,
recognizing keys to all 12 ARB files and regenerate AppLocalizations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
dbastrikin
2026-03-19 23:05:11 +02:00
parent 54b10d51e2
commit 9e7fc09f4b
27 changed files with 373 additions and 46 deletions

View File

@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import '../../l10n/app_localizations.dart';
import 'recognition_service.dart'; import 'recognition_service.dart';
/// Entry screen — lets the user choose how to add products. /// Entry screen — lets the user choose how to add products.
@@ -16,38 +17,32 @@ class ScanScreen extends ConsumerStatefulWidget {
class _ScanScreenState extends ConsumerState<ScanScreen> { class _ScanScreenState extends ConsumerState<ScanScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return Scaffold( return Scaffold(
appBar: AppBar(title: const Text('Добавить продукты')), appBar: AppBar(title: Text(l10n.addFromReceiptOrPhoto)),
body: ListView( body: ListView(
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
children: [ children: [
const SizedBox(height: 16), const SizedBox(height: 16),
Text( Text(
'Выберите способ', l10n.chooseMethod,
style: Theme.of(context).textTheme.titleLarge, style: Theme.of(context).textTheme.titleLarge,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
const SizedBox(height: 32), const SizedBox(height: 32),
_ModeCard( _ModeCard(
emoji: '🧾', emoji: '🧾',
title: 'Сфотографировать чек', title: l10n.photoReceipt,
subtitle: 'Распознаем все продукты из чека', subtitle: l10n.photoReceiptSubtitle,
onTap: () => _pickAndRecognize(context, _Mode.receipt), onTap: () => _pickAndRecognize(context, _Mode.receipt),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
_ModeCard( _ModeCard(
emoji: '🥦', emoji: '🥦',
title: 'Сфотографировать продукты', title: l10n.photoProducts,
subtitle: 'Холодильник, стол, полка — до 3 фото', subtitle: l10n.photoProductsSubtitle,
onTap: () => _pickAndRecognize(context, _Mode.products), onTap: () => _pickAndRecognize(context, _Mode.products),
), ),
const SizedBox(height: 16),
_ModeCard(
emoji: '✏️',
title: 'Добавить вручную',
subtitle: 'Ввести название, количество и срок',
onTap: () => context.push('/products/add'),
),
], ],
), ),
); );
@@ -85,12 +80,13 @@ class _ScanScreenState extends ConsumerState<ScanScreen> {
if (!context.mounted) return; if (!context.mounted) return;
final service = ref.read(recognitionServiceProvider); final service = ref.read(recognitionServiceProvider);
final l10n = AppLocalizations.of(context)!;
// Show loading overlay while the AI processes. // Show loading overlay while the AI processes.
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (_) => const _LoadingDialog(), builder: (dialogContext) => _LoadingDialog(label: l10n.recognizing),
); );
try { try {
@@ -113,15 +109,14 @@ class _ScanScreenState extends ConsumerState<ScanScreen> {
if (context.mounted) { if (context.mounted) {
Navigator.pop(context); // close loading Navigator.pop(context); // close loading
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(content: Text(l10n.recognitionFailed)),
content: Text('Не удалось распознать. Попробуйте ещё раз.'),
),
); );
} }
} }
} }
Future<ImageSource?> _chooseSource(BuildContext context) async { Future<ImageSource?> _chooseSource(BuildContext context) async {
final l10n = AppLocalizations.of(context)!;
return showModalBottomSheet<ImageSource>( return showModalBottomSheet<ImageSource>(
context: context, context: context,
builder: (_) => SafeArea( builder: (_) => SafeArea(
@@ -130,12 +125,12 @@ class _ScanScreenState extends ConsumerState<ScanScreen> {
children: [ children: [
ListTile( ListTile(
leading: const Icon(Icons.camera_alt), leading: const Icon(Icons.camera_alt),
title: const Text('Камера'), title: Text(l10n.camera),
onTap: () => Navigator.pop(context, ImageSource.camera), onTap: () => Navigator.pop(context, ImageSource.camera),
), ),
ListTile( ListTile(
leading: const Icon(Icons.photo_library), leading: const Icon(Icons.photo_library),
title: const Text('Галерея'), title: Text(l10n.gallery),
onTap: () => Navigator.pop(context, ImageSource.gallery), onTap: () => Navigator.pop(context, ImageSource.gallery),
), ),
], ],
@@ -186,17 +181,19 @@ class _ModeCard extends StatelessWidget {
} }
class _LoadingDialog extends StatelessWidget { class _LoadingDialog extends StatelessWidget {
const _LoadingDialog(); const _LoadingDialog({required this.label});
final String label;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return const AlertDialog( return AlertDialog(
content: Column( content: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
CircularProgressIndicator(), const CircularProgressIndicator(),
SizedBox(height: 16), const SizedBox(height: 16),
Text('Распознаём...'), Text(label),
], ],
), ),
); );

View File

@@ -96,5 +96,11 @@
"mealTypeSnack": "وجبة خفيفة", "mealTypeSnack": "وجبة خفيفة",
"navHome": "الرئيسية", "navHome": "الرئيسية",
"navProducts": "المنتجات", "navProducts": "المنتجات",
"navRecipes": "الوصفات" "navRecipes": "الوصفات",
"addFromReceiptOrPhoto": "إضافة من الإيصال أو الصورة",
"chooseMethod": "اختر الطريقة",
"photoReceipt": "تصوير الإيصال",
"photoReceiptSubtitle": "التعرف على جميع المنتجات من الإيصال",
"photoProducts": "تصوير المنتجات",
"photoProductsSubtitle": "الثلاجة، الطاولة، الرف — حتى 3 صور"
} }

View File

@@ -96,5 +96,11 @@
"mealTypeSnack": "Snack", "mealTypeSnack": "Snack",
"navHome": "Startseite", "navHome": "Startseite",
"navProducts": "Produkte", "navProducts": "Produkte",
"navRecipes": "Rezepte" "navRecipes": "Rezepte",
"addFromReceiptOrPhoto": "Aus Kassenbon oder Foto hinzufügen",
"chooseMethod": "Methode wählen",
"photoReceipt": "Kassenbon fotografieren",
"photoReceiptSubtitle": "Alle Produkte vom Kassenbon erkennen",
"photoProducts": "Produkte fotografieren",
"photoProductsSubtitle": "Kühlschrank, Tisch, Regal — bis zu 3 Fotos"
} }

View File

@@ -96,5 +96,11 @@
"mealTypeSnack": "Snack", "mealTypeSnack": "Snack",
"navHome": "Home", "navHome": "Home",
"navProducts": "Products", "navProducts": "Products",
"navRecipes": "Recipes" "navRecipes": "Recipes",
"addFromReceiptOrPhoto": "Add from receipt or photo",
"chooseMethod": "Choose method",
"photoReceipt": "Photo of receipt",
"photoReceiptSubtitle": "Recognize all items from a receipt",
"photoProducts": "Photo of products",
"photoProductsSubtitle": "Fridge, table, shelf — up to 3 photos"
} }

View File

@@ -96,5 +96,11 @@
"mealTypeSnack": "Aperitivo", "mealTypeSnack": "Aperitivo",
"navHome": "Inicio", "navHome": "Inicio",
"navProducts": "Productos", "navProducts": "Productos",
"navRecipes": "Recetas" "navRecipes": "Recetas",
"addFromReceiptOrPhoto": "Añadir desde recibo o foto",
"chooseMethod": "Elegir método",
"photoReceipt": "Fotografiar recibo",
"photoReceiptSubtitle": "Reconocemos todos los productos del recibo",
"photoProducts": "Fotografiar productos",
"photoProductsSubtitle": "Nevera, mesa, estante — hasta 3 fotos"
} }

View File

@@ -96,5 +96,11 @@
"mealTypeSnack": "Collation", "mealTypeSnack": "Collation",
"navHome": "Accueil", "navHome": "Accueil",
"navProducts": "Produits", "navProducts": "Produits",
"navRecipes": "Recettes" "navRecipes": "Recettes",
"addFromReceiptOrPhoto": "Ajouter depuis ticket ou photo",
"chooseMethod": "Choisir la méthode",
"photoReceipt": "Photographier le ticket",
"photoReceiptSubtitle": "Reconnaissance de tous les produits du ticket",
"photoProducts": "Photographier les produits",
"photoProductsSubtitle": "Réfrigérateur, table, étagère — jusqu'à 3 photos"
} }

View File

@@ -96,5 +96,11 @@
"mealTypeSnack": "स्नैक", "mealTypeSnack": "स्नैक",
"navHome": "होम", "navHome": "होम",
"navProducts": "उत्पाद", "navProducts": "उत्पाद",
"navRecipes": "रेसिपी" "navRecipes": "रेसिपी",
"addFromReceiptOrPhoto": "रसीद या फ़ोटो से जोड़ें",
"chooseMethod": "तरीका चुनें",
"photoReceipt": "रसीद की फ़ोटो",
"photoReceiptSubtitle": "रसीद से सभी उत्पाद पहचानें",
"photoProducts": "उत्पादों की फ़ोटो",
"photoProductsSubtitle": "फ्रिज, टेबल, शेल्फ — 3 फ़ोटो तक"
} }

View File

@@ -96,5 +96,11 @@
"mealTypeSnack": "Spuntino", "mealTypeSnack": "Spuntino",
"navHome": "Home", "navHome": "Home",
"navProducts": "Prodotti", "navProducts": "Prodotti",
"navRecipes": "Ricette" "navRecipes": "Ricette",
"addFromReceiptOrPhoto": "Aggiungi da scontrino o foto",
"chooseMethod": "Scegli il metodo",
"photoReceipt": "Fotografa scontrino",
"photoReceiptSubtitle": "Riconosciamo tutti i prodotti dallo scontrino",
"photoProducts": "Fotografa i prodotti",
"photoProductsSubtitle": "Frigo, tavolo, scaffale — fino a 3 foto"
} }

View File

@@ -96,5 +96,11 @@
"mealTypeSnack": "間食", "mealTypeSnack": "間食",
"navHome": "ホーム", "navHome": "ホーム",
"navProducts": "食品", "navProducts": "食品",
"navRecipes": "レシピ" "navRecipes": "レシピ",
"addFromReceiptOrPhoto": "レシートや写真から追加",
"chooseMethod": "方法を選択",
"photoReceipt": "レシートを撮影",
"photoReceiptSubtitle": "レシートから全商品を認識",
"photoProducts": "食品を撮影",
"photoProductsSubtitle": "冷蔵庫・テーブル・棚 — 最大3枚"
} }

View File

@@ -96,5 +96,11 @@
"mealTypeSnack": "스낵", "mealTypeSnack": "스낵",
"navHome": "홈", "navHome": "홈",
"navProducts": "식품", "navProducts": "식품",
"navRecipes": "레시피" "navRecipes": "레시피",
"addFromReceiptOrPhoto": "영수증 또는 사진으로 추가",
"chooseMethod": "방법 선택",
"photoReceipt": "영수증 촬영",
"photoReceiptSubtitle": "영수증의 모든 상품 인식",
"photoProducts": "식품 촬영",
"photoProductsSubtitle": "냉장고, 테이블, 선반 — 최대 3장"
} }

View File

@@ -669,6 +669,42 @@ abstract class AppLocalizations {
/// In en, this message translates to: /// In en, this message translates to:
/// **'Recipes'** /// **'Recipes'**
String get navRecipes; String get navRecipes;
/// No description provided for @addFromReceiptOrPhoto.
///
/// In en, this message translates to:
/// **'Add from receipt or photo'**
String get addFromReceiptOrPhoto;
/// No description provided for @chooseMethod.
///
/// In en, this message translates to:
/// **'Choose method'**
String get chooseMethod;
/// No description provided for @photoReceipt.
///
/// In en, this message translates to:
/// **'Photo of receipt'**
String get photoReceipt;
/// No description provided for @photoReceiptSubtitle.
///
/// In en, this message translates to:
/// **'Recognize all items from a receipt'**
String get photoReceiptSubtitle;
/// No description provided for @photoProducts.
///
/// In en, this message translates to:
/// **'Photo of products'**
String get photoProducts;
/// No description provided for @photoProductsSubtitle.
///
/// In en, this message translates to:
/// **'Fridge, table, shelf — up to 3 photos'**
String get photoProductsSubtitle;
} }
class _AppLocalizationsDelegate class _AppLocalizationsDelegate

View File

@@ -286,4 +286,22 @@ class AppLocalizationsAr extends AppLocalizations {
@override @override
String get navRecipes => 'الوصفات'; String get navRecipes => 'الوصفات';
@override
String get addFromReceiptOrPhoto => 'إضافة من الإيصال أو الصورة';
@override
String get chooseMethod => 'اختر الطريقة';
@override
String get photoReceipt => 'تصوير الإيصال';
@override
String get photoReceiptSubtitle => 'التعرف على جميع المنتجات من الإيصال';
@override
String get photoProducts => 'تصوير المنتجات';
@override
String get photoProductsSubtitle => 'الثلاجة، الطاولة، الرف — حتى 3 صور';
} }

View File

@@ -287,4 +287,23 @@ class AppLocalizationsDe extends AppLocalizations {
@override @override
String get navRecipes => 'Rezepte'; String get navRecipes => 'Rezepte';
@override
String get addFromReceiptOrPhoto => 'Aus Kassenbon oder Foto hinzufügen';
@override
String get chooseMethod => 'Methode wählen';
@override
String get photoReceipt => 'Kassenbon fotografieren';
@override
String get photoReceiptSubtitle => 'Alle Produkte vom Kassenbon erkennen';
@override
String get photoProducts => 'Produkte fotografieren';
@override
String get photoProductsSubtitle =>
'Kühlschrank, Tisch, Regal — bis zu 3 Fotos';
} }

View File

@@ -286,4 +286,22 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String get navRecipes => 'Recipes'; String get navRecipes => 'Recipes';
@override
String get addFromReceiptOrPhoto => 'Add from receipt or photo';
@override
String get chooseMethod => 'Choose method';
@override
String get photoReceipt => 'Photo of receipt';
@override
String get photoReceiptSubtitle => 'Recognize all items from a receipt';
@override
String get photoProducts => 'Photo of products';
@override
String get photoProductsSubtitle => 'Fridge, table, shelf — up to 3 photos';
} }

View File

@@ -287,4 +287,23 @@ class AppLocalizationsEs extends AppLocalizations {
@override @override
String get navRecipes => 'Recetas'; String get navRecipes => 'Recetas';
@override
String get addFromReceiptOrPhoto => 'Añadir desde recibo o foto';
@override
String get chooseMethod => 'Elegir método';
@override
String get photoReceipt => 'Fotografiar recibo';
@override
String get photoReceiptSubtitle =>
'Reconocemos todos los productos del recibo';
@override
String get photoProducts => 'Fotografiar productos';
@override
String get photoProductsSubtitle => 'Nevera, mesa, estante — hasta 3 fotos';
} }

View File

@@ -287,4 +287,24 @@ class AppLocalizationsFr extends AppLocalizations {
@override @override
String get navRecipes => 'Recettes'; String get navRecipes => 'Recettes';
@override
String get addFromReceiptOrPhoto => 'Ajouter depuis ticket ou photo';
@override
String get chooseMethod => 'Choisir la méthode';
@override
String get photoReceipt => 'Photographier le ticket';
@override
String get photoReceiptSubtitle =>
'Reconnaissance de tous les produits du ticket';
@override
String get photoProducts => 'Photographier les produits';
@override
String get photoProductsSubtitle =>
'Réfrigérateur, table, étagère — jusqu\'à 3 photos';
} }

View File

@@ -287,4 +287,22 @@ class AppLocalizationsHi extends AppLocalizations {
@override @override
String get navRecipes => 'रेसिपी'; String get navRecipes => 'रेसिपी';
@override
String get addFromReceiptOrPhoto => 'रसीद या फ़ोटो से जोड़ें';
@override
String get chooseMethod => 'तरीका चुनें';
@override
String get photoReceipt => 'रसीद की फ़ोटो';
@override
String get photoReceiptSubtitle => 'रसीद से सभी उत्पाद पहचानें';
@override
String get photoProducts => 'उत्पादों की फ़ोटो';
@override
String get photoProductsSubtitle => 'फ्रिज, टेबल, शेल्फ — 3 फ़ोटो तक';
} }

View File

@@ -287,4 +287,23 @@ class AppLocalizationsIt extends AppLocalizations {
@override @override
String get navRecipes => 'Ricette'; String get navRecipes => 'Ricette';
@override
String get addFromReceiptOrPhoto => 'Aggiungi da scontrino o foto';
@override
String get chooseMethod => 'Scegli il metodo';
@override
String get photoReceipt => 'Fotografa scontrino';
@override
String get photoReceiptSubtitle =>
'Riconosciamo tutti i prodotti dallo scontrino';
@override
String get photoProducts => 'Fotografa i prodotti';
@override
String get photoProductsSubtitle => 'Frigo, tavolo, scaffale — fino a 3 foto';
} }

View File

@@ -285,4 +285,22 @@ class AppLocalizationsJa extends AppLocalizations {
@override @override
String get navRecipes => 'レシピ'; String get navRecipes => 'レシピ';
@override
String get addFromReceiptOrPhoto => 'レシートや写真から追加';
@override
String get chooseMethod => '方法を選択';
@override
String get photoReceipt => 'レシートを撮影';
@override
String get photoReceiptSubtitle => 'レシートから全商品を認識';
@override
String get photoProducts => '食品を撮影';
@override
String get photoProductsSubtitle => '冷蔵庫・テーブル・棚 — 最大3枚';
} }

View File

@@ -285,4 +285,22 @@ class AppLocalizationsKo extends AppLocalizations {
@override @override
String get navRecipes => '레시피'; String get navRecipes => '레시피';
@override
String get addFromReceiptOrPhoto => '영수증 또는 사진으로 추가';
@override
String get chooseMethod => '방법 선택';
@override
String get photoReceipt => '영수증 촬영';
@override
String get photoReceiptSubtitle => '영수증의 모든 상품 인식';
@override
String get photoProducts => '식품 촬영';
@override
String get photoProductsSubtitle => '냉장고, 테이블, 선반 — 최대 3장';
} }

View File

@@ -287,4 +287,23 @@ class AppLocalizationsPt extends AppLocalizations {
@override @override
String get navRecipes => 'Receitas'; String get navRecipes => 'Receitas';
@override
String get addFromReceiptOrPhoto => 'Adicionar de recibo ou foto';
@override
String get chooseMethod => 'Escolher método';
@override
String get photoReceipt => 'Fotografar recibo';
@override
String get photoReceiptSubtitle => 'Reconhecemos todos os produtos do recibo';
@override
String get photoProducts => 'Fotografar produtos';
@override
String get photoProductsSubtitle =>
'Geladeira, mesa, prateleira — até 3 fotos';
} }

View File

@@ -286,4 +286,22 @@ class AppLocalizationsRu extends AppLocalizations {
@override @override
String get navRecipes => 'Рецепты'; String get navRecipes => 'Рецепты';
@override
String get addFromReceiptOrPhoto => 'Добавить из чека или фото';
@override
String get chooseMethod => 'Выберите способ';
@override
String get photoReceipt => 'Сфотографировать чек';
@override
String get photoReceiptSubtitle => 'Распознаем все продукты из чека';
@override
String get photoProducts => 'Сфотографировать продукты';
@override
String get photoProductsSubtitle => 'Холодильник, стол, полка — до 3 фото';
} }

View File

@@ -285,4 +285,22 @@ class AppLocalizationsZh extends AppLocalizations {
@override @override
String get navRecipes => '食谱'; String get navRecipes => '食谱';
@override
String get addFromReceiptOrPhoto => '从收据或照片添加';
@override
String get chooseMethod => '选择方式';
@override
String get photoReceipt => '拍摄收据';
@override
String get photoReceiptSubtitle => '识别收据中的所有商品';
@override
String get photoProducts => '拍摄食品';
@override
String get photoProductsSubtitle => '冰箱、桌子、货架 — 最多3张照片';
} }

View File

@@ -96,5 +96,11 @@
"mealTypeSnack": "Petisco", "mealTypeSnack": "Petisco",
"navHome": "Início", "navHome": "Início",
"navProducts": "Produtos", "navProducts": "Produtos",
"navRecipes": "Receitas" "navRecipes": "Receitas",
"addFromReceiptOrPhoto": "Adicionar de recibo ou foto",
"chooseMethod": "Escolher método",
"photoReceipt": "Fotografar recibo",
"photoReceiptSubtitle": "Reconhecemos todos os produtos do recibo",
"photoProducts": "Fotografar produtos",
"photoProductsSubtitle": "Geladeira, mesa, prateleira — até 3 fotos"
} }

View File

@@ -96,5 +96,11 @@
"mealTypeSnack": "Перекус", "mealTypeSnack": "Перекус",
"navHome": "Главная", "navHome": "Главная",
"navProducts": "Продукты", "navProducts": "Продукты",
"navRecipes": "Рецепты" "navRecipes": "Рецепты",
"addFromReceiptOrPhoto": "Добавить из чека или фото",
"chooseMethod": "Выберите способ",
"photoReceipt": "Сфотографировать чек",
"photoReceiptSubtitle": "Распознаем все продукты из чека",
"photoProducts": "Сфотографировать продукты",
"photoProductsSubtitle": "Холодильник, стол, полка — до 3 фото"
} }

View File

@@ -96,5 +96,11 @@
"mealTypeSnack": "零食", "mealTypeSnack": "零食",
"navHome": "首页", "navHome": "首页",
"navProducts": "食品", "navProducts": "食品",
"navRecipes": "食谱" "navRecipes": "食谱",
"addFromReceiptOrPhoto": "从收据或照片添加",
"chooseMethod": "选择方式",
"photoReceipt": "拍摄收据",
"photoReceiptSubtitle": "识别收据中的所有商品",
"photoProducts": "拍摄食品",
"photoProductsSubtitle": "冰箱、桌子、货架 — 最多3张照片"
} }

View File

@@ -125,10 +125,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.1" version: "1.4.0"
checked_yaml: checked_yaml:
dependency: transitive dependency: transitive
description: description:
@@ -689,26 +689,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.12.19" version: "0.12.17"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.13.0" version: "0.11.1"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.17.0" version: "1.16.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@@ -1070,10 +1070,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.10" version: "0.7.6"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description: