From 5ce0ec4f8006a7f14fdcd61a2507ddb051ef06e6 Mon Sep 17 00:00:00 2001 From: Fransolet Thomas Date: Thu, 18 Aug 2022 18:12:45 +0200 Subject: [PATCH] Scanner popup + list config + check internet --- .flutter-plugins-dependencies | 2 +- lib/Components/Loading.dart | 19 ++ lib/Components/ScannerBouton.dart | 1 - lib/Components/ScannerDialog.dart | 234 +++++++++++------- lib/Helpers/networkCheck.dart | 10 + lib/Screens/Article/article.dart | 2 +- lib/Screens/Home/home.dart | 182 ++++++++------ .../{scanner.dart => scanner_old.dart} | 2 +- lib/Screens/Visit/visit.dart | 2 +- lib/app_context.dart | 2 +- lib/constants.dart | 10 +- lib/main.dart | 2 +- 12 files changed, 298 insertions(+), 170 deletions(-) create mode 100644 lib/Components/Loading.dart create mode 100644 lib/Helpers/networkCheck.dart rename lib/Screens/Scanner/{scanner.dart => scanner_old.dart} (99%) diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 96ff109..18b8405 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"qr_code_scanner","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\qr_code_scanner-1.0.0\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-2.0.3+1\\\\","native_build":true,"dependencies":[]}],"android":[{"name":"qr_code_scanner","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\qr_code_scanner-1.0.0\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-2.0.3+1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"sqflite","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-2.0.3+1\\\\","native_build":true,"dependencies":[]}],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"qr_code_scanner","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2022-08-12 17:52:32.581414","version":"3.0.3"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"qr_code_scanner","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\qr_code_scanner-1.0.0\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-2.0.3+1\\\\","native_build":true,"dependencies":[]}],"android":[{"name":"qr_code_scanner","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\qr_code_scanner-1.0.0\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-2.0.3+1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"sqflite","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-2.0.3+1\\\\","native_build":true,"dependencies":[]}],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"qr_code_scanner","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2022-08-18 17:59:37.167796","version":"3.0.3"} \ No newline at end of file diff --git a/lib/Components/Loading.dart b/lib/Components/Loading.dart new file mode 100644 index 0000000..4bc123a --- /dev/null +++ b/lib/Components/Loading.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:mymuseum_visitapp/constants.dart'; + +class Loading extends StatelessWidget { + const Loading({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + height: 85.0, + width: 85.0, + child: const Center( + child: Text("Loading.."), + ), + ); + } +} + + diff --git a/lib/Components/ScannerBouton.dart b/lib/Components/ScannerBouton.dart index 89d96a6..d8f00a2 100644 --- a/lib/Components/ScannerBouton.dart +++ b/lib/Components/ScannerBouton.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:mymuseum_visitapp/Screens/Scanner/scanner.dart'; import 'package:mymuseum_visitapp/constants.dart'; import 'ScannerDialog.dart'; diff --git a/lib/Components/ScannerDialog.dart b/lib/Components/ScannerDialog.dart index 07a8ae4..463fda7 100644 --- a/lib/Components/ScannerDialog.dart +++ b/lib/Components/ScannerDialog.dart @@ -1,10 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:mymuseum_visitapp/Screens/Scanner/scanner.dart'; import 'dart:io'; import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:mymuseum_visitapp/Components/CustomAppBar.dart'; import 'package:mymuseum_visitapp/Screens/Article/article.dart'; +import 'package:mymuseum_visitapp/constants.dart'; import 'package:qr_code_scanner/qr_code_scanner.dart'; @@ -36,89 +34,153 @@ class _ScannerTESTState extends State { Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; return Container( - height: size.height *0.6, + height: size.height *0.5, width: size.width *0.9, - color: Colors.blueAccent, - child: Column( - children: [ - Expanded(flex: 4, child: _buildQrView(context)), - Expanded( - flex: 1, - child: FittedBox( - fit: BoxFit.contain, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - margin: const EdgeInsets.all(8), - child: ElevatedButton( - onPressed: () async { - await controller?.toggleFlash(); - setState(() {}); - }, - child: FutureBuilder( - future: controller?.getFlashStatus(), - builder: (context, snapshot) { - return Icon(Icons.flash_on); - }, - )), - ), - Container( - margin: const EdgeInsets.all(8), - child: ElevatedButton( - onPressed: () async { - await controller?.flipCamera(); - setState(() {}); - }, - child: FutureBuilder( - future: controller?.getCameraInfo(), - builder: (context, snapshot) { - if (snapshot.data != null) { - return Text( - 'Camera facing ${describeEnum(snapshot.data!)}'); - } else { - return const Text('loading'); - } - }, - )), - ) - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - margin: const EdgeInsets.all(8), - child: ElevatedButton( - onPressed: () async { - await controller?.pauseCamera(); - }, - child: const Text('pause', - style: TextStyle(fontSize: 20)), - ), - ), - Container( - margin: const EdgeInsets.all(8), - child: ElevatedButton( - onPressed: () async { - print(controller); - await controller?.resumeCamera(); - }, - child: const Text('resume', - style: TextStyle(fontSize: 20)), - ), - ) - ], - ), - ], + child: Stack( + children: [ + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(10.0), + child: _buildQrView(context), + ) + ), + Positioned( + top: 0, + right: 0, + child: Container( + width: 45, + height: 45, + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: kMainColor, + borderRadius: BorderRadius.circular(20.0), ), + margin: const EdgeInsets.all(8), + child: InkWell( + onTap: () async { + await controller?.toggleFlash(); + setState(() {}); + }, + child: FutureBuilder( + future: controller?.getFlashStatus(), + builder: (context, snapshot) { + return const Icon(Icons.flash_on, color: Colors.white); + }, + )), ), - ) + ), + Positioned( + bottom: 0, + right: 0, + child: Container( + width: 45, + height: 45, + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: kMainColor, + borderRadius: BorderRadius.circular(20.0), + ), + margin: const EdgeInsets.all(8), + child: InkWell( + onTap: () async { + await controller?.flipCamera(); + setState(() {}); + }, + child: FutureBuilder( + future: controller?.getCameraInfo(), + builder: (context, snapshot) { + return const Icon(Icons.flip_camera_android, color: Colors.white); + }, + )), + /*child: FutureBuilder( + future: controller?.getFlashStatus(), + builder: (context, snapshot) { + return Icon(Icons.flip_camera_android, color: Colors.white); + }, + )*/), + ), + /*Column( + children: [ + Expanded(flex: 4, child: _buildQrView(context)), + Expanded( + flex: 1, + child: FittedBox( + fit: BoxFit.contain, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + margin: const EdgeInsets.all(8), + child: ElevatedButton( + onPressed: () async { + await controller?.toggleFlash(); + setState(() {}); + }, + child: FutureBuilder( + future: controller?.getFlashStatus(), + builder: (context, snapshot) { + return Icon(Icons.flash_on); + }, + )), + ), + Container( + margin: const EdgeInsets.all(8), + child: ElevatedButton( + onPressed: () async { + await controller?.flipCamera(); + setState(() {}); + }, + child: FutureBuilder( + future: controller?.getCameraInfo(), + builder: (context, snapshot) { + if (snapshot.data != null) { + return Text( + 'Camera facing ${describeEnum(snapshot.data!)}'); + } else { + return const Text('loading'); + } + }, + )), + ) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + margin: const EdgeInsets.all(8), + child: ElevatedButton( + onPressed: () async { + await controller?.pauseCamera(); + }, + child: const Text('pause', + style: TextStyle(fontSize: 20)), + ), + ), + Container( + margin: const EdgeInsets.all(8), + child: ElevatedButton( + onPressed: () async { + print(controller); + await controller?.resumeCamera(); + }, + child: const Text('resume', + style: TextStyle(fontSize: 20)), + ), + ) + ], + ), + ], + ), + ), + ) + ], + ),*/ ], ), ); @@ -136,7 +198,7 @@ class _ScannerTESTState extends State { key: qrKey, onQRViewCreated: _onQRViewCreated, overlay: QrScannerOverlayShape( - borderColor: Colors.blueAccent, + borderColor: kMainColor, borderRadius: 10, borderLength: 25, borderWidth: 5, @@ -203,8 +265,8 @@ class _ScannerTESTState extends State { showScannerDialog (String question, BuildContext context) { showDialog( - builder: (BuildContext context) => AlertDialog( - shape: const RoundedRectangleBorder( + builder: (BuildContext context) => const AlertDialog( + shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)) ), content: ScannerTEST( diff --git a/lib/Helpers/networkCheck.dart b/lib/Helpers/networkCheck.dart new file mode 100644 index 0000000..cc7fb19 --- /dev/null +++ b/lib/Helpers/networkCheck.dart @@ -0,0 +1,10 @@ +import 'dart:io'; + +Future hasNetwork() async { + try { + final result = await InternetAddress.lookup('example.com'); + return result.isNotEmpty && result[0].rawAddress.isNotEmpty; + } on SocketException catch (_) { + return false; + } +} \ No newline at end of file diff --git a/lib/Screens/Article/article.dart b/lib/Screens/Article/article.dart index d76caef..03cd3a0 100644 --- a/lib/Screens/Article/article.dart +++ b/lib/Screens/Article/article.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:mymuseum_visitapp/Components/CustomAppBar.dart'; import 'package:mymuseum_visitapp/Components/ScannerBouton.dart'; -import 'package:mymuseum_visitapp/Screens/Scanner/scanner.dart'; +import 'package:mymuseum_visitapp/Screens/Scanner/scanner_old.dart'; import 'package:mymuseum_visitapp/constants.dart'; class ArticlePage extends StatefulWidget { diff --git a/lib/Screens/Home/home.dart b/lib/Screens/Home/home.dart index 7df31de..4292dd0 100644 --- a/lib/Screens/Home/home.dart +++ b/lib/Screens/Home/home.dart @@ -1,14 +1,18 @@ +import 'dart:io'; + import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:manager_api/api.dart'; import 'package:mymuseum_visitapp/Components/CustomAppBar.dart'; +import 'package:mymuseum_visitapp/Components/Loading.dart'; import 'package:mymuseum_visitapp/Components/ScannerBouton.dart'; -import 'package:mymuseum_visitapp/Components/ScannerDialog.dart'; -import 'package:mymuseum_visitapp/Screens/Scanner/scanner.dart'; +import 'package:mymuseum_visitapp/Helpers/networkCheck.dart'; import 'package:mymuseum_visitapp/Screens/Visit/visit.dart'; +import 'package:mymuseum_visitapp/app_context.dart'; import 'package:mymuseum_visitapp/client.dart'; import 'package:mymuseum_visitapp/constants.dart'; +import 'package:provider/provider.dart'; class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @@ -18,11 +22,13 @@ class HomePage extends StatefulWidget { } class _HomePageState extends State { - List configurations = [ConfigurationDTO(label: "Test 0", isOffline: false), ConfigurationDTO(label: "Test 1", isOffline: true), ConfigurationDTO(label: "Test 2", isOffline: true)]; + //List configurations = [ConfigurationDTO(label: "Test 0", isOffline: false), ConfigurationDTO(label: "Test 1", isOffline: true), ConfigurationDTO(label: "Test 2", isOffline: true)]; + List configurations = []; @override Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; + final appContext = Provider.of(context); return Scaffold( appBar: CustomAppBar( title: "Home page - liste parcours", @@ -32,84 +38,112 @@ class _HomePageState extends State { child: Container( width: size.width, height: size.height, - child: GridView.builder( - shrinkWrap: true, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 1), - itemCount: configurations.length, - itemBuilder: (BuildContext context, int index) { - return InkWell( - onTap: () { - setState(() { - //sectionSelected = snapshot.data[index]; - print("config selected"); - getConfiguration(); + child: FutureBuilder( + future: getConfiguration(appContext.clientAPI), + builder: (context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + configurations = List.from(snapshot.data).where((configuration) => configuration.isMobile!).toList(); + return RefreshIndicator ( + onRefresh: () { + setState(() {}); + return Future(() => null); + }, + color: kSecondColor, + child: ListView.builder( + shrinkWrap: true, //I've set this as true here depending on what your listview content is + //physics: NeverScrollableScrollPhysics(),//This prevents scrolling, but may inhibit refresh indicator, remove as you need + itemBuilder: (BuildContext context, int index) { + return InkWell( + onTap: () { + setState(() { + print(configurations[index].label); - Navigator.of(context).pushReplacement(MaterialPageRoute( - builder: (context) => const VisitPage(configurationId: "TODO"), - )); - }); - }, - child: Container( - decoration: boxDecoration(configurations[index], false), - padding: const EdgeInsets.all(25), - margin: const EdgeInsets.symmetric(vertical: 25, horizontal: 25), - child: Align( - alignment: Alignment.bottomRight, - child: FractionallySizedBox( - heightFactor: 0.4, - child: Column( - children: [ - Align( - alignment: Alignment.centerRight, - child: AutoSizeText( - configurations[index].label!, - style: const TextStyle(fontSize: kMenuTitleDetailSize), - maxLines: 1, + Navigator.of(context).pushReplacement(MaterialPageRoute( + builder: (context) => VisitPage(configurationId: configurations[index].id!), + )); + }); + }, + child: Container( + height: size.height*0.15, + decoration: boxDecoration(configurations[index], false), + margin: const EdgeInsets.symmetric(vertical: 10, horizontal: 20), + child: Stack( + children: [ + Align( + alignment: Alignment.topLeft, + child: Padding( + padding: const EdgeInsets.only(top: 20, left: 10), + child: AutoSizeText( + configurations[index].label!, + style: const TextStyle(fontSize: kMenuTitleDetailSize), + maxLines: 1, + ), + ), ), - ), - Align( - alignment: Alignment.centerRight, - child: AutoSizeText( - configurations[index].isOffline.toString(), - style: const TextStyle(fontSize: kMenuDescriptionDetailSize, fontFamily: ""), - maxLines: 1, - ), - ), - ], - ) - ), + if(configurations[index].isOffline!) // TODO check if already downloaded + Positioned( + bottom: 0, + right: 0, + child: Container( + width: 45, + height: 45, + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: kMainColor, + borderRadius: BorderRadius.circular(20.0), + ), + margin: const EdgeInsets.all(8), + child: InkWell( + onTap: () async { + print("TODO download"); + }, + child: Icon(Icons.download_outlined, color: Colors.white), + ), + /*AutoSizeText( + configurations[index].isOffline.toString(), + style: const TextStyle(fontSize: kMenuDescriptionDetailSize, fontFamily: ""), + maxLines: 1, + ),*/ + ) + ) + ], + ), + ), + ); + }, + itemCount: configurations.length ), - ), - ); + ); + } else if (snapshot.connectionState == ConnectionState.none) { + return Text("No data"); + } else { + return Center( + child: Container( + height: size.height * 0.15, + child: Loading() + ) + ); + } } ), ), ), floatingActionButton: const ScannerBouton(isReplacement: false), //floatingActionButtonLocation: FloatingActionButtonLocation.miniCenterFloat, - /*bottomNavigationBar: BottomNavigationBar( - items: const [ - BottomNavigationBarItem( - icon: Icon(Icons.home), - label: 'Home', - ), - BottomNavigationBarItem( - icon: Icon(Icons.qr_code_scanner), - label: 'Scanner', - ), - ], - selectedItemColor: kMainRed, - onTap: _onItemTapped, - ),*/ ); } - Future?> getConfiguration() async { + Future?> getConfiguration(Client client) async { try { - var client = new Client("http://192.168.31.140:8089"); - List? configurations = await client.configurationApi!.configurationGet(); - print(configurations); - return configurations; + bool isOnline = await hasNetwork(); + if(isOnline) { + //var client = new Client("http://192.168.31.140:8089"); // TODO REMOVE + List? configurations = await client.configurationApi!.configurationGet(); + print(configurations); + return configurations; + } else { + return []; // TODO return local list.. + } } catch (e) { print(e); print("IN CATCH"); @@ -119,15 +153,15 @@ class _HomePageState extends State { boxDecoration(ConfigurationDTO configuration, bool isSelected) { // TODO to change return BoxDecoration( - color: Colors.cyan, + color: kSecondColor, shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(30.0), + borderRadius: BorderRadius.circular(20.0), boxShadow: const [ BoxShadow( - color: kBackgroundSecondGrey, - spreadRadius: 0.5, - blurRadius: 5, - offset: Offset(0, 1.5), // changes position of shadow + color: kSecondColor, + spreadRadius: 0.15, + blurRadius: 3.5, + offset: Offset(0, 1), // changes position of shadow ), ], ); diff --git a/lib/Screens/Scanner/scanner.dart b/lib/Screens/Scanner/scanner_old.dart similarity index 99% rename from lib/Screens/Scanner/scanner.dart rename to lib/Screens/Scanner/scanner_old.dart index 5581d29..4217b88 100644 --- a/lib/Screens/Scanner/scanner.dart +++ b/lib/Screens/Scanner/scanner_old.dart @@ -7,7 +7,7 @@ import 'package:mymuseum_visitapp/Components/CustomAppBar.dart'; import 'package:mymuseum_visitapp/Screens/Article/article.dart'; import 'package:qr_code_scanner/qr_code_scanner.dart'; - +// NOT USED ANYMORE class ScannerPage extends StatefulWidget { const ScannerPage({Key? key}) : super(key: key); diff --git a/lib/Screens/Visit/visit.dart b/lib/Screens/Visit/visit.dart index 1062d10..e86962d 100644 --- a/lib/Screens/Visit/visit.dart +++ b/lib/Screens/Visit/visit.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:manager_api/api.dart'; import 'package:mymuseum_visitapp/Components/CustomAppBar.dart'; import 'package:mymuseum_visitapp/Components/ScannerBouton.dart'; -import 'package:mymuseum_visitapp/Screens/Scanner/scanner.dart'; +import 'package:mymuseum_visitapp/Screens/Scanner/scanner_old.dart'; import 'package:mymuseum_visitapp/client.dart'; import 'package:mymuseum_visitapp/constants.dart'; diff --git a/lib/app_context.dart b/lib/app_context.dart index be9d9bd..4ee98e7 100644 --- a/lib/app_context.dart +++ b/lib/app_context.dart @@ -6,7 +6,7 @@ import 'Models/visitContext.dart'; class AppContext with ChangeNotifier { VisitAppContext _visitContext; - Client clientAPI = Client(""); + Client clientAPI = Client("http://192.168.31.140:8089"); AppContext(this._visitContext); diff --git a/lib/constants.dart b/lib/constants.dart index 6fac6e8..d98bd39 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -2,7 +2,11 @@ import 'package:flutter/material.dart'; // Colors - TO FILL WIT CORRECT COLOR const kBackgroundColor = Color(0xFFFFFFFF); -const kMainColor = Color(0xFF8b0000); +const kMainColor = Color(0xFF306bac); +const kSecondColor = Color(0xFF309cb0); +const kConfigurationColor = Color(0xFF2F4858); + + const List languages = ["FR", "NL", "EN", "DE"]; // hmmmm depends on config.. @@ -31,8 +35,8 @@ const kDescriptionSize = 25.0; const kSectionTitleDetailSize = 50.0; const kSectionDescriptionDetailSize = 35.0; -const kMenuTitleDetailSize = 45.0; -const kMenuDescriptionDetailSize = 28.0; +const kMenuTitleDetailSize = 30.0; +const kMenuDescriptionDetailSize = 18.0; const kNoneInfoOrIncorrect = 35.0; diff --git a/lib/main.dart b/lib/main.dart index 1cb871d..b63917f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,7 +4,7 @@ import 'package:mymuseum_visitapp/Screens/Home/home.dart'; import 'package:provider/provider.dart'; import 'Models/visitContext.dart'; -import 'Screens/Scanner/scanner.dart'; +import 'Screens/Scanner/scanner_old.dart'; import 'app_context.dart'; import 'constants.dart';