diff --git a/lib/barcode.dart b/lib/barcode.dart index ced482e3..2f7a79ea 100644 --- a/lib/barcode.dart +++ b/lib/barcode.dart @@ -247,7 +247,11 @@ class StockItemBarcodeAssignmentHandler extends BarcodeHandler { final InvenTreeStockItem item; - StockItemBarcodeAssignmentHandler(this.item); + StockItemBarcodeAssignmentHandler(this.item) { + if (item == null) { + throw new AssertionError("null StockItem passed to barcode handler"); + } + } @override String getOverlayText(BuildContext context) => L10().barcodeScanAssign; @@ -322,7 +326,11 @@ class StockItemScanIntoLocationHandler extends BarcodeHandler { final InvenTreeStockItem item; - StockItemScanIntoLocationHandler(this.item); + StockItemScanIntoLocationHandler(this.item) { + if (item == null) { + throw new AssertionError("null StockItem passed to StockItemScanIntoLocationHandler"); + } + } @override String getOverlayText(BuildContext context) => L10().barcodeScanLocation; @@ -378,7 +386,11 @@ class StockLocationScanInItemsHandler extends BarcodeHandler { final InvenTreeStockLocation location; - StockLocationScanInItemsHandler(this.location); + StockLocationScanInItemsHandler(this.location) { + if (location == null) { + throw new AssertionError("null StockLocation passed to StockLocationScanInItemsHandler"); + } + } @override String getOverlayText(BuildContext context) => L10().barcodeScanItem; diff --git a/lib/inventree/sentry.dart b/lib/inventree/sentry.dart index f0b63793..65a997a0 100644 --- a/lib/inventree/sentry.dart +++ b/lib/inventree/sentry.dart @@ -86,7 +86,7 @@ bool isInDebugMode() { Future sentryReportError(dynamic error, dynamic stackTrace) async { - print('Intercepted error: $error'); + print('----- Sentry Intercepted error: $error -----'); print(stackTrace); // Errors thrown in development mode are unlikely to be interesting. You can @@ -94,7 +94,7 @@ Future sentryReportError(dynamic error, dynamic stackTrace) async { // the report. if (isInDebugMode()) { - print('In dev mode. Not sending report to Sentry.io.'); + print('----- In dev mode. Not sending report to Sentry.io -----'); return; } diff --git a/lib/l10n b/lib/l10n index 7a23f04b..05a5cbf6 160000 --- a/lib/l10n +++ b/lib/l10n @@ -1 +1 @@ -Subproject commit 7a23f04bfc11dd099511536bdb8b72a9b35edecf +Subproject commit 05a5cbf63b4b5479162905def9fdadf21041212e diff --git a/lib/main.dart b/lib/main.dart index db2e4323..3d8fbb56 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -12,37 +12,32 @@ import 'package:one_context/one_context.dart'; import 'dsn.dart'; +import 'package:flutter/foundation.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; -void main() async { - - - await Sentry.init((options) { - options.dsn = SENTRY_DSN_KEY; - }, - //appRunner: () => runApp(InvenTreeApp()) - ); +Future main() async { await runZonedGuarded>(() async { - WidgetsFlutterBinding.ensureInitialized(); + await Sentry.init((options) { + options.dsn = SENTRY_DSN_KEY; + }); - // This captures errors reported by the Flutter framework. - FlutterError.onError = (FlutterErrorDetails details) async { - if (isInDebugMode()) { - // In development mode simply print to console. - FlutterError.dumpErrorToConsole(details); - } else { - // In production mode report to the application zone to report to - // Sentry. - Zone.current.handleUncaughtError(details.exception, details.stack); - } - }; + WidgetsFlutterBinding.ensureInitialized(); - runApp(InvenTreeApp()); + // Pass any flutter errors off to the Sentry reporting context! + FlutterError.onError = (FlutterErrorDetails details) async { - }, (Object error, StackTrace stackTrace) { + // Ensure that the error gets reported to sentry! + await sentryReportError(details.exception, details.stack); + }; + + runApp( + InvenTreeApp() + ); + + }, (Object error, StackTrace stackTrace) async { sentryReportError(error, stackTrace); }); @@ -81,6 +76,7 @@ class InvenTreeApp extends StatelessWidget { const Locale('tr', ''), const Locale('zh', ''), ], + ); } } \ No newline at end of file diff --git a/lib/widget/location_display.dart b/lib/widget/location_display.dart index a295e3cb..e6e75a12 100644 --- a/lib/widget/location_display.dart +++ b/lib/widget/location_display.dart @@ -297,27 +297,29 @@ List detailTiles() { List tiles = []; tiles.add(locationDescriptionCard(includeActions: false)); - - // Stock adjustment actions - if (InvenTreeAPI().checkPermission('stock', 'change')) { - // Scan items into location - tiles.add( - ListTile( - title: Text(L10().barcodeScanInItems), - leading: FaIcon(FontAwesomeIcons.exchangeAlt), - trailing: FaIcon(FontAwesomeIcons.qrcode), - onTap: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => - InvenTreeQRView( - StockLocationScanInItemsHandler(location))) - ).then((context) { - refresh(); - }); - }, - ) - ); + + if (location != null) { + // Stock adjustment actions + if (InvenTreeAPI().checkPermission('stock', 'change')) { + // Scan items into location + tiles.add( + ListTile( + title: Text(L10().barcodeScanInItems), + leading: FaIcon(FontAwesomeIcons.exchangeAlt), + trailing: FaIcon(FontAwesomeIcons.qrcode), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => + InvenTreeQRView( + StockLocationScanInItemsHandler(location))) + ).then((context) { + refresh(); + }); + }, + ) + ); + } } // Move location into another location @@ -332,6 +334,19 @@ List detailTiles() { ); */ + if (tiles.length <= 1) { + tiles.add( + ListTile( + title: Text( + L10().actionsNone, + style: TextStyle( + fontStyle: FontStyle.italic + ), + ) + ) + ); + } + return tiles; } diff --git a/lib/widget/part_detail.dart b/lib/widget/part_detail.dart index c0714c12..d28102f8 100644 --- a/lib/widget/part_detail.dart +++ b/lib/widget/part_detail.dart @@ -94,7 +94,7 @@ class _PartDisplayState extends RefreshableState { void _toggleStar() async { - if (InvenTreeAPI().checkPermission('part', 'change')) { + if (InvenTreeAPI().checkPermission('part', 'view')) { await part.update(context, values: {"starred": "${!part.starred}"}); refresh(); } @@ -105,7 +105,7 @@ class _PartDisplayState extends RefreshableState { final bool result = await part.update(context, values: values); if (result) { - showSnackIcon("Part edited", success: true); + showSnackIcon(L10().partEdited, success: true); } /* showSnackIcon( @@ -130,14 +130,15 @@ class _PartDisplayState extends RefreshableState { L10().imageUploadSuccess, success: true ); + + refresh(); + } else { showSnackIcon( L10().imageUploadFailure, success: false, ); } - - refresh(); } void _selectImage() { @@ -432,7 +433,7 @@ class _PartDisplayState extends RefreshableState { L10().stockItems, style: TextStyle(fontWeight: FontWeight.bold), ), - subtitle: part.stockItems.isEmpty ? Text("No stock items available") : null, + subtitle: part.stockItems.isEmpty ? Text(L10().stockItemsNotAvailable) : null, trailing: part.stockItems.isNotEmpty ? Text("${part.stockItems.length}") : null, ) ); @@ -463,7 +464,7 @@ class _PartDisplayState extends RefreshableState { tiles.add( ListTile( - title: Text("Scan New Stock Item"), + title: Text(L10().barcodeScanItem), leading: FaIcon(FontAwesomeIcons.box), trailing: FaIcon(FontAwesomeIcons.qrcode), onTap: null, diff --git a/lib/widget/stock_detail.dart b/lib/widget/stock_detail.dart index 1d64d6a8..e96381cb 100644 --- a/lib/widget/stock_detail.dart +++ b/lib/widget/stock_detail.dart @@ -141,7 +141,7 @@ class _StockItemDisplayState extends RefreshableState { void _stockUpdateMessage(bool result) { if (result) { - showSnackIcon("Stock item updated", success: true); + showSnackIcon(L10().stockItemUpdated, success: true); } } @@ -258,7 +258,7 @@ class _StockItemDisplayState extends RefreshableState { refresh(); if (result) { - showSnackIcon("Stock item transferred", success: true); + showSnackIcon(L10().stockItemTransferred, success: true); } } @@ -287,7 +287,7 @@ class _StockItemDisplayState extends RefreshableState { controller: _selectedController, autofocus: true, decoration: InputDecoration( - hintText: "Search for location", + hintText: L10().searchLocation, border: OutlineInputBorder() ) ), @@ -575,7 +575,7 @@ class _StockItemDisplayState extends RefreshableState { ); // Add or remove custom barcode - if (item.uid.isEmpty) { + if (item != null && item.uid.isEmpty) { tiles.add( ListTile( title: Text(L10().barcodeAssign),