mirror of
				https://github.com/inventree/inventree-app.git
				synced 2025-10-30 21:05:42 +00:00 
			
		
		
		
	Refactor audio file player
- Do not play if there is no context available (e.g. unit testing)
This commit is contained in:
		| @@ -335,7 +335,7 @@ class APIFormField { | ||||
|               controller.text = hash; | ||||
|               data["value"] = hash; | ||||
|  | ||||
|               successTone(); | ||||
|               barcodeSuccessTone(); | ||||
|  | ||||
|               showSnackIcon( | ||||
|                   L10().barcodeAssigned, | ||||
|   | ||||
| @@ -11,15 +11,38 @@ import "package:qr_code_scanner/qr_code_scanner.dart"; | ||||
|  | ||||
| import "package:inventree/inventree/stock.dart"; | ||||
| import "package:inventree/inventree/part.dart"; | ||||
| import "package:inventree/l10.dart"; | ||||
| import "package:inventree/helpers.dart"; | ||||
| import "package:inventree/api.dart"; | ||||
| import "package:inventree/helpers.dart"; | ||||
| import "package:inventree/l10.dart"; | ||||
| import "package:inventree/preferences.dart"; | ||||
|  | ||||
| import "package:inventree/widget/location_display.dart"; | ||||
| import "package:inventree/widget/part_detail.dart"; | ||||
| import "package:inventree/widget/stock_detail.dart"; | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Play an audible 'success' alert to the user. | ||||
|  */ | ||||
| Future<void> barcodeSuccessTone() async { | ||||
|  | ||||
|   final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool; | ||||
|  | ||||
|   if (en) { | ||||
|     playAudioFile("sounds/barcode_scan.mp3"); | ||||
|   } | ||||
| } | ||||
|  | ||||
| Future <void> barcodeFailureTone() async { | ||||
|  | ||||
|   final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool; | ||||
|  | ||||
|   if (en) { | ||||
|     playAudioFile("sounds/barcode_error.mp3"); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| class BarcodeHandler { | ||||
|   /* | ||||
|    * Class which "handles" a barcode, by communicating with the InvenTree server, | ||||
| @@ -44,7 +67,7 @@ class BarcodeHandler { | ||||
|       // Called when the server does not know about a barcode | ||||
|       // Override this function | ||||
|  | ||||
|       failureTone(); | ||||
|       barcodeFailureTone(); | ||||
|  | ||||
|       showSnackIcon( | ||||
|         L10().barcodeNoMatch, | ||||
| @@ -55,7 +78,7 @@ class BarcodeHandler { | ||||
|  | ||||
|     Future<void> onBarcodeUnhandled(BuildContext context, Map<String, dynamic> data) async { | ||||
|  | ||||
|       failureTone(); | ||||
|       barcodeFailureTone(); | ||||
|  | ||||
|       // Called when the server returns an unhandled response | ||||
|       showServerError(L10().responseUnknown, data.toString()); | ||||
| @@ -125,7 +148,7 @@ class BarcodeScanHandler extends BarcodeHandler { | ||||
|   @override | ||||
|   Future<void> onBarcodeUnknown(BuildContext context, Map<String, dynamic> data) async { | ||||
|  | ||||
|     failureTone(); | ||||
|     barcodeFailureTone(); | ||||
|  | ||||
|     showSnackIcon( | ||||
|         L10().barcodeNoMatch, | ||||
| @@ -146,7 +169,7 @@ class BarcodeScanHandler extends BarcodeHandler { | ||||
|  | ||||
|       if (pk > 0) { | ||||
|  | ||||
|         successTone(); | ||||
|         barcodeSuccessTone(); | ||||
|  | ||||
|         InvenTreeStockLocation().get(pk).then((var loc) { | ||||
|           if (loc is InvenTreeStockLocation) { | ||||
| @@ -156,7 +179,7 @@ class BarcodeScanHandler extends BarcodeHandler { | ||||
|         }); | ||||
|       } else { | ||||
|  | ||||
|         failureTone(); | ||||
|         barcodeFailureTone(); | ||||
|  | ||||
|         showSnackIcon( | ||||
|           L10().invalidStockLocation, | ||||
| @@ -170,7 +193,7 @@ class BarcodeScanHandler extends BarcodeHandler { | ||||
|  | ||||
|       if (pk > 0) { | ||||
|  | ||||
|         successTone(); | ||||
|         barcodeSuccessTone(); | ||||
|  | ||||
|         InvenTreeStockItem().get(pk).then((var item) { | ||||
|  | ||||
| @@ -183,7 +206,7 @@ class BarcodeScanHandler extends BarcodeHandler { | ||||
|         }); | ||||
|       } else { | ||||
|  | ||||
|         failureTone(); | ||||
|         barcodeFailureTone(); | ||||
|  | ||||
|         showSnackIcon( | ||||
|             L10().invalidStockItem, | ||||
| @@ -196,7 +219,7 @@ class BarcodeScanHandler extends BarcodeHandler { | ||||
|  | ||||
|       if (pk > 0) { | ||||
|  | ||||
|         successTone(); | ||||
|         barcodeSuccessTone(); | ||||
|  | ||||
|         InvenTreePart().get(pk).then((var part) { | ||||
|  | ||||
| @@ -209,7 +232,7 @@ class BarcodeScanHandler extends BarcodeHandler { | ||||
|         }); | ||||
|       } else { | ||||
|  | ||||
|         failureTone(); | ||||
|         barcodeFailureTone(); | ||||
|  | ||||
|         showSnackIcon( | ||||
|             L10().invalidPart, | ||||
| @@ -218,7 +241,7 @@ class BarcodeScanHandler extends BarcodeHandler { | ||||
|       } | ||||
|     } else { | ||||
|  | ||||
|       failureTone(); | ||||
|       barcodeFailureTone(); | ||||
|  | ||||
|       showSnackIcon( | ||||
|         L10().barcodeUnknown, | ||||
| @@ -275,7 +298,7 @@ class StockItemScanIntoLocationHandler extends BarcodeHandler { | ||||
|  | ||||
|       if (result) { | ||||
|  | ||||
|         successTone(); | ||||
|         barcodeSuccessTone(); | ||||
|  | ||||
|         Navigator.of(context).pop(); | ||||
|  | ||||
| @@ -285,7 +308,7 @@ class StockItemScanIntoLocationHandler extends BarcodeHandler { | ||||
|         ); | ||||
|       } else { | ||||
|  | ||||
|         failureTone(); | ||||
|         barcodeFailureTone(); | ||||
|  | ||||
|         showSnackIcon( | ||||
|           L10().barcodeScanIntoLocationFailure, | ||||
| @@ -294,7 +317,7 @@ class StockItemScanIntoLocationHandler extends BarcodeHandler { | ||||
|       } | ||||
|     } else { | ||||
|  | ||||
|       failureTone(); | ||||
|       barcodeFailureTone(); | ||||
|  | ||||
|       showSnackIcon( | ||||
|         L10().invalidStockLocation, | ||||
| @@ -329,14 +352,14 @@ class StockLocationScanInItemsHandler extends BarcodeHandler { | ||||
|  | ||||
|       if (item == null) { | ||||
|  | ||||
|         failureTone(); | ||||
|         barcodeFailureTone(); | ||||
|  | ||||
|         showSnackIcon( | ||||
|           L10().invalidStockItem, | ||||
|           success: false, | ||||
|         ); | ||||
|       } else if (item.locationId == location.pk) { | ||||
|         failureTone(); | ||||
|         barcodeFailureTone(); | ||||
|  | ||||
|         showSnackIcon( | ||||
|             L10().itemInLocation, | ||||
| @@ -347,7 +370,7 @@ class StockLocationScanInItemsHandler extends BarcodeHandler { | ||||
|  | ||||
|         if (result) { | ||||
|  | ||||
|           successTone(); | ||||
|           barcodeSuccessTone(); | ||||
|  | ||||
|           showSnackIcon( | ||||
|             L10().barcodeScanIntoLocationSuccess, | ||||
| @@ -355,7 +378,7 @@ class StockLocationScanInItemsHandler extends BarcodeHandler { | ||||
|           ); | ||||
|         } else { | ||||
|  | ||||
|           failureTone(); | ||||
|           barcodeFailureTone(); | ||||
|  | ||||
|           showSnackIcon( | ||||
|             L10().barcodeScanIntoLocationFailure, | ||||
| @@ -365,7 +388,7 @@ class StockLocationScanInItemsHandler extends BarcodeHandler { | ||||
|       } | ||||
|     } else { | ||||
|  | ||||
|       failureTone(); | ||||
|       barcodeFailureTone(); | ||||
|  | ||||
|       // Does not match a valid stock item! | ||||
|       showSnackIcon( | ||||
| @@ -401,7 +424,7 @@ class UniqueBarcodeHandler extends BarcodeHandler { | ||||
|   @override | ||||
|   Future<void> onBarcodeMatched(BuildContext context, Map<String, dynamic> data) async { | ||||
|  | ||||
|     failureTone(); | ||||
|     barcodeFailureTone(); | ||||
|  | ||||
|     // If the barcode is known, we can"t assign it to the stock item! | ||||
|     showSnackIcon( | ||||
| @@ -424,7 +447,7 @@ class UniqueBarcodeHandler extends BarcodeHandler { | ||||
|       String hash = (data["hash"] ?? "") as String; | ||||
|  | ||||
|       if (hash.isEmpty) { | ||||
|         failureTone(); | ||||
|         barcodeFailureTone(); | ||||
|  | ||||
|         showSnackIcon( | ||||
|           L10().barcodeError, | ||||
| @@ -432,7 +455,7 @@ class UniqueBarcodeHandler extends BarcodeHandler { | ||||
|         ); | ||||
|       } else { | ||||
|  | ||||
|         successTone(); | ||||
|         barcodeSuccessTone(); | ||||
|  | ||||
|         // Close the barcode scanner | ||||
|         Navigator.of(context).pop(); | ||||
|   | ||||
| @@ -8,8 +8,7 @@ | ||||
|  */ | ||||
|  | ||||
| import "package:audioplayers/audioplayers.dart"; | ||||
|  | ||||
| import "package:inventree/preferences.dart"; | ||||
| import "package:one_context/one_context.dart"; | ||||
|  | ||||
| String simpleNumberString(double number) { | ||||
|   // Ref: https://stackoverflow.com/questions/55152175/how-to-remove-trailing-zeros-using-dart | ||||
| @@ -17,22 +16,19 @@ String simpleNumberString(double number) { | ||||
|   return number.toStringAsFixed(number.truncateToDouble() == number ? 0 : 1); | ||||
| } | ||||
|  | ||||
| Future<void> successTone() async { | ||||
| /* | ||||
|  * Play an audio file from the requested path. | ||||
|  * | ||||
|  * Note: If OneContext module fails the 'hasConext' check, | ||||
|  *       we will not attempt to play the sound | ||||
|  */ | ||||
| Future<void> playAudioFile(String path) async { | ||||
|  | ||||
|   final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool; | ||||
|  | ||||
|   if (en) { | ||||
|     final player = AudioCache(); | ||||
|     player.play("sounds/barcode_scan.mp3"); | ||||
|   } | ||||
| } | ||||
|  | ||||
| Future <void> failureTone() async { | ||||
|  | ||||
|   final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool; | ||||
|  | ||||
|   if (en) { | ||||
|     final player = AudioCache(); | ||||
|     player.play("sounds/barcode_error.mp3"); | ||||
|   if (!OneContext.hasContext) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   final player = AudioCache(); | ||||
|   player.play(path); | ||||
|  | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| import "package:audioplayers/audioplayers.dart"; | ||||
| import "package:flutter/material.dart"; | ||||
| import "package:font_awesome_flutter/font_awesome_flutter.dart"; | ||||
| import "package:inventree/helpers.dart"; | ||||
| import "package:one_context/one_context.dart"; | ||||
|  | ||||
| import "package:inventree/l10.dart"; | ||||
| @@ -108,8 +108,7 @@ Future<void> showServerError(String title, String description) async { | ||||
|   final bool tones = await InvenTreeSettingsManager().getValue(INV_SOUNDS_SERVER, true) as bool; | ||||
|  | ||||
|   if (tones) { | ||||
|     final player = AudioCache(); | ||||
|     player.play("sounds/server_error.mp3"); | ||||
|     playAudioFile("sounds/server_error.mp3"); | ||||
|   } | ||||
|  | ||||
|   showSnackIcon( | ||||
|   | ||||
| @@ -19,7 +19,6 @@ import "package:inventree/widget/stock_item_history.dart"; | ||||
| import "package:inventree/widget/stock_item_test_results.dart"; | ||||
| import "package:inventree/widget/stock_notes.dart"; | ||||
| import "package:inventree/l10.dart"; | ||||
| import "package:inventree/helpers.dart"; | ||||
| import "package:inventree/api.dart"; | ||||
| import "package:inventree/api_form.dart"; | ||||
| import "package:inventree/preferences.dart"; | ||||
| @@ -1008,7 +1007,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> { | ||||
|                 } | ||||
|               ).then((result) { | ||||
|                 if (result) { | ||||
|                   successTone(); | ||||
|                   barcodeSuccessTone(); | ||||
|  | ||||
|                   showSnackIcon( | ||||
|                     L10().barcodeAssigned, | ||||
|   | ||||
| @@ -39,10 +39,10 @@ dependencies: | ||||
|  | ||||
| dev_dependencies: | ||||
|   flutter_launcher_icons: ^0.9.0 | ||||
|   lint: ^1.8.0 | ||||
|   test: ^1.19.0 | ||||
|   flutter_test: | ||||
|     sdk: flutter | ||||
|   lint: ^1.8.0 | ||||
|   test: ^1.19.0 | ||||
|  | ||||
| flutter_icons: | ||||
|   android: true | ||||
|   | ||||
| @@ -39,6 +39,30 @@ void main() { | ||||
|  | ||||
|     }); | ||||
|  | ||||
|     test("Login Failure", () async { | ||||
|       // Tests for various types of login failures | ||||
|       var api = InvenTreeAPI(); | ||||
|  | ||||
|       // Incorrect server address | ||||
|       var profile = await UserProfileDBManager().getSelectedProfile(); | ||||
|  | ||||
|       assert(profile != null); | ||||
|  | ||||
|       if (profile != null) { | ||||
|         profile.server = "http://localhost:5555"; | ||||
|         await UserProfileDBManager().updateProfile(profile); | ||||
|       } | ||||
|  | ||||
|       bool result = await api.connectToServer(); | ||||
|  | ||||
|       assert(!result); | ||||
|  | ||||
|       // TODO: Test the the right 'error message' is returned | ||||
|  | ||||
|       // TODO: Test incorrect login details | ||||
|  | ||||
|     }); | ||||
|  | ||||
|     test("Login Success", () async { | ||||
|       // Test that we can login to the server successfully | ||||
|       var api = InvenTreeAPI(); | ||||
| @@ -46,10 +70,13 @@ void main() { | ||||
|       // Attempt to connect | ||||
|       final bool result = await api.connectToServer(); | ||||
|  | ||||
|       // Check expected values | ||||
|       expect(result, equals(true)); | ||||
|       expect(api.hasToken, equals(true)); | ||||
|  | ||||
|       expect(api.baseUrl, equals("http://localhost:12345/")); | ||||
|  | ||||
|       expect(api.isConnected(), equals(true)); | ||||
|       expect(api.isConnecting(), equals(false)); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user