diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml
index 60aebe4f..17b388b0 100644
--- a/.gitea/workflows/test.yml
+++ b/.gitea/workflows/test.yml
@@ -3,7 +3,7 @@ name: Eatvio App Android Test
on: [ pull_request ]
env:
- flutter_version: "3.35.1"
+ flutter_version: "3.38.1"
java_version: "21.x"
flutter_channel: "stable"
my_local_cache_dir: "/opt/hostedtoolcache/"
@@ -71,7 +71,7 @@ jobs:
- name: Install utils for Android SDK
run: |
apt-get update
- apt-get install -y openjdk-11-jdk wget jq clang cmake ninja-build libgtk-3-dev
+ apt-get install -y openjdk-17-jdk wget jq clang cmake ninja-build libgtk-3-dev
- name: Install Android SDK
if: steps.cache-sdk.outputs.cache-hit != 'true'
diff --git a/android/build/reports/problems/problems-report.html b/android/build/reports/problems/problems-report.html
index ce07f9e3..746fadde 100644
--- a/android/build/reports/problems/problems-report.html
+++ b/android/build/reports/problems/problems-report.html
@@ -650,7 +650,7 @@ code + .copy-button {
diff --git a/lib/features/diary/presentation/pages/barcode_scanner_screen.dart b/lib/features/diary/presentation/pages/barcode_scanner_screen.dart
new file mode 100644
index 00000000..19994568
--- /dev/null
+++ b/lib/features/diary/presentation/pages/barcode_scanner_screen.dart
@@ -0,0 +1,87 @@
+import 'package:flutter/material.dart';
+import 'package:mobile_scanner/mobile_scanner.dart';
+
+class BarcodeScannerScreen extends StatefulWidget {
+ const BarcodeScannerScreen({super.key});
+
+ @override
+ State createState() => _BarcodeScannerScreenState();
+}
+
+class _BarcodeScannerScreenState extends State {
+ final MobileScannerController _controller = MobileScannerController();
+ String? _detectedBarcode;
+
+ @override
+ void dispose() {
+ _controller.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: const Text('Сканирование штрихкода'),
+ centerTitle: true,
+ ),
+ body: Column(
+ children: [
+ Expanded(
+ child: MobileScanner(
+ controller: _controller,
+ onDetect: (capture) {
+ final List barcodes = capture.barcodes;
+ if (barcodes.isEmpty) return;
+ final rawValue = barcodes.first.rawValue;
+ if (rawValue == null || rawValue == _detectedBarcode) return;
+ setState(() {
+ _detectedBarcode = rawValue;
+ });
+ },
+ ),
+ ),
+ Container(
+ width: double.infinity,
+ padding: const EdgeInsets.all(16),
+ decoration: const BoxDecoration(
+ color: Color(0xFFF6F6F6),
+ borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
+ ),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Text(
+ 'Найденный штрихкод',
+ style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
+ ),
+ const SizedBox(height: 8),
+ Text(
+ _detectedBarcode ?? 'Наведите камеру на штрихкод',
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w600,
+ color: _detectedBarcode == null ? Colors.grey : Colors.black,
+ ),
+ ),
+ const SizedBox(height: 16),
+ if (_detectedBarcode != null)
+ SizedBox(
+ width: double.infinity,
+ child: ElevatedButton(
+ onPressed: () {
+ Navigator.of(context).pop(_detectedBarcode);
+ },
+ child: const Text('Использовать штрихкод'),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
+
diff --git a/lib/features/diary/presentation/widgets/add_product_modal.dart b/lib/features/diary/presentation/widgets/add_product_modal.dart
index 4b0a3806..9d77249e 100644
--- a/lib/features/diary/presentation/widgets/add_product_modal.dart
+++ b/lib/features/diary/presentation/widgets/add_product_modal.dart
@@ -5,9 +5,11 @@ import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart';
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
+import 'package:eatvio_app/features/diary/presentation/pages/barcode_scanner_screen.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/glossary_moderation_request_modal_widget.dart';
import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
import 'package:flutter/material.dart';
+import 'package:material_symbols_icons/material_symbols_icons.dart';
class AddProductModal extends StatefulWidget {
final PortionModel? portion;
@@ -62,9 +64,25 @@ class _AddProductModalState extends State {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
- const Text(
- 'Добавление блюда',
- style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600, color: Color(0xFF323F4B)),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ const Text(
+ 'Добавление блюда',
+ style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600, color: Color(0xFF323F4B)),
+ ),
+ IconButton(
+ onPressed: () async {
+ final barcode = await Navigator.of(context).push(MaterialPageRoute(builder: (context) => const BarcodeScannerScreen()));
+ if (barcode != null && barcode.isNotEmpty) {
+ productNameController.text = barcode;
+ setState(() {});
+ }
+ },
+ splashRadius: 20,
+ icon: const Icon(Symbols.barcode_scanner, color: Color(0xFF323F4B)),
+ ),
+ ],
),
const SizedBox(height: 16),
Row(
diff --git a/pubspec.yaml b/pubspec.yaml
index 96d5b2b2..7f6f9014 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -79,6 +79,7 @@ dependencies:
markdown: ^7.3.0
flutter_password_generator: ^1.0.3
mobile_scanner: ^7.1.3
+ material_symbols_icons: ^4.2874.0
dev_dependencies:
build_runner: ^2.7.0