Julian Steenbakker
Committed by GitHub

Merge pull request #110 from juliansteenbakker/lint

Apply flutter lint
1 # mobile_scanner 1 # mobile_scanner
2 2
3 [![pub package](https://img.shields.io/pub/v/mobile_scanner.svg)](https://pub.dev/packages/mobile_scanner) 3 [![pub package](https://img.shields.io/pub/v/mobile_scanner.svg)](https://pub.dev/packages/mobile_scanner)
  4 +[![style: lint](https://img.shields.io/badge/style-lint-4BC0F5.svg)](https://pub.dev/packages/lint)
4 [![mobile_scanner](https://github.com/juliansteenbakker/mobile_scanner/actions/workflows/flutter.yml/badge.svg)](https://github.com/juliansteenbakker/mobile_scanner/actions/workflows/flutter.yml) 5 [![mobile_scanner](https://github.com/juliansteenbakker/mobile_scanner/actions/workflows/flutter.yml/badge.svg)](https://github.com/juliansteenbakker/mobile_scanner/actions/workflows/flutter.yml)
5 [![GitHub Sponsors](https://img.shields.io/github/sponsors/juliansteenbakker?label=Want%20personal%20and%20fast%20support%3F%20Sponsor%20me%20and%20I%27ll%20contact%20you%21)](https://github.com/sponsors/juliansteenbakker) 6 [![GitHub Sponsors](https://img.shields.io/github/sponsors/juliansteenbakker?label=Want%20personal%20and%20fast%20support%3F%20Sponsor%20me%20and%20I%27ll%20contact%20you%21)](https://github.com/sponsors/juliansteenbakker)
6 7
1 -include: package:flutter_lints/flutter.yaml  
2 -  
3 -linter:  
4 - rules:  
5 - unawaited_futures: true  
  1 +include: package:lint/analysis_options_package.yaml
1 -# This file configures the analyzer, which statically analyzes Dart code to  
2 -# check for errors, warnings, and lints.  
3 -#  
4 -# The issues identified by the analyzer are surfaced in the UI of Dart-enabled  
5 -# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be  
6 -# invoked from the command line by running `flutter analyze`.  
7 -  
8 -# The following line activates a set of recommended lints for Flutter apps,  
9 -# packages, and plugins designed to encourage good coding practices.  
10 -include: package:flutter_lints/flutter.yaml  
11 -  
12 -linter:  
13 - # The lint rules applied to this project can be customized in the  
14 - # section below to disable rules from the `package:flutter_lints/flutter.yaml`  
15 - # included above or to enable additional rules. A list of all available lints  
16 - # and their documentation is published at  
17 - # https://dart-lang.github.io/linter/lints/index.html.  
18 - #  
19 - # Instead of disabling a lint rule for the entire project in the  
20 - # section below, it can also be suppressed for a single line of code  
21 - # or a specific dart file by using the `// ignore: name_of_lint` and  
22 - # `// ignore_for_file: name_of_lint` syntax on the line or in the file  
23 - # producing the lint.  
24 - rules:  
25 - # avoid_print: false # Uncomment to disable the `avoid_print` rule  
26 - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule  
27 -  
28 -# Additional information about this file can be found at  
29 -# https://dart.dev/guides/language/analysis-options 1 +include: package:lint/analysis_options.yaml
@@ -355,7 +355,7 @@ @@ -355,7 +355,7 @@
355 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 355 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
356 CLANG_ENABLE_MODULES = YES; 356 CLANG_ENABLE_MODULES = YES;
357 CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 357 CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
358 - DEVELOPMENT_TEAM = 75Y2P2WSQQ; 358 + DEVELOPMENT_TEAM = 3K8Q7WKS3W;
359 ENABLE_BITCODE = NO; 359 ENABLE_BITCODE = NO;
360 INFOPLIST_FILE = Runner/Info.plist; 360 INFOPLIST_FILE = Runner/Info.plist;
361 LD_RUNPATH_SEARCH_PATHS = ( 361 LD_RUNPATH_SEARCH_PATHS = (
@@ -484,7 +484,7 @@ @@ -484,7 +484,7 @@
484 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 484 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
485 CLANG_ENABLE_MODULES = YES; 485 CLANG_ENABLE_MODULES = YES;
486 CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 486 CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
487 - DEVELOPMENT_TEAM = 75Y2P2WSQQ; 487 + DEVELOPMENT_TEAM = 3K8Q7WKS3W;
488 ENABLE_BITCODE = NO; 488 ENABLE_BITCODE = NO;
489 INFOPLIST_FILE = Runner/Info.plist; 489 INFOPLIST_FILE = Runner/Info.plist;
490 LD_RUNPATH_SEARCH_PATHS = ( 490 LD_RUNPATH_SEARCH_PATHS = (
@@ -507,7 +507,7 @@ @@ -507,7 +507,7 @@
507 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 507 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
508 CLANG_ENABLE_MODULES = YES; 508 CLANG_ENABLE_MODULES = YES;
509 CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 509 CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
510 - DEVELOPMENT_TEAM = 75Y2P2WSQQ; 510 + DEVELOPMENT_TEAM = 3K8Q7WKS3W;
511 ENABLE_BITCODE = NO; 511 ENABLE_BITCODE = NO;
512 INFOPLIST_FILE = Runner/Info.plist; 512 INFOPLIST_FILE = Runner/Info.plist;
513 LD_RUNPATH_SEARCH_PATHS = ( 513 LD_RUNPATH_SEARCH_PATHS = (
@@ -27,10 +27,11 @@ class _BarcodeScannerWithControllerState @@ -27,10 +27,11 @@ class _BarcodeScannerWithControllerState
27 Widget build(BuildContext context) { 27 Widget build(BuildContext context) {
28 return Scaffold( 28 return Scaffold(
29 backgroundColor: Colors.black, 29 backgroundColor: Colors.black,
30 - body: Builder(builder: (context) {  
31 - return Stack(  
32 - children: [  
33 - MobileScanner( 30 + body: Builder(
  31 + builder: (context) {
  32 + return Stack(
  33 + children: [
  34 + MobileScanner(
34 controller: controller, 35 controller: controller,
35 fit: BoxFit.contain, 36 fit: BoxFit.contain,
36 // allowDuplicates: true, 37 // allowDuplicates: true,
@@ -42,112 +43,130 @@ class _BarcodeScannerWithControllerState @@ -42,112 +43,130 @@ class _BarcodeScannerWithControllerState
42 setState(() { 43 setState(() {
43 this.barcode = barcode.rawValue; 44 this.barcode = barcode.rawValue;
44 }); 45 });
45 - }),  
46 - Align(  
47 - alignment: Alignment.bottomCenter,  
48 - child: Container( 46 + },
  47 + ),
  48 + Align(
49 alignment: Alignment.bottomCenter, 49 alignment: Alignment.bottomCenter,
50 - height: 100,  
51 - color: Colors.black.withOpacity(0.4),  
52 - child: Row(  
53 - crossAxisAlignment: CrossAxisAlignment.center,  
54 - mainAxisAlignment: MainAxisAlignment.spaceEvenly,  
55 - children: [  
56 - IconButton(  
57 - color: Colors.white,  
58 - icon: ValueListenableBuilder(  
59 - valueListenable: controller.torchState,  
60 - builder: (context, state, child) {  
61 - switch (state as TorchState) {  
62 - case TorchState.off:  
63 - return const Icon(Icons.flash_off,  
64 - color: Colors.grey);  
65 - case TorchState.on:  
66 - return const Icon(Icons.flash_on,  
67 - color: Colors.yellow);  
68 - }  
69 - }, 50 + child: Container(
  51 + alignment: Alignment.bottomCenter,
  52 + height: 100,
  53 + color: Colors.black.withOpacity(0.4),
  54 + child: Row(
  55 + mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  56 + children: [
  57 + IconButton(
  58 + color: Colors.white,
  59 + icon: ValueListenableBuilder(
  60 + valueListenable: controller.torchState,
  61 + builder: (context, state, child) {
  62 + if (state == null) {
  63 + return const Icon(
  64 + Icons.flash_off,
  65 + color: Colors.grey,
  66 + );
  67 + }
  68 + switch (state as TorchState) {
  69 + case TorchState.off:
  70 + return const Icon(
  71 + Icons.flash_off,
  72 + color: Colors.grey,
  73 + );
  74 + case TorchState.on:
  75 + return const Icon(
  76 + Icons.flash_on,
  77 + color: Colors.yellow,
  78 + );
  79 + }
  80 + },
  81 + ),
  82 + iconSize: 32.0,
  83 + onPressed: () => controller.toggleTorch(),
70 ), 84 ),
71 - iconSize: 32.0,  
72 - onPressed: () => controller.toggleTorch(),  
73 - ),  
74 - IconButton( 85 + IconButton(
75 color: Colors.white, 86 color: Colors.white,
76 icon: isStarted 87 icon: isStarted
77 ? const Icon(Icons.stop) 88 ? const Icon(Icons.stop)
78 : const Icon(Icons.play_arrow), 89 : const Icon(Icons.play_arrow),
79 iconSize: 32.0, 90 iconSize: 32.0,
80 onPressed: () => setState(() { 91 onPressed: () => setState(() {
81 - isStarted  
82 - ? controller.stop()  
83 - : controller.start();  
84 - isStarted = !isStarted;  
85 - })),  
86 - Center(  
87 - child: SizedBox(  
88 - width: MediaQuery.of(context).size.width - 200,  
89 - height: 50,  
90 - child: FittedBox(  
91 - child: Text(  
92 - barcode ?? 'Scan something!',  
93 - overflow: TextOverflow.fade,  
94 - style: Theme.of(context)  
95 - .textTheme  
96 - .headline4!  
97 - .copyWith(color: Colors.white), 92 + isStarted ? controller.stop() : controller.start();
  93 + isStarted = !isStarted;
  94 + }),
  95 + ),
  96 + Center(
  97 + child: SizedBox(
  98 + width: MediaQuery.of(context).size.width - 200,
  99 + height: 50,
  100 + child: FittedBox(
  101 + child: Text(
  102 + barcode ?? 'Scan something!',
  103 + overflow: TextOverflow.fade,
  104 + style: Theme.of(context)
  105 + .textTheme
  106 + .headline4!
  107 + .copyWith(color: Colors.white),
  108 + ),
98 ), 109 ),
99 ), 110 ),
100 ), 111 ),
101 - ),  
102 - IconButton(  
103 - color: Colors.white,  
104 - icon: ValueListenableBuilder(  
105 - valueListenable: controller.cameraFacingState,  
106 - builder: (context, state, child) {  
107 - switch (state as CameraFacing) {  
108 - case CameraFacing.front: 112 + IconButton(
  113 + color: Colors.white,
  114 + icon: ValueListenableBuilder(
  115 + valueListenable: controller.cameraFacingState,
  116 + builder: (context, state, child) {
  117 + if (state == null) {
109 return const Icon(Icons.camera_front); 118 return const Icon(Icons.camera_front);
110 - case CameraFacing.back:  
111 - return const Icon(Icons.camera_rear); 119 + }
  120 + switch (state as CameraFacing) {
  121 + case CameraFacing.front:
  122 + return const Icon(Icons.camera_front);
  123 + case CameraFacing.back:
  124 + return const Icon(Icons.camera_rear);
  125 + }
  126 + },
  127 + ),
  128 + iconSize: 32.0,
  129 + onPressed: () => controller.switchCamera(),
  130 + ),
  131 + IconButton(
  132 + color: Colors.white,
  133 + icon: const Icon(Icons.image),
  134 + iconSize: 32.0,
  135 + onPressed: () async {
  136 + final ImagePicker _picker = ImagePicker();
  137 + // Pick an image
  138 + final XFile? image = await _picker.pickImage(
  139 + source: ImageSource.gallery,
  140 + );
  141 + if (image != null) {
  142 + if (await controller.analyzeImage(image.path)) {
  143 + if (!mounted) return;
  144 + ScaffoldMessenger.of(context).showSnackBar(
  145 + const SnackBar(
  146 + content: Text('Barcode found!'),
  147 + backgroundColor: Colors.green,
  148 + ),
  149 + );
  150 + } else {
  151 + if (!mounted) return;
  152 + ScaffoldMessenger.of(context).showSnackBar(
  153 + const SnackBar(
  154 + content: Text('No barcode found!'),
  155 + backgroundColor: Colors.red,
  156 + ),
  157 + );
  158 + }
112 } 159 }
113 }, 160 },
114 ), 161 ),
115 - iconSize: 32.0,  
116 - onPressed: () => controller.switchCamera(),  
117 - ),  
118 - IconButton(  
119 - color: Colors.white,  
120 - icon: const Icon(Icons.image),  
121 - iconSize: 32.0,  
122 - onPressed: () async {  
123 - final ImagePicker _picker = ImagePicker();  
124 - // Pick an image  
125 - final XFile? image = await _picker.pickImage(  
126 - source: ImageSource.gallery);  
127 - if (image != null) {  
128 - if (await controller.analyzeImage(image.path)) {  
129 - ScaffoldMessenger.of(context)  
130 - .showSnackBar(const SnackBar(  
131 - content: Text('Barcode found!'),  
132 - backgroundColor: Colors.green,  
133 - ));  
134 - } else {  
135 - ScaffoldMessenger.of(context)  
136 - .showSnackBar(const SnackBar(  
137 - content: Text('No barcode found!'),  
138 - backgroundColor: Colors.red,  
139 - ));  
140 - }  
141 - }  
142 - },  
143 - ),  
144 - ], 162 + ],
  163 + ),
145 ), 164 ),
146 ), 165 ),
147 - ),  
148 - ],  
149 - );  
150 - }), 166 + ],
  167 + );
  168 + },
  169 + ),
151 ); 170 );
152 } 171 }
153 } 172 }
@@ -18,50 +18,52 @@ class _BarcodeScannerWithoutControllerState @@ -18,50 +18,52 @@ class _BarcodeScannerWithoutControllerState
18 Widget build(BuildContext context) { 18 Widget build(BuildContext context) {
19 return Scaffold( 19 return Scaffold(
20 backgroundColor: Colors.black, 20 backgroundColor: Colors.black,
21 - body: Builder(builder: (context) {  
22 - return Stack(  
23 - children: [  
24 - MobileScanner( 21 + body: Builder(
  22 + builder: (context) {
  23 + return Stack(
  24 + children: [
  25 + MobileScanner(
25 fit: BoxFit.contain, 26 fit: BoxFit.contain,
26 // allowDuplicates: false, 27 // allowDuplicates: false,
27 onDetect: (barcode, args) { 28 onDetect: (barcode, args) {
28 setState(() { 29 setState(() {
29 this.barcode = barcode.rawValue; 30 this.barcode = barcode.rawValue;
30 }); 31 });
31 - }),  
32 - Align(  
33 - alignment: Alignment.bottomCenter,  
34 - child: Container( 32 + },
  33 + ),
  34 + Align(
35 alignment: Alignment.bottomCenter, 35 alignment: Alignment.bottomCenter,
36 - height: 100,  
37 - color: Colors.black.withOpacity(0.4),  
38 - child: Row(  
39 - crossAxisAlignment: CrossAxisAlignment.center,  
40 - mainAxisAlignment: MainAxisAlignment.spaceEvenly,  
41 - children: [  
42 - Center(  
43 - child: SizedBox(  
44 - width: MediaQuery.of(context).size.width - 120,  
45 - height: 50,  
46 - child: FittedBox(  
47 - child: Text(  
48 - barcode ?? 'Scan something!',  
49 - overflow: TextOverflow.fade,  
50 - style: Theme.of(context)  
51 - .textTheme  
52 - .headline4!  
53 - .copyWith(color: Colors.white), 36 + child: Container(
  37 + alignment: Alignment.bottomCenter,
  38 + height: 100,
  39 + color: Colors.black.withOpacity(0.4),
  40 + child: Row(
  41 + mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  42 + children: [
  43 + Center(
  44 + child: SizedBox(
  45 + width: MediaQuery.of(context).size.width - 120,
  46 + height: 50,
  47 + child: FittedBox(
  48 + child: Text(
  49 + barcode ?? 'Scan something!',
  50 + overflow: TextOverflow.fade,
  51 + style: Theme.of(context)
  52 + .textTheme
  53 + .headline4!
  54 + .copyWith(color: Colors.white),
  55 + ),
54 ), 56 ),
55 ), 57 ),
56 ), 58 ),
57 - ),  
58 - ], 59 + ],
  60 + ),
59 ), 61 ),
60 ), 62 ),
61 - ),  
62 - ],  
63 - );  
64 - }), 63 + ],
  64 + );
  65 + },
  66 + ),
65 ); 67 );
66 } 68 }
67 } 69 }
@@ -16,21 +16,25 @@ class MyHome extends StatelessWidget { @@ -16,21 +16,25 @@ class MyHome extends StatelessWidget {
16 height: MediaQuery.of(context).size.height, 16 height: MediaQuery.of(context).size.height,
17 child: Column( 17 child: Column(
18 mainAxisAlignment: MainAxisAlignment.center, 18 mainAxisAlignment: MainAxisAlignment.center,
19 - crossAxisAlignment: CrossAxisAlignment.center,  
20 children: [ 19 children: [
21 ElevatedButton( 20 ElevatedButton(
22 onPressed: () { 21 onPressed: () {
23 - Navigator.of(context).push(MaterialPageRoute(  
24 - builder: (context) => const BarcodeScannerWithController(),  
25 - )); 22 + Navigator.of(context).push(
  23 + MaterialPageRoute(
  24 + builder: (context) => const BarcodeScannerWithController(),
  25 + ),
  26 + );
26 }, 27 },
27 child: const Text('MobileScanner with Controller'), 28 child: const Text('MobileScanner with Controller'),
28 ), 29 ),
29 ElevatedButton( 30 ElevatedButton(
30 onPressed: () { 31 onPressed: () {
31 - Navigator.of(context).push(MaterialPageRoute(  
32 - builder: (context) => const BarcodeScannerWithoutController(),  
33 - )); 32 + Navigator.of(context).push(
  33 + MaterialPageRoute(
  34 + builder: (context) =>
  35 + const BarcodeScannerWithoutController(),
  36 + ),
  37 + );
34 }, 38 },
35 child: const Text('MobileScanner without Controller'), 39 child: const Text('MobileScanner without Controller'),
36 ), 40 ),
@@ -6,9 +6,9 @@ environment: @@ -6,9 +6,9 @@ environment:
6 sdk: ">=2.12.0 <3.0.0" 6 sdk: ">=2.12.0 <3.0.0"
7 7
8 dependencies: 8 dependencies:
9 - image_picker: ^0.8.4+9  
10 flutter: 9 flutter:
11 sdk: flutter 10 sdk: flutter
  11 + image_picker: ^0.8.4+9
12 12
13 mobile_scanner: 13 mobile_scanner:
14 path: ../ 14 path: ../
@@ -16,7 +16,7 @@ dependencies: @@ -16,7 +16,7 @@ dependencies:
16 dev_dependencies: 16 dev_dependencies:
17 flutter_test: 17 flutter_test:
18 sdk: flutter 18 sdk: flutter
19 - flutter_lints: ^1.0.4 19 + lint: ^1.8.2
20 20
21 flutter: 21 flutter:
22 uses-material-design: true 22 uses-material-design: true
1 library mobile_scanner; 1 library mobile_scanner;
2 2
3 export 'src/mobile_scanner.dart'; 3 export 'src/mobile_scanner.dart';
4 -export 'src/mobile_scanner_controller.dart';  
5 export 'src/mobile_scanner_arguments.dart'; 4 export 'src/mobile_scanner_arguments.dart';
  5 +export 'src/mobile_scanner_controller.dart';
6 export 'src/objects/barcode.dart'; 6 export 'src/objects/barcode.dart';
1 import 'dart:async'; 1 import 'dart:async';
  2 +import 'dart:html' as html;
  3 +import 'dart:ui' as ui;
2 4
3 import 'package:flutter/material.dart'; 5 import 'package:flutter/material.dart';
4 import 'package:flutter/services.dart'; 6 import 'package:flutter/services.dart';
5 import 'package:flutter_web_plugins/flutter_web_plugins.dart'; 7 import 'package:flutter_web_plugins/flutter_web_plugins.dart';
6 import 'package:mobile_scanner/mobile_scanner.dart'; 8 import 'package:mobile_scanner/mobile_scanner.dart';
7 import 'package:mobile_scanner/src/web/jsqr.dart'; 9 import 'package:mobile_scanner/src/web/jsqr.dart';
8 -import 'dart:html' as html;  
9 -import 'dart:ui' as ui;  
10 -  
11 import 'package:mobile_scanner/src/web/media.dart'; 10 import 'package:mobile_scanner/src/web/media.dart';
12 11
13 /// This plugin is the web implementation of mobile_scanner. 12 /// This plugin is the web implementation of mobile_scanner.
14 /// It only supports QR codes. 13 /// It only supports QR codes.
15 class MobileScannerWebPlugin { 14 class MobileScannerWebPlugin {
16 static void registerWith(Registrar registrar) { 15 static void registerWith(Registrar registrar) {
17 - PluginEventChannel event = PluginEventChannel(  
18 - 'dev.steenbakker.mobile_scanner/scanner/event',  
19 - const StandardMethodCodec(),  
20 - registrar);  
21 - MethodChannel channel = MethodChannel(  
22 - 'dev.steenbakker.mobile_scanner/scanner/method',  
23 - const StandardMethodCodec(),  
24 - registrar); 16 + final PluginEventChannel event = PluginEventChannel(
  17 + 'dev.steenbakker.mobile_scanner/scanner/event',
  18 + const StandardMethodCodec(),
  19 + registrar,
  20 + );
  21 + final MethodChannel channel = MethodChannel(
  22 + 'dev.steenbakker.mobile_scanner/scanner/method',
  23 + const StandardMethodCodec(),
  24 + registrar,
  25 + );
25 final MobileScannerWebPlugin instance = MobileScannerWebPlugin(); 26 final MobileScannerWebPlugin instance = MobileScannerWebPlugin();
26 WidgetsFlutterBinding.ensureInitialized(); 27 WidgetsFlutterBinding.ensureInitialized();
27 28
@@ -51,16 +52,17 @@ class MobileScannerWebPlugin { @@ -51,16 +52,17 @@ class MobileScannerWebPlugin {
51 Future<dynamic> handleMethodCall(MethodCall call) async { 52 Future<dynamic> handleMethodCall(MethodCall call) async {
52 switch (call.method) { 53 switch (call.method) {
53 case 'start': 54 case 'start':
54 - return await _start(call.arguments); 55 + return _start(call.arguments as Map);
55 case 'torch': 56 case 'torch':
56 - return await _torch(call.arguments); 57 + return _torch(call.arguments);
57 case 'stop': 58 case 'stop':
58 - return await cancel(); 59 + return cancel();
59 default: 60 default:
60 throw PlatformException( 61 throw PlatformException(
61 - code: 'Unimplemented',  
62 - details: "The mobile_scanner plugin for web doesn't implement "  
63 - "the method '${call.method}'"); 62 + code: 'Unimplemented',
  63 + details: "The mobile_scanner plugin for web doesn't implement "
  64 + "the method '${call.method}'",
  65 + );
64 } 66 }
65 } 67 }
66 68
@@ -77,21 +79,22 @@ class MobileScannerWebPlugin { @@ -77,21 +79,22 @@ class MobileScannerWebPlugin {
77 } 79 }
78 80
79 /// Starts the video stream and the scanner 81 /// Starts the video stream and the scanner
80 - Future<Map> _start(arguments) async { 82 + Future<Map> _start(Map arguments) async {
81 vidDiv.children = [video]; 83 vidDiv.children = [video];
82 84
83 var cameraFacing = CameraFacing.front; 85 var cameraFacing = CameraFacing.front;
84 if (arguments.containsKey('facing')) { 86 if (arguments.containsKey('facing')) {
85 - cameraFacing = CameraFacing.values[arguments['facing']]; 87 + cameraFacing = CameraFacing.values[arguments['facing'] as int];
86 } 88 }
87 89
88 // See https://github.com/flutter/flutter/issues/41563 90 // See https://github.com/flutter/flutter/issues/41563
89 - // ignore: UNDEFINED_PREFIXED_NAME 91 + // ignore: UNDEFINED_PREFIXED_NAME, avoid_dynamic_calls
90 ui.platformViewRegistry.registerViewFactory( 92 ui.platformViewRegistry.registerViewFactory(
91 - viewID,  
92 - (int id) => vidDiv  
93 - ..style.width = '100%'  
94 - ..style.height = '100%'); 93 + viewID,
  94 + (int id) => vidDiv
  95 + ..style.width = '100%'
  96 + ..style.height = '100%',
  97 + );
95 98
96 // Check if stream is running 99 // Check if stream is running
97 if (_localStream != null) { 100 if (_localStream != null) {
@@ -104,13 +107,14 @@ class MobileScannerWebPlugin { @@ -104,13 +107,14 @@ class MobileScannerWebPlugin {
104 107
105 try { 108 try {
106 // Check if browser supports multiple camera's and set if supported 109 // Check if browser supports multiple camera's and set if supported
107 - Map? capabilities = 110 + final Map? capabilities =
108 html.window.navigator.mediaDevices?.getSupportedConstraints(); 111 html.window.navigator.mediaDevices?.getSupportedConstraints();
109 - if (capabilities != null && capabilities['facingMode']) {  
110 - var constraints = { 112 + if (capabilities != null && capabilities['facingMode'] as bool) {
  113 + final constraints = {
111 'video': VideoOptions( 114 'video': VideoOptions(
112 - facingMode:  
113 - (cameraFacing == CameraFacing.front ? 'user' : 'environment')) 115 + facingMode:
  116 + cameraFacing == CameraFacing.front ? 'user' : 'environment',
  117 + )
114 }; 118 };
115 119
116 _localStream = 120 _localStream =
@@ -156,6 +160,8 @@ class MobileScannerWebPlugin { @@ -156,6 +160,8 @@ class MobileScannerWebPlugin {
156 final sources = 160 final sources =
157 await html.window.navigator.mediaDevices!.enumerateDevices(); 161 await html.window.navigator.mediaDevices!.enumerateDevices();
158 for (final e in sources) { 162 for (final e in sources) {
  163 + // TODO:
  164 + // ignore: avoid_dynamic_calls
159 if (e.kind == 'videoinput') { 165 if (e.kind == 'videoinput') {
160 return true; 166 return true;
161 } 167 }
@@ -28,13 +28,13 @@ class MobileScanner extends StatefulWidget { @@ -28,13 +28,13 @@ class MobileScanner extends StatefulWidget {
28 final bool allowDuplicates; 28 final bool allowDuplicates;
29 29
30 /// Create a [MobileScanner] with a [controller], the [controller] must has been initialized. 30 /// Create a [MobileScanner] with a [controller], the [controller] must has been initialized.
31 - const MobileScanner(  
32 - {Key? key,  
33 - this.onDetect,  
34 - this.controller,  
35 - this.fit = BoxFit.cover,  
36 - this.allowDuplicates = false})  
37 - : super(key: key); 31 + const MobileScanner({
  32 + Key? key,
  33 + this.onDetect,
  34 + this.controller,
  35 + this.fit = BoxFit.cover,
  36 + this.allowDuplicates = false,
  37 + }) : super(key: key);
38 38
39 @override 39 @override
40 State<MobileScanner> createState() => _MobileScannerState(); 40 State<MobileScanner> createState() => _MobileScannerState();
@@ -69,8 +69,9 @@ class _MobileScannerState extends State<MobileScanner> @@ -69,8 +69,9 @@ class _MobileScannerState extends State<MobileScanner>
69 69
70 @override 70 @override
71 Widget build(BuildContext context) { 71 Widget build(BuildContext context) {
72 - return LayoutBuilder(builder: (context, BoxConstraints constraints) {  
73 - return ValueListenableBuilder( 72 + return LayoutBuilder(
  73 + builder: (context, BoxConstraints constraints) {
  74 + return ValueListenableBuilder(
74 valueListenable: controller.args, 75 valueListenable: controller.args,
75 builder: (context, value, child) { 76 builder: (context, value, child) {
76 value = value as MobileScannerArguments?; 77 value = value as MobileScannerArguments?;
@@ -81,10 +82,10 @@ class _MobileScannerState extends State<MobileScanner> @@ -81,10 +82,10 @@ class _MobileScannerState extends State<MobileScanner>
81 if (!widget.allowDuplicates) { 82 if (!widget.allowDuplicates) {
82 if (lastScanned != barcode.rawValue) { 83 if (lastScanned != barcode.rawValue) {
83 lastScanned = barcode.rawValue; 84 lastScanned = barcode.rawValue;
84 - widget.onDetect!(barcode, value as MobileScannerArguments); 85 + widget.onDetect!(barcode, value! as MobileScannerArguments);
85 } 86 }
86 } else { 87 } else {
87 - widget.onDetect!(barcode, value as MobileScannerArguments); 88 + widget.onDetect!(barcode, value! as MobileScannerArguments);
88 } 89 }
89 }); 90 });
90 return ClipRect( 91 return ClipRect(
@@ -104,8 +105,10 @@ class _MobileScannerState extends State<MobileScanner> @@ -104,8 +105,10 @@ class _MobileScannerState extends State<MobileScanner>
104 ), 105 ),
105 ); 106 );
106 } 107 }
107 - });  
108 - }); 108 + },
  109 + );
  110 + },
  111 + );
109 } 112 }
110 113
111 @override 114 @override
@@ -13,6 +13,10 @@ class MobileScannerArguments { @@ -13,6 +13,10 @@ class MobileScannerArguments {
13 final String? webId; 13 final String? webId;
14 14
15 /// Create a [MobileScannerArguments]. 15 /// Create a [MobileScannerArguments].
16 - MobileScannerArguments(  
17 - {this.textureId, required this.size, required this.hasTorch, this.webId}); 16 + MobileScannerArguments({
  17 + this.textureId,
  18 + required this.size,
  19 + required this.hasTorch,
  20 + this.webId,
  21 + });
18 } 22 }
@@ -5,8 +5,7 @@ import 'package:flutter/cupertino.dart'; @@ -5,8 +5,7 @@ import 'package:flutter/cupertino.dart';
5 import 'package:flutter/foundation.dart'; 5 import 'package:flutter/foundation.dart';
6 import 'package:flutter/services.dart'; 6 import 'package:flutter/services.dart';
7 import 'package:mobile_scanner/mobile_scanner.dart'; 7 import 'package:mobile_scanner/mobile_scanner.dart';
8 -  
9 -import 'objects/barcode_utility.dart'; 8 +import 'package:mobile_scanner/src/objects/barcode_utility.dart';
10 9
11 /// The facing of a camera. 10 /// The facing of a camera.
12 enum CameraFacing { 11 enum CameraFacing {
@@ -56,11 +55,12 @@ class MobileScannerController { @@ -56,11 +55,12 @@ class MobileScannerController {
56 55
57 Stream<Barcode> get barcodes => barcodesController.stream; 56 Stream<Barcode> get barcodes => barcodesController.stream;
58 57
59 - MobileScannerController(  
60 - {this.facing = CameraFacing.back,  
61 - this.ratio,  
62 - this.torchEnabled,  
63 - this.formats}) { 58 + MobileScannerController({
  59 + this.facing = CameraFacing.back,
  60 + this.ratio,
  61 + this.torchEnabled,
  62 + this.formats,
  63 + }) {
64 // In case a new instance is created before calling dispose() 64 // In case a new instance is created before calling dispose()
65 if (_controllerHashcode != null) { 65 if (_controllerHashcode != null) {
66 stop(); 66 stop();
@@ -80,26 +80,30 @@ class MobileScannerController { @@ -80,26 +80,30 @@ class MobileScannerController {
80 // Listen to events from the platform specific code 80 // Listen to events from the platform specific code
81 events = eventChannel 81 events = eventChannel
82 .receiveBroadcastStream() 82 .receiveBroadcastStream()
83 - .listen((data) => handleEvent(data)); 83 + .listen((data) => handleEvent(data as Map));
84 } 84 }
85 85
86 - void handleEvent(Map<dynamic, dynamic> event) { 86 + void handleEvent(Map event) {
87 final name = event['name']; 87 final name = event['name'];
88 final data = event['data']; 88 final data = event['data'];
89 switch (name) { 89 switch (name) {
90 case 'torchState': 90 case 'torchState':
91 - final state = TorchState.values[data]; 91 + final state = TorchState.values[data as int];
92 torchState.value = state; 92 torchState.value = state;
93 break; 93 break;
94 case 'barcode': 94 case 'barcode':
95 - final barcode = Barcode.fromNative(data); 95 + final barcode = Barcode.fromNative(data as Map);
96 barcodesController.add(barcode); 96 barcodesController.add(barcode);
97 break; 97 break;
98 case 'barcodeMac': 98 case 'barcodeMac':
99 - barcodesController.add(Barcode(rawValue: data['payload'])); 99 + barcodesController.add(
  100 + Barcode(
  101 + rawValue: (data as Map)['payload'] as String,
  102 + ),
  103 + );
100 break; 104 break;
101 case 'barcodeWeb': 105 case 'barcodeWeb':
102 - barcodesController.add(Barcode(rawValue: data)); 106 + barcodesController.add(Barcode(rawValue: data as String));
103 break; 107 break;
104 default: 108 default:
105 throw UnimplementedError(); 109 throw UnimplementedError();
@@ -129,11 +133,12 @@ class MobileScannerController { @@ -129,11 +133,12 @@ class MobileScannerController {
129 133
130 // Check authorization status 134 // Check authorization status
131 if (!kIsWeb) { 135 if (!kIsWeb) {
132 - MobileScannerState state =  
133 - MobileScannerState.values[await methodChannel.invokeMethod('state')]; 136 + MobileScannerState state = MobileScannerState
  137 + .values[await methodChannel.invokeMethod('state') as int];
134 switch (state) { 138 switch (state) {
135 case MobileScannerState.undetermined: 139 case MobileScannerState.undetermined:
136 - final bool result = await methodChannel.invokeMethod('request'); 140 + final bool result =
  141 + await methodChannel.invokeMethod('request') as bool;
137 state = result 142 state = result
138 ? MobileScannerState.authorized 143 ? MobileScannerState.authorized
139 : MobileScannerState.denied; 144 : MobileScannerState.denied;
@@ -149,7 +154,7 @@ class MobileScannerController { @@ -149,7 +154,7 @@ class MobileScannerController {
149 cameraFacingState.value = facing; 154 cameraFacingState.value = facing;
150 155
151 // Set the starting arguments for the camera 156 // Set the starting arguments for the camera
152 - Map arguments = {}; 157 + final Map arguments = {};
153 arguments['facing'] = facing.index; 158 arguments['facing'] = facing.index;
154 if (ratio != null) arguments['ratio'] = ratio; 159 if (ratio != null) arguments['ratio'] = ratio;
155 if (torchEnabled != null) arguments['torch'] = torchEnabled; 160 if (torchEnabled != null) arguments['torch'] = torchEnabled;
@@ -166,7 +171,9 @@ class MobileScannerController { @@ -166,7 +171,9 @@ class MobileScannerController {
166 Map<String, dynamic>? startResult = {}; 171 Map<String, dynamic>? startResult = {};
167 try { 172 try {
168 startResult = await methodChannel.invokeMapMethod<String, dynamic>( 173 startResult = await methodChannel.invokeMapMethod<String, dynamic>(
169 - 'start', arguments); 174 + 'start',
  175 + arguments,
  176 + );
170 } on PlatformException catch (error) { 177 } on PlatformException catch (error) {
171 debugPrint('${error.code}: ${error.message}'); 178 debugPrint('${error.code}: ${error.message}');
172 isStarting = false; 179 isStarting = false;
@@ -179,18 +186,23 @@ class MobileScannerController { @@ -179,18 +186,23 @@ class MobileScannerController {
179 throw PlatformException(code: 'INITIALIZATION ERROR'); 186 throw PlatformException(code: 'INITIALIZATION ERROR');
180 } 187 }
181 188
182 - hasTorch = startResult['torchable']; 189 + hasTorch = startResult['torchable'] as bool;
183 190
184 if (kIsWeb) { 191 if (kIsWeb) {
185 args.value = MobileScannerArguments( 192 args.value = MobileScannerArguments(
186 - webId: startResult['ViewID'],  
187 - size: Size(startResult['videoWidth'], startResult['videoHeight']),  
188 - hasTorch: hasTorch); 193 + webId: startResult['ViewID'] as String?,
  194 + size: Size(
  195 + startResult['videoWidth'] as double,
  196 + startResult['videoHeight'] as double,
  197 + ),
  198 + hasTorch: hasTorch,
  199 + );
189 } else { 200 } else {
190 args.value = MobileScannerArguments( 201 args.value = MobileScannerArguments(
191 - textureId: startResult['textureId'],  
192 - size: toSize(startResult['size']),  
193 - hasTorch: hasTorch); 202 + textureId: startResult['textureId'] as int,
  203 + size: toSize(startResult['size'] as Map),
  204 + hasTorch: hasTorch,
  205 + );
194 } 206 }
195 207
196 isStarting = false; 208 isStarting = false;
@@ -214,7 +226,7 @@ class MobileScannerController { @@ -214,7 +226,7 @@ class MobileScannerController {
214 return; 226 return;
215 } 227 }
216 228
217 - TorchState state = 229 + final TorchState state =
218 torchState.value == TorchState.off ? TorchState.on : TorchState.off; 230 torchState.value == TorchState.off ? TorchState.on : TorchState.off;
219 231
220 try { 232 try {
@@ -233,7 +245,8 @@ class MobileScannerController { @@ -233,7 +245,8 @@ class MobileScannerController {
233 await methodChannel.invokeMethod('stop'); 245 await methodChannel.invokeMethod('stop');
234 } on PlatformException catch (error) { 246 } on PlatformException catch (error) {
235 debugPrint( 247 debugPrint(
236 - '${error.code}: camera is stopped! Please start before switching camera.'); 248 + '${error.code}: camera is stopped! Please start before switching camera.',
  249 + );
237 return; 250 return;
238 } 251 }
239 facing = 252 facing =
@@ -247,7 +260,7 @@ class MobileScannerController { @@ -247,7 +260,7 @@ class MobileScannerController {
247 /// 260 ///
248 /// [path] The path of the image on the devices 261 /// [path] The path of the image on the devices
249 Future<bool> analyzeImage(String path) async { 262 Future<bool> analyzeImage(String path) async {
250 - return await methodChannel.invokeMethod('analyzeImage', path); 263 + return methodChannel.invokeMethod('analyzeImage', path) as bool;
251 } 264 }
252 265
253 /// Disposes the MobileScannerController and closes all listeners. 266 /// Disposes the MobileScannerController and closes all listeners.
1 import 'dart:typed_data'; 1 import 'dart:typed_data';
2 import 'dart:ui'; 2 import 'dart:ui';
3 3
4 -import 'barcode_utility.dart'; 4 +import 'package:mobile_scanner/src/objects/barcode_utility.dart';
5 5
6 /// Represents a single recognized barcode and its value. 6 /// Represents a single recognized barcode and its value.
7 class Barcode { 7 class Barcode {
@@ -63,38 +63,39 @@ class Barcode { @@ -63,38 +63,39 @@ class Barcode {
63 /// Gets parsed WiFi AP details. 63 /// Gets parsed WiFi AP details.
64 final WiFi? wifi; 64 final WiFi? wifi;
65 65
66 - Barcode(  
67 - {this.corners,  
68 - this.format = BarcodeFormat.ean13,  
69 - this.rawBytes,  
70 - this.type = BarcodeType.text,  
71 - this.calendarEvent,  
72 - this.contactInfo,  
73 - this.driverLicense,  
74 - this.email,  
75 - this.geoPoint,  
76 - this.phone,  
77 - this.sms,  
78 - this.url,  
79 - this.wifi,  
80 - required this.rawValue}); 66 + Barcode({
  67 + this.corners,
  68 + this.format = BarcodeFormat.ean13,
  69 + this.rawBytes,
  70 + this.type = BarcodeType.text,
  71 + this.calendarEvent,
  72 + this.contactInfo,
  73 + this.driverLicense,
  74 + this.email,
  75 + this.geoPoint,
  76 + this.phone,
  77 + this.sms,
  78 + this.url,
  79 + this.wifi,
  80 + required this.rawValue,
  81 + });
81 82
82 /// Create a [Barcode] from native data. 83 /// Create a [Barcode] from native data.
83 - Barcode.fromNative(Map<dynamic, dynamic> data)  
84 - : corners = toCorners(data['corners']),  
85 - format = toFormat(data['format']),  
86 - rawBytes = data['rawBytes'],  
87 - rawValue = data['rawValue'],  
88 - type = BarcodeType.values[data['type']],  
89 - calendarEvent = toCalendarEvent(data['calendarEvent']),  
90 - contactInfo = toContactInfo(data['contactInfo']),  
91 - driverLicense = toDriverLicense(data['driverLicense']),  
92 - email = toEmail(data['email']),  
93 - geoPoint = toGeoPoint(data['geoPoint']),  
94 - phone = toPhone(data['phone']),  
95 - sms = toSMS(data['sms']),  
96 - url = toUrl(data['url']),  
97 - wifi = toWiFi(data['wifi']); 84 + Barcode.fromNative(Map data)
  85 + : corners = toCorners(data['corners'] as List?),
  86 + format = toFormat(data['format'] as int),
  87 + rawBytes = data['rawBytes'] as Uint8List?,
  88 + rawValue = data['rawValue'] as String?,
  89 + type = BarcodeType.values[data['type'] as int],
  90 + calendarEvent = toCalendarEvent(data['calendarEvent'] as Map?),
  91 + contactInfo = toContactInfo(data['contactInfo'] as Map?),
  92 + driverLicense = toDriverLicense(data['driverLicense'] as Map?),
  93 + email = toEmail(data['email'] as Map?),
  94 + geoPoint = toGeoPoint(data['geoPoint'] as Map?),
  95 + phone = toPhone(data['phone'] as Map?),
  96 + sms = toSMS(data['sms'] as Map?),
  97 + url = toUrl(data['url'] as Map?),
  98 + wifi = toWiFi(data['wifi'] as Map?);
98 } 99 }
99 100
100 /// A calendar event extracted from QRCode. 101 /// A calendar event extracted from QRCode.
@@ -135,14 +136,18 @@ class CalendarEvent { @@ -135,14 +136,18 @@ class CalendarEvent {
135 final String? summary; 136 final String? summary;
136 137
137 /// Create a [CalendarEvent] from native data. 138 /// Create a [CalendarEvent] from native data.
138 - CalendarEvent.fromNative(Map<dynamic, dynamic> data)  
139 - : description = data['description'],  
140 - start = DateTime.tryParse(data['start']),  
141 - end = DateTime.tryParse(data['end']),  
142 - location = data['location'],  
143 - organizer = data['organizer'],  
144 - status = data['status'],  
145 - summary = data['summary']; 139 + CalendarEvent.fromNative(Map data)
  140 + : description = data['description'] as String?,
  141 + start = data['start'] != null
  142 + ? DateTime.tryParse(data['start'] as String)
  143 + : null,
  144 + end = data['end'] != null
  145 + ? DateTime.tryParse(data['end'] as String)
  146 + : null,
  147 + location = data['location'] as String?,
  148 + organizer = data['organizer'] as String?,
  149 + status = data['status'] as String?,
  150 + summary = data['summary'] as String?;
146 } 151 }
147 152
148 /// A person's or organization's business card. For example a VCARD. 153 /// A person's or organization's business card. For example a VCARD.
@@ -183,17 +188,20 @@ class ContactInfo { @@ -183,17 +188,20 @@ class ContactInfo {
183 final List<String>? urls; 188 final List<String>? urls;
184 189
185 /// Create a [ContactInfo] from native data. 190 /// Create a [ContactInfo] from native data.
186 - ContactInfo.fromNative(Map<dynamic, dynamic> data) 191 + ContactInfo.fromNative(Map data)
187 : addresses = List.unmodifiable( 192 : addresses = List.unmodifiable(
188 - data['addresses'].map((e) => Address.fromNative(e))),  
189 - emails =  
190 - List.unmodifiable(data['emails'].map((e) => Email.fromNative(e))),  
191 - name = toName(data['name']),  
192 - organization = data['organization'],  
193 - phones =  
194 - List.unmodifiable(data['phones'].map((e) => Phone.fromNative(e))),  
195 - title = data['title'],  
196 - urls = List.unmodifiable(data['urls']); 193 + (data['addresses'] as List).map((e) => Address.fromNative(e as Map)),
  194 + ),
  195 + emails = List.unmodifiable(
  196 + (data['emails'] as List).map((e) => Email.fromNative(e as Map)),
  197 + ),
  198 + name = toName(data['name'] as Map?),
  199 + organization = data['organization'] as String?,
  200 + phones = List.unmodifiable(
  201 + (data['phones'] as List).map((e) => Phone.fromNative(e as Map)),
  202 + ),
  203 + title = data['title'] as String?,
  204 + urls = List.unmodifiable(data['urls'] as List);
197 } 205 }
198 206
199 /// An address. 207 /// An address.
@@ -207,9 +215,9 @@ class Address { @@ -207,9 +215,9 @@ class Address {
207 final AddressType? type; 215 final AddressType? type;
208 216
209 /// Create a [Address] from native data. 217 /// Create a [Address] from native data.
210 - Address.fromNative(Map<dynamic, dynamic> data)  
211 - : addressLines = List.unmodifiable(data['addressLines']),  
212 - type = AddressType.values[data['type']]; 218 + Address.fromNative(Map data)
  219 + : addressLines = List.unmodifiable(data['addressLines'] as List),
  220 + type = AddressType.values[data['type'] as int];
213 } 221 }
214 222
215 /// A person's name, both formatted version and individual name components. 223 /// A person's name, both formatted version and individual name components.
@@ -250,14 +258,14 @@ class PersonName { @@ -250,14 +258,14 @@ class PersonName {
250 final String? pronunciation; 258 final String? pronunciation;
251 259
252 /// Create a [PersonName] from native data. 260 /// Create a [PersonName] from native data.
253 - PersonName.fromNative(Map<dynamic, dynamic> data)  
254 - : first = data['first'],  
255 - middle = data['middle'],  
256 - last = data['last'],  
257 - prefix = data['prefix'],  
258 - suffix = data['suffix'],  
259 - formattedName = data['formattedName'],  
260 - pronunciation = data['pronunciation']; 261 + PersonName.fromNative(Map data)
  262 + : first = data['first'] as String?,
  263 + middle = data['middle'] as String?,
  264 + last = data['last'] as String?,
  265 + prefix = data['prefix'] as String?,
  266 + suffix = data['suffix'] as String?,
  267 + formattedName = data['formattedName'] as String?,
  268 + pronunciation = data['pronunciation'] as String?;
261 } 269 }
262 270
263 /// A driver license or ID card. 271 /// A driver license or ID card.
@@ -335,21 +343,21 @@ class DriverLicense { @@ -335,21 +343,21 @@ class DriverLicense {
335 final String? middleName; 343 final String? middleName;
336 344
337 /// Create a [DriverLicense] from native data. 345 /// Create a [DriverLicense] from native data.
338 - DriverLicense.fromNative(Map<dynamic, dynamic> data)  
339 - : addressCity = data['addressCity'],  
340 - addressState = data['addressState'],  
341 - addressStreet = data['addressStreet'],  
342 - addressZip = data['addressZip'],  
343 - birthDate = data['birthDate'],  
344 - documentType = data['documentType'],  
345 - expiryDate = data['expiryDate'],  
346 - firstName = data['firstName'],  
347 - gender = data['gender'],  
348 - issueDate = data['issueDate'],  
349 - issuingCountry = data['issuingCountry'],  
350 - lastName = data['lastName'],  
351 - licenseNumber = data['licenseNumber'],  
352 - middleName = data['middleName']; 346 + DriverLicense.fromNative(Map data)
  347 + : addressCity = data['addressCity'] as String?,
  348 + addressState = data['addressState'] as String?,
  349 + addressStreet = data['addressStreet'] as String?,
  350 + addressZip = data['addressZip'] as String?,
  351 + birthDate = data['birthDate'] as String?,
  352 + documentType = data['documentType'] as String?,
  353 + expiryDate = data['expiryDate'] as String?,
  354 + firstName = data['firstName'] as String?,
  355 + gender = data['gender'] as String?,
  356 + issueDate = data['issueDate'] as String?,
  357 + issuingCountry = data['issuingCountry'] as String?,
  358 + lastName = data['lastName'] as String?,
  359 + licenseNumber = data['licenseNumber'] as String?,
  360 + middleName = data['middleName'] as String?;
353 } 361 }
354 362
355 /// An email message from a 'MAILTO:' or similar QRCode type. 363 /// An email message from a 'MAILTO:' or similar QRCode type.
@@ -376,11 +384,11 @@ class Email { @@ -376,11 +384,11 @@ class Email {
376 final EmailType? type; 384 final EmailType? type;
377 385
378 /// Create a [Email] from native data. 386 /// Create a [Email] from native data.
379 - Email.fromNative(Map<dynamic, dynamic> data)  
380 - : address = data['address'],  
381 - body = data['body'],  
382 - subject = data['subject'],  
383 - type = EmailType.values[data['type']]; 387 + Email.fromNative(Map data)
  388 + : address = data['address'] as String?,
  389 + body = data['body'] as String?,
  390 + subject = data['subject'] as String?,
  391 + type = EmailType.values[data['type'] as int];
384 } 392 }
385 393
386 /// GPS coordinates from a 'GEO:' or similar QRCode type. 394 /// GPS coordinates from a 'GEO:' or similar QRCode type.
@@ -392,9 +400,9 @@ class GeoPoint { @@ -392,9 +400,9 @@ class GeoPoint {
392 final double? longitude; 400 final double? longitude;
393 401
394 /// Create a [GeoPoint] from native data. 402 /// Create a [GeoPoint] from native data.
395 - GeoPoint.fromNative(Map<dynamic, dynamic> data)  
396 - : latitude = data['latitude'],  
397 - longitude = data['longitude']; 403 + GeoPoint.fromNative(Map data)
  404 + : latitude = data['latitude'] as double?,
  405 + longitude = data['longitude'] as double?;
398 } 406 }
399 407
400 /// Phone number info. 408 /// Phone number info.
@@ -411,9 +419,9 @@ class Phone { @@ -411,9 +419,9 @@ class Phone {
411 final PhoneType? type; 419 final PhoneType? type;
412 420
413 /// Create a [Phone] from native data. 421 /// Create a [Phone] from native data.
414 - Phone.fromNative(Map<dynamic, dynamic> data)  
415 - : number = data['number'],  
416 - type = PhoneType.values[data['type']]; 422 + Phone.fromNative(Map data)
  423 + : number = data['number'] as String?,
  424 + type = PhoneType.values[data['type'] as int];
417 } 425 }
418 426
419 /// A sms message from a 'SMS:' or similar QRCode type. 427 /// A sms message from a 'SMS:' or similar QRCode type.
@@ -429,9 +437,9 @@ class SMS { @@ -429,9 +437,9 @@ class SMS {
429 final String? phoneNumber; 437 final String? phoneNumber;
430 438
431 /// Create a [SMS] from native data. 439 /// Create a [SMS] from native data.
432 - SMS.fromNative(Map<dynamic, dynamic> data)  
433 - : message = data['message'],  
434 - phoneNumber = data['phoneNumber']; 440 + SMS.fromNative(Map data)
  441 + : message = data['message'] as String?,
  442 + phoneNumber = data['phoneNumber'] as String?;
435 } 443 }
436 444
437 /// A URL and title from a 'MEBKM:' or similar QRCode type. 445 /// A URL and title from a 'MEBKM:' or similar QRCode type.
@@ -447,9 +455,9 @@ class UrlBookmark { @@ -447,9 +455,9 @@ class UrlBookmark {
447 final String? url; 455 final String? url;
448 456
449 /// Create a [UrlBookmark] from native data. 457 /// Create a [UrlBookmark] from native data.
450 - UrlBookmark.fromNative(Map<dynamic, dynamic> data)  
451 - : title = data['title'],  
452 - url = data['url']; 458 + UrlBookmark.fromNative(Map data)
  459 + : title = data['title'] as String?,
  460 + url = data['url'] as String?;
453 } 461 }
454 462
455 /// A wifi network parameters from a 'WIFI:' or similar QRCode type. 463 /// A wifi network parameters from a 'WIFI:' or similar QRCode type.
@@ -470,10 +478,10 @@ class WiFi { @@ -470,10 +478,10 @@ class WiFi {
470 final String? password; 478 final String? password;
471 479
472 /// Create a [WiFi] from native data. 480 /// Create a [WiFi] from native data.
473 - WiFi.fromNative(Map<dynamic, dynamic> data)  
474 - : encryptionType = EncryptionType.values[data['encryptionType']],  
475 - ssid = data['ssid'],  
476 - password = data['password']; 481 + WiFi.fromNative(Map data)
  482 + : encryptionType = EncryptionType.values[data['encryptionType'] as int],
  483 + ssid = data['ssid'] as String?,
  484 + password = data['password'] as String?;
477 } 485 }
478 486
479 enum BarcodeFormat { 487 enum BarcodeFormat {
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
  2 +import 'package:mobile_scanner/mobile_scanner.dart';
2 3
3 -import 'barcode.dart';  
4 -  
5 -Size toSize(Map<dynamic, dynamic> data) {  
6 - final width = data['width'];  
7 - final height = data['height']; 4 +Size toSize(Map data) {
  5 + final width = data['width'] as double;
  6 + final height = data['height'] as double;
8 return Size(width, height); 7 return Size(width, height);
9 } 8 }
10 9
11 -List<Offset>? toCorners(List<dynamic>? data) { 10 +List<Offset>? toCorners(List? data) {
12 if (data != null) { 11 if (data != null) {
13 - return List.unmodifiable(data.map((e) => Offset(e['x'], e['y']))); 12 + return List.unmodifiable(
  13 + data.map((e) => Offset((e as Map)['x'] as double, e['y'] as double)),
  14 + );
14 } else { 15 } else {
15 return null; 16 return null;
16 } 17 }
@@ -51,7 +52,7 @@ BarcodeFormat toFormat(int value) { @@ -51,7 +52,7 @@ BarcodeFormat toFormat(int value) {
51 } 52 }
52 } 53 }
53 54
54 -CalendarEvent? toCalendarEvent(Map<dynamic, dynamic>? data) { 55 +CalendarEvent? toCalendarEvent(Map? data) {
55 if (data != null) { 56 if (data != null) {
56 return CalendarEvent.fromNative(data); 57 return CalendarEvent.fromNative(data);
57 } else { 58 } else {
@@ -59,15 +60,15 @@ CalendarEvent? toCalendarEvent(Map<dynamic, dynamic>? data) { @@ -59,15 +60,15 @@ CalendarEvent? toCalendarEvent(Map<dynamic, dynamic>? data) {
59 } 60 }
60 } 61 }
61 62
62 -DateTime? toDateTime(Map<dynamic, dynamic>? data) { 63 +DateTime? toDateTime(Map<String, dynamic>? data) {
63 if (data != null) { 64 if (data != null) {
64 - final year = data['year'];  
65 - final month = data['month'];  
66 - final day = data['day'];  
67 - final hour = data['hours'];  
68 - final minute = data['minutes'];  
69 - final second = data['seconds'];  
70 - return data['isUtc'] 65 + final year = data['year'] as int;
  66 + final month = data['month'] as int;
  67 + final day = data['day'] as int;
  68 + final hour = data['hours'] as int;
  69 + final minute = data['minutes'] as int;
  70 + final second = data['seconds'] as int;
  71 + return data['isUtc'] as bool
71 ? DateTime.utc(year, month, day, hour, minute, second) 72 ? DateTime.utc(year, month, day, hour, minute, second)
72 : DateTime(year, month, day, hour, minute, second); 73 : DateTime(year, month, day, hour, minute, second);
73 } else { 74 } else {
@@ -75,7 +76,7 @@ DateTime? toDateTime(Map<dynamic, dynamic>? data) { @@ -75,7 +76,7 @@ DateTime? toDateTime(Map<dynamic, dynamic>? data) {
75 } 76 }
76 } 77 }
77 78
78 -ContactInfo? toContactInfo(Map<dynamic, dynamic>? data) { 79 +ContactInfo? toContactInfo(Map? data) {
79 if (data != null) { 80 if (data != null) {
80 return ContactInfo.fromNative(data); 81 return ContactInfo.fromNative(data);
81 } else { 82 } else {
@@ -83,7 +84,7 @@ ContactInfo? toContactInfo(Map<dynamic, dynamic>? data) { @@ -83,7 +84,7 @@ ContactInfo? toContactInfo(Map<dynamic, dynamic>? data) {
83 } 84 }
84 } 85 }
85 86
86 -PersonName? toName(Map<dynamic, dynamic>? data) { 87 +PersonName? toName(Map? data) {
87 if (data != null) { 88 if (data != null) {
88 return PersonName.fromNative(data); 89 return PersonName.fromNative(data);
89 } else { 90 } else {
@@ -91,7 +92,7 @@ PersonName? toName(Map<dynamic, dynamic>? data) { @@ -91,7 +92,7 @@ PersonName? toName(Map<dynamic, dynamic>? data) {
91 } 92 }
92 } 93 }
93 94
94 -DriverLicense? toDriverLicense(Map<dynamic, dynamic>? data) { 95 +DriverLicense? toDriverLicense(Map? data) {
95 if (data != null) { 96 if (data != null) {
96 return DriverLicense.fromNative(data); 97 return DriverLicense.fromNative(data);
97 } else { 98 } else {
@@ -99,7 +100,7 @@ DriverLicense? toDriverLicense(Map<dynamic, dynamic>? data) { @@ -99,7 +100,7 @@ DriverLicense? toDriverLicense(Map<dynamic, dynamic>? data) {
99 } 100 }
100 } 101 }
101 102
102 -Email? toEmail(Map<dynamic, dynamic>? data) { 103 +Email? toEmail(Map? data) {
103 if (data != null) { 104 if (data != null) {
104 return Email.fromNative(data); 105 return Email.fromNative(data);
105 } else { 106 } else {
@@ -107,7 +108,7 @@ Email? toEmail(Map<dynamic, dynamic>? data) { @@ -107,7 +108,7 @@ Email? toEmail(Map<dynamic, dynamic>? data) {
107 } 108 }
108 } 109 }
109 110
110 -GeoPoint? toGeoPoint(Map<dynamic, dynamic>? data) { 111 +GeoPoint? toGeoPoint(Map? data) {
111 if (data != null) { 112 if (data != null) {
112 return GeoPoint.fromNative(data); 113 return GeoPoint.fromNative(data);
113 } else { 114 } else {
@@ -115,7 +116,7 @@ GeoPoint? toGeoPoint(Map<dynamic, dynamic>? data) { @@ -115,7 +116,7 @@ GeoPoint? toGeoPoint(Map<dynamic, dynamic>? data) {
115 } 116 }
116 } 117 }
117 118
118 -Phone? toPhone(Map<dynamic, dynamic>? data) { 119 +Phone? toPhone(Map? data) {
119 if (data != null) { 120 if (data != null) {
120 return Phone.fromNative(data); 121 return Phone.fromNative(data);
121 } else { 122 } else {
@@ -123,7 +124,7 @@ Phone? toPhone(Map<dynamic, dynamic>? data) { @@ -123,7 +124,7 @@ Phone? toPhone(Map<dynamic, dynamic>? data) {
123 } 124 }
124 } 125 }
125 126
126 -SMS? toSMS(Map<dynamic, dynamic>? data) { 127 +SMS? toSMS(Map? data) {
127 if (data != null) { 128 if (data != null) {
128 return SMS.fromNative(data); 129 return SMS.fromNative(data);
129 } else { 130 } else {
@@ -131,7 +132,7 @@ SMS? toSMS(Map<dynamic, dynamic>? data) { @@ -131,7 +132,7 @@ SMS? toSMS(Map<dynamic, dynamic>? data) {
131 } 132 }
132 } 133 }
133 134
134 -UrlBookmark? toUrl(Map<dynamic, dynamic>? data) { 135 +UrlBookmark? toUrl(Map? data) {
135 if (data != null) { 136 if (data != null) {
136 return UrlBookmark.fromNative(data); 137 return UrlBookmark.fromNative(data);
137 } else { 138 } else {
@@ -139,7 +140,7 @@ UrlBookmark? toUrl(Map<dynamic, dynamic>? data) { @@ -139,7 +140,7 @@ UrlBookmark? toUrl(Map<dynamic, dynamic>? data) {
139 } 140 }
140 } 141 }
141 142
142 -WiFi? toWiFi(Map<dynamic, dynamic>? data) { 143 +WiFi? toWiFi(Map? data) {
143 if (data != null) { 144 if (data != null) {
144 return WiFi.fromNative(data); 145 return WiFi.fromNative(data);
145 } else { 146 } else {
@@ -4,7 +4,7 @@ library jsqr; @@ -4,7 +4,7 @@ library jsqr;
4 import 'package:js/js.dart'; 4 import 'package:js/js.dart';
5 5
6 @JS('jsQR') 6 @JS('jsQR')
7 -external Code? jsQR(var data, int? width, int? height); 7 +external Code? jsQR(dynamic data, int? width, int? height);
8 8
9 @JS() 9 @JS()
10 class Code { 10 class Code {
@@ -25,8 +25,12 @@ class VideoOptions { @@ -25,8 +25,12 @@ class VideoOptions {
25 external Map get width; 25 external Map get width;
26 external Map get height; 26 external Map get height;
27 27
28 - external factory VideoOptions(  
29 - {String? facingMode, DeviceIdOptions? deviceId, Map? width, Map? height}); 28 + external factory VideoOptions({
  29 + String? facingMode,
  30 + DeviceIdOptions? deviceId,
  31 + Map? width,
  32 + Map? height,
  33 + });
30 } 34 }
31 35
32 @JS() 36 @JS()
@@ -4,7 +4,7 @@ library qrscanner; @@ -4,7 +4,7 @@ library qrscanner;
4 import 'package:js/js.dart'; 4 import 'package:js/js.dart';
5 5
6 @JS('QrScanner') 6 @JS('QrScanner')
7 -external String scanImage(var data); 7 +external String scanImage(dynamic data);
8 8
9 @JS() 9 @JS()
10 class QrScanner { 10 class QrScanner {
@@ -8,16 +8,16 @@ environment: @@ -8,16 +8,16 @@ environment:
8 flutter: ">=1.10.0" 8 flutter: ">=1.10.0"
9 9
10 dependencies: 10 dependencies:
11 - js: ^0.6.3  
12 flutter: 11 flutter:
13 sdk: flutter 12 sdk: flutter
14 flutter_web_plugins: 13 flutter_web_plugins:
15 sdk: flutter 14 sdk: flutter
  15 + js: ^0.6.3
16 16
17 dev_dependencies: 17 dev_dependencies:
18 flutter_test: 18 flutter_test:
19 sdk: flutter 19 sdk: flutter
20 - flutter_lints: ^1.0.4 20 + lint: ^1.8.2
21 21
22 flutter: 22 flutter:
23 plugin: 23 plugin: