chore: add high level classes

Signed-off-by: The one with the braid <the-one@with-the-braid.cf>
This commit is contained in:
The one with the braid 2023-08-27 17:47:11 +02:00
parent 165226bee1
commit 78f88305ec
13 changed files with 678 additions and 316 deletions

View file

@ -0,0 +1,171 @@
import 'package:pkpass/src/utils/mabe_decode.dart';
/// Keys that define the structure of the pass.
///
/// These keys are used for all pass styles and partition the fields into the various parts of the pass.
class PassStructureDictionary {
/// Fields to be displayed in the header on the front of the pass.
///
/// Use header fields sparingly; unlike all other fields, they remain visible when a stack of passes are displayed.
final List<DictionaryField> headerFields;
/// Fields to be displayed prominently on the front of the pass.
final List<DictionaryField> primaryFields;
/// Fields to be displayed on the front of the pass.
final List<DictionaryField> secondaryFields;
/// Fields to be on the back of the pass.
final List<DictionaryField> backFields;
/// Additional fields to be displayed on the front of the pass.
final List<DictionaryField> auxiliaryFields;
/// Required for boarding passes; otherwise not allowed. Type of transit.
final TransitType? transitType;
const PassStructureDictionary({
this.headerFields = const [],
this.primaryFields = const [],
this.secondaryFields = const [],
this.backFields = const [],
this.auxiliaryFields = const [],
this.transitType,
});
factory PassStructureDictionary.fromJson(Map<String, Object?> json) =>
PassStructureDictionary(
headerFields: (json['headerFields'] as List?)
?.map((i) => DictionaryField.fromJson(i))
.toList() ??
[],
primaryFields: (json['primaryFields'] as List?)
?.map((i) => DictionaryField.fromJson(i))
.toList() ??
[],
secondaryFields: (json['secondaryFields'] as List?)
?.map((i) => DictionaryField.fromJson(i))
.toList() ??
[],
backFields: (json['backFields'] as List?)
?.map((i) => DictionaryField.fromJson(i))
.toList() ??
[],
auxiliaryFields: (json['auxiliaryFields'] as List?)
?.map((i) => DictionaryField.fromJson(i))
.toList() ??
[],
transitType: _TarnsitType.parse(json['transitType'] as String?),
);
}
/// Information about a field.
class DictionaryField {
/// The key must be unique within the scope of the entire pass. For example, departure-gate.
final String key;
/// Value of the field, for example, 42.
final DictionaryValue value;
/// Label text for the field.
final String? label;
/// Format string for the alert text that is displayed when the pass is updated. The format string must contain the escape %@, which is replaced with the fields new value. For example, Gate changed to %@.
///
/// If you dont specify a change message, the user isnt notified when the field changes.
final String? changeMessage;
/// Alignment for the fields contents.
final PassTextAlign? textAlignment;
/// Attributed value of the field.
///
/// The value may contain HTML markup for links. Only the <a> tag and its href attribute are supported. For example, the following is key-value pair specifies a link with the text Edit my profile:
///
/// "attributedValue": "<a href='http://example.com/customers/123'>Edit my profile</a>"
///
/// This keys value overrides the text specified by the value key.
final DictionaryValue? attributedValue;
const DictionaryField({
required this.key,
required this.value,
this.label,
this.changeMessage,
this.textAlignment,
this.attributedValue,
});
factory DictionaryField.fromJson(Map<String, Object?> json) =>
DictionaryField(
key: json['key'] as String,
value: DictionaryValue.parse(json['value'] as String),
label: json['label'] as String?,
changeMessage: json['changeMessage'] as String?,
textAlignment:
MaybeDecode.maybeTextAlign(json['textAlignment'] as String?),
attributedValue: json['attributedValue'] == null
? null
: DictionaryValue.parse(json['attributedValue'] as String),
);
}
abstract class DictionaryValue {
const DictionaryValue();
factory DictionaryValue.parse(String value) {
final number = int.tryParse(value);
if (number != null) return NumberDictionaryValue(number);
final dateTime = DateTime.tryParse(value);
if (dateTime != null) return DateTimeDictionaryValue(dateTime);
return StringDictionaryValue(value);
}
}
class StringDictionaryValue extends DictionaryValue {
final String string;
const StringDictionaryValue(this.string);
}
class DateTimeDictionaryValue extends DictionaryValue {
final DateTime dateTime;
const DateTimeDictionaryValue(this.dateTime);
}
class NumberDictionaryValue extends DictionaryValue {
final int number;
const NumberDictionaryValue(this.number);
}
enum TransitType {
air,
boat,
bus,
generic,
train,
}
enum PassTextAlign { left, center, right, natural }
extension _TarnsitType on TransitType {
static TransitType? parse(String? type) {
if (type == null) return null;
switch (type) {
case 'PKTransitTypeAir':
return TransitType.air;
case 'PKTransitTypeBoat':
return TransitType.boat;
case 'PKTransitTypeBus':
return TransitType.bus;
case 'PKTransitTypeTrain':
return TransitType.train;
default:
return TransitType.generic;
}
}
}