summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxAlpharax <42233094+xAlpharax@users.noreply.github.com>2023-09-28 19:02:06 +0300
committerxAlpharax <42233094+xAlpharax@users.noreply.github.com>2023-09-28 19:02:06 +0300
commit7606ef1d9872ca0466e57779aeaf0ce690cac69b (patch)
tree65c985972734ed2bb146abd578eaf8ced3c2eb1e
parent549a51b021217a25426625a962ede562bb069191 (diff)
Getting basic functionalities over from the OCR app like the camera.
Changes to be committed: modified: lib/main.dart new file: lib/result_screen.dart modified: pubspec.lock modified: pubspec.yaml modified: test/widget_test.dart
-rw-r--r--lib/main.dart284
-rw-r--r--lib/result_screen.dart19
-rw-r--r--pubspec.lock280
-rw-r--r--pubspec.yaml6
-rw-r--r--test/widget_test.dart2
5 files changed, 515 insertions, 76 deletions
diff --git a/lib/main.dart b/lib/main.dart
index d7cd012..30c90ef 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,107 +1,249 @@
import 'package:camera/camera.dart';
import 'package:permission_handler/permission_handler.dart';
+import 'package:google_mlkit_text_recognition/google_mlkit_text_recognition.dart';
+import 'package:google_mlkit_object_detection/google_mlkit_object_detection.dart';
import 'package:flutter_tflite/flutter_tflite.dart';
import 'package:flutter_tts/flutter_tts.dart';
+import 'package:yolo/result_screen.dart';
import 'package:flutter/material.dart';
import 'dart:io';
void main() {
- runApp(const MyApp());
+ runApp(const App());
}
-class MyApp extends StatelessWidget {
- const MyApp({super.key});
+class App extends StatelessWidget {
+ const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
- title: 'Flutter Demo',
+ title: 'MegaView',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurpleAccent),
useMaterial3: true,
),
debugShowCheckedModeBanner: false,
- home: const MyHomePage(title: 'Flutter Demo Home Page'),
+ home: const MainScreen(),
);
}
}
-class MyHomePage extends StatefulWidget {
- const MyHomePage({super.key, required this.title});
-
- final String title;
+class MainScreen extends StatefulWidget {
+ const MainScreen({super.key});
@override
- State<MyHomePage> createState() => _MyHomePageState();
+ State<MainScreen> createState() => _MainScreenState();
}
-class _MyHomePageState extends State<MyHomePage> {
- int _counter = 0;
-
- void _incrementCounter() {
- setState(() {
- // This call to setState tells the Flutter framework that something has
- // changed in this State, which causes it to rerun the build method below
- // so that the display can reflect the updated values. If we changed
- // _counter without calling setState(), then the build method would not be
- // called again, and so nothing would appear to happen.
- _counter++;
- });
+class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
+ bool _isPermissionGranted = false;
+
+ late final Future<void> _future;
+ CameraController? _cameraController;
+
+ final textRecognizer = TextRecognizer();
+
+ FlutterTts flutterTts = FlutterTts(); // TTS
+
+ @override
+ void initState() {
+ super.initState();
+ initTTS(); // TTS
+
+ WidgetsBinding.instance.addObserver(this);
+
+ _future = _requestCameraPermission();
+ }
+
+ Future<void> initTTS() async { // TTS
+ await flutterTts.setLanguage("en-US"); // Set the language you want
+ await flutterTts.setSpeechRate(0.5); // Adjust speech rate (1.0 is normal but too fast for my liking)
+ await flutterTts.setVolume(1.0); // Adjust volume (0.0 to 1.0)
+ await flutterTts.setPitch(1.0); // Adjust pitch (1.0 is normal)
+
+ // You can set other configurations as well
+
+ // Check if TTS is available
+ // bool isAvailable = await flutterTts.isLanguageAvailable("en-US");
+ // print("TTS is available: $isAvailable");
+ }
+
+ Future<void> speak(String text) async {
+ await flutterTts.speak(text); // TTS
+ }
+
+ @override
+ void dispose() {
+ WidgetsBinding.instance.removeObserver(this);
+ _stopCamera();
+ textRecognizer.close();
+ flutterTts.stop(); // TTS Stop
+ super.dispose();
+ }
+
+ @override
+ void didChangeAppLifecycleState(AppLifecycleState state) {
+ if (_cameraController == null || !_cameraController!.value.isInitialized) {
+ return;
+ }
+
+ if (state == AppLifecycleState.inactive) {
+ _stopCamera();
+ } else if (state == AppLifecycleState.resumed &&
+ _cameraController != null &&
+ _cameraController!.value.isInitialized) {
+ _startCamera();
+ }
}
@override
Widget build(BuildContext context) {
- // This method is rerun every time setState is called, for instance as done
- // by the _incrementCounter method above.
- //
- // The Flutter framework has been optimized to make rerunning build methods
- // fast, so that you can just rebuild anything that needs updating rather
- // than having to individually change instances of widgets.
- return Scaffold(
- appBar: AppBar(
- // TRY THIS: Try changing the color here to a specific color (to
- // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
- // change color while the other colors stay the same.
- backgroundColor: Theme.of(context).colorScheme.inversePrimary,
- // Here we take the value from the MyHomePage object that was created by
- // the App.build method, and use it to set our appbar title.
- title: Text(widget.title),
- ),
- body: Center(
- // Center is a layout widget. It takes a single child and positions it
- // in the middle of the parent.
- child: Column(
- // Column is also a layout widget. It takes a list of children and
- // arranges them vertically. By default, it sizes itself to fit its
- // children horizontally, and tries to be as tall as its parent.
- //
- // Column has various properties to control how it sizes itself and
- // how it positions its children. Here we use mainAxisAlignment to
- // center the children vertically; the main axis here is the vertical
- // axis because Columns are vertical (the cross axis would be
- // horizontal).
- //
- // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
- // action in the IDE, or press "p" in the console), to see the
- // wireframe for each widget.
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- const Text(
- 'You have pushed the button this many times:',
- ),
- Text(
- '$_counter',
- style: Theme.of(context).textTheme.headlineMedium,
+ return FutureBuilder(
+ future: _future,
+ builder: (context, snapshot) {
+ return Stack(
+ children: [
+ if (_isPermissionGranted)
+ FutureBuilder<List<CameraDescription>>(
+ future: availableCameras(),
+ builder: (context, snapshot) {
+ if (snapshot.hasData) {
+ _initCameraController(snapshot.data!);
+
+ return Center(child: CameraPreview(_cameraController!));
+ } else {
+ return const LinearProgressIndicator();
+ }
+ },
+ ),
+ Scaffold(
+ appBar: AppBar(
+ backgroundColor: Theme.of(context).colorScheme.inversePrimary,
+ title: const Text('MegaView Text Recognition'),
+ ),
+ backgroundColor: _isPermissionGranted ? Colors.transparent : null,
+ body: _isPermissionGranted
+ ? Column(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ Container(),
+ Container(
+ color: Theme.of(context).colorScheme.inversePrimary,
+ alignment: Alignment.center,
+ child: Padding(
+ padding: const EdgeInsets.symmetric(vertical: 8.0),
+ child: ElevatedButton(
+ onPressed: _scanImage,
+ style: ButtonStyle(
+ minimumSize: MaterialStateProperty.all<Size>(
+ const Size(256, 64), // Set the desired width and height
+ ),
+ ),
+ child: const Text('Scan text'),
+ ),
+ ),
+ ),
+ ],
+ )
+ : Center(
+ child: Container(
+ padding: const EdgeInsets.only(left: 24.0, right: 24.0),
+ child: const Text(
+ 'Camera permission denied',
+ textAlign: TextAlign.center,
+ ),
+ ),
+ ),
),
],
- ),
- ),
- floatingActionButton: FloatingActionButton(
- onPressed: _incrementCounter,
- tooltip: 'Increment',
- child: const Icon(Icons.add),
- ), // This trailing comma makes auto-formatting nicer for build methods.
+ );
+ },
);
}
-}
+
+ Future<void> _requestCameraPermission() async {
+ final status = await Permission.camera.request();
+ _isPermissionGranted = status == PermissionStatus.granted;
+ }
+
+ void _startCamera() {
+ if (_cameraController != null) {
+ _cameraSelected(_cameraController!.description);
+ }
+ }
+
+ void _stopCamera() {
+ if (_cameraController != null) {
+ _cameraController?.dispose();
+ }
+ }
+
+ void _initCameraController(List<CameraDescription> cameras) {
+ if (_cameraController != null) {
+ return;
+ }
+
+ // Select the first rear camera.
+ CameraDescription? camera;
+ for (var i = 0; i < cameras.length; i++) {
+ final CameraDescription current = cameras[i];
+ if (current.lensDirection == CameraLensDirection.back) {
+ camera = current;
+ break;
+ }
+ }
+
+ if (camera != null) {
+ _cameraSelected(camera);
+ }
+ }
+
+ Future<void> _cameraSelected(CameraDescription camera) async {
+ _cameraController = CameraController(
+ camera,
+ ResolutionPreset.high,
+ enableAudio: false,
+ );
+
+ await _cameraController!.initialize();
+ await _cameraController!.setFlashMode(FlashMode.off);
+
+ if (!mounted) {
+ return;
+ }
+ setState(() {});
+ }
+
+ Future<void> _scanImage() async {
+ if (_cameraController == null) return;
+
+ final navigator = Navigator.of(context);
+
+ try {
+ final pictureFile = await _cameraController!.takePicture();
+
+ final file = File(pictureFile.path);
+
+ final inputImage = InputImage.fromFile(file);
+ final recognizedText = await textRecognizer.processImage(inputImage);
+
+ speak(recognizedText.text);
+
+ await navigator.push(
+ MaterialPageRoute(
+ builder: (BuildContext context) =>
+ ResultScreen(text: recognizedText.text)
+ ),
+ );
+ } catch (e) {
+ // ignore: use_build_context_synchronously
+ ScaffoldMessenger.of(context).showSnackBar(
+ const SnackBar(
+ content: Text('An error occurred when scanning text'),
+ ),
+ );
+ }
+ }
+} \ No newline at end of file
diff --git a/lib/result_screen.dart b/lib/result_screen.dart
new file mode 100644
index 0000000..d5a64ea
--- /dev/null
+++ b/lib/result_screen.dart
@@ -0,0 +1,19 @@
+import 'package:flutter/material.dart';
+
+class ResultScreen extends StatelessWidget {
+ final String text;
+
+ const ResultScreen({super.key, required this.text});
+
+ @override
+ Widget build(BuildContext context) => Scaffold(
+ appBar: AppBar(
+ //backgroundColor: Theme.of(context).colorScheme.inversePrimary,
+ title: const Text('Result'),
+ ),
+ body: Container(
+ padding: const EdgeInsets.all(30.0),
+ child: Text(text),
+ ),
+ );
+} \ No newline at end of file
diff --git a/pubspec.lock b/pubspec.lock
index 25dd5dc..46fabca 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -153,6 +153,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.1"
+ ffi:
+ dependency: transitive
+ description:
+ name: ffi
+ sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.0"
file_selector_linux:
dependency: transitive
description:
@@ -165,10 +173,10 @@ packages:
dependency: transitive
description:
name: file_selector_macos
- sha256: "182c3f8350cee659f7b115e956047ee3dc672a96665883a545e81581b9a82c72"
+ sha256: b15c3da8bd4908b9918111fa486903f5808e388b8d1c559949f584725a6594d6
url: "https://pub.dev"
source: hosted
- version: "0.9.3+2"
+ version: "0.9.3+3"
file_selector_platform_interface:
dependency: transitive
description:
@@ -214,6 +222,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.16"
+ flutter_sound:
+ dependency: "direct main"
+ description:
+ name: flutter_sound
+ sha256: "090a4694b11ecc744c2010621c4ffc5fe7c3079d304ea014961a72c7b72cfe6c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "9.2.13"
+ flutter_sound_platform_interface:
+ dependency: transitive
+ description:
+ name: flutter_sound_platform_interface
+ sha256: "4537eaeb58a32748c42b621ad6116f7f4c6ee0a8d6ffaa501b165fe1c9df4753"
+ url: "https://pub.dev"
+ source: hosted
+ version: "9.2.13"
+ flutter_sound_web:
+ dependency: transitive
+ description:
+ name: flutter_sound_web
+ sha256: ad4ca92671a1879e1f613e900bbbdb8170b20d57d1e4e6363018fe56b055594f
+ url: "https://pub.dev"
+ source: hosted
+ version: "9.2.13"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -240,6 +272,126 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ google_ml_kit:
+ dependency: "direct main"
+ description:
+ name: google_ml_kit
+ sha256: "9d98ed5ff96c1295d08f96c807a70d53b56a43a7a18ae86d4ea4d09cf7310fc9"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.16.2"
+ google_mlkit_barcode_scanning:
+ dependency: transitive
+ description:
+ name: google_mlkit_barcode_scanning
+ sha256: "033401bc992315fe3d6ed9265b97bf1e620fa12ddaffda830107d6852abcde77"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.9.0"
+ google_mlkit_commons:
+ dependency: transitive
+ description:
+ name: google_mlkit_commons
+ sha256: "42173a8ba89f386486cc5b8249e84da4a4b861daa70498373627d985eb418689"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.5.0"
+ google_mlkit_digital_ink_recognition:
+ dependency: transitive
+ description:
+ name: google_mlkit_digital_ink_recognition
+ sha256: f48a90cd2bb8dc6a0432a1ba89a1a488d4e7ba3132fe4dfd75a9eab0e0a1b90a
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.9.0"
+ google_mlkit_entity_extraction:
+ dependency: transitive
+ description:
+ name: google_mlkit_entity_extraction
+ sha256: e4801253f9913a84793f338fb45923825fc2799f8608a1f0d0f5ca43b5062fbc
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.0"
+ google_mlkit_face_detection:
+ dependency: transitive
+ description:
+ name: google_mlkit_face_detection
+ sha256: "567339c67530b22b22917622df9bba40547a4719fa108819901f95ffb7cd3399"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.8.0"
+ google_mlkit_face_mesh_detection:
+ dependency: transitive
+ description:
+ name: google_mlkit_face_mesh_detection
+ sha256: "3f64635fe096fef3167da6f69a30b1744ddfb4590acdaa2b7757c6f30455b0f5"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.0.1"
+ google_mlkit_image_labeling:
+ dependency: transitive
+ description:
+ name: google_mlkit_image_labeling
+ sha256: "38c7225e22ec558bfd78015ef9e9ae4812cee8715f03a9c82b87d3e0b530d00c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.9.0"
+ google_mlkit_language_id:
+ dependency: transitive
+ description:
+ name: google_mlkit_language_id
+ sha256: cb4241297552f22be638be620add294b6a6c9043eefc1f4c18597ee66ce31a98
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.8.0"
+ google_mlkit_object_detection:
+ dependency: "direct main"
+ description:
+ name: google_mlkit_object_detection
+ sha256: "52b11c335cbf45da561127de586e1ab32ba5526eb04d7a3a683c787279a47153"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.0"
+ google_mlkit_pose_detection:
+ dependency: transitive
+ description:
+ name: google_mlkit_pose_detection
+ sha256: "08759fc095751cf84f6758f276212881388e04210c64087341e260f9f233316e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.9.0"
+ google_mlkit_selfie_segmentation:
+ dependency: transitive
+ description:
+ name: google_mlkit_selfie_segmentation
+ sha256: "5b2931f86e9476daaf5710f9e0d281ec06f7d0ee664a3688b791bfcfb7c4afd5"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.5.0"
+ google_mlkit_smart_reply:
+ dependency: transitive
+ description:
+ name: google_mlkit_smart_reply
+ sha256: "97165ea8667aa94de20d782862ecd791daf0e884c48b8cb1cedd9ebafda5d52c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.8.0"
+ google_mlkit_text_recognition:
+ dependency: "direct main"
+ description:
+ name: google_mlkit_text_recognition
+ sha256: "588021c99536fdfb173eeecc4ee1b60ea4e0bd4be9787f52363c85346ae20364"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.0"
+ google_mlkit_translation:
+ dependency: transitive
+ description:
+ name: google_mlkit_translation
+ sha256: "175a0cb801b5fa01140f62344bbda6a8dcbb7977ae057f1dab1b74eddc60d71c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.8.0"
http:
dependency: transitive
description:
@@ -276,10 +428,10 @@ packages:
dependency: transitive
description:
name: image_picker_android
- sha256: d32a997bcc4ee135aebca8e272b7c517927aa65a74b9c60a81a2764ef1a0462d
+ sha256: "0c7b83bbe2980c8a8e36e974f055e11e51675784e13a4762889feed0f3937ff2"
url: "https://pub.dev"
source: hosted
- version: "0.8.7+5"
+ version: "0.8.8+1"
image_picker_for_web:
dependency: transitive
description:
@@ -352,6 +504,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.1"
+ logger:
+ dependency: transitive
+ description:
+ name: logger
+ sha256: "7ad7215c15420a102ec687bb320a7312afd449bac63bfb1c60d9787c27b9767f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.4.0"
matcher:
dependency: transitive
description:
@@ -384,6 +544,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.4"
+ nested:
+ dependency: transitive
+ description:
+ name: nested
+ sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.0"
path:
dependency: transitive
description:
@@ -392,6 +560,54 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.8.3"
+ path_provider:
+ dependency: transitive
+ description:
+ name: path_provider
+ sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.1"
+ path_provider_android:
+ dependency: transitive
+ description:
+ name: path_provider_android
+ sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.0"
+ path_provider_foundation:
+ dependency: transitive
+ description:
+ name: path_provider_foundation
+ sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.1"
+ path_provider_linux:
+ dependency: transitive
+ description:
+ name: path_provider_linux
+ sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.1"
+ path_provider_platform_interface:
+ dependency: transitive
+ description:
+ name: path_provider_platform_interface
+ sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.1"
+ path_provider_windows:
+ dependency: transitive
+ description:
+ name: path_provider_windows
+ sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.1"
permission_handler:
dependency: "direct main"
description:
@@ -440,6 +656,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.4.0"
+ platform:
+ dependency: transitive
+ description:
+ name: platform
+ sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.2"
plugin_platform_interface:
dependency: transitive
description:
@@ -456,6 +680,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.7.3"
+ provider:
+ dependency: transitive
+ description:
+ name: provider
+ sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.0.5"
quiver:
dependency: transitive
description:
@@ -464,6 +696,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.2.1"
+ recase:
+ dependency: transitive
+ description:
+ name: recase
+ sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.1.0"
sky_engine:
dependency: transitive
description: flutter
@@ -509,6 +749,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
+ synchronized:
+ dependency: transitive
+ description:
+ name: synchronized
+ sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.0"
term_glyph:
dependency: transitive
description:
@@ -533,6 +781,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.2"
+ uuid:
+ dependency: transitive
+ description:
+ name: uuid
+ sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.7"
vector_math:
dependency: transitive
description:
@@ -549,6 +805,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
+ win32:
+ dependency: transitive
+ description:
+ name: win32
+ sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.0.9"
+ xdg_directories:
+ dependency: transitive
+ description:
+ name: xdg_directories
+ sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.3"
xml:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 65a1cdc..9dc7251 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -15,6 +15,12 @@ dependencies:
permission_handler: ^10.4.3
flutter_tts: ^3.8.2
+ google_mlkit_text_recognition: ^0.10.0
+ google_mlkit_object_detection: ^0.10.0
+
+ flutter_sound: ^9.2.13
+ google_ml_kit: ^0.16.2
+
cupertino_icons: ^1.0.2
dev_dependencies:
diff --git a/test/widget_test.dart b/test/widget_test.dart
index e980ae6..58066c6 100644
--- a/test/widget_test.dart
+++ b/test/widget_test.dart
@@ -13,7 +13,7 @@ import 'package:yolo/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
- await tester.pumpWidget(const MyApp());
+ await tester.pumpWidget(const App());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);