Skip to content

Commit

Permalink
Merge pull request #819 from navaronbracke/reorganise_classes
Browse files Browse the repository at this point in the history
feat: Barcode class fixes
  • Loading branch information
navaronbracke authored Oct 23, 2023
2 parents cabebb0 + 1afb870 commit ffd0c02
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 82 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ Improvements:
* The list of `corners` of a `Barcode` is now non-null.
* The internal `fromNative()` methods now accept a `Map<Object?, Object?>` instead of `Map<dynamic, dynamic>`.

Bugs fixed:
* Fixed the default values for the `format` and `type` arguments of the Barcode constructor.
These now use `BarcodeFormat.unknown` and `BarcodeType.unknown`, rather than `BarcodeFormat.ean13` and `BarcodeType.text`.
(thanks @navaronbracke !)

## 3.5.0
New Features:
* Added the option to switch between bundled and unbundled MLKit for Android. (thanks @woolfred !)
Expand Down
201 changes: 119 additions & 82 deletions lib/src/objects/barcode.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'dart:typed_data';
import 'dart:ui';

import 'package:mobile_scanner/src/barcode_utility.dart';
import 'package:mobile_scanner/src/enums/barcode_format.dart';
import 'package:mobile_scanner/src/enums/barcode_type.dart';
import 'package:mobile_scanner/src/objects/calendar_event.dart';
Expand All @@ -16,109 +15,147 @@ import 'package:mobile_scanner/src/objects/wifi.dart';

/// Represents a single recognized barcode and its value.
class Barcode {
/// Returns four corner points in clockwise direction starting with top-left.
///
/// Due to the possible perspective distortions, this is not necessarily a rectangle.
///
/// Returns null if the corner points can not be determined.
final List<Offset> corners;
/// Creates a new [Barcode] instance.
const Barcode({
this.calendarEvent,
this.contactInfo,
this.corners = const <Offset>[],
this.displayValue,
this.driverLicense,
this.email,
this.format = BarcodeFormat.unknown,
this.geoPoint,
this.phone,
this.rawBytes,
this.rawValue,
this.sms,
this.type = BarcodeType.unknown,
this.url,
this.wifi,
});

/// Returns barcode format
final BarcodeFormat format;
/// Creates a new [Barcode] instance from the given [data].
factory Barcode.fromNative(Map<Object?, Object?> data) {
final Map<Object?, Object?>? calendarEvent =
data['calendarEvent'] as Map<Object?, Object?>?;
final List<Object?>? corners = data['corners'] as List<Object?>?;
final Map<Object?, Object?>? contactInfo =
data['contactInfo'] as Map<Object?, Object?>?;
final Map<Object?, Object?>? driverLicense =
data['driverLicense'] as Map<Object?, Object?>?;
final Map<Object?, Object?>? email =
data['email'] as Map<Object?, Object?>?;
final Map<Object?, Object?>? geoPoint =
data['geoPoint'] as Map<Object?, Object?>?;
final Map<Object?, Object?>? phone =
data['phone'] as Map<Object?, Object?>?;
final Map<Object?, Object?>? sms = data['sms'] as Map<Object?, Object?>?;
final Map<Object?, Object?>? url = data['url'] as Map<Object?, Object?>?;
final Map<Object?, Object?>? wifi = data['wifi'] as Map<Object?, Object?>?;

return Barcode(
calendarEvent: calendarEvent == null
? null
: CalendarEvent.fromNative(calendarEvent),
contactInfo:
contactInfo == null ? null : ContactInfo.fromNative(contactInfo),
corners: corners == null
? const <Offset>[]
: List.unmodifiable(
corners.cast<Map<String, double>>().map((Map<String, double> e) {
return Offset(e['x']!, e['y']!);
}),
),
displayValue: data['displayValue'] as String?,
driverLicense: driverLicense == null
? null
: DriverLicense.fromNative(driverLicense),
email: email == null ? null : Email.fromNative(email),
format: BarcodeFormat.fromRawValue(data['format'] as int? ?? -1),
geoPoint: geoPoint == null ? null : GeoPoint.fromNative(geoPoint),
phone: phone == null ? null : Phone.fromNative(phone),
rawBytes: data['rawBytes'] as Uint8List?,
rawValue: data['rawValue'] as String?,
sms: sms == null ? null : SMS.fromNative(sms),
type: BarcodeType.fromRawValue(data['type'] as int? ?? 0),
url: url == null ? null : UrlBookmark.fromNative(url),
wifi: wifi == null ? null : WiFi.fromNative(wifi),
);
}

/// The calendar event that is embedded in the barcode.
final CalendarEvent? calendarEvent;

/// Returns raw bytes as it was encoded in the barcode.
///
/// Returns null if the raw bytes can not be determined.
final Uint8List? rawBytes;
/// The contact information that is embedded in the barcode.
final ContactInfo? contactInfo;

/// Returns barcode value as it was encoded in the barcode. Structured values are not parsed, for example: 'MEBKM:TITLE:Google;URL://www.google.com;;'.
/// The four corner points of the barcode,
/// in clockwise order, starting with the top-left point.
///
/// It's only available when the barcode is encoded in the UTF-8 format, and for non-UTF8 ones use [rawBytes] instead.
/// Due to the possible perspective distortions, this is not necessarily a rectangle.
///
/// Returns null if the raw value can not be determined.
final String? rawValue;
/// This list is empty if the corners can not be determined.
final List<Offset> corners;

/// Returns barcode value in a user-friendly format.
/// The barcode value in a user-friendly format.
///
/// This method may omit some of the information encoded in the barcode. For example, if [rawValue] returns 'MEBKM:TITLE:Google;URL://www.google.com;;', the display value might be '//www.google.com'.
/// This value may omit some of the information encoded in the barcode.
/// For example, if [rawValue] returns `MEBKM:TITLE:Google;URL://www.google.com;;`,
/// the display value might be `//www.google.com`.
///
/// This value may be multiline, for example, when line breaks are encoded into the original TEXT barcode value. May include the supplement value.
/// This value may be multiline if line breaks are encoded in the barcode.
/// This value may include the supplement value.
///
/// Returns null if nothing found.
/// This is null if there is no user-friendly value for the given barcode.
final String? displayValue;

/// Returns format type of the barcode value.
///
/// For example, TYPE_TEXT, TYPE_PRODUCT, TYPE_URL, etc.
///
/// If the value structure cannot be parsed, TYPE_TEXT will be returned. If the recognized structure type is not defined in your current version of SDK, TYPE_UNKNOWN will be returned.
///
/// Note that the built-in parsers only recognize a few popular value structures. For your specific use case, you might want to directly consume rawValue and implement your own parsing logic.
final BarcodeType type;

/// Gets parsed calendar event details.
final CalendarEvent? calendarEvent;

/// Gets parsed contact details.
final ContactInfo? contactInfo;

/// Gets parsed driver license details.
/// The driver license information that is embedded in the barcode.
final DriverLicense? driverLicense;

/// Gets parsed email details.
/// The email message that is embedded in the barcode.
final Email? email;

/// Gets parsed geo coordinates.
/// The format of the barcode.
final BarcodeFormat format;

/// The geographic point that is embedded in the barcode.
final GeoPoint? geoPoint;

/// Gets parsed phone number details.
/// The phone number that is embedded in the barcode.
final Phone? phone;

/// Gets parsed SMS details.
/// The raw bytes of the barcode.
///
/// This is null if the raw bytes are not available.
final Uint8List? rawBytes;

/// The raw value of `UTF-8` encoded barcodes.
///
/// Structured values are not parsed,
/// for example: 'MEBKM:TITLE:Google;URL://www.google.com;;'.
///
/// For non-UTF-8 barcodes, prefer using [rawBytes] instead.
///
/// This is null if the raw value is not available.
final String? rawValue;

/// The SMS message that is embedded in the barcode.
final SMS? sms;

/// Gets parsed URL bookmark details.
/// The type of the [format] of the barcode.
///
/// For types that are recognized,
/// but could not be parsed correctly, [BarcodeType.text] will be returned.
///
/// For types that are not recognised, [BarcodeType.unknown] will be returned.
///
/// If a given barcode was not correctly identified,
/// consider parsing [rawValue] manually instead.
final BarcodeType type;

/// The URL bookmark that is embedded in the barcode.
final UrlBookmark? url;

/// Gets parsed WiFi AP details.
/// The Wireless network information that is embedded in the barcode.
final WiFi? wifi;

Barcode({
this.corners = const <Offset>[],
this.format = BarcodeFormat.ean13,
this.rawBytes,
this.type = BarcodeType.text,
this.calendarEvent,
this.contactInfo,
this.driverLicense,
this.email,
this.geoPoint,
this.phone,
this.sms,
this.url,
this.wifi,
this.displayValue,
required this.rawValue,
});

/// Create a [Barcode] from native data.
Barcode.fromNative(Map data)
: corners = toCorners(
(data['corners'] as List?)?.cast<Map<Object?, Object?>>(),
) ??
const <Offset>[],
format = toFormat(data['format'] as int),
rawBytes = data['rawBytes'] as Uint8List?,
rawValue = data['rawValue'] as String?,
displayValue = data['displayValue'] as String?,
type = BarcodeType.values[data['type'] as int],
calendarEvent = toCalendarEvent(data['calendarEvent'] as Map?),
contactInfo = toContactInfo(data['contactInfo'] as Map?),
driverLicense = toDriverLicense(data['driverLicense'] as Map?),
email = toEmail(data['email'] as Map?),
geoPoint = toGeoPoint(data['geoPoint'] as Map?),
phone = toPhone(data['phone'] as Map?),
sms = toSMS(data['sms'] as Map?),
url = toUrl(data['url'] as Map?),
wifi = toWiFi(data['wifi'] as Map?);
}

0 comments on commit ffd0c02

Please sign in to comment.