feat: implement web service

Signed-off-by: The one with the braid <info@braid.business>
This commit is contained in:
The one with the braid 2023-11-26 19:42:29 +01:00
parent 44494eaa90
commit 6e7f19a764
26 changed files with 331 additions and 512 deletions

View file

@ -1,235 +0,0 @@
import 'package:intl/locale.dart';
import 'package:pkpass/pkpass.dart';
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),
);
/// Localized version of [label] based on given [locale] and [pass].
String? getLocalizedLabel(PassFile pass, Locale? locale) {
final localizations = pass.getLocalizations(locale);
return localizations?[label] ?? label;
}
/// Localized version of [changeMessage] based on given [locale] and [pass].
String? getLocalizedChangeMessage(PassFile pass, Locale? locale) {
final localizations = pass.getLocalizations(locale);
return localizations?[changeMessage] ?? changeMessage;
}
}
/// represents the possible values of a [DictionaryField].
abstract class DictionaryValue {
const DictionaryValue();
/// parses the correct [DictionaryValue] implementor based on a given [value].
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);
}
/// Localized value based on given [locale] and [pass].
DictionaryValue getLocalizedValue(PassFile pass, Locale? locale);
}
/// [String] content of a [DictionaryField].
class StringDictionaryValue extends DictionaryValue {
final String string;
const StringDictionaryValue(this.string);
@override
/// Localized value based on given [locale] and [pass].
DictionaryValue getLocalizedValue(PassFile pass, Locale? locale) {
final localizations = pass.getLocalizations(locale);
return StringDictionaryValue(localizations?[string] ?? string);
}
}
/// [DateTime] content of a [DictionaryField].
class DateTimeDictionaryValue extends DictionaryValue {
final DateTime dateTime;
const DateTimeDictionaryValue(this.dateTime);
@override
/// Localized value based on given [locale] and [pass]. Same as [dateTime].
DictionaryValue getLocalizedValue(PassFile pass, Locale? locale) => this;
}
/// [int] content of a [DictionaryField].
class NumberDictionaryValue extends DictionaryValue {
final int number;
const NumberDictionaryValue(this.number);
@override
/// Localized value based on given [locale] and [pass]. Same as [number].
DictionaryValue getLocalizedValue(PassFile pass, Locale? locale) => this;
}
/// Possible types of [PassStructureDictionary.transitType].
enum TransitType {
/// PKTransitTypeAir
air,
/// PKTransitTypeBoat
boat,
/// PKTransitTypeBus
bus,
/// PKTransitTypeGeneric
generic,
/// PKTransitTypeTrain
train,
}
/// Possible types of [DictionaryField.textAlignment].
enum PassTextAlign {
/// PKTextAlignmentLeft, corresponds `dart:ui` [TextAlign.left]
left,
/// PKTextAlignmentCenter, corresponds `dart:ui` [TextAlign.center]
center,
/// PKTextAlignmentRight, corresponds `dart:ui` [TextAlign.left]
right,
/// PKTextAlignmentNatural, corresponds `dart:ui` [TextAlign.start]
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;
}
}
}