170 lines
5.1 KiB
Dart
170 lines
5.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'dart:io';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:manager_api_new/api.dart';
|
|
import 'package:mymuseum_visitapp/Components/SlideFromRouteRight.dart';
|
|
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
|
import 'package:mymuseum_visitapp/Screens/section_page.dart';
|
|
import 'package:mymuseum_visitapp/app_context.dart';
|
|
import 'package:mymuseum_visitapp/constants.dart';
|
|
import 'package:mobile_scanner/mobile_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> {
|
|
final MobileScannerController controller = MobileScannerController();
|
|
bool isProcessing = false;
|
|
|
|
@override
|
|
void reassemble() {
|
|
super.reassemble();
|
|
if (Platform.isAndroid) {
|
|
controller.stop();
|
|
}
|
|
controller.start();
|
|
}
|
|
|
|
@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: MobileScanner(
|
|
controller: controller,
|
|
//allowDuplicates: false,
|
|
onDetect: (barcodes) => _onDetect(barcodes),
|
|
),
|
|
),
|
|
),
|
|
_buildControlButton(
|
|
icon: Icons.flash_on,
|
|
onTap: () => controller.toggleTorch(),
|
|
alignment: Alignment.topRight,
|
|
),
|
|
_buildControlButton(
|
|
icon: Icons.flip_camera_android,
|
|
onTap: () => controller.switchCamera(),
|
|
alignment: Alignment.bottomRight,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildControlButton({
|
|
required IconData icon,
|
|
required VoidCallback onTap,
|
|
required Alignment alignment,
|
|
}) {
|
|
return Align(
|
|
alignment: alignment,
|
|
child: Container(
|
|
width: 45,
|
|
height: 45,
|
|
margin: const EdgeInsets.all(8),
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.rectangle,
|
|
color: kMainColor1,
|
|
borderRadius: BorderRadius.circular(20.0),
|
|
),
|
|
child: InkWell(
|
|
onTap: onTap,
|
|
child: Icon(icon, color: Colors.white),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void _onDetect(BarcodeCapture capture) {
|
|
if (isProcessing) return;
|
|
|
|
final barcode = capture.barcodes.first;
|
|
final code = barcode.rawValue ?? "";
|
|
|
|
if (barcode.format == BarcodeFormat.qrCode && code.isNotEmpty) {
|
|
isProcessing = true;
|
|
|
|
RegExp regExp = RegExp(r'^(?:https:\/\/web\.myinfomate\.be\/([^\/]+)\/([^\/]+)\/([^\/]+)|([^\/]+))$');
|
|
RegExp regExp2 = RegExp(r'^(?:https:\/\/web\.mymuseum\.be\/([^\/]+)\/([^\/]+)\/([^\/]+)|([^\/]+))$');
|
|
var match = regExp.firstMatch(code);
|
|
var match2 = regExp2.firstMatch(code);
|
|
String? instanceId;
|
|
String? configurationId;
|
|
String? sectionId;
|
|
|
|
if(match == null) {
|
|
instanceId = match2?.group(1);
|
|
configurationId = match2?.group(2);
|
|
sectionId = match2?.group(3) ?? match2?.group(4);
|
|
} else {
|
|
instanceId = match.group(1);
|
|
configurationId = match.group(2);
|
|
sectionId = match.group(3) ?? match.group(4);
|
|
}
|
|
|
|
if ((match == null && match2 == null) || sectionId == null) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(content: Text("L'URL ne correspond pas au format attendu."), backgroundColor: kMainColor2),
|
|
);
|
|
Navigator.of(context).pop();
|
|
return;
|
|
}
|
|
|
|
VisitAppContext visitAppContext = widget.appContext!.getContext();
|
|
|
|
if (visitAppContext.sectionIds == null || !visitAppContext.sectionIds!.contains(sectionId)) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(content: Text(TranslationHelper.getFromLocale('invalidQRCode', visitAppContext)), backgroundColor: kMainColor2),
|
|
);
|
|
Navigator.of(context).pop();
|
|
} else {
|
|
dynamic rawSection = visitAppContext.currentSections!.firstWhere((cs) => cs!['id'] == sectionId)!;
|
|
Navigator.of(context).pop();
|
|
Navigator.push(
|
|
context,
|
|
SlideFromRightRoute(page: SectionPage(
|
|
configuration: visitAppContext.configuration!,
|
|
rawSection: rawSection,
|
|
visitAppContextIn: visitAppContext,
|
|
sectionId: rawSection['id'],
|
|
)),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
controller.dispose();
|
|
super.dispose();
|
|
}
|
|
}
|
|
|
|
showScannerDialog(BuildContext context, AppContext appContext) {
|
|
showDialog(
|
|
context: context,
|
|
builder: (BuildContext context) => AlertDialog(
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
|
),
|
|
content: ScannerDialog(appContext: appContext),
|
|
contentPadding: EdgeInsets.zero,
|
|
),
|
|
);
|
|
}
|