mirror of
https://github.com/inventree/inventree-app.git
synced 2025-06-15 19:55:27 +00:00
Barcode refactor (#363)
* Move barcode.dart * Fix * Refactoring barcode scanner code: - Abstract the "controller" class (for future development) - Break barcode scanning code out into multiple files - Add CameraBarcodeController class (qr_code_scanner) * Add await * Make barcode scan delay configurable * remove unused import * Handle camera exceptions * Improve sequencing for camera scanner - Show loading overlay - Prevent reload if view is no longer mounted * Update docstring * Update release notes
This commit is contained in:
108
lib/barcode/controller.dart
Normal file
108
lib/barcode/controller.dart
Normal file
@ -0,0 +1,108 @@
|
||||
import "package:flutter/material.dart";
|
||||
import "package:one_context/one_context.dart";
|
||||
|
||||
import "package:inventree/preferences.dart";
|
||||
|
||||
import "package:inventree/barcode/handler.dart";
|
||||
|
||||
import "package:inventree/widget/progress.dart";
|
||||
|
||||
/*
|
||||
* Generic class which provides a barcode scanner interface.
|
||||
*
|
||||
* When the controller is instantiated, it is passed a "handler" class,
|
||||
* which is used to process the scanned barcode.
|
||||
*/
|
||||
class InvenTreeBarcodeController extends StatefulWidget {
|
||||
|
||||
const InvenTreeBarcodeController(this.handler, {Key? key}) : super(key: key);
|
||||
|
||||
final BarcodeHandler handler;
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => InvenTreeBarcodeControllerState();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Base state widget for the barcode controller.
|
||||
* This defines the basic interface for the barcode controller.
|
||||
*/
|
||||
class InvenTreeBarcodeControllerState extends State<InvenTreeBarcodeController> {
|
||||
|
||||
InvenTreeBarcodeControllerState() : super();
|
||||
|
||||
final GlobalKey barcodeControllerKey = GlobalKey(debugLabel: "barcodeController");
|
||||
|
||||
// Internal state flag to test if we are currently processing a barcode
|
||||
bool processingBarcode = false;
|
||||
|
||||
/*
|
||||
* Method to handle scanned data.
|
||||
* Any implementing class should call this method when a barcode is scanned.
|
||||
* Barcode data should be passed as a string
|
||||
*/
|
||||
Future<void> handleBarcodeData(String? data) async {
|
||||
|
||||
// Check that the data is valid, and this view is still mounted
|
||||
if (!mounted || data == null || data.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Currently processing a barcode - ignore this one
|
||||
if (processingBarcode) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
processingBarcode = true;
|
||||
});
|
||||
|
||||
BuildContext? context = OneContext().context;
|
||||
|
||||
showLoadingOverlay(context!);
|
||||
await pauseScan();
|
||||
|
||||
await widget.handler.processBarcode(data);
|
||||
|
||||
// processBarcode may have popped the context
|
||||
if (!mounted) {
|
||||
hideLoadingOverlay();
|
||||
return;
|
||||
}
|
||||
|
||||
int delay = await InvenTreeSettingsManager().getValue(INV_BARCODE_SCAN_DELAY, 500) as int;
|
||||
|
||||
Future.delayed(Duration(milliseconds: delay), () {
|
||||
hideLoadingOverlay();
|
||||
if (mounted) {
|
||||
resumeScan().then((_) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
processingBarcode = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Hook function to "pause" the barcode scanner
|
||||
Future<void> pauseScan() async {
|
||||
// Implement this function in subclass
|
||||
}
|
||||
|
||||
// Hook function to "resume" the barcode scanner
|
||||
Future<void> resumeScan() async {
|
||||
// Implement this function in subclass
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementing classes are in control of building out the widget
|
||||
*/
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container();
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user