2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-28 13:36:50 +00:00

Barcode camera fix (#270)

* Bug fix for multiple barcode scans

- Do not resume scan until action is performed
- Add in delay before re-starting camera

* Change release notes to 0.10.1

* linting fixes
This commit is contained in:
Oliver 2023-02-22 00:52:26 +11:00 committed by GitHub
parent 5c06e3c9de
commit fb80029c0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 61 deletions

View File

@ -1,10 +1,11 @@
## InvenTree App Release Notes
---
### 0.11.0 -
### 0.10.1 - February 2023
---
- Add support for attachments on Companies
- Fix duplicate scanning of barcodes
### 0.10.0 - February 2023
---

View File

@ -58,8 +58,6 @@ class BarcodeHandler {
String getOverlayText(BuildContext context) => "Barcode Overlay";
QRViewController? _controller;
Future<void> onBarcodeMatched(Map<String, dynamic> data) async {
// Called when the server "matches" a barcode
// Override this function
@ -78,21 +76,18 @@ class BarcodeHandler {
);
}
Future<void> onBarcodeUnhandled(Map<String, dynamic> data) async {
// Called when the server returns an unhandled response
Future<void> onBarcodeUnhandled(Map<String, dynamic> data) async {
barcodeFailureTone();
// Called when the server returns an unhandled response
showServerError("barcode/", L10().responseUnknown, data.toString());
_controller?.resumeCamera();
}
/*
* Base function to capture and process barcode data.
*
* Returns true only if the barcode scanner should remain open
*/
Future<void> processBarcode(QRViewController? _controller, String barcode, {String url = "barcode/"}) async {
this._controller = _controller;
debug("Scanned barcode data: '${barcode}'");
@ -122,8 +117,6 @@ class BarcodeHandler {
debug("Barcode scan response" + response.data.toString());
_controller?.resumeCamera();
Map<String, dynamic> data = response.asMap();
// Handle strange response from the server
@ -188,53 +181,55 @@ class BarcodeScanHandler extends BarcodeHandler {
* Response when a "Part" instance is scanned
*/
Future<void> handlePart(int pk) async {
InvenTreePart().get(pk).then((var part) {
// Dismiss the barcode scanner
OneContext().pop();
if (part is InvenTreePart) {
OneContext().push(MaterialPageRoute(builder: (context) => PartDetailWidget(part)));
}
});
var part = await InvenTreePart().get(pk);
if (part is InvenTreePart) {
OneContext().pop();
OneContext().push(MaterialPageRoute(builder: (context) => PartDetailWidget(part)));
}
}
/*
* Response when a "StockItem" instance is scanned
*/
Future<void> handleStockItem(int pk) async {
InvenTreeStockItem().get(pk).then((var item) {
var item = await InvenTreeStockItem().get(pk);
if (item is InvenTreeStockItem) {
OneContext().pop();
if (item is InvenTreeStockItem) {
OneContext().push(MaterialPageRoute(
OneContext().push(MaterialPageRoute(
builder: (context) => StockDetailWidget(item)));
}
});
}
}
/*
* Response when a "StockLocation" instance is scanned
*/
Future<void> handleStockLocation(int pk) async {
InvenTreeStockLocation().get(pk).then((var loc) {
if (loc is InvenTreeStockLocation) {
OneContext().pop();
OneContext().navigator.push(MaterialPageRoute(
builder: (context) => LocationDisplayWidget(loc)));
}
});
var loc = await InvenTreeStockLocation().get(pk);
if (loc is InvenTreeStockLocation) {
OneContext().pop();
OneContext().navigator.push(MaterialPageRoute(
builder: (context) => LocationDisplayWidget(loc)));
}
}
/*
* Response when a "SupplierPart" instance is scanned
*/
Future<void> handleSupplierPart(int pk) async {
InvenTreeSupplierPart().get(pk).then((var supplierpart) {
OneContext().pop();
if (supplierpart is InvenTreeSupplierPart) {
OneContext().push(MaterialPageRoute(builder: (context) => SupplierPartDetailWidget(supplierpart)));
}
});
var supplierpart = await InvenTreeSupplierPart().get(pk);
if (supplierpart is InvenTreeSupplierPart) {
OneContext().pop();
OneContext().push(MaterialPageRoute(
builder: (context) => SupplierPartDetailWidget(supplierpart)));
}
}
@override
@ -270,19 +265,19 @@ class BarcodeScanHandler extends BarcodeHandler {
switch (model) {
case "part":
handlePart(pk);
await handlePart(pk);
return;
case "stockitem":
handleStockItem(pk);
await handleStockItem(pk);
return;
case "stocklocation":
handleStockLocation(pk);
await handleStockLocation(pk);
return;
case "supplierpart":
handleSupplierPart(pk);
await handleSupplierPart(pk);
return;
default:
// Fall through to failure state
// Fall through to failure state
break;
}
}
@ -339,9 +334,8 @@ class BarcodeScanStockLocationHandler extends BarcodeHandler {
if (result && OneContext.hasContext) {
OneContext().pop();
return;
}
return;
}
}
@ -386,13 +380,12 @@ class BarcodeScanStockItemHandler extends BarcodeHandler {
barcodeSuccessTone();
final bool result = await onItemScanned(_item);
bool result = await onItemScanned(_item);
if (result && OneContext.hasContext) {
OneContext().pop();
return;
}
return;
}
}
@ -410,7 +403,6 @@ class BarcodeScanStockItemHandler extends BarcodeHandler {
// Re-implement this for particular subclass
return false;
}
}
@ -480,10 +472,10 @@ class StockLocationScanInItemsHandler extends BarcodeScanStockItemHandler {
}
}
showSnackIcon(
result ? L10().barcodeScanIntoLocationSuccess : L10().barcodeScanIntoLocationFailure,
success: result
);
showSnackIcon(
result ? L10().barcodeScanIntoLocationSuccess : L10().barcodeScanIntoLocationFailure,
success: result
);
// We always return false here, to ensure the barcode scan dialog remains open
return false;
@ -641,6 +633,8 @@ class _QRViewState extends State<InvenTreeQRView> {
bool flash_status = false;
bool currently_processing = false;
Future<void> updateFlashStatus() async {
final bool? status = await _controller?.getFlashStatus();
@ -658,21 +652,53 @@ class _QRViewState extends State<InvenTreeQRView> {
void reassemble() {
super.reassemble();
if (Platform.isAndroid) {
_controller!.pauseCamera();
}
if (mounted) {
if (Platform.isAndroid) {
_controller!.pauseCamera();
}
_controller!.resumeCamera();
_controller!.resumeCamera();
}
}
/* Callback function when the Barcode scanner view is initially created */
void _onViewCreated(BuildContext context, QRViewController controller) {
_controller = controller;
controller.scannedDataStream.listen((barcode) {
_controller?.pauseCamera();
if (barcode.code != null) {
widget._handler.processBarcode(_controller, barcode.code ?? "");
}
controller.scannedDataStream.listen((barcode) {
handleBarcode(barcode.code);
});
}
/* Handle scanned data */
Future<void> handleBarcode(String? data) async {
// Empty or missing data, or we have navigated away
if (!mounted || data == null || data.isEmpty) {
return;
}
// Currently processing a barcode - return!
if (currently_processing) {
return;
}
setState(() {
currently_processing = true;
});
// Pause camera functionality until we are done processing
_controller?.pauseCamera();
// processBarcode returns true if the scanner window is to remain open
widget._handler.processBarcode(_controller, data).then((value) {
// Re-start the process after some delay
Future.delayed(Duration(milliseconds: 500)).then((value) {
if (mounted) {
_controller?.resumeCamera();
currently_processing = false;
}
});
});
}