mirror of
				https://github.com/inventree/inventree-app.git
				synced 2025-10-29 20:40:35 +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:
		
							
								
								
									
										121
									
								
								lib/barcode/handler.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								lib/barcode/handler.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
|  | ||||
| import "package:flutter/material.dart"; | ||||
|  | ||||
| import "package:font_awesome_flutter/font_awesome_flutter.dart"; | ||||
|  | ||||
| import "package:inventree/api.dart"; | ||||
| import "package:inventree/helpers.dart"; | ||||
| import "package:inventree/l10.dart"; | ||||
|  | ||||
| import "package:inventree/barcode/tones.dart"; | ||||
|  | ||||
| import "package:inventree/inventree/sentry.dart"; | ||||
|  | ||||
| import "package:inventree/widget/dialogs.dart"; | ||||
| import "package:inventree/widget/snacks.dart"; | ||||
|  | ||||
|  | ||||
| /* Generic class which "handles" a barcode, by communicating with the InvenTree server, | ||||
|  * and handling match / unknown / error cases. | ||||
|  * | ||||
|  * Override functionality of this class to perform custom actions, | ||||
|  * based on the response returned from the InvenTree server | ||||
|  */ | ||||
| class BarcodeHandler { | ||||
|  | ||||
|   BarcodeHandler(); | ||||
|  | ||||
|   // Return the text to display on the barcode overlay | ||||
|   // Note: Will be overridden by child classes | ||||
|   String getOverlayText(BuildContext context) => "Barcode Overlay"; | ||||
|  | ||||
|   // Called when the server "matches" a barcode | ||||
|   Future<void> onBarcodeMatched(Map<String, dynamic> data) async { | ||||
|     // Override this function | ||||
|   } | ||||
|  | ||||
|   // Called when the server does not know about a barcode | ||||
|   Future<void> onBarcodeUnknown(Map<String, dynamic> data) async { | ||||
|     // Override this function | ||||
|  | ||||
|     barcodeFailureTone(); | ||||
|  | ||||
|     showSnackIcon( | ||||
|       L10().barcodeNoMatch, | ||||
|       success: false, | ||||
|       icon: Icons.qr_code, | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   // Called when the server returns an unhandled response | ||||
|   Future<void> onBarcodeUnhandled(Map<String, dynamic> data) async { | ||||
|     barcodeFailureTone(); | ||||
|     showServerError("barcode/", L10().responseUnknown, data.toString()); | ||||
|   } | ||||
|  | ||||
|   /* | ||||
|     * Base function to capture and process barcode data. | ||||
|     * | ||||
|     * Returns true only if the barcode scanner should remain open | ||||
|     */ | ||||
|   Future<void> processBarcode(String barcode, {String url = "barcode/"}) async { | ||||
|  | ||||
|     debug("Scanned barcode data: '${barcode}'"); | ||||
|  | ||||
|     barcode = barcode.trim(); | ||||
|  | ||||
|     // Empty barcode is invalid | ||||
|     if (barcode.isEmpty) { | ||||
|  | ||||
|       barcodeFailureTone(); | ||||
|  | ||||
|       showSnackIcon( | ||||
|         L10().barcodeError, | ||||
|         icon: FontAwesomeIcons.circleExclamation, | ||||
|         success: false | ||||
|       ); | ||||
|  | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     var response = await InvenTreeAPI().post( | ||||
|         url, | ||||
|         body: { | ||||
|           "barcode": barcode, | ||||
|         }, | ||||
|         expectedStatusCode: null,  // Do not show an error on "unexpected code" | ||||
|     ); | ||||
|  | ||||
|     debug("Barcode scan response" + response.data.toString()); | ||||
|  | ||||
|     Map<String, dynamic> data = response.asMap(); | ||||
|  | ||||
|     // Handle strange response from the server | ||||
|     if (!response.isValid() || !response.isMap()) { | ||||
|       onBarcodeUnknown({}); | ||||
|  | ||||
|       showSnackIcon(L10().serverError, success: false); | ||||
|  | ||||
|       // We want to know about this one! | ||||
|       await sentryReportMessage( | ||||
|           "BarcodeHandler.processBarcode returned unexpected value", | ||||
|           context: { | ||||
|             "data": response.data?.toString() ?? "null", | ||||
|             "barcode": barcode, | ||||
|             "url": url, | ||||
|             "statusCode": response.statusCode.toString(), | ||||
|             "valid": response.isValid().toString(), | ||||
|             "error": response.error, | ||||
|             "errorDetail": response.errorDetail, | ||||
|             "className": "${this}", | ||||
|           } | ||||
|       ); | ||||
|     } else if (data.containsKey("success")) { | ||||
|       await onBarcodeMatched(data); | ||||
|     } else if ((response.statusCode >= 400) || data.containsKey("error")) { | ||||
|       await onBarcodeUnknown(data); | ||||
|     } else { | ||||
|       await onBarcodeUnhandled(data); | ||||
|     } | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user