stable version of null-safetyflutter-beta
| @@ -8,18 +8,16 @@ jobs: | |||||
| runs-on: ubuntu-latest | runs-on: ubuntu-latest | ||||
| steps: | steps: | ||||
| - uses: actions/checkout@v1 | |||||
| - uses: actions/setup-java@v1 | |||||
| with: | |||||
| java-version: '12.x' | |||||
| - uses: subosito/flutter-action@v1 | |||||
| with: | |||||
| channel: 'stable' | |||||
| - name: Version | |||||
| run: flutter doctor -v | |||||
| - name: Install dependencies | |||||
| run: flutter pub get | |||||
| - name: Format | |||||
| run: dartfmt -n --set-exit-if-changed . | |||||
| - name: Linter | |||||
| run: dartanalyzer . --options=analysis_options.yaml --fatal-hints | |||||
| - uses: actions/checkout@v2 | |||||
| - uses: actions/setup-java@v1 | |||||
| with: | |||||
| java-version: '12.x' | |||||
| - uses: subosito/flutter-action@v1 | |||||
| - name: Version | |||||
| run: flutter doctor -v | |||||
| - name: Install dependencies | |||||
| run: flutter pub get | |||||
| - name: Format | |||||
| run: flutter format -n --set-exit-if-changed . | |||||
| - name: Linter | |||||
| run: flutter analyze | |||||
| @@ -1,107 +1 @@ | |||||
| include: package:pedantic/analysis_options.yaml | |||||
| linter: | |||||
| rules: | |||||
| - always_put_required_named_parameters_first | |||||
| - always_require_non_null_named_parameters | |||||
| - avoid_annotating_with_dynamic | |||||
| - avoid_bool_literals_in_conditional_expressions | |||||
| - avoid_catching_errors | |||||
| - avoid_classes_with_only_static_members | |||||
| - avoid_empty_else | |||||
| - avoid_init_to_null | |||||
| - avoid_null_checks_in_equality_operators | |||||
| - avoid_print | |||||
| - avoid_relative_lib_imports | |||||
| - avoid_return_types_on_setters | |||||
| - avoid_returning_null | |||||
| - avoid_returning_null_for_future | |||||
| - avoid_returning_null_for_void | |||||
| - avoid_shadowing_type_parameters | |||||
| - avoid_single_cascade_in_expression_statements | |||||
| - avoid_types_as_parameter_names | |||||
| - avoid_types_on_closure_parameters | |||||
| - avoid_void_async | |||||
| - await_only_futures | |||||
| - camel_case_types | |||||
| - cancel_subscriptions | |||||
| - cascade_invocations | |||||
| - close_sinks | |||||
| - comment_references | |||||
| - constant_identifier_names | |||||
| - control_flow_in_finally | |||||
| - curly_braces_in_flow_control_structures | |||||
| - directives_ordering | |||||
| - empty_catches | |||||
| - empty_constructor_bodies | |||||
| - empty_statements | |||||
| - file_names | |||||
| - hash_and_equals | |||||
| - implementation_imports | |||||
| - invariant_booleans | |||||
| - iterable_contains_unrelated_type | |||||
| - join_return_with_assignment | |||||
| - library_names | |||||
| - library_prefixes | |||||
| - list_remove_unrelated_type | |||||
| - no_duplicate_case_values | |||||
| - non_constant_identifier_names | |||||
| - null_closures | |||||
| - only_throw_errors | |||||
| - overridden_fields | |||||
| - package_api_docs | |||||
| - package_names | |||||
| - package_prefixed_library_names | |||||
| - prefer_collection_literals | |||||
| - prefer_conditional_assignment | |||||
| - prefer_const_declarations | |||||
| - prefer_contains | |||||
| - prefer_equal_for_default_values | |||||
| - prefer_final_fields | |||||
| - prefer_for_elements_to_map_fromIterable | |||||
| - prefer_foreach | |||||
| - prefer_function_declarations_over_variables | |||||
| - prefer_if_elements_to_conditional_expressions | |||||
| - prefer_if_null_operators | |||||
| - prefer_initializing_formals | |||||
| - prefer_inlined_adds | |||||
| - prefer_int_literals | |||||
| - prefer_interpolation_to_compose_strings | |||||
| - prefer_is_empty | |||||
| - prefer_is_not_empty | |||||
| - prefer_iterable_whereType | |||||
| - prefer_null_aware_operators | |||||
| - prefer_void_to_null | |||||
| - provide_deprecation_message | |||||
| - recursive_getters | |||||
| - slash_for_doc_comments | |||||
| - sort_child_properties_last | |||||
| - sort_constructors_first | |||||
| - sort_pub_dependencies | |||||
| - sort_unnamed_constructors_first | |||||
| - test_types_in_equals | |||||
| - throw_in_finally | |||||
| - type_init_formals | |||||
| - unawaited_futures | |||||
| - unnecessary_await_in_return | |||||
| - unnecessary_brace_in_string_interps | |||||
| - unnecessary_const | |||||
| - unnecessary_getters_setters | |||||
| - unnecessary_lambdas | |||||
| - unnecessary_new | |||||
| - unnecessary_null_aware_assignments | |||||
| - unnecessary_null_in_if_null_operators | |||||
| - unnecessary_overrides | |||||
| - unnecessary_parenthesis | |||||
| - unnecessary_statements | |||||
| - unnecessary_this | |||||
| - unrelated_type_equality_checks | |||||
| - unsafe_html | |||||
| - use_full_hex_values_for_flutter_colors | |||||
| - use_function_type_syntax_for_parameters | |||||
| - use_rethrow_when_possible | |||||
| - use_setters_to_change_properties | |||||
| - use_string_buffers | |||||
| - use_to_and_as_if_applicable | |||||
| - valid_regexps | |||||
| - void_checks | |||||
| include: package:pedantic/analysis_options.yaml | |||||
| @@ -7,17 +7,13 @@ import 'package:qr_code_scanner/qr_code_scanner.dart'; | |||||
| void main() => runApp(MaterialApp(home: QRViewExample())); | void main() => runApp(MaterialApp(home: QRViewExample())); | ||||
| class QRViewExample extends StatefulWidget { | class QRViewExample extends StatefulWidget { | ||||
| const QRViewExample({ | |||||
| Key key, | |||||
| }) : super(key: key); | |||||
| @override | @override | ||||
| State<StatefulWidget> createState() => _QRViewExampleState(); | State<StatefulWidget> createState() => _QRViewExampleState(); | ||||
| } | } | ||||
| class _QRViewExampleState extends State<QRViewExample> { | class _QRViewExampleState extends State<QRViewExample> { | ||||
| Barcode result; | |||||
| QRViewController controller; | |||||
| Barcode? result; | |||||
| QRViewController? controller; | |||||
| final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); | final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); | ||||
| // In order to get hot reload to work we need to pause the camera if the platform | // In order to get hot reload to work we need to pause the camera if the platform | ||||
| @@ -26,9 +22,9 @@ class _QRViewExampleState extends State<QRViewExample> { | |||||
| void reassemble() { | void reassemble() { | ||||
| super.reassemble(); | super.reassemble(); | ||||
| if (Platform.isAndroid) { | if (Platform.isAndroid) { | ||||
| controller.pauseCamera(); | |||||
| controller!.pauseCamera(); | |||||
| } | } | ||||
| controller.resumeCamera(); | |||||
| controller!.resumeCamera(); | |||||
| } | } | ||||
| @override | @override | ||||
| @@ -46,7 +42,7 @@ class _QRViewExampleState extends State<QRViewExample> { | |||||
| children: <Widget>[ | children: <Widget>[ | ||||
| if (result != null) | if (result != null) | ||||
| Text( | Text( | ||||
| 'Barcode Type: ${describeEnum(result.format)} Data: ${result.code}') | |||||
| 'Barcode Type: ${describeEnum(result!.format)} Data: ${result!.code}') | |||||
| else | else | ||||
| Text('Scan a code'), | Text('Scan a code'), | ||||
| Row( | Row( | ||||
| @@ -79,7 +75,7 @@ class _QRViewExampleState extends State<QRViewExample> { | |||||
| builder: (context, snapshot) { | builder: (context, snapshot) { | ||||
| if (snapshot.data != null) { | if (snapshot.data != null) { | ||||
| return Text( | return Text( | ||||
| 'Camera facing ${describeEnum(snapshot.data)}'); | |||||
| 'Camera facing ${describeEnum(snapshot.data!)}'); | |||||
| } else { | } else { | ||||
| return Text('loading'); | return Text('loading'); | ||||
| } | } | ||||
| @@ -3,17 +3,14 @@ description: Demonstrates how to use the flutter_qr plugin. | |||||
| publish_to: 'none' | publish_to: 'none' | ||||
| environment: | environment: | ||||
| sdk: ">=2.6.0 <3.0.0" | |||||
| sdk: '>=2.12.0 <3.0.0' | |||||
| dependencies: | dependencies: | ||||
| flutter: | flutter: | ||||
| sdk: flutter | sdk: flutter | ||||
| # The following adds the Cupertino Icons font to your application. | |||||
| # Use with the CupertinoIcons class for iOS style icons. | |||||
| cupertino_icons: ^0.1.2 | |||||
| dev_dependencies: | dev_dependencies: | ||||
| pedantic: ^1.11.0 | |||||
| flutter_test: | flutter_test: | ||||
| sdk: flutter | sdk: flutter | ||||
| @@ -3,28 +3,20 @@ import 'package:flutter/foundation.dart'; | |||||
| class LifecycleEventHandler extends WidgetsBindingObserver { | class LifecycleEventHandler extends WidgetsBindingObserver { | ||||
| LifecycleEventHandler({ | LifecycleEventHandler({ | ||||
| this.resumeCallBack, | |||||
| this.suspendingCallBack, | |||||
| required this.resumeCallBack, | |||||
| }); | }); | ||||
| final AsyncCallback resumeCallBack; | |||||
| final AsyncCallback suspendingCallBack; | |||||
| late final AsyncCallback resumeCallBack; | |||||
| @override | @override | ||||
| Future<void> didChangeAppLifecycleState(AppLifecycleState state) async { | Future<void> didChangeAppLifecycleState(AppLifecycleState state) async { | ||||
| switch (state) { | switch (state) { | ||||
| case AppLifecycleState.resumed: | case AppLifecycleState.resumed: | ||||
| if (resumeCallBack != null) { | |||||
| await resumeCallBack(); | |||||
| } | |||||
| await resumeCallBack(); | |||||
| break; | break; | ||||
| case AppLifecycleState.inactive: | case AppLifecycleState.inactive: | ||||
| case AppLifecycleState.paused: | case AppLifecycleState.paused: | ||||
| case AppLifecycleState.detached: | case AppLifecycleState.detached: | ||||
| if (suspendingCallBack != null) { | |||||
| await suspendingCallBack(); | |||||
| } | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -20,23 +20,21 @@ typedef PermissionSetCallback = void Function(QRViewController, bool); | |||||
| /// and the barcode scanner gets displayed. | /// and the barcode scanner gets displayed. | ||||
| class QRView extends StatefulWidget { | class QRView extends StatefulWidget { | ||||
| const QRView({ | const QRView({ | ||||
| @required Key key, | |||||
| @required this.onQRViewCreated, | |||||
| required Key key, | |||||
| required this.onQRViewCreated, | |||||
| this.overlay, | this.overlay, | ||||
| this.overlayMargin = EdgeInsets.zero, | this.overlayMargin = EdgeInsets.zero, | ||||
| this.cameraFacing = CameraFacing.back, | this.cameraFacing = CameraFacing.back, | ||||
| this.onPermissionSet, | this.onPermissionSet, | ||||
| this.formatsAllowed, | |||||
| }) : assert(key != null), | |||||
| assert(onQRViewCreated != null), | |||||
| super(key: key); | |||||
| this.formatsAllowed = const <BarcodeFormat>[], | |||||
| }) : super(key: key); | |||||
| /// [onQRViewCreated] gets called when the view is created | /// [onQRViewCreated] gets called when the view is created | ||||
| final QRViewCreatedCallback onQRViewCreated; | final QRViewCreatedCallback onQRViewCreated; | ||||
| /// Use [overlay] to provide an overlay for the view. | /// Use [overlay] to provide an overlay for the view. | ||||
| /// This can be used to create a certain scan area. | /// This can be used to create a certain scan area. | ||||
| final QrScannerOverlayShape overlay; | |||||
| final QrScannerOverlayShape? overlay; | |||||
| /// Use [overlayMargin] to provide a margin to [overlay] | /// Use [overlayMargin] to provide a margin to [overlay] | ||||
| final EdgeInsetsGeometry overlayMargin; | final EdgeInsetsGeometry overlayMargin; | ||||
| @@ -48,7 +46,7 @@ class QRView extends StatefulWidget { | |||||
| final CameraFacing cameraFacing; | final CameraFacing cameraFacing; | ||||
| /// Calls the provided [onPermissionSet] callback when the permission is set. | /// Calls the provided [onPermissionSet] callback when the permission is set. | ||||
| final PermissionSetCallback onPermissionSet; | |||||
| final PermissionSetCallback? onPermissionSet; | |||||
| /// Use [formatsAllowed] to specify which formats needs to be scanned. | /// Use [formatsAllowed] to specify which formats needs to be scanned. | ||||
| final List<BarcodeFormat> formatsAllowed; | final List<BarcodeFormat> formatsAllowed; | ||||
| @@ -58,21 +56,14 @@ class QRView extends StatefulWidget { | |||||
| } | } | ||||
| class _QRViewState extends State<QRView> { | class _QRViewState extends State<QRView> { | ||||
| var _channel; | |||||
| var _observer; | |||||
| late MethodChannel _channel; | |||||
| late LifecycleEventHandler _observer; | |||||
| @override | @override | ||||
| void initState() { | void initState() { | ||||
| super.initState(); | super.initState(); | ||||
| _observer = LifecycleEventHandler( | |||||
| resumeCallBack: () async => { | |||||
| if (_channel != null) | |||||
| { | |||||
| QRViewController.updateDimensions(widget.key, _channel, | |||||
| overlay: widget.overlay) | |||||
| } | |||||
| }); | |||||
| WidgetsBinding.instance.addObserver(_observer); | |||||
| _observer = LifecycleEventHandler(resumeCallBack: updateDimensions); | |||||
| WidgetsBinding.instance!.addObserver(_observer); | |||||
| } | } | ||||
| @override | @override | ||||
| @@ -90,15 +81,17 @@ class _QRViewState extends State<QRView> { | |||||
| @override | @override | ||||
| void dispose() { | void dispose() { | ||||
| super.dispose(); | super.dispose(); | ||||
| WidgetsBinding.instance.removeObserver(_observer); | |||||
| WidgetsBinding.instance!.removeObserver(_observer); | |||||
| } | } | ||||
| bool onNotification(notification) { | |||||
| Future.microtask(() => { | |||||
| QRViewController.updateDimensions(widget.key, _channel, | |||||
| overlay: widget.overlay) | |||||
| }); | |||||
| Future<void> updateDimensions() async { | |||||
| await QRViewController.updateDimensions( | |||||
| widget.key as GlobalKey<State<StatefulWidget>>, _channel, | |||||
| overlay: widget.overlay); | |||||
| } | |||||
| bool onNotification(notification) { | |||||
| updateDimensions(); | |||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -109,7 +102,7 @@ class _QRViewState extends State<QRView> { | |||||
| Container( | Container( | ||||
| padding: widget.overlayMargin, | padding: widget.overlayMargin, | ||||
| decoration: ShapeDecoration( | decoration: ShapeDecoration( | ||||
| shape: widget.overlay, | |||||
| shape: widget.overlay!, | |||||
| ), | ), | ||||
| ) | ) | ||||
| ], | ], | ||||
| @@ -139,7 +132,7 @@ class _QRViewState extends State<QRView> { | |||||
| break; | break; | ||||
| default: | default: | ||||
| throw UnsupportedError( | throw UnsupportedError( | ||||
| "Trying to use the default webview implementation for $defaultTargetPlatform but there isn't a default one"); | |||||
| "Trying to use the default qrview implementation for $defaultTargetPlatform but there isn't a default one"); | |||||
| } | } | ||||
| return _platformQrView; | return _platformQrView; | ||||
| } | } | ||||
| @@ -149,19 +142,21 @@ class _QRViewState extends State<QRView> { | |||||
| // Start scan after creation of the view | // Start scan after creation of the view | ||||
| final controller = QRViewController._( | final controller = QRViewController._( | ||||
| _channel, widget.key, widget.onPermissionSet, widget.cameraFacing) | |||||
| .._startScan(widget.key, widget.overlay, widget.formatsAllowed); | |||||
| _channel, | |||||
| widget.key as GlobalKey<State<StatefulWidget>>?, | |||||
| widget.onPermissionSet, | |||||
| widget.cameraFacing) | |||||
| .._startScan(widget.key as GlobalKey<State<StatefulWidget>>, | |||||
| widget.overlay, widget.formatsAllowed); | |||||
| // Initialize the controller for controlling the QRView | // Initialize the controller for controlling the QRView | ||||
| if (widget.onQRViewCreated != null) { | |||||
| widget.onQRViewCreated(controller); | |||||
| } | |||||
| widget.onQRViewCreated(controller); | |||||
| } | } | ||||
| } | } | ||||
| class _QrCameraSettings { | class _QrCameraSettings { | ||||
| _QrCameraSettings({ | _QrCameraSettings({ | ||||
| this.cameraFacing, | |||||
| this.cameraFacing = CameraFacing.unknown, | |||||
| }); | }); | ||||
| final CameraFacing cameraFacing; | final CameraFacing cameraFacing; | ||||
| @@ -174,8 +169,8 @@ class _QrCameraSettings { | |||||
| } | } | ||||
| class QRViewController { | class QRViewController { | ||||
| QRViewController._(MethodChannel channel, GlobalKey qrKey, | |||||
| PermissionSetCallback onPermissionSet, CameraFacing cameraFacing) | |||||
| QRViewController._(MethodChannel channel, GlobalKey? qrKey, | |||||
| PermissionSetCallback? onPermissionSet, CameraFacing cameraFacing) | |||||
| : _channel = channel, | : _channel = channel, | ||||
| _cameraFacing = cameraFacing { | _cameraFacing = cameraFacing { | ||||
| _channel.setMethodCallHandler((call) async { | _channel.setMethodCallHandler((call) async { | ||||
| @@ -186,9 +181,9 @@ class QRViewController { | |||||
| final code = args['code'] as String; | final code = args['code'] as String; | ||||
| final rawType = args['type'] as String; | final rawType = args['type'] as String; | ||||
| // Raw bytes are only supported by Android. | // Raw bytes are only supported by Android. | ||||
| final rawBytes = args['rawBytes'] as List<int>; | |||||
| final rawBytes = args['rawBytes'] as List<int>?; | |||||
| final format = BarcodeTypesExtension.fromString(rawType); | final format = BarcodeTypesExtension.fromString(rawType); | ||||
| if (format != null) { | |||||
| if (format != BarcodeFormat.unknown) { | |||||
| final barcode = Barcode(code, format, rawBytes); | final barcode = Barcode(code, format, rawBytes); | ||||
| _scanUpdateController.sink.add(barcode); | _scanUpdateController.sink.add(barcode); | ||||
| } else { | } else { | ||||
| @@ -197,15 +192,14 @@ class QRViewController { | |||||
| } | } | ||||
| break; | break; | ||||
| case 'onPermissionSet': | case 'onPermissionSet': | ||||
| await getSystemFeatures(); // if we have no permission all features will not be avaible | |||||
| if (call.arguments != null) { | |||||
| if (call.arguments as bool) { | |||||
| if (call.arguments != null && call.arguments is bool) { | |||||
| if (call.arguments) { | |||||
| _hasPermissions = true; | _hasPermissions = true; | ||||
| } else { | } else { | ||||
| _hasPermissions = false; | _hasPermissions = false; | ||||
| } | } | ||||
| if (onPermissionSet != null) { | if (onPermissionSet != null) { | ||||
| onPermissionSet(this, call.arguments as bool); | |||||
| onPermissionSet(this, call.arguments); | |||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| @@ -220,20 +214,17 @@ class QRViewController { | |||||
| Stream<Barcode> get scannedDataStream => _scanUpdateController.stream; | Stream<Barcode> get scannedDataStream => _scanUpdateController.stream; | ||||
| SystemFeatures _features; | |||||
| bool _hasPermissions; | |||||
| SystemFeatures get systemFeatures => _features; | |||||
| bool _hasPermissions = false; | |||||
| bool get hasPermissions => _hasPermissions; | bool get hasPermissions => _hasPermissions; | ||||
| /// Starts the barcode scanner | /// Starts the barcode scanner | ||||
| Future<void> _startScan(GlobalKey key, QrScannerOverlayShape overlay, | |||||
| List<BarcodeFormat> barcodeFormats) async { | |||||
| Future<void> _startScan(GlobalKey key, QrScannerOverlayShape? overlay, | |||||
| List<BarcodeFormat>? barcodeFormats) async { | |||||
| // We need to update the dimension before the scan is started. | // We need to update the dimension before the scan is started. | ||||
| try { | try { | ||||
| await QRViewController.updateDimensions(key, _channel, overlay: overlay); | await QRViewController.updateDimensions(key, _channel, overlay: overlay); | ||||
| return await _channel.invokeMethod( | return await _channel.invokeMethod( | ||||
| 'startScan', barcodeFormats?.map((e) => e.asInt())?.toList() ?? []); | |||||
| 'startScan', barcodeFormats?.map((e) => e.asInt()).toList() ?? []); | |||||
| } on PlatformException catch (e) { | } on PlatformException catch (e) { | ||||
| throw CameraException(e.code, e.message); | throw CameraException(e.code, e.message); | ||||
| } | } | ||||
| @@ -262,7 +253,7 @@ class QRViewController { | |||||
| } | } | ||||
| /// Get flashlight status | /// Get flashlight status | ||||
| Future<bool> getFlashStatus() async { | |||||
| Future<bool?> getFlashStatus() async { | |||||
| try { | try { | ||||
| return await _channel.invokeMethod('getFlashInfo'); | return await _channel.invokeMethod('getFlashInfo'); | ||||
| } on PlatformException catch (e) { | } on PlatformException catch (e) { | ||||
| @@ -273,7 +264,7 @@ class QRViewController { | |||||
| /// Toggles the flashlight between available modes | /// Toggles the flashlight between available modes | ||||
| Future<void> toggleFlash() async { | Future<void> toggleFlash() async { | ||||
| try { | try { | ||||
| await _channel.invokeMethod('toggleFlash') as bool; | |||||
| await _channel.invokeMethod('toggleFlash') as bool?; | |||||
| } on PlatformException catch (e) { | } on PlatformException catch (e) { | ||||
| throw CameraException(e.code, e.message); | throw CameraException(e.code, e.message); | ||||
| } | } | ||||
| @@ -311,7 +302,10 @@ class QRViewController { | |||||
| try { | try { | ||||
| var features = | var features = | ||||
| await _channel.invokeMapMethod<String, dynamic>('getSystemFeatures'); | await _channel.invokeMapMethod<String, dynamic>('getSystemFeatures'); | ||||
| return SystemFeatures.fromJson(features); | |||||
| if (features != null) { | |||||
| return SystemFeatures.fromJson(features); | |||||
| } | |||||
| throw CameraException('Error', 'Could not get system features'); | |||||
| } on PlatformException catch (e) { | } on PlatformException catch (e) { | ||||
| throw CameraException(e.code, e.message); | throw CameraException(e.code, e.message); | ||||
| } | } | ||||
| @@ -324,12 +318,13 @@ class QRViewController { | |||||
| } | } | ||||
| /// Updates the view dimensions for iOS. | /// Updates the view dimensions for iOS. | ||||
| static Future<void> updateDimensions(GlobalKey key, MethodChannel channel, | |||||
| {QrScannerOverlayShape overlay}) async { | |||||
| static Future<bool> updateDimensions(GlobalKey key, MethodChannel channel, | |||||
| {QrScannerOverlayShape? overlay}) async { | |||||
| if (defaultTargetPlatform == TargetPlatform.iOS) { | if (defaultTargetPlatform == TargetPlatform.iOS) { | ||||
| // Add small delay to ensure the renderbox is loaded | |||||
| // Add small delay to ensure the render box is loaded | |||||
| await Future.delayed(Duration(milliseconds: 100)); | await Future.delayed(Duration(milliseconds: 100)); | ||||
| final RenderBox renderBox = key.currentContext.findRenderObject(); | |||||
| if (key.currentContext == null) return false; | |||||
| final renderBox = key.currentContext!.findRenderObject() as RenderBox; | |||||
| try { | try { | ||||
| await channel.invokeMethod('setDimensions', { | await channel.invokeMethod('setDimensions', { | ||||
| 'width': renderBox.size.width, | 'width': renderBox.size.width, | ||||
| @@ -337,9 +332,11 @@ class QRViewController { | |||||
| 'scanArea': overlay?.cutOutSize ?? 0, | 'scanArea': overlay?.cutOutSize ?? 0, | ||||
| 'scanAreaOffset': overlay?.cutOutBottomOffset ?? 0 | 'scanAreaOffset': overlay?.cutOutBottomOffset ?? 0 | ||||
| }); | }); | ||||
| return true; | |||||
| } on PlatformException catch (e) { | } on PlatformException catch (e) { | ||||
| throw CameraException(e.code, e.message); | throw CameraException(e.code, e.message); | ||||
| } | } | ||||
| } | } | ||||
| return false; | |||||
| } | } | ||||
| } | } | ||||
| @@ -11,10 +11,7 @@ class QrScannerOverlayShape extends ShapeBorder { | |||||
| this.borderLength = 40, | this.borderLength = 40, | ||||
| this.cutOutSize = 250, | this.cutOutSize = 250, | ||||
| this.cutOutBottomOffset = 0, | this.cutOutBottomOffset = 0, | ||||
| }) : assert( | |||||
| cutOutSize != null ?? | |||||
| cutOutSize != null ?? | |||||
| borderLength <= cutOutSize / 2 + borderWidth * 2, | |||||
| }) : assert(borderLength <= cutOutSize / 2 + borderWidth * 2, | |||||
| "Border can't be larger than ${cutOutSize / 2 + borderWidth * 2}"); | "Border can't be larger than ${cutOutSize / 2 + borderWidth * 2}"); | ||||
| final Color borderColor; | final Color borderColor; | ||||
| @@ -29,14 +26,14 @@ class QrScannerOverlayShape extends ShapeBorder { | |||||
| EdgeInsetsGeometry get dimensions => const EdgeInsets.all(10); | EdgeInsetsGeometry get dimensions => const EdgeInsets.all(10); | ||||
| @override | @override | ||||
| Path getInnerPath(Rect rect, {TextDirection textDirection}) { | |||||
| Path getInnerPath(Rect rect, {TextDirection? textDirection}) { | |||||
| return Path() | return Path() | ||||
| ..fillType = PathFillType.evenOdd | ..fillType = PathFillType.evenOdd | ||||
| ..addPath(getOuterPath(rect), Offset.zero); | ..addPath(getOuterPath(rect), Offset.zero); | ||||
| } | } | ||||
| @override | @override | ||||
| Path getOuterPath(Rect rect, {TextDirection textDirection}) { | |||||
| Path getOuterPath(Rect rect, {TextDirection? textDirection}) { | |||||
| Path _getLeftTopPath(Rect rect) { | Path _getLeftTopPath(Rect rect) { | ||||
| return Path() | return Path() | ||||
| ..moveTo(rect.left, rect.bottom) | ..moveTo(rect.left, rect.bottom) | ||||
| @@ -60,7 +57,7 @@ class QrScannerOverlayShape extends ShapeBorder { | |||||
| } | } | ||||
| @override | @override | ||||
| void paint(Canvas canvas, Rect rect, {TextDirection textDirection}) { | |||||
| void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) { | |||||
| final width = rect.width; | final width = rect.width; | ||||
| final borderWidthSize = width / 2; | final borderWidthSize = width / 2; | ||||
| final height = rect.height; | final height = rect.height; | ||||
| @@ -68,9 +65,7 @@ class QrScannerOverlayShape extends ShapeBorder { | |||||
| final _borderLength = borderLength > cutOutSize / 2 + borderWidth * 2 | final _borderLength = borderLength > cutOutSize / 2 + borderWidth * 2 | ||||
| ? borderWidthSize / 2 | ? borderWidthSize / 2 | ||||
| : borderLength; | : borderLength; | ||||
| final _cutOutSize = cutOutSize != null && cutOutSize < width | |||||
| ? cutOutSize | |||||
| : width - borderOffset; | |||||
| final _cutOutSize = cutOutSize < width ? cutOutSize : width - borderOffset; | |||||
| final backgroundPaint = Paint() | final backgroundPaint = Paint() | ||||
| ..color = overlayColor | ..color = overlayColor | ||||
| @@ -12,5 +12,5 @@ class Barcode { | |||||
| final BarcodeFormat format; | final BarcodeFormat format; | ||||
| /// Raw bytes are only supported by Android. | /// Raw bytes are only supported by Android. | ||||
| final List<int> rawBytes; | |||||
| final List<int>? rawBytes; | |||||
| } | } | ||||
| @@ -53,7 +53,10 @@ enum BarcodeFormat { | |||||
| upcE, | upcE, | ||||
| /// UPC/EAN extension format. Not a stand-alone format. | /// UPC/EAN extension format. Not a stand-alone format. | ||||
| upcEanExtension | |||||
| upcEanExtension, | |||||
| /// Unknown | |||||
| unknown | |||||
| } | } | ||||
| extension BarcodeTypesExtension on BarcodeFormat { | extension BarcodeTypesExtension on BarcodeFormat { | ||||
| @@ -65,57 +68,40 @@ extension BarcodeTypesExtension on BarcodeFormat { | |||||
| switch (format) { | switch (format) { | ||||
| case 'AZTEC': | case 'AZTEC': | ||||
| return BarcodeFormat.aztec; | return BarcodeFormat.aztec; | ||||
| break; | |||||
| case 'CODABAR': | case 'CODABAR': | ||||
| return BarcodeFormat.codabar; | return BarcodeFormat.codabar; | ||||
| break; | |||||
| case 'CODE_39': | case 'CODE_39': | ||||
| return BarcodeFormat.code39; | return BarcodeFormat.code39; | ||||
| break; | |||||
| case 'CODE_93': | case 'CODE_93': | ||||
| return BarcodeFormat.code93; | return BarcodeFormat.code93; | ||||
| break; | |||||
| case 'CODE_128': | case 'CODE_128': | ||||
| return BarcodeFormat.code128; | return BarcodeFormat.code128; | ||||
| break; | |||||
| case 'DATA_MATRIX': | case 'DATA_MATRIX': | ||||
| return BarcodeFormat.dataMatrix; | return BarcodeFormat.dataMatrix; | ||||
| break; | |||||
| case 'EAN_8': | case 'EAN_8': | ||||
| return BarcodeFormat.ean8; | return BarcodeFormat.ean8; | ||||
| break; | |||||
| case 'EAN_13': | case 'EAN_13': | ||||
| return BarcodeFormat.ean13; | return BarcodeFormat.ean13; | ||||
| break; | |||||
| case 'ITF': | case 'ITF': | ||||
| return BarcodeFormat.itf; | return BarcodeFormat.itf; | ||||
| break; | |||||
| case 'MAXICODE': | case 'MAXICODE': | ||||
| return BarcodeFormat.maxicode; | return BarcodeFormat.maxicode; | ||||
| break; | |||||
| case 'PDF_417': | case 'PDF_417': | ||||
| return BarcodeFormat.pdf417; | return BarcodeFormat.pdf417; | ||||
| break; | |||||
| case 'QR_CODE': | case 'QR_CODE': | ||||
| return BarcodeFormat.qrcode; | return BarcodeFormat.qrcode; | ||||
| break; | |||||
| case 'RSS14': | case 'RSS14': | ||||
| return BarcodeFormat.rss14; | return BarcodeFormat.rss14; | ||||
| break; | |||||
| case 'RSS_EXPANDED': | case 'RSS_EXPANDED': | ||||
| return BarcodeFormat.rssExpanded; | return BarcodeFormat.rssExpanded; | ||||
| break; | |||||
| case 'UPC_A': | case 'UPC_A': | ||||
| return BarcodeFormat.upcA; | return BarcodeFormat.upcA; | ||||
| break; | |||||
| case 'UPC_E': | case 'UPC_E': | ||||
| return BarcodeFormat.upcE; | return BarcodeFormat.upcE; | ||||
| break; | |||||
| case 'UPC_EAN_EXTENSION': | case 'UPC_EAN_EXTENSION': | ||||
| return BarcodeFormat.upcEanExtension; | return BarcodeFormat.upcEanExtension; | ||||
| break; | |||||
| default: | default: | ||||
| return null; | |||||
| return BarcodeFormat.unknown; | |||||
| } | } | ||||
| } | } | ||||
| @@ -123,57 +109,40 @@ extension BarcodeTypesExtension on BarcodeFormat { | |||||
| switch (this) { | switch (this) { | ||||
| case BarcodeFormat.aztec: | case BarcodeFormat.aztec: | ||||
| return 'AZTEC'; | return 'AZTEC'; | ||||
| break; | |||||
| case BarcodeFormat.codabar: | case BarcodeFormat.codabar: | ||||
| return 'CODABAR'; | return 'CODABAR'; | ||||
| break; | |||||
| case BarcodeFormat.code39: | case BarcodeFormat.code39: | ||||
| return 'CODE_39'; | return 'CODE_39'; | ||||
| break; | |||||
| case BarcodeFormat.code93: | case BarcodeFormat.code93: | ||||
| return 'CODE_93'; | return 'CODE_93'; | ||||
| break; | |||||
| case BarcodeFormat.code128: | case BarcodeFormat.code128: | ||||
| return 'CODE_128'; | return 'CODE_128'; | ||||
| break; | |||||
| case BarcodeFormat.dataMatrix: | case BarcodeFormat.dataMatrix: | ||||
| return 'DATA_MATRIX'; | return 'DATA_MATRIX'; | ||||
| break; | |||||
| case BarcodeFormat.ean8: | case BarcodeFormat.ean8: | ||||
| return 'EAN_8'; | return 'EAN_8'; | ||||
| break; | |||||
| case BarcodeFormat.ean13: | case BarcodeFormat.ean13: | ||||
| return 'EAN_13'; | return 'EAN_13'; | ||||
| break; | |||||
| case BarcodeFormat.itf: | case BarcodeFormat.itf: | ||||
| return 'ITF'; | return 'ITF'; | ||||
| break; | |||||
| case BarcodeFormat.maxicode: | case BarcodeFormat.maxicode: | ||||
| return 'MAXICODE'; | return 'MAXICODE'; | ||||
| break; | |||||
| case BarcodeFormat.pdf417: | case BarcodeFormat.pdf417: | ||||
| return 'PDF_417'; | return 'PDF_417'; | ||||
| break; | |||||
| case BarcodeFormat.qrcode: | case BarcodeFormat.qrcode: | ||||
| return 'QR_CODE'; | return 'QR_CODE'; | ||||
| break; | |||||
| case BarcodeFormat.rss14: | case BarcodeFormat.rss14: | ||||
| return 'RSS14'; | return 'RSS14'; | ||||
| break; | |||||
| case BarcodeFormat.rssExpanded: | case BarcodeFormat.rssExpanded: | ||||
| return 'RSS_EXPANDED'; | return 'RSS_EXPANDED'; | ||||
| break; | |||||
| case BarcodeFormat.upcA: | case BarcodeFormat.upcA: | ||||
| return 'UPC_A'; | return 'UPC_A'; | ||||
| break; | |||||
| case BarcodeFormat.upcE: | case BarcodeFormat.upcE: | ||||
| return 'UPC_E'; | return 'UPC_E'; | ||||
| break; | |||||
| case BarcodeFormat.upcEanExtension: | case BarcodeFormat.upcEanExtension: | ||||
| return 'UPC_EAN_EXTENSION'; | return 'UPC_EAN_EXTENSION'; | ||||
| break; | |||||
| default: | default: | ||||
| return 'NOT_VALID'; | |||||
| return 'UNKNOWN'; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -3,5 +3,8 @@ enum CameraFacing { | |||||
| back, | back, | ||||
| /// Shows front facing camera. | /// Shows front facing camera. | ||||
| front | |||||
| front, | |||||
| /// Unknown camera | |||||
| unknown | |||||
| } | } | ||||
| @@ -7,7 +7,7 @@ class CameraException implements Exception { | |||||
| String code; | String code; | ||||
| /// Textual description of the error. | /// Textual description of the error. | ||||
| String description; | |||||
| String? description; | |||||
| @override | @override | ||||
| String toString() => 'CameraException($code, $description)'; | String toString() => 'CameraException($code, $description)'; | ||||
| @@ -5,7 +5,7 @@ homepage: https://juliuscanute.com | |||||
| repository: https://github.com/juliuscanute/qr_code_scanner | repository: https://github.com/juliuscanute/qr_code_scanner | ||||
| environment: | environment: | ||||
| sdk: ">=2.6.0 <3.0.0" | |||||
| sdk: '>=2.12.0 <3.0.0' | |||||
| flutter: ">=1.10.0" | flutter: ">=1.10.0" | ||||
| dependencies: | dependencies: | ||||
| @@ -13,7 +13,7 @@ dependencies: | |||||
| sdk: flutter | sdk: flutter | ||||
| dev_dependencies: | dev_dependencies: | ||||
| pedantic: ^1.9.2 | |||||
| pedantic: ^1.11.0 | |||||
| flutter: | flutter: | ||||
| plugin: | plugin: | ||||