mirror of
https://gitlab.com/TheOneWithTheBraid/dart_pkpass.git
synced 2025-07-05 12:58:47 +00:00
210 lines
7.7 KiB
Dart
210 lines
7.7 KiB
Dart
import 'package:intl/locale.dart';
|
||
|
||
import 'package:pkpass/pkpass.dart';
|
||
import 'package:pkpass/pkpass/utils/maybe_decode.dart';
|
||
|
||
/// Information that is required for all passes.
|
||
class PassMetadata {
|
||
/// Brief description of the pass, used by accessibility technologies.
|
||
///
|
||
/// Don’t try to include all of the data on the pass in its description,
|
||
/// just include enough detail to distinguish passes of the same type.
|
||
final String description;
|
||
|
||
/// Version of the file format. The value must be 1.
|
||
final int formatVersion;
|
||
|
||
/// Display name of the organization that originated and signed the pass.
|
||
final String organizationName;
|
||
|
||
/// Pass type identifier, as issued by Apple. The value must correspond with
|
||
/// your signing certificate.
|
||
final String passTypeIdentifier;
|
||
|
||
/// Serial number that uniquely identifies the pass. No two passes with the
|
||
/// same pass type identifier may have the same serial number.
|
||
final String serialNumber;
|
||
|
||
/// Team identifier of the organization that originated and signed the pass,
|
||
/// as issued by Apple.
|
||
final String teamIdentifier;
|
||
|
||
/// A URL to be passed to the associated app when launching it.
|
||
final String? appLaunchURL;
|
||
|
||
/// Date and time when the pass expires.
|
||
final DateTime? expirationDate;
|
||
|
||
/// Indicates that the pass is void—for example, a one time use coupon that
|
||
/// has been redeemed. The default value is false.
|
||
final bool voided;
|
||
|
||
/// Beacons marking locations where the pass is relevant.
|
||
final List<Beacon> beacons;
|
||
|
||
/// Locations where the pass is relevant. For example, the location of your store.
|
||
final List<Location> locations;
|
||
|
||
/// Maximum distance in meters from a relevant latitude and longitude that
|
||
/// the pass is relevant. This number is compared to the pass’s default
|
||
/// distance and the smaller value is used.
|
||
final int? maxDistance;
|
||
|
||
/// Recommended for event tickets and boarding passes; otherwise optional.
|
||
/// Date and time when the pass becomes relevant. For example, the start
|
||
/// time of a movie.
|
||
final DateTime? relevantDate;
|
||
|
||
/// Information specific to a boarding pass.
|
||
final PassStructureDictionary? boardingPass;
|
||
|
||
/// Information specific to a coupon.
|
||
final PassStructureDictionary? coupon;
|
||
|
||
/// Information specific to an event ticket.
|
||
final PassStructureDictionary? eventTicket;
|
||
|
||
/// Information specific to a generic pass.
|
||
final PassStructureDictionary? generic;
|
||
|
||
/// Information specific to a store card.
|
||
final PassStructureDictionary? storeCard;
|
||
|
||
/// Information specific to the pass’s barcode.
|
||
/// The system uses the first valid barcode dictionary in the array.
|
||
/// Additional dictionaries can be added as fallbacks.
|
||
final List<PassBarcode> barcodes;
|
||
|
||
/// Background color of the pass.
|
||
final int? backgroundColor;
|
||
|
||
/// Foreground color of the pass.
|
||
final int? foregroundColor;
|
||
|
||
/// Optional for event tickets and boarding passes; otherwise not allowed.
|
||
/// Identifier used to group related passes. If a grouping identifier is
|
||
/// specified, passes with the same style, pass type identifier, and grouping
|
||
/// identifier are displayed as a group. Otherwise, passes are grouped
|
||
/// automatically.
|
||
///
|
||
/// Use this to group passes that are tightly related, such as the boarding
|
||
/// passes for different connections of the same trip.
|
||
final String? groupingIdentifier;
|
||
|
||
/// Color of the label text.
|
||
final int? labelColor;
|
||
|
||
/// Text displayed next to the logo on the pass.
|
||
final String? logoText;
|
||
|
||
/// Information used to update passes using the web service.
|
||
final PassWebService? webService;
|
||
|
||
const PassMetadata({
|
||
required this.description,
|
||
required this.formatVersion,
|
||
required this.organizationName,
|
||
required this.passTypeIdentifier,
|
||
required this.serialNumber,
|
||
required this.teamIdentifier,
|
||
this.appLaunchURL,
|
||
this.expirationDate,
|
||
this.voided = false,
|
||
this.beacons = const [],
|
||
this.locations = const [],
|
||
this.maxDistance,
|
||
this.relevantDate,
|
||
this.boardingPass,
|
||
this.coupon,
|
||
this.eventTicket,
|
||
this.generic,
|
||
this.storeCard,
|
||
this.barcodes = const [],
|
||
this.backgroundColor,
|
||
this.foregroundColor,
|
||
this.groupingIdentifier,
|
||
this.labelColor,
|
||
this.logoText,
|
||
this.webService,
|
||
});
|
||
|
||
factory PassMetadata.fromJson(Map<String, Object?> json) => PassMetadata(
|
||
description: json['description'] as String,
|
||
formatVersion: json['formatVersion'] as int,
|
||
organizationName: json['organizationName'] as String,
|
||
passTypeIdentifier: json['passTypeIdentifier'] as String,
|
||
serialNumber: json['serialNumber'] as String,
|
||
teamIdentifier: json['teamIdentifier'] as String,
|
||
boardingPass: json['boardingPass'] == null
|
||
? null
|
||
: PassStructureDictionary.fromJson(
|
||
(json['boardingPass'] as Map).cast<String, Object?>(),
|
||
),
|
||
coupon: json['coupon'] == null
|
||
? null
|
||
: PassStructureDictionary.fromJson(
|
||
(json['coupon'] as Map).cast<String, Object?>(),
|
||
),
|
||
eventTicket: json['eventTicket'] == null
|
||
? null
|
||
: PassStructureDictionary.fromJson(
|
||
(json['eventTicket'] as Map).cast<String, Object?>(),
|
||
),
|
||
generic: json['generic'] == null
|
||
? null
|
||
: PassStructureDictionary.fromJson(
|
||
(json['generic'] as Map).cast<String, Object?>(),
|
||
),
|
||
storeCard: json['storeCard'] == null
|
||
? null
|
||
: PassStructureDictionary.fromJson(
|
||
(json['storeCard'] as Map).cast<String, Object?>(),
|
||
),
|
||
barcodes: (json['barcodes'] as List? ??
|
||
[if (json['barcode'] != null) json['barcode']])
|
||
.map((i) => PassBarcode.fromJson(i))
|
||
.toList(),
|
||
locations: (json['locations'] as List? ?? [])
|
||
.map((i) => Location.fromJson(i))
|
||
.toList(),
|
||
appLaunchURL: json['appLaunchURL'] as String?,
|
||
expirationDate:
|
||
MaybeDecode.maybeDateTime(json['expirationDate'] as String?),
|
||
voided: json['voided'] as bool? ?? false,
|
||
beacons: (json['beacons'] as List? ?? [])
|
||
.map((i) => Beacon.fromJson(i))
|
||
.toList(),
|
||
maxDistance: json['maxDistance'] as int?,
|
||
relevantDate:
|
||
MaybeDecode.maybeDateTime(json['relevantDate'] as String?),
|
||
backgroundColor:
|
||
MaybeDecode.maybeColor(json['backgroundColor'] as String?),
|
||
foregroundColor:
|
||
MaybeDecode.maybeColor(json['foregroundColor'] as String?),
|
||
groupingIdentifier: json['locoText'] as String?,
|
||
labelColor: MaybeDecode.maybeColor(json['labelColor'] as String?),
|
||
logoText: json['locoText'] as String?,
|
||
webService: PassWebService.maybe(
|
||
authenticationToken: json['authenticationToken'] as String?,
|
||
webServiceURL: json['webServiceURL'] as String?,
|
||
),
|
||
);
|
||
|
||
/// Localized version of [description] based on given [locale] and [pass].
|
||
String getLocalizedDescription(PassFile pass, Locale? locale) {
|
||
final localizations = pass.getLocalizations(locale);
|
||
return localizations?[description] ?? description;
|
||
}
|
||
|
||
/// Localized version of [organizationName] based on given [locale] and [pass].
|
||
String getLocalizedOrganizationName(PassFile pass, Locale? locale) {
|
||
final localizations = pass.getLocalizations(locale);
|
||
return localizations?[organizationName] ?? organizationName;
|
||
}
|
||
|
||
/// Localized version of [logoText] based on given [locale] and [pass].
|
||
String? getLocalizedLogoText(PassFile pass, Locale? locale) {
|
||
final localizations = pass.getLocalizations(locale);
|
||
return localizations?[logoText] ?? logoText;
|
||
}
|
||
}
|