mymuseum-visitapp/lib/Components/ScannerDialog.dart

227 lines
7.2 KiB
Dart

import 'package:flutter/material.dart';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:manager_api/api.dart';
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
import 'package:mymuseum_visitapp/Models/visitContext.dart';
import 'package:mymuseum_visitapp/Screens/Article/article_page.dart';
import 'package:mymuseum_visitapp/Screens/Quizz/quizz_page.dart';
import 'package:mymuseum_visitapp/app_context.dart';
import 'package:mymuseum_visitapp/constants.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
class ScannerDialog extends StatefulWidget {
const ScannerDialog({Key? key, required this.appContext}) : super(key: key);
final AppContext? appContext;
@override
State<ScannerDialog> createState() => _ScannerDialogState();
}
class _ScannerDialogState extends State<ScannerDialog> {
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() {
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.5,
width: size.width *0.9,
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: kBlue1,
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: kBlue1,
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);
},
)),
),
),
],
),
);
}
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: kBlue1,
borderRadius: 10,
borderLength: 25,
borderWidth: 5,
cutOutSize: 225.0),
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
);
}
_onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
if (Platform.isAndroid) {
controller.pauseCamera();
}
controller.resumeCamera();
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
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()}')),
);*/
VisitAppContext visitAppContext = widget.appContext!.getContext();
if(!visitAppContext.sectionIds!.contains(code)) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(TranslationHelper.getFromLocale('invalidQRCode', widget.appContext!.getContext())), backgroundColor: kBlue2),
);
Navigator.of(context).pop();
} else {
SectionDTO section = visitAppContext.currentSections!.firstWhere((cs) => cs!.id == code)!;
switch(section.type) {
case SectionType.Article:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return ArticlePage(visitAppContextIn: visitAppContext, articleId: code);
},
),
);
break;
case SectionType.Quizz:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return QuizzPage(visitAppContextIn: visitAppContext, sectionId: code);
},
),
);
break;
}
}
}
});
});
}
Future<void> _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) async {
//log('${DateTime.now().toIso8601String()}_onPermissionSet $p');
if (!p) {
var status = await Permission.camera.status;
if(!status.isGranted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('no Permission')),
);
// You can request multiple permissions at once.
Map<Permission, PermissionStatus> statuses = await [
Permission.camera,
].request();
print(statuses[Permission.camera]);
print(status);
}
}
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
}
showScannerDialog (BuildContext context, AppContext appContext) {
showDialog(
builder: (BuildContext context) => AlertDialog(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))
),
content: ScannerDialog(appContext: appContext),
contentPadding: EdgeInsets.zero,
), context: context
);
}