Wip Scanner in dialog + route etc

This commit is contained in:
Fransolet Thomas 2022-08-12 17:56:54 +02:00
parent a0d43f56eb
commit 00a42010b4
19 changed files with 645 additions and 132 deletions

View File

@ -1,2 +1,3 @@
# This is a generated file; do not edit or check into version control.
qr_code_scanner=C:\\Users\\thoma\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dartlang.org\\qr_code_scanner-1.0.0\\
sqflite=C:\\Users\\thoma\\AppData\\Local\\Pub\\Cache\\hosted\\pub.dartlang.org\\sqflite-2.0.3+1\\

View File

@ -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":[]}],"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":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"qr_code_scanner","dependencies":[]}],"date_created":"2022-08-10 17:58:03.305902","version":"3.0.3"}
{"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"}

View File

@ -3,7 +3,7 @@
#
# For more info see: https://dart.dev/go/dot-packages-deprecation
#
# Generated by pub on 2022-08-10 17:15:09.111761.
# Generated by pub on 2022-08-11 17:42:29.200149.
_fe_analyzer_shared:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/_fe_analyzer_shared-31.0.0/lib/
analyzer:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/analyzer-2.8.0/lib/
args:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/args-2.3.1/lib/
@ -34,6 +34,7 @@ file:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/file
fixnum:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/fixnum-1.0.1/lib/
flutter:file:///C:/Users/thoma/Documents/flutter/packages/flutter/lib/
flutter_lints:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/flutter_lints-1.0.4/lib/
flutter_svg:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/flutter_svg-1.1.3/lib/
flutter_test:file:///C:/Users/thoma/Documents/flutter/packages/flutter_test/lib/
flutter_web_plugins:file:///C:/Users/thoma/Documents/flutter/packages/flutter_web_plugins/lib/
glob:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/glob-2.1.0/lib/
@ -52,13 +53,18 @@ matcher:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/m
material_color_utilities:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/material_color_utilities-0.1.4/lib/
meta:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/meta-1.7.0/lib/
mime:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/mime-1.0.2/lib/
nested:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/nested-1.0.0/lib/
openapi_generator:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/openapi_generator-4.0.0/lib/
openapi_generator_annotations:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/openapi_generator_annotations-4.0.0/lib/
openapi_generator_cli:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/openapi_generator_cli-4.0.0/lib/
package_config:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/package_config-2.1.0/lib/
path:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/path-1.8.1/lib/
path_drawing:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/path_drawing-1.0.1/lib/
path_parsing:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/path_parsing-1.0.1/lib/
pedantic:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/pedantic-1.11.1/lib/
petitparser:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/petitparser-5.0.0/lib/
pool:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/pool-1.5.1/lib/
provider:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/provider-5.0.0/lib/
pub_semver:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/pub_semver-2.1.1/lib/
pubspec_parse:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/pubspec_parse-1.2.0/lib/
qr_code_scanner:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/qr_code_scanner-1.0.0/lib/
@ -67,10 +73,13 @@ shelf_web_socket:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartl
sky_engine:file:///C:/Users/thoma/Documents/flutter/bin/cache/pkg/sky_engine/lib/
source_gen:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/source_gen-1.0.5/lib/
source_span:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/source_span-1.8.2/lib/
sqflite:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/sqflite-2.0.3+1/lib/
sqflite_common:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/sqflite_common-2.2.1+1/lib/
stack_trace:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/
stream_channel:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib/
stream_transform:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/stream_transform-2.0.0/lib/
string_scanner:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/string_scanner-1.1.0/lib/
synchronized:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/synchronized-3.0.0+2/lib/
term_glyph:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/term_glyph-1.2.0/lib/
test_api:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/test_api-0.4.9/lib/
timing:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/timing-1.0.0/lib/
@ -78,5 +87,6 @@ typed_data:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.or
vector_math:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/vector_math-2.1.2/lib/
watcher:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/watcher-1.0.1/lib/
web_socket_channel:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/web_socket_channel-2.2.0/lib/
xml:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/xml-6.1.0/lib/
yaml:file:///C:/Users/thoma/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/yaml-3.1.1/lib/
mymuseum_visitapp:lib/

View File

@ -4,4 +4,8 @@
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-feature android:name="android.hardware.camera" />
</manifest>

View File

@ -1,8 +1,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="be.unov.myvisit.mymuseum_visitapp">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-feature android:name="android.hardware.camera" />
<application
android:label="mymuseum_visitapp"
android:name="${applicationName}"

View File

@ -4,4 +4,8 @@
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-feature android:name="android.hardware.camera" />
</manifest>

View File

@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'package:mymuseum_visitapp/Screens/Home/home.dart';
import 'package:mymuseum_visitapp/constants.dart';
//import 'package:flutter_svg/svg.dart';
import 'package:provider/provider.dart';
class CustomAppBar extends StatefulWidget implements PreferredSizeWidget {
CustomAppBar({Key? key, required this.title, required this.isHomeButton});
final String title;
final bool isHomeButton;
final double _preferredHeight = 50;
@override
State<CustomAppBar> createState() => _CustomAppBarState();
@override
Size get preferredSize => Size.fromHeight(_preferredHeight);
}
class _CustomAppBarState extends State<CustomAppBar> {
final double _preferredHeight = 50;
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
//final index = Provider.of<Index>(context);
final notchInset = MediaQuery.of(context).padding;
return AppBar(
title: Text(widget.title),
centerTitle: true,
leading: widget.isHomeButton ? IconButton(
icon: Icon(Icons.home),
onPressed: () {
// Set new State
setState(() {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => const HomePage(),
));
});
}
) : null,
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerRight,
end: Alignment.centerLeft,
colors: [
/*Color(0xFFDD79C2),
Color(0xFFB65FBE),
Color(0xFF9146BA),
Color(0xFF7633B8),
Color(0xFF6528B6),
Color(0xFF6025B6)*/
Color(0xFF306bac),
Color(0xFF308aae),
Color(0xFF309cb0),
],
),
),
),
);
}
}

View File

@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
import 'package:mymuseum_visitapp/Screens/Scanner/scanner.dart';
import 'package:mymuseum_visitapp/constants.dart';
import 'ScannerDialog.dart';
class ScannerBouton extends StatefulWidget {
const ScannerBouton({Key? key, required this.isReplacement}) : super(key: key);
final bool isReplacement;
@override
State<ScannerBouton> createState() => _ScannerBoutonState();
}
class _ScannerBoutonState extends State<ScannerBouton> {
void _onItemTapped() {
setState(() {
showScannerDialog("nn rien", context);
/*if(widget.isReplacement) {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => const ScannerPage(),
));
} else {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const ScannerPage(),
));
}*/
});
}
@override
Widget build(BuildContext context) {
return Container(
height: 85.0,
width: 85.0,
child: FittedBox(
child: FloatingActionButton(
onPressed: _onItemTapped,
tooltip: 'Scanner',
backgroundColor: kMainColor,
child: const Icon(Icons.qr_code_scanner),
),
),
);
}
}

View File

@ -0,0 +1,217 @@
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:qr_code_scanner/qr_code_scanner.dart';
class ScannerTEST extends StatefulWidget {
const ScannerTEST({Key? key}) : super(key: key);
@override
State<ScannerTEST> createState() => _ScannerTESTState();
}
class _ScannerTESTState extends State<ScannerTEST> {
Barcode? result;
QRViewController? controller;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
// In order to get hot reload to work we need to pause the camera if the platform
// is android, or resume the camera if the platform is iOS.
@override
void reassemble() {
print("reassemble ");
super.reassemble();
if (Platform.isAndroid) {
controller!.pauseCamera();
}
controller!.resumeCamera();
}
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
height: size.height *0.6,
width: size.width *0.9,
color: Colors.blueAccent,
child: Column(
children: <Widget>[
Expanded(flex: 4, child: _buildQrView(context)),
Expanded(
flex: 1,
child: FittedBox(
fit: BoxFit.contain,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
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: <Widget>[
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)),
),
)
],
),
],
),
),
)
],
),
);
}
Widget _buildQrView(BuildContext context) {
// For this example we check how width or tall the device is and change the scanArea and overlay accordingly.
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 225.0
: 300.0;
// To ensure the Scanner view is properly sizes after rotation
// we need to listen for Flutter SizeChanged notification and update controller
return QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.blueAccent,
borderRadius: 10,
borderLength: 25,
borderWidth: 5,
cutOutSize: 225.0),
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
);
}
void _onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
if (Platform.isAndroid) {
controller!.pauseCamera();
}
controller!.resumeCamera();
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
print(result);
print(result!.code.toString());
var code = result == null ? "" : result!.code.toString();
if(result!.format == BarcodeFormat.qrcode) {
controller.pauseCamera();
print("QR CODE FOUND");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('QR CODE FOUND - ${code.toString()}')),
);
// TODO search in local if data == Id of Article
//Navigator.of(context).pop();
// If so, navigate to article view
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return ArticlePage(articleId: code);
},
),
);
//Navigator.of(context).pop();
}
});
});
}
void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
//log('${DateTime.now().toIso8601String()}_onPermissionSet $p');
if (!p) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('no Permission')),
);
}
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
}
showScannerDialog (String question, BuildContext context) {
showDialog(
builder: (BuildContext context) => AlertDialog(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))
),
content: ScannerTEST(
),
contentPadding: EdgeInsets.zero,
), context: context
);
}

View File

@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
class VisitAppContext with ChangeNotifier{
String? userId = "";
String? token = "";
String? host = "";
String? language = "";
VisitAppContext({this.userId, this.token, this.host, this.language});
Map<String, dynamic> toMap() {
return {
'userId': userId,
'host': host,
'language': language,
'token': token
};
}
factory VisitAppContext.fromJson(Map<String, dynamic> json) {
return VisitAppContext(
userId: json['userId'] as String,
host: json['host'] as String,
language: json['language'] as String,
token: json['token'] as String,
);
}
// Implement toString to make it easier to see information about
@override
String toString() {
return 'VisitAppContext{userId: $userId, language: $language, host: $host}';
}
}

View File

@ -1,87 +1,41 @@
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/constants.dart';
class ArticlePage extends StatefulWidget {
const ArticlePage({Key? key, required this.title}) : super(key: key);
const ArticlePage({Key? key, required this.articleId}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
final String articleId;
@override
State<ArticlePage> createState() => _ArticlePageState();
}
class _ArticlePageState extends State<ArticlePage> {
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++;
});
}
@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(
// 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("ArticlePage"),
appBar: CustomAppBar(
title: "ArticlePage",
isHomeButton: false,
),
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.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// 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).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(widget.articleId),
Text(
'$_counter',
'coucou',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
floatingActionButton: const ScannerBouton(isReplacement: true),
);
}
}

View File

@ -2,23 +2,16 @@
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/ScannerBouton.dart';
import 'package:mymuseum_visitapp/Components/ScannerDialog.dart';
import 'package:mymuseum_visitapp/Screens/Scanner/scanner.dart';
import 'package:mymuseum_visitapp/Screens/Visit/visit.dart';
import 'package:mymuseum_visitapp/client.dart';
import 'package:mymuseum_visitapp/constants.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key, required this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
@ -26,19 +19,14 @@ class HomePage extends StatefulWidget {
class _HomePageState extends State<HomePage> {
List<ConfigurationDTO> configurations = [ConfigurationDTO(label: "Test 0", isOffline: false), ConfigurationDTO(label: "Test 1", isOffline: true), ConfigurationDTO(label: "Test 2", isOffline: true)];
//List<dynamic> configurations = [];
void _incrementCounter() {
setState(() {
//_counter++;
});
}
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
appBar: CustomAppBar(
title: "Home page - liste parcours",
isHomeButton: false,
),
body: SingleChildScrollView(
child: Container(
@ -56,14 +44,9 @@ class _HomePageState extends State<HomePage> {
print("config selected");
getConfiguration();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ScannerPage(title: "test");
},
),
);
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => const VisitPage(configurationId: "TODO"),
));
});
},
child: Container(
@ -101,7 +84,23 @@ class _HomePageState extends State<HomePage> {
}
),
),
), // This trailing comma makes auto-formatting nicer for build methods.
),
floatingActionButton: const ScannerBouton(isReplacement: false),
//floatingActionButtonLocation: FloatingActionButtonLocation.miniCenterFloat,
/*bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.qr_code_scanner),
label: 'Scanner',
),
],
selectedItemColor: kMainRed,
onTap: _onItemTapped,
),*/
);
}

View File

@ -3,23 +3,13 @@ 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:qr_code_scanner/qr_code_scanner.dart';
class ScannerPage extends StatefulWidget {
const ScannerPage({Key? key, required this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
const ScannerPage({Key? key}) : super(key: key);
@override
State<ScannerPage> createState() => _ScannerPageState();
@ -34,6 +24,7 @@ class _ScannerPageState extends State<ScannerPage> {
// is android, or resume the camera if the platform is iOS.
@override
void reassemble() {
print("reassemble ");
super.reassemble();
if (Platform.isAndroid) {
controller!.pauseCamera();
@ -44,6 +35,10 @@ class _ScannerPageState extends State<ScannerPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: "QR Code scan",
isHomeButton: false,
),
body: Column(
children: <Widget>[
Expanded(flex: 4, child: _buildQrView(context)),
@ -77,7 +72,7 @@ class _ScannerPageState extends State<ScannerPage> {
},
)),
),
/*Container(
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
@ -95,7 +90,7 @@ class _ScannerPageState extends State<ScannerPage> {
}
},
)),
)*/
)
],
),
Row(
@ -116,6 +111,7 @@ class _ScannerPageState extends State<ScannerPage> {
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
print(controller);
await controller?.resumeCamera();
},
child: const Text('resume',
@ -158,25 +154,31 @@ class _ScannerPageState extends State<ScannerPage> {
setState(() {
this.controller = controller;
});
if (Platform.isAndroid) {
controller!.pauseCamera();
}
controller!.resumeCamera();
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
print(result);
print(result!.code.toString());
var code = result == null ? "" : result!.code.toString();
if(result!.format == BarcodeFormat.qrcode) {
controller.pauseCamera();
print("QR CODE FOUND");
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('QR CODE FOUND')),
SnackBar(content: Text('QR CODE FOUND - ${code.toString()}')),
);
// TODO search in local if data == Id of Article
// If so, navigate to article view
Navigator.push(
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return ArticlePage(title: "test");
return ArticlePage(articleId: code);
},
),
);

View File

@ -0,0 +1,36 @@
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/ScannerBouton.dart';
import 'package:mymuseum_visitapp/Screens/Scanner/scanner.dart';
import 'package:mymuseum_visitapp/client.dart';
import 'package:mymuseum_visitapp/constants.dart';
class VisitPage extends StatefulWidget {
const VisitPage({Key? key, required this.configurationId}) : super(key: key);
final String configurationId;
@override
State<VisitPage> createState() => _VisitPageState();
}
class _VisitPageState extends State<VisitPage> {
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
appBar: CustomAppBar(
title: "Visit page",
isHomeButton: true,
),
body: Text(
"TODO description du parcours puis bouton scanner, ou visite virtuelle ?"
),
floatingActionButton: const ScannerBouton(isReplacement: false),
);
}
}

19
lib/app_context.dart Normal file
View File

@ -0,0 +1,19 @@
import 'package:flutter/material.dart';
import 'package:mymuseum_visitapp/client.dart';
import 'Models/visitContext.dart';
class AppContext with ChangeNotifier {
VisitAppContext _visitContext;
Client clientAPI = Client("");
AppContext(this._visitContext);
getContext() => _visitContext;
setContext(VisitAppContext appContext) async {
_visitContext = appContext;
notifyListeners();
}
}

View File

@ -2,11 +2,22 @@ import 'package:flutter/material.dart';
// Colors - TO FILL WIT CORRECT COLOR
const kBackgroundColor = Color(0xFFFFFFFF);
const kMainColor = Color(0xFF8b0000);
const List<String> languages = ["FR", "NL", "EN", "DE"]; // hmmmm depends on config..
// Text Style
const kHeadingTextStyle = TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Color(0xFFFFFFFF)
);
const kMainGrey = Color(0xFF424242);
const kSecondGrey = Color(0xFF555457);
const kTestSecondColor = Color(0xFF2F4858);
const kMainRed = Color(0xFF8b0000);
const kSecondRed = Color(0xFF622727);
const kTextRed = Color(0xFFba0505);
const kBackgroundGrey = Color(0xFFb5b7b9);
@ -14,8 +25,6 @@ const kBackgroundSecondGrey = Color(0xFF5b5b63);
const kBackgroundLight = Color(0xfff3f3f3);
const List<String> languages = ["FR", "NL", "EN", "DE"];
const kTitleSize = 40.0;
const kDescriptionSize = 25.0;

View File

@ -1,34 +1,71 @@
import 'package:flutter/material.dart';
import 'package:mymuseum_visitapp/Screens/Article/article.dart';
import 'package:mymuseum_visitapp/Screens/Home/home.dart';
import 'package:provider/provider.dart';
import 'Models/visitContext.dart';
import 'Screens/Scanner/scanner.dart';
import 'app_context.dart';
import 'constants.dart';
void main() {
runApp(const MyApp());
void main() async {
WidgetsFlutterBinding.ensureInitialized();
String initialRoute;
VisitAppContext localContext = VisitAppContext(language: "FR", host: "http://192.168.31.140:8089");
//localContext = await DatabaseHelper.instance.getData();
if(localContext != null) {
print("we've got an local db !");
print(localContext);
} else {
print("NO LOCAL DB !");
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
initialRoute = '/home';
final MyApp myApp = MyApp(
initialRoute: initialRoute,
visitAppContext: localContext,
);
runApp(myApp);
}
class MyApp extends StatefulWidget {
String initialRoute = "";
VisitAppContext visitAppContext;
MyApp({Key? key, required this.initialRoute, required this.visitAppContext}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MyVisit App',
return ChangeNotifierProvider<AppContext>(
create: (_) => AppContext(widget.visitAppContext),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'MyVisit App Demo',
initialRoute: widget.initialRoute,
/*supportedLocales: [
const Locale('en', 'US'),
//const Locale('fr', 'FR'),
],*/
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
scaffoldBackgroundColor: kBackgroundColor,
//fontFamily: "Vollkorn",
textTheme: const TextTheme(bodyText1: TextStyle(color: kTestSecondColor)),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
routes: {
'/home': (context) => const HomePage(),
}
),
home: const HomePage(title: 'MyVisit App'), // Scanner to test
);
}
}

View File

@ -209,6 +209,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
flutter_svg:
dependency: "direct main"
description:
name: flutter_svg
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.3"
flutter_test:
dependency: "direct dev"
description: flutter
@ -331,6 +338,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
nested:
dependency: transitive
description:
name: nested
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
openapi_generator:
dependency: "direct main"
description:
@ -366,6 +380,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
path_drawing:
dependency: transitive
description:
name: path_drawing
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
path_parsing:
dependency: transitive
description:
name: path_parsing
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
pedantic:
dependency: transitive
description:
@ -373,6 +401,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.11.1"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.0"
pool:
dependency: transitive
description:
@ -380,6 +415,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.1"
provider:
dependency: "direct main"
description:
name: provider
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.0"
pub_semver:
dependency: transitive
description:
@ -434,6 +476,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.2"
sqflite:
dependency: "direct main"
description:
name: sqflite
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3+1"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.1+1"
stack_trace:
dependency: transitive
description:
@ -462,6 +518,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
synchronized:
dependency: transitive
description:
name: synchronized
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0+2"
term_glyph:
dependency: transitive
description:
@ -511,6 +574,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.0"
yaml:
dependency: transitive
description:
@ -520,4 +590,4 @@ packages:
version: "3.1.1"
sdks:
dart: ">=2.17.0 <3.0.0"
flutter: ">=1.12.0"
flutter: ">=3.0.0"

View File

@ -34,6 +34,9 @@ dependencies:
openapi_generator_cli: ^4.0.0
openapi_generator: ^4.0.0
openapi_generator_annotations: ^4.0.0
sqflite:
provider: ^5.0.0
flutter_svg: ^1.1.3
manager_api:
path: manager_api