Navaron Bracke
Committed by GitHub

Merge pull request #818 from navaronbracke/reorganise_classes

feat: Move classes into their own files
  1 +## NEXT
  2 +Improvements:
  3 +* The `type` of an `Address` is now non-null.
  4 +* The `type` of an `Email` is now non-null.
  5 +* The `phoneNumber` of an `SMS` is now non-null.
  6 +* The `latitude` and `longitude` of a `GeoPoint` are now non-null.
  7 +* The `phones` and `urls` of `ContactInfo` are now non-null.
  8 +* The `url` of a `UrlBookmark` is now non-null.
  9 +* The `type` of `Phone` is now non-null.
  10 +* The `width` and `height` of `BarcodeCapture` are now non-null.
  11 +* The `BarcodeCapture` class now exposes a `size`.
  12 +* The list of `corners` of a `Barcode` is now non-null.
  13 +* The internal `fromNative()` methods now accept a `Map<Object?, Object?>` instead of `Map<dynamic, dynamic>`.
  14 +
1 ## 3.5.0 15 ## 3.5.0
2 New Features: 16 New Features:
3 * Added the option to switch between bundled and unbundled MLKit for Android. (thanks @woolfred !) 17 * Added the option to switch between bundled and unbundled MLKit for Android. (thanks @woolfred !)
1 import 'dart:io'; 1 import 'dart:io';
2 2
  3 +import 'package:flutter/foundation.dart';
3 import 'package:flutter/material.dart'; 4 import 'package:flutter/material.dart';
4 import 'package:mobile_scanner/mobile_scanner.dart'; 5 import 'package:mobile_scanner/mobile_scanner.dart';
5 6
@@ -150,7 +151,10 @@ class BarcodeOverlay extends CustomPainter { @@ -150,7 +151,10 @@ class BarcodeOverlay extends CustomPainter {
150 151
151 @override 152 @override
152 void paint(Canvas canvas, Size size) { 153 void paint(Canvas canvas, Size size) {
153 - if (barcode.corners == null) return; 154 + if (barcode.corners.isEmpty) {
  155 + return;
  156 + }
  157 +
154 final adjustedSize = applyBoxFit(boxFit, arguments.size, size); 158 final adjustedSize = applyBoxFit(boxFit, arguments.size, size);
155 159
156 double verticalPadding = size.height - adjustedSize.destination.height; 160 double verticalPadding = size.height - adjustedSize.destination.height;
@@ -167,15 +171,19 @@ class BarcodeOverlay extends CustomPainter { @@ -167,15 +171,19 @@ class BarcodeOverlay extends CustomPainter {
167 horizontalPadding = 0; 171 horizontalPadding = 0;
168 } 172 }
169 173
170 - final ratioWidth =  
171 - (Platform.isIOS ? capture.width! : arguments.size.width) /  
172 - adjustedSize.destination.width;  
173 - final ratioHeight =  
174 - (Platform.isIOS ? capture.height! : arguments.size.height) /  
175 - adjustedSize.destination.height; 174 + final double ratioWidth;
  175 + final double ratioHeight;
  176 +
  177 + if (!kIsWeb && Platform.isIOS) {
  178 + ratioWidth = capture.size.width / adjustedSize.destination.width;
  179 + ratioHeight = capture.size.height / adjustedSize.destination.height;
  180 + } else {
  181 + ratioWidth = arguments.size.width / adjustedSize.destination.width;
  182 + ratioHeight = arguments.size.height / adjustedSize.destination.height;
  183 + }
176 184
177 final List<Offset> adjustedOffset = []; 185 final List<Offset> adjustedOffset = [];
178 - for (final offset in barcode.corners!) { 186 + for (final offset in barcode.corners) {
179 adjustedOffset.add( 187 adjustedOffset.add(
180 Offset( 188 Offset(
181 offset.dx / ratioWidth + horizontalPadding, 189 offset.dx / ratioWidth + horizontalPadding,
@@ -12,6 +12,17 @@ export 'src/enums/torch_state.dart'; @@ -12,6 +12,17 @@ export 'src/enums/torch_state.dart';
12 export 'src/mobile_scanner.dart'; 12 export 'src/mobile_scanner.dart';
13 export 'src/mobile_scanner_controller.dart'; 13 export 'src/mobile_scanner_controller.dart';
14 export 'src/mobile_scanner_exception.dart'; 14 export 'src/mobile_scanner_exception.dart';
  15 +export 'src/objects/address.dart';
15 export 'src/objects/barcode.dart'; 16 export 'src/objects/barcode.dart';
16 export 'src/objects/barcode_capture.dart'; 17 export 'src/objects/barcode_capture.dart';
  18 +export 'src/objects/calendar_event.dart';
  19 +export 'src/objects/contact_info.dart';
  20 +export 'src/objects/driver_license.dart';
  21 +export 'src/objects/email.dart';
  22 +export 'src/objects/geo_point.dart';
17 export 'src/objects/mobile_scanner_arguments.dart'; 23 export 'src/objects/mobile_scanner_arguments.dart';
  24 +export 'src/objects/person_name.dart';
  25 +export 'src/objects/phone.dart';
  26 +export 'src/objects/sms.dart';
  27 +export 'src/objects/url_bookmark.dart';
  28 +export 'src/objects/wifi.dart';
@@ -130,8 +130,6 @@ class MobileScannerWebPlugin { @@ -130,8 +130,6 @@ class MobileScannerWebPlugin {
130 _barCodeStreamSubscription = 130 _barCodeStreamSubscription =
131 barCodeReader.detectBarcodeContinuously().listen((code) { 131 barCodeReader.detectBarcodeContinuously().listen((code) {
132 if (code != null) { 132 if (code != null) {
133 - final List<Offset>? corners = code.corners;  
134 -  
135 controller.add({ 133 controller.add({
136 'name': 'barcodeWeb', 134 'name': 'barcodeWeb',
137 'data': { 135 'data': {
@@ -140,8 +138,8 @@ class MobileScannerWebPlugin { @@ -140,8 +138,8 @@ class MobileScannerWebPlugin {
140 'format': code.format.rawValue, 138 'format': code.format.rawValue,
141 'displayValue': code.displayValue, 139 'displayValue': code.displayValue,
142 'type': code.type.rawValue, 140 'type': code.type.rawValue,
143 - if (corners != null && corners.isNotEmpty)  
144 - 'corners': corners 141 + if (code.corners.isNotEmpty)
  142 + 'corners': code.corners
145 .map( 143 .map(
146 (Offset c) => <Object?, Object?>{'x': c.dx, 'y': c.dy}, 144 (Offset c) => <Object?, Object?>{'x': c.dx, 'y': c.dy},
147 ) 145 )
@@ -442,9 +442,10 @@ class MobileScannerController { @@ -442,9 +442,10 @@ class MobileScannerController {
442 rawBytes: barcode['rawBytes'] as Uint8List?, 442 rawBytes: barcode['rawBytes'] as Uint8List?,
443 format: toFormat(barcode['format'] as int), 443 format: toFormat(barcode['format'] as int),
444 corners: toCorners( 444 corners: toCorners(
445 - (barcode['corners'] as List<Object?>? ?? [])  
446 - .cast<Map<Object?, Object?>>(),  
447 - ), 445 + (barcode['corners'] as List<Object?>? ?? [])
  446 + .cast<Map<Object?, Object?>>(),
  447 + ) ??
  448 + const <Offset>[],
448 ), 449 ),
449 ], 450 ],
450 ), 451 ),
  1 +import 'package:mobile_scanner/src/enums/address_type.dart';
  2 +
  3 +/// An address.
  4 +class Address {
  5 + /// Creates a new [Address] instance.
  6 + const Address({
  7 + this.addressLines = const <String>[],
  8 + this.type = AddressType.unknown,
  9 + });
  10 +
  11 + /// Creates a new [Address] instance from a map.
  12 + factory Address.fromNative(Map<Object?, Object?> data) {
  13 + final List<Object?>? addressLines = data['addressLines'] as List<Object?>?;
  14 + final AddressType type = AddressType.fromRawValue(
  15 + data['type'] as int? ?? 0,
  16 + );
  17 +
  18 + if (addressLines == null) {
  19 + return Address(type: type);
  20 + }
  21 +
  22 + return Address(
  23 + addressLines: List.unmodifiable(addressLines.cast<String>()),
  24 + type: type,
  25 + );
  26 + }
  27 +
  28 + /// The address lines that represent this address.
  29 + final List<String> addressLines;
  30 +
  31 + /// Gets type of the address.
  32 + final AddressType type;
  33 +}
@@ -2,12 +2,17 @@ import 'dart:typed_data'; @@ -2,12 +2,17 @@ import 'dart:typed_data';
2 import 'dart:ui'; 2 import 'dart:ui';
3 3
4 import 'package:mobile_scanner/src/barcode_utility.dart'; 4 import 'package:mobile_scanner/src/barcode_utility.dart';
5 -import 'package:mobile_scanner/src/enums/address_type.dart';  
6 import 'package:mobile_scanner/src/enums/barcode_format.dart'; 5 import 'package:mobile_scanner/src/enums/barcode_format.dart';
7 import 'package:mobile_scanner/src/enums/barcode_type.dart'; 6 import 'package:mobile_scanner/src/enums/barcode_type.dart';
8 -import 'package:mobile_scanner/src/enums/email_type.dart';  
9 -import 'package:mobile_scanner/src/enums/encryption_type.dart';  
10 -import 'package:mobile_scanner/src/enums/phone_type.dart'; 7 +import 'package:mobile_scanner/src/objects/calendar_event.dart';
  8 +import 'package:mobile_scanner/src/objects/contact_info.dart';
  9 +import 'package:mobile_scanner/src/objects/driver_license.dart';
  10 +import 'package:mobile_scanner/src/objects/email.dart';
  11 +import 'package:mobile_scanner/src/objects/geo_point.dart';
  12 +import 'package:mobile_scanner/src/objects/phone.dart';
  13 +import 'package:mobile_scanner/src/objects/sms.dart';
  14 +import 'package:mobile_scanner/src/objects/url_bookmark.dart';
  15 +import 'package:mobile_scanner/src/objects/wifi.dart';
11 16
12 /// Represents a single recognized barcode and its value. 17 /// Represents a single recognized barcode and its value.
13 class Barcode { 18 class Barcode {
@@ -16,7 +21,7 @@ class Barcode { @@ -16,7 +21,7 @@ class Barcode {
16 /// Due to the possible perspective distortions, this is not necessarily a rectangle. 21 /// Due to the possible perspective distortions, this is not necessarily a rectangle.
17 /// 22 ///
18 /// Returns null if the corner points can not be determined. 23 /// Returns null if the corner points can not be determined.
19 - final List<Offset>? corners; 24 + final List<Offset> corners;
20 25
21 /// Returns barcode format 26 /// Returns barcode format
22 final BarcodeFormat format; 27 final BarcodeFormat format;
@@ -79,7 +84,7 @@ class Barcode { @@ -79,7 +84,7 @@ class Barcode {
79 final WiFi? wifi; 84 final WiFi? wifi;
80 85
81 Barcode({ 86 Barcode({
82 - this.corners, 87 + this.corners = const <Offset>[],
83 this.format = BarcodeFormat.ean13, 88 this.format = BarcodeFormat.ean13,
84 this.rawBytes, 89 this.rawBytes,
85 this.type = BarcodeType.text, 90 this.type = BarcodeType.text,
@@ -99,8 +104,9 @@ class Barcode { @@ -99,8 +104,9 @@ class Barcode {
99 /// Create a [Barcode] from native data. 104 /// Create a [Barcode] from native data.
100 Barcode.fromNative(Map data) 105 Barcode.fromNative(Map data)
101 : corners = toCorners( 106 : corners = toCorners(
102 - (data['corners'] as List?)?.cast<Map<Object?, Object?>>(),  
103 - ), 107 + (data['corners'] as List?)?.cast<Map<Object?, Object?>>(),
  108 + ) ??
  109 + const <Offset>[],
104 format = toFormat(data['format'] as int), 110 format = toFormat(data['format'] as int),
105 rawBytes = data['rawBytes'] as Uint8List?, 111 rawBytes = data['rawBytes'] as Uint8List?,
106 rawValue = data['rawValue'] as String?, 112 rawValue = data['rawValue'] as String?,
@@ -116,393 +122,3 @@ class Barcode { @@ -116,393 +122,3 @@ class Barcode {
116 url = toUrl(data['url'] as Map?), 122 url = toUrl(data['url'] as Map?),
117 wifi = toWiFi(data['wifi'] as Map?); 123 wifi = toWiFi(data['wifi'] as Map?);
118 } 124 }
119 -  
120 -/// A calendar event extracted from QRCode.  
121 -class CalendarEvent {  
122 - /// Gets the description of the calendar event.  
123 - ///  
124 - /// Returns null if not available.  
125 - final String? description;  
126 -  
127 - /// Gets the start date time of the calendar event.  
128 - ///  
129 - /// Returns null if not available.  
130 - final DateTime? start;  
131 -  
132 - /// Gets the end date time of the calendar event.  
133 - ///  
134 - /// Returns null if not available.  
135 - final DateTime? end;  
136 -  
137 - /// Gets the location of the calendar event.  
138 - ///  
139 - /// Returns null if not available.  
140 - final String? location;  
141 -  
142 - /// Gets the organizer of the calendar event.  
143 - ///  
144 - /// Returns null if not available.  
145 - final String? organizer;  
146 -  
147 - /// Gets the status of the calendar event.  
148 - ///  
149 - /// Returns null if not available.  
150 - final String? status;  
151 -  
152 - /// Gets the summary of the calendar event.  
153 - ///  
154 - /// Returns null if not available.  
155 - final String? summary;  
156 -  
157 - /// Create a [CalendarEvent] from native data.  
158 - CalendarEvent.fromNative(Map data)  
159 - : description = data['description'] as String?,  
160 - start = data['start'] != null  
161 - ? DateTime.tryParse(data['start'] as String)  
162 - : null,  
163 - end = data['end'] != null  
164 - ? DateTime.tryParse(data['end'] as String)  
165 - : null,  
166 - location = data['location'] as String?,  
167 - organizer = data['organizer'] as String?,  
168 - status = data['status'] as String?,  
169 - summary = data['summary'] as String?;  
170 -}  
171 -  
172 -/// A person's or organization's business card. For example a VCARD.  
173 -class ContactInfo {  
174 - /// Gets contact person's addresses.  
175 - ///  
176 - /// Returns an empty list if nothing found.  
177 - final List<Address> addresses;  
178 -  
179 - /// Gets contact person's emails.  
180 - ///  
181 - /// Returns an empty list if nothing found.  
182 - final List<Email> emails;  
183 -  
184 - /// Gets contact person's name.  
185 - ///  
186 - /// Returns null if not available.  
187 - final PersonName? name;  
188 -  
189 - /// Gets contact person's organization.  
190 - ///  
191 - /// Returns null if not available.  
192 - final String? organization;  
193 -  
194 - /// Gets contact person's phones.  
195 - ///  
196 - /// Returns an empty list if nothing found.  
197 - final List<Phone>? phones;  
198 -  
199 - /// Gets contact person's title.  
200 - ///  
201 - /// Returns null if not available.  
202 - final String? title;  
203 -  
204 - /// Gets contact person's urls.  
205 - ///  
206 - /// Returns an empty list if nothing found.  
207 - final List<String>? urls;  
208 -  
209 - /// Create a [ContactInfo] from native data.  
210 - ContactInfo.fromNative(Map data)  
211 - : addresses = List.unmodifiable(  
212 - (data['addresses'] as List? ?? [])  
213 - .cast<Map>()  
214 - .map(Address.fromNative),  
215 - ),  
216 - emails = List.unmodifiable(  
217 - (data['emails'] as List? ?? []).cast<Map>().map(Email.fromNative),  
218 - ),  
219 - name = toName(data['name'] as Map?),  
220 - organization = data['organization'] as String?,  
221 - phones = List.unmodifiable(  
222 - (data['phones'] as List? ?? []).cast<Map>().map(Phone.fromNative),  
223 - ),  
224 - title = data['title'] as String?,  
225 - urls = List.unmodifiable((data['urls'] as List? ?? []).cast<String>());  
226 -}  
227 -  
228 -/// An address.  
229 -class Address {  
230 - /// Gets formatted address, multiple lines when appropriate. This field always contains at least one line.  
231 - final List<String> addressLines;  
232 -  
233 - /// Gets type of the address.  
234 - ///  
235 - /// Returns null if not available.  
236 - final AddressType? type;  
237 -  
238 - /// Create a [Address] from native data.  
239 - Address.fromNative(Map data)  
240 - : addressLines = List.unmodifiable(  
241 - (data['addressLines'] as List? ?? []).cast<String>(),  
242 - ),  
243 - type = AddressType.values[data['type'] as int];  
244 -}  
245 -  
246 -/// A person's name, both formatted version and individual name components.  
247 -class PersonName {  
248 - /// Gets first name.  
249 - ///  
250 - /// Returns null if not available.  
251 - final String? first;  
252 -  
253 - /// Gets middle name.  
254 - ///  
255 - /// Returns null if not available.  
256 - final String? middle;  
257 -  
258 - /// Gets last name.  
259 - ///  
260 - /// Returns null if not available.  
261 - final String? last;  
262 -  
263 - /// Gets prefix of the name.  
264 - ///  
265 - /// Returns null if not available.  
266 - final String? prefix;  
267 -  
268 - /// Gets suffix of the person's name.  
269 - ///  
270 - /// Returns null if not available.  
271 - final String? suffix;  
272 -  
273 - /// Gets the properly formatted name.  
274 - ///  
275 - /// Returns null if not available.  
276 - final String? formattedName;  
277 -  
278 - /// Designates a text string to be set as the kana name in the phonebook. Used for Japanese contacts.  
279 - ///  
280 - /// Returns null if not available.  
281 - final String? pronunciation;  
282 -  
283 - /// Create a [PersonName] from native data.  
284 - PersonName.fromNative(Map data)  
285 - : first = data['first'] as String?,  
286 - middle = data['middle'] as String?,  
287 - last = data['last'] as String?,  
288 - prefix = data['prefix'] as String?,  
289 - suffix = data['suffix'] as String?,  
290 - formattedName = data['formattedName'] as String?,  
291 - pronunciation = data['pronunciation'] as String?;  
292 -}  
293 -  
294 -/// A driver license or ID card.  
295 -class DriverLicense {  
296 - /// Gets city of holder's address.  
297 - ///  
298 - /// Returns null if not available.  
299 - final String? addressCity;  
300 -  
301 - /// Gets state of holder's address.  
302 - ///  
303 - /// Returns null if not available.  
304 - final String? addressState;  
305 -  
306 - /// Gets holder's street address.  
307 - ///  
308 - /// Returns null if not available.  
309 - final String? addressStreet;  
310 -  
311 - /// Gets postal code of holder's address.  
312 - ///  
313 - /// Returns null if not available.  
314 - final String? addressZip;  
315 -  
316 - /// Gets birth date of the holder.  
317 - ///  
318 - /// Returns null if not available.  
319 - final String? birthDate;  
320 -  
321 - /// Gets "DL" for driver licenses, "ID" for ID cards.  
322 - ///  
323 - /// Returns null if not available.  
324 - final String? documentType;  
325 -  
326 - /// Gets expiry date of the license.  
327 - ///  
328 - /// Returns null if not available.  
329 - final String? expiryDate;  
330 -  
331 - /// Gets holder's first name.  
332 - ///  
333 - /// Returns null if not available.  
334 - final String? firstName;  
335 -  
336 - /// Gets holder's gender. 1 - male, 2 - female.  
337 - ///  
338 - /// Returns null if not available.  
339 - final String? gender;  
340 -  
341 - /// Gets issue date of the license.  
342 - ///  
343 - /// The date format depends on the issuing country. MMDDYYYY for the US, YYYYMMDD for Canada.  
344 - ///  
345 - /// Returns null if not available.  
346 - final String? issueDate;  
347 -  
348 - /// Gets the three-letter country code in which DL/ID was issued.  
349 - ///  
350 - /// Returns null if not available.  
351 - final String? issuingCountry;  
352 -  
353 - /// Gets holder's last name.  
354 - ///  
355 - /// Returns null if not available.  
356 - final String? lastName;  
357 -  
358 - /// Gets driver license ID number.  
359 - ///  
360 - /// Returns null if not available.  
361 - final String? licenseNumber;  
362 -  
363 - /// Gets holder's middle name.  
364 - ///  
365 - /// Returns null if not available.  
366 - final String? middleName;  
367 -  
368 - /// Create a [DriverLicense] from native data.  
369 - DriverLicense.fromNative(Map data)  
370 - : addressCity = data['addressCity'] as String?,  
371 - addressState = data['addressState'] as String?,  
372 - addressStreet = data['addressStreet'] as String?,  
373 - addressZip = data['addressZip'] as String?,  
374 - birthDate = data['birthDate'] as String?,  
375 - documentType = data['documentType'] as String?,  
376 - expiryDate = data['expiryDate'] as String?,  
377 - firstName = data['firstName'] as String?,  
378 - gender = data['gender'] as String?,  
379 - issueDate = data['issueDate'] as String?,  
380 - issuingCountry = data['issuingCountry'] as String?,  
381 - lastName = data['lastName'] as String?,  
382 - licenseNumber = data['licenseNumber'] as String?,  
383 - middleName = data['middleName'] as String?;  
384 -}  
385 -  
386 -/// An email message from a 'MAILTO:' or similar QRCode type.  
387 -class Email {  
388 - /// Gets email's address.  
389 - ///  
390 - /// Returns null if not available.  
391 - final String? address;  
392 -  
393 - /// Gets email's body.  
394 - ///  
395 - /// Returns null if not available.  
396 - final String? body;  
397 -  
398 - /// Gets email's subject.  
399 - ///  
400 - /// Returns null if not available.  
401 - final String? subject;  
402 -  
403 - /// Gets type of the email.  
404 - ///  
405 - /// See also [EmailType].  
406 - /// Returns null if not available.  
407 - final EmailType? type;  
408 -  
409 - /// Create a [Email] from native data.  
410 - Email.fromNative(Map data)  
411 - : address = data['address'] as String?,  
412 - body = data['body'] as String?,  
413 - subject = data['subject'] as String?,  
414 - type = EmailType.values[data['type'] as int];  
415 -}  
416 -  
417 -/// GPS coordinates from a 'GEO:' or similar QRCode type.  
418 -class GeoPoint {  
419 - /// Gets the latitude.  
420 - final double? latitude;  
421 -  
422 - /// Gets the longitude.  
423 - final double? longitude;  
424 -  
425 - /// Create a [GeoPoint] from native data.  
426 - GeoPoint.fromNative(Map data)  
427 - : latitude = data['latitude'] as double?,  
428 - longitude = data['longitude'] as double?;  
429 -}  
430 -  
431 -/// Phone number info.  
432 -class Phone {  
433 - /// Gets phone number.  
434 - ///  
435 - /// Returns null if not available.  
436 - final String? number;  
437 -  
438 - /// Gets type of the phone number.  
439 - ///  
440 - /// See also [PhoneType].  
441 - /// Returns null if not available.  
442 - final PhoneType? type;  
443 -  
444 - /// Create a [Phone] from native data.  
445 - Phone.fromNative(Map data)  
446 - : number = data['number'] as String?,  
447 - type = PhoneType.values[data['type'] as int];  
448 -}  
449 -  
450 -/// A sms message from a 'SMS:' or similar QRCode type.  
451 -class SMS {  
452 - /// Gets the message content of the sms.  
453 - ///  
454 - /// Returns null if not available.  
455 - final String? message;  
456 -  
457 - /// Gets the phone number of the sms.  
458 - ///  
459 - /// Returns null if not available.  
460 - final String? phoneNumber;  
461 -  
462 - /// Create a [SMS] from native data.  
463 - SMS.fromNative(Map data)  
464 - : message = data['message'] as String?,  
465 - phoneNumber = data['phoneNumber'] as String?;  
466 -}  
467 -  
468 -/// A URL and title from a 'MEBKM:' or similar QRCode type.  
469 -class UrlBookmark {  
470 - /// Gets the title of the bookmark.  
471 - ///  
472 - /// Returns null if not available.  
473 - final String? title;  
474 -  
475 - /// Gets the url of the bookmark.  
476 - ///  
477 - /// Returns null if not available.  
478 - final String? url;  
479 -  
480 - /// Create a [UrlBookmark] from native data.  
481 - UrlBookmark.fromNative(Map data)  
482 - : title = data['title'] as String?,  
483 - url = data['url'] as String?;  
484 -}  
485 -  
486 -/// A wifi network parameters from a 'WIFI:' or similar QRCode type.  
487 -class WiFi {  
488 - /// Gets the encryption type of the WIFI.  
489 - ///  
490 - /// See all [EncryptionType].  
491 - final EncryptionType encryptionType;  
492 -  
493 - /// Gets the ssid of the WIFI.  
494 - ///  
495 - /// Returns null if not available.  
496 - final String? ssid;  
497 -  
498 - /// Gets the password of the WIFI.  
499 - ///  
500 - /// Returns null if not available.  
501 - final String? password;  
502 -  
503 - /// Create a [WiFi] from native data.  
504 - WiFi.fromNative(Map data)  
505 - : encryptionType = EncryptionType.values[data['encryptionType'] as int],  
506 - ssid = data['ssid'] as String?,  
507 - password = data['password'] as String?;  
508 -}  
1 import 'dart:typed_data'; 1 import 'dart:typed_data';
  2 +import 'dart:ui';
2 3
3 import 'package:mobile_scanner/src/objects/barcode.dart'; 4 import 'package:mobile_scanner/src/objects/barcode.dart';
4 5
5 -/// The return object after a frame is scanned.  
6 -///  
7 -/// [barcodes] A list with barcodes. A scanned frame can contain multiple  
8 -/// barcodes.  
9 -/// [image] If enabled, an image of the scanned frame. 6 +/// This class represents a scanned barcode.
10 class BarcodeCapture { 7 class BarcodeCapture {
  8 + /// Create a new [BarcodeCapture] instance.
  9 + BarcodeCapture({
  10 + this.barcodes = const <Barcode>[],
  11 + double? height,
  12 + this.image,
  13 + this.raw,
  14 + double? width,
  15 + }) : size =
  16 + width == null && height == null ? Size.zero : Size(width!, height!);
  17 +
  18 + /// The list of scanned barcodes.
11 final List<Barcode> barcodes; 19 final List<Barcode> barcodes;
12 - final dynamic raw;  
13 20
  21 + /// The bytes of the image that is embedded in the barcode.
  22 + ///
  23 + /// This null if [MobileScannerController.returnImage] is false.
14 final Uint8List? image; 24 final Uint8List? image;
15 25
16 - final double? width; 26 + /// The raw data of the scanned barcode.
  27 + final dynamic raw; // TODO: this should be `Object?` instead of dynamic
17 28
18 - final double? height; 29 + /// The size of the scanned barcode.
  30 + final Size size;
19 31
20 - BarcodeCapture({  
21 - required this.barcodes,  
22 - required this.raw,  
23 - this.image,  
24 - this.width,  
25 - this.height,  
26 - }); 32 + /// The width of the scanned barcode.
  33 + ///
  34 + /// Prefer using `size.width` instead,
  35 + /// as this getter will be removed in the future.
  36 + double get width => size.width;
  37 +
  38 + /// The height of the scanned barcode.
  39 + ///
  40 + /// Prefer using `size.height` instead,
  41 + /// as this getter will be removed in the future.
  42 + double get height => size.height;
27 } 43 }
  1 +/// A calendar event extracted from a QRCode.
  2 +class CalendarEvent {
  3 + /// Create a new [CalendarEvent] instance.
  4 + const CalendarEvent({
  5 + this.description,
  6 + this.start,
  7 + this.end,
  8 + this.location,
  9 + this.organizer,
  10 + this.status,
  11 + this.summary,
  12 + });
  13 +
  14 + /// Create a new [CalendarEvent] instance from a map.
  15 + factory CalendarEvent.fromNative(Map<Object?, Object?> data) {
  16 + return CalendarEvent(
  17 + description: data['description'] as String?,
  18 + start: DateTime.tryParse(data['start'] as String? ?? ''),
  19 + end: DateTime.tryParse(data['end'] as String? ?? ''),
  20 + location: data['location'] as String?,
  21 + organizer: data['organizer'] as String?,
  22 + status: data['status'] as String?,
  23 + summary: data['summary'] as String?,
  24 + );
  25 + }
  26 +
  27 + /// The description of the calendar event.
  28 + final String? description;
  29 +
  30 + /// The start time of the calendar event.
  31 + final DateTime? start;
  32 +
  33 + /// The end time of the calendar event.
  34 + final DateTime? end;
  35 +
  36 + /// The location of the calendar event.
  37 + final String? location;
  38 +
  39 + /// The organizer of the calendar event.
  40 + final String? organizer;
  41 +
  42 + /// The status of the calendar event.
  43 + final String? status;
  44 +
  45 + /// The summary of the calendar event.
  46 + final String? summary;
  47 +}
  1 +import 'package:mobile_scanner/src/objects/address.dart';
  2 +import 'package:mobile_scanner/src/objects/email.dart';
  3 +import 'package:mobile_scanner/src/objects/person_name.dart';
  4 +import 'package:mobile_scanner/src/objects/phone.dart';
  5 +
  6 +/// A person's or organization's business card.
  7 +/// For example a VCARD.
  8 +class ContactInfo {
  9 + /// Create a new [ContactInfo] instance.
  10 + const ContactInfo({
  11 + this.addresses = const <Address>[],
  12 + this.emails = const <Email>[],
  13 + this.name,
  14 + this.organization,
  15 + this.phones = const <Phone>[],
  16 + this.title,
  17 + this.urls = const <String>[],
  18 + });
  19 +
  20 + /// Create a new [ContactInfo] instance from a map.
  21 + factory ContactInfo.fromNative(Map<Object?, Object?> data) {
  22 + final List<Object?>? addresses = data['addresses'] as List<Object?>?;
  23 + final List<Object?>? emails = data['emails'] as List<Object?>?;
  24 + final List<Object?>? phones = data['phones'] as List<Object?>?;
  25 + final List<Object?>? urls = data['urls'] as List<Object?>?;
  26 + final Map<Object?, Object?>? name = data['name'] as Map<Object?, Object?>?;
  27 +
  28 + return ContactInfo(
  29 + addresses: addresses == null
  30 + ? const <Address>[]
  31 + : List.unmodifiable(
  32 + addresses.cast<Map<Object?, Object?>>().map(Address.fromNative),
  33 + ),
  34 + emails: emails == null
  35 + ? const <Email>[]
  36 + : List.unmodifiable(
  37 + emails.cast<Map<Object?, Object?>>().map(Email.fromNative),
  38 + ),
  39 + name: name == null ? null : PersonName.fromNative(name),
  40 + organization: data['organization'] as String?,
  41 + phones: phones == null
  42 + ? const <Phone>[]
  43 + : List.unmodifiable(
  44 + phones.cast<Map<Object?, Object?>>().map(Phone.fromNative),
  45 + ),
  46 + title: data['title'] as String?,
  47 + urls: urls == null
  48 + ? const <String>[]
  49 + : List.unmodifiable(urls.cast<String>()),
  50 + );
  51 + }
  52 +
  53 + /// The list of addresses for the person or organisation.
  54 + final List<Address> addresses;
  55 +
  56 + /// The list of email addresses for the person or organisation.
  57 + final List<Email> emails;
  58 +
  59 + /// The name of the contact person.
  60 + final PersonName? name;
  61 +
  62 + /// The name of the organization.
  63 + final String? organization;
  64 +
  65 + /// The available phone numbers for the contact person or organisation.
  66 + final List<Phone> phones;
  67 +
  68 + /// The contact person's title.
  69 + final String? title;
  70 +
  71 + /// The urls associated with the contact person or organisation.
  72 + final List<String> urls;
  73 +}
  1 +/// A driver license or ID card.
  2 +class DriverLicense {
  3 + /// Create a new [DriverLicense].
  4 + const DriverLicense({
  5 + this.addressCity,
  6 + this.addressState,
  7 + this.addressStreet,
  8 + this.addressZip,
  9 + this.birthDate,
  10 + this.documentType,
  11 + this.expiryDate,
  12 + this.firstName,
  13 + this.gender,
  14 + this.issueDate,
  15 + this.issuingCountry,
  16 + this.lastName,
  17 + this.licenseNumber,
  18 + this.middleName,
  19 + });
  20 +
  21 + /// Create a [DriverLicense] from a map.
  22 + factory DriverLicense.fromNative(Map<Object?, Object?> data) {
  23 + return DriverLicense(
  24 + addressCity: data['addressCity'] as String?,
  25 + addressState: data['addressState'] as String?,
  26 + addressStreet: data['addressStreet'] as String?,
  27 + addressZip: data['addressZip'] as String?,
  28 + birthDate: data['birthDate'] as String?,
  29 + documentType: data['documentType'] as String?,
  30 + expiryDate: data['expiryDate'] as String?,
  31 + firstName: data['firstName'] as String?,
  32 + gender: data['gender'] as String?,
  33 + issueDate: data['issueDate'] as String?,
  34 + issuingCountry: data['issuingCountry'] as String?,
  35 + lastName: data['lastName'] as String?,
  36 + licenseNumber: data['licenseNumber'] as String?,
  37 + middleName: data['middleName'] as String?,
  38 + );
  39 + }
  40 +
  41 + /// The city of the holder's address.
  42 + final String? addressCity;
  43 +
  44 + /// The state of the holder's address.
  45 + final String? addressState;
  46 +
  47 + /// The street address of the holder's address.
  48 + final String? addressStreet;
  49 +
  50 + /// The postal code of the holder's address.
  51 + final String? addressZip;
  52 +
  53 + /// The holder's birth date.
  54 + final String? birthDate;
  55 +
  56 + /// The type of the license.
  57 + ///
  58 + /// This is either "DL" for driver licenses or "ID" for ID cards.
  59 + final String? documentType;
  60 +
  61 + /// The expiry date of the license.
  62 + final String? expiryDate;
  63 +
  64 + /// The holder's first name.
  65 + final String? firstName;
  66 +
  67 + /// The holder's gender.
  68 + ///
  69 + /// This is either '1' for male or '2' for female.
  70 + final String? gender;
  71 +
  72 + /// The issue date of the license.
  73 + ///
  74 + /// The date format depends on the issuing country.
  75 + /// For example `MMDDYYYY` is used in the US,
  76 + /// and `YYYYMMDD` is used in Canada.
  77 + final String? issueDate;
  78 +
  79 + /// The three-letter country code in which this license was issued.
  80 + final String? issuingCountry;
  81 +
  82 + /// The holder's last name.
  83 + final String? lastName;
  84 +
  85 + /// The identifying number for this license.
  86 + final String? licenseNumber;
  87 +
  88 + /// The holder's middle name.
  89 + final String? middleName;
  90 +}
  1 +import 'package:mobile_scanner/src/enums/email_type.dart';
  2 +
  3 +/// An email message from a 'MAILTO:' or similar QRCode type.
  4 +class Email {
  5 + /// Construct a new [Email] instance.
  6 + const Email({
  7 + this.address,
  8 + this.body,
  9 + this.subject,
  10 + this.type = EmailType.unknown,
  11 + });
  12 +
  13 + /// Construct an [Email] from the given [data].
  14 + factory Email.fromNative(Map<Object?, Object?> data) {
  15 + return Email(
  16 + address: data['address'] as String?,
  17 + body: data['body'] as String?,
  18 + subject: data['subject'] as String?,
  19 + type: EmailType.fromRawValue(data['type'] as int? ?? 0),
  20 + );
  21 + }
  22 +
  23 + /// The email address.
  24 + final String? address;
  25 +
  26 + /// The body of the email.
  27 + final String? body;
  28 +
  29 + /// The subject of the email.
  30 + final String? subject;
  31 +
  32 + /// The type of the email.
  33 + final EmailType type;
  34 +}
  1 +/// GPS coordinates from a `GEO:` or similar QRCode type.
  2 +class GeoPoint {
  3 + /// Construct a new [GeoPoint] instance.
  4 + const GeoPoint({
  5 + required this.latitude,
  6 + required this.longitude,
  7 + });
  8 +
  9 + /// Construct a [GeoPoint] from the given [data].
  10 + ///
  11 + /// If the data does not contain valid GeoPoint coordinates,
  12 + /// then `0,0` is returned.
  13 + factory GeoPoint.fromNative(Map<Object?, Object?> data) {
  14 + final double? latitude = data['latitude'] as double?;
  15 + final double? longitude = data['longitude'] as double?;
  16 +
  17 + // If either is not set, then this GeoPoint is invalid.
  18 + // Return the geographic center as fallback.
  19 + if (latitude == null || longitude == null) {
  20 + return const GeoPoint(latitude: 0.0, longitude: 0.0);
  21 + }
  22 +
  23 + return GeoPoint(latitude: latitude, longitude: longitude);
  24 + }
  25 +
  26 + /// The latitude of the coordinate.
  27 + final double latitude;
  28 +
  29 + /// The longitude of the coordinate.
  30 + final double longitude;
  31 +}
  1 +/// A person's name, divided into individual components.
  2 +class PersonName {
  3 + /// Create a new [PersonName] instance.
  4 + const PersonName({
  5 + this.first,
  6 + this.middle,
  7 + this.last,
  8 + this.prefix,
  9 + this.suffix,
  10 + this.formattedName,
  11 + this.pronunciation,
  12 + });
  13 +
  14 + /// Create a [PersonName] from a map.
  15 + factory PersonName.fromNative(Map<Object?, Object?> data) {
  16 + return PersonName(
  17 + first: data['first'] as String?,
  18 + middle: data['middle'] as String?,
  19 + last: data['last'] as String?,
  20 + prefix: data['prefix'] as String?,
  21 + suffix: data['suffix'] as String?,
  22 + formattedName: data['formattedName'] as String?,
  23 + pronunciation: data['pronunciation'] as String?,
  24 + );
  25 + }
  26 +
  27 + /// The person's first name.
  28 + final String? first;
  29 +
  30 + /// The person's middle name.
  31 + final String? middle;
  32 +
  33 + /// The person's last name.
  34 + final String? last;
  35 +
  36 + /// The prefix of the person's name.
  37 + final String? prefix;
  38 +
  39 + /// The suffix of the person's name.
  40 + final String? suffix;
  41 +
  42 + /// The person's name in a structured format.
  43 + final String? formattedName;
  44 +
  45 + /// The pronunciation of the person's name.
  46 + ///
  47 + /// This is used for the "kana" name in Japanese phonebooks.
  48 + final String? pronunciation;
  49 +}
  1 +import 'package:mobile_scanner/src/enums/phone_type.dart';
  2 +
  3 +/// Phone number information from a barcode.
  4 +class Phone {
  5 + /// Construct a new [Phone] instance.
  6 + const Phone({
  7 + this.number,
  8 + this.type = PhoneType.unknown,
  9 + });
  10 +
  11 + /// Create a [Phone] from the given [data].
  12 + factory Phone.fromNative(Map<Object?, Object?> data) {
  13 + return Phone(
  14 + number: data['number'] as String?,
  15 + type: PhoneType.fromRawValue(data['type'] as int? ?? 0),
  16 + );
  17 + }
  18 +
  19 + /// The phone number value.
  20 + final String? number;
  21 +
  22 + /// The type of the phone number.
  23 + final PhoneType type;
  24 +}
  1 +/// An sms message from a `SMS:` or similar QRCode type.
  2 +class SMS {
  3 + /// Construct a new [SMS] instance.
  4 + const SMS({
  5 + this.message,
  6 + required this.phoneNumber,
  7 + });
  8 +
  9 + /// Construct a new [SMS] instance from the given [data].
  10 + factory SMS.fromNative(Map<Object?, Object?> data) {
  11 + return SMS(
  12 + message: data['message'] as String?,
  13 + phoneNumber: data['phoneNumber'] as String? ?? '',
  14 + );
  15 + }
  16 +
  17 + /// The message contained in the sms.
  18 + final String? message;
  19 +
  20 + /// The phone number which sent the sms.
  21 + final String phoneNumber;
  22 +}
  1 +/// A URL and title from a `MEBKM:` or similar QRCode type.
  2 +class UrlBookmark {
  3 + /// Construct a new [UrlBookmark] instance.
  4 + const UrlBookmark({
  5 + this.title,
  6 + required this.url,
  7 + });
  8 +
  9 + /// Construct a new [UrlBookmark] instance from the given [data].
  10 + factory UrlBookmark.fromNative(Map<Object?, Object?> data) {
  11 + return UrlBookmark(
  12 + title: data['title'] as String?,
  13 + url: data['url'] as String? ?? '',
  14 + );
  15 + }
  16 +
  17 + /// The title of the bookmark.
  18 + final String? title;
  19 +
  20 + /// The url of the bookmark.
  21 + final String url;
  22 +}
  1 +import 'package:mobile_scanner/src/enums/barcode_type.dart';
  2 +import 'package:mobile_scanner/src/enums/encryption_type.dart';
  3 +
  4 +/// Wireless network information from [BarcodeType.wifi] barcodes.
  5 +class WiFi {
  6 + /// Construct a new [WiFi] instance.
  7 + const WiFi({
  8 + this.encryptionType = EncryptionType.none,
  9 + this.ssid,
  10 + this.password,
  11 + });
  12 +
  13 + /// Construct a new [WiFi] instance from the given [data].
  14 + factory WiFi.fromNative(Map<Object?, Object?> data) {
  15 + return WiFi(
  16 + encryptionType: EncryptionType.fromRawValue(
  17 + data['encryptionType'] as int? ?? 0,
  18 + ),
  19 + ssid: data['ssid'] as String?,
  20 + password: data['password'] as String?,
  21 + );
  22 + }
  23 +
  24 + /// The encryption type of the wireless network.
  25 + final EncryptionType encryptionType;
  26 +
  27 + /// The ssid of the wireless network.
  28 + final String? ssid;
  29 +
  30 + /// The password of the wireless network.
  31 + final String? password;
  32 +}