Skip to content

Commit

Permalink
655: replace qr_code_scanner
Browse files Browse the repository at this point in the history
  • Loading branch information
sarahsporck committed Dec 19, 2022
1 parent 496a8ae commit 3a19a8d
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 121 deletions.
2 changes: 1 addition & 1 deletion frontend/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ android {

applicationId buildConfig.applicationId

minSdkVersion 20
minSdkVersion 21
targetSdkVersion 30
multiDexEnabled true
versionCode flutterVersionCode.toInteger()
Expand Down
85 changes: 46 additions & 39 deletions frontend/lib/qr_code_scanner/qr_code_scanner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'dart:math';

import 'package:ehrenamtskarte/qr_code_scanner/qr_code_scanner_controls.dart';
import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:mobile_scanner/mobile_scanner.dart';

const scanDelayAfterErrorMs = 500;

Expand All @@ -18,7 +18,10 @@ class QrCodeScanner extends StatefulWidget {
}

class _QRViewState extends State<QrCodeScanner> {
QRViewController? _controller;
final MobileScannerController _controller = MobileScannerController(
torchEnabled: true,
formats: [BarcodeFormat.qrCode],
);
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
bool isProcessingCode = false;

Expand All @@ -29,35 +32,46 @@ class _QRViewState extends State<QrCodeScanner> {
children: <Widget>[
Expanded(
flex: 4,
child: QRView(
key: qrKey,
onQRViewCreated: _onQrViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Theme.of(context).colorScheme.secondary,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: _calculateScanArea(context),
),
),
),
if (controller != null)
Expanded(
flex: 1,
child: FittedBox(
fit: BoxFit.contain,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
margin: const EdgeInsets.all(8),
child: const Text('Halten Sie die Kamera auf den QR Code.'),
child: Stack(
children: [
MobileScanner(
key: qrKey,
onDetect: (barcode, args) => _onCodeScanned(barcode),
allowDuplicates: false,
controller: controller,
),
Padding(
padding: EdgeInsets.zero,
child: DecoratedBox(
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(
color: Colors.orange,
width: 10,
style: BorderStyle.solid,
),
),
QrCodeScannerControls(controller: controller)
],
),
),
],
),
),
Expanded(
flex: 1,
child: FittedBox(
fit: BoxFit.contain,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
margin: const EdgeInsets.all(8),
child: const Text('Halten Sie die Kamera auf den QR Code.'),
),
QrCodeScannerControls(controller: controller)
],
),
)
),
)
],
);
}
Expand All @@ -76,17 +90,10 @@ class _QRViewState extends State<QrCodeScanner> {
return scanArea;
}

void _onQrViewCreated(QRViewController controller) {
setState(() {
_controller = controller;
});
controller.scannedDataStream.listen(_onCodeScanned);
}

Future<void> _onCodeScanned(Barcode scanData) async {
final controller = _controller;
final code = scanData.code;
if (controller == null || code == null) {
final code = scanData.rawValue;
if (code == null) {
return;
}

Expand All @@ -96,15 +103,15 @@ class _QRViewState extends State<QrCodeScanner> {
return;
}
isProcessingCode = true;
controller.pauseCamera();
controller.stop();

await widget.onCodeScanned(code);

// give the user time to move the camara away from the qr code
await Future.delayed(const Duration(milliseconds: scanDelayAfterErrorMs));

if (mounted) {
controller.resumeCamera();
controller.start();
}
isProcessingCode = false;
}
Expand Down
106 changes: 33 additions & 73 deletions frontend/lib/qr_code_scanner/qr_code_scanner_controls.dart
Original file line number Diff line number Diff line change
@@ -1,84 +1,44 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:mobile_scanner/mobile_scanner.dart';

class QrCodeScannerControls extends StatelessWidget {
final QRViewController controller;

// Not really nice. We need to update the button texts after we pressed them.
// Other possibility would be to convert this to a stateful widget without
// state and just call setState({}) to trigger redrawing of whole widget.
final StreamController<bool> flashStreamController = StreamController();
final StreamController<CameraFacing> cameraStreamController = StreamController<CameraFacing>();

QrCodeScannerControls({super.key, required this.controller}) {
updateFlashStream();
updateCameraStream();
}

Future<void> updateFlashStream() =>
controller.getFlashStatus().then((flashStatus) => flashStreamController.add(flashStatus ?? false));
final MobileScannerController controller;

Future<void> updateCameraStream() => controller.getCameraInfo().then(cameraStreamController.add);
const QrCodeScannerControls({super.key, required this.controller});

@override
Widget build(BuildContext context) {
return FutureBuilder<SystemFeatures>(
future: _tryToGetSystemFeatures(),
builder: (context, snapshot) {
final SystemFeatures? systemFeatures = snapshot.data;

if (snapshot.hasData || systemFeatures == null) {
return const Center();
}

return Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
if (systemFeatures.hasFlash)
Container(
margin: const EdgeInsets.all(8),
child: OutlinedButton(
onPressed: () => controller.toggleFlash().whenComplete(updateFlashStream),
child: StreamBuilder<bool>(
stream: flashStreamController.stream,
builder: (ctx, snapshot) => Text(
snapshot.data == null ? "Blitz aus" : "Blitz an",
style: const TextStyle(fontSize: 16),
),
),
),
return Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: const EdgeInsets.all(8),
child: OutlinedButton(
onPressed: () => controller.toggleTorch(),
child: ValueListenableBuilder(
valueListenable: controller.torchState,
builder: (ctx, state, child) => Text(
state == TorchState.on ? "Blitz an" : "Blitz aus",
style: const TextStyle(fontSize: 16),
),
),
),
),
Container(
margin: const EdgeInsets.all(8),
child: OutlinedButton(
onPressed: () => controller.switchCamera(),
child: ValueListenableBuilder(
valueListenable: controller.cameraFacingState,
builder: (ctx, state, child) => Text(
state == CameraFacing.back ? "Frontkamera" : "Standard-Kamera",
style: const TextStyle(fontSize: 16),
),
if (systemFeatures.hasBackCamera && systemFeatures.hasFrontCamera)
Container(
margin: const EdgeInsets.all(8),
child: OutlinedButton(
onPressed: () => controller.flipCamera().whenComplete(updateCameraStream),
child: StreamBuilder<CameraFacing>(
stream: cameraStreamController.stream,
builder: (ctx, snapshot) => Text(
snapshot.data == CameraFacing.back ? "Frontkamera" : "Standard-Kamera",
style: const TextStyle(fontSize: 16),
),
),
),
)
],
);
},
),
),
)
],
);
}

Future<SystemFeatures> _tryToGetSystemFeatures() async {
for (var i = 0; i < 10; i++) {
try {
return await controller.getSystemFeatures();
} on CameraException {
await Future.delayed(const Duration(milliseconds: 50));
}
}
return SystemFeatures(true, true, true);
}
}
14 changes: 7 additions & 7 deletions frontend/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
mobile_scanner:
dependency: "direct main"
description:
name: mobile_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
mutex:
dependency: "direct main"
description:
Expand Down Expand Up @@ -918,13 +925,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
qr_code_scanner:
dependency: "direct main"
description:
name: qr_code_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
qr_flutter:
dependency: "direct main"
description:
Expand Down
2 changes: 1 addition & 1 deletion frontend/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ dependencies:
maps_launcher: ^2.0.1
flutter_svg: ^1.1.4
package_info_plus: ^1.4.3+1 # for about dialog
qr_code_scanner: ^1.0.1
mobile_scanner: ^2.1.0
flutter_secure_storage: ^6.0.0
infinite_scroll_pagination: ^3.2.0
geolocator: ^9.0.1
Expand Down

0 comments on commit 3a19a8d

Please sign in to comment.