implemented RMV public transit module including trip search, station departures, and nearby stop lookup, added "Marianum Connect" API integration with bearer token authentication and auto-refresh logic, integrated geolocator for location-based station search, added persistent storage for favorite stations and recent trip queries, and implemented comprehensive UI for journey details, trip results, and disruption alerts
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/// ISO-8601 duration (`PT1H30M5S`) ↔ Dart `Duration`. Backend serialises
|
||||
/// `java.time.Duration` in this format; Dart has no builtin parser.
|
||||
class IsoDuration {
|
||||
IsoDuration._();
|
||||
|
||||
static final RegExp _pattern = RegExp(
|
||||
r'^P(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$',
|
||||
);
|
||||
|
||||
static Duration? fromJson(String? iso) {
|
||||
if (iso == null || iso.isEmpty) return null;
|
||||
final match = _pattern.firstMatch(iso);
|
||||
if (match == null) return null;
|
||||
final hours = int.parse(match.group(1) ?? '0');
|
||||
final minutes = int.parse(match.group(2) ?? '0');
|
||||
final secondsRaw = match.group(3) ?? '0';
|
||||
final secondsValue = double.parse(secondsRaw);
|
||||
return Duration(
|
||||
hours: hours,
|
||||
minutes: minutes,
|
||||
milliseconds: (secondsValue * 1000).round(),
|
||||
);
|
||||
}
|
||||
|
||||
static String? toJson(Duration? d) {
|
||||
if (d == null) return null;
|
||||
final hours = d.inHours;
|
||||
final minutes = d.inMinutes.remainder(60);
|
||||
final seconds = d.inSeconds.remainder(60);
|
||||
final buf = StringBuffer('PT');
|
||||
if (hours > 0) buf.write('${hours}H');
|
||||
if (minutes > 0) buf.write('${minutes}M');
|
||||
if (seconds > 0 || (hours == 0 && minutes == 0)) buf.write('${seconds}S');
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/// Formats a [DateTime] as `2026-05-19T14:30:00` for Java's
|
||||
/// `LocalDateTime` parser (no timezone, no millis).
|
||||
String formatLocalDateTime(DateTime dt) {
|
||||
String two(int v) => v.toString().padLeft(2, '0');
|
||||
return '${dt.year}-${two(dt.month)}-${two(dt.day)}T'
|
||||
'${two(dt.hour)}:${two(dt.minute)}:${two(dt.second)}';
|
||||
}
|
||||
|
||||
/// Formats a [DateTime] as `2026-05-19` for Java's `LocalDate` parser.
|
||||
String formatLocalDate(DateTime dt) {
|
||||
String two(int v) => v.toString().padLeft(2, '0');
|
||||
return '${dt.year}-${two(dt.month)}-${two(dt.day)}';
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../connect_api.dart';
|
||||
import '../rmv_models.dart';
|
||||
import '_query_format.dart';
|
||||
|
||||
class GetArrivals extends ConnectApi<List<Arrival>> {
|
||||
final String stopId;
|
||||
final DateTime? when;
|
||||
final int durationMinutes;
|
||||
final int maxJourneys;
|
||||
|
||||
GetArrivals({
|
||||
required this.stopId,
|
||||
this.when,
|
||||
this.durationMinutes = 60,
|
||||
this.maxJourneys = -1,
|
||||
}) : super('rmv/arrivals');
|
||||
|
||||
@override
|
||||
Map<String, String>? get queryParameters => {
|
||||
'stopId': stopId,
|
||||
if (when != null) 'when': formatLocalDateTime(when!),
|
||||
'duration': durationMinutes.toString(),
|
||||
'max': maxJourneys.toString(),
|
||||
};
|
||||
|
||||
@override
|
||||
List<Arrival> assemble(String raw) => (jsonDecode(raw) as List)
|
||||
.map((e) => Arrival.fromJson(e as Map<String, dynamic>))
|
||||
.toList(growable: false);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../connect_api.dart';
|
||||
import '../rmv_models.dart';
|
||||
import '_query_format.dart';
|
||||
|
||||
class GetDepartures extends ConnectApi<List<Departure>> {
|
||||
final String stopId;
|
||||
final DateTime? when;
|
||||
final int durationMinutes;
|
||||
final int maxJourneys;
|
||||
|
||||
GetDepartures({
|
||||
required this.stopId,
|
||||
this.when,
|
||||
this.durationMinutes = 60,
|
||||
this.maxJourneys = -1,
|
||||
}) : super('rmv/departures');
|
||||
|
||||
@override
|
||||
Map<String, String>? get queryParameters => {
|
||||
'stopId': stopId,
|
||||
if (when != null) 'when': formatLocalDateTime(when!),
|
||||
'duration': durationMinutes.toString(),
|
||||
'max': maxJourneys.toString(),
|
||||
};
|
||||
|
||||
@override
|
||||
List<Departure> assemble(String raw) => (jsonDecode(raw) as List)
|
||||
.map((e) => Departure.fromJson(e as Map<String, dynamic>))
|
||||
.toList(growable: false);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../connect_api.dart';
|
||||
import '../rmv_models.dart';
|
||||
import '_query_format.dart';
|
||||
|
||||
class GetDisruptions extends ConnectApi<List<HimMessage>> {
|
||||
final DateTime? when;
|
||||
|
||||
GetDisruptions({this.when}) : super('rmv/disruptions');
|
||||
|
||||
@override
|
||||
Map<String, String>? get queryParameters =>
|
||||
when == null ? null : {'when': formatLocalDateTime(when!)};
|
||||
|
||||
@override
|
||||
List<HimMessage> assemble(String raw) => (jsonDecode(raw) as List)
|
||||
.map((e) => HimMessage.fromJson(e as Map<String, dynamic>))
|
||||
.toList(growable: false);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../connect_api.dart';
|
||||
import '../rmv_models.dart';
|
||||
import '_query_format.dart';
|
||||
|
||||
class GetJourneyDetail extends ConnectApi<JourneyDetail> {
|
||||
final String journeyRef;
|
||||
final DateTime? date;
|
||||
|
||||
GetJourneyDetail({required this.journeyRef, this.date})
|
||||
: super('rmv/journey');
|
||||
|
||||
@override
|
||||
Map<String, String>? get queryParameters => {
|
||||
'ref': journeyRef,
|
||||
if (date != null) 'date': formatLocalDate(date!),
|
||||
};
|
||||
|
||||
@override
|
||||
JourneyDetail assemble(String raw) =>
|
||||
JourneyDetail.fromJson(jsonDecode(raw) as Map<String, dynamic>);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../connect_api.dart';
|
||||
import '../rmv_models.dart';
|
||||
|
||||
class MoreTrips extends ConnectApi<TripSearchResult> {
|
||||
final String ctx;
|
||||
|
||||
MoreTrips({required this.ctx}) : super('rmv/trips/more');
|
||||
|
||||
@override
|
||||
Map<String, String>? get queryParameters => {'ctx': ctx};
|
||||
|
||||
@override
|
||||
TripSearchResult assemble(String raw) =>
|
||||
TripSearchResult.fromJson(jsonDecode(raw) as Map<String, dynamic>);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../connect_api.dart';
|
||||
import '../rmv_models.dart';
|
||||
|
||||
class NearbyStops extends ConnectApi<List<StopLocation>> {
|
||||
final double lat;
|
||||
final double lon;
|
||||
final int radiusMeters;
|
||||
final int max;
|
||||
|
||||
NearbyStops({
|
||||
required this.lat,
|
||||
required this.lon,
|
||||
this.radiusMeters = 1000,
|
||||
this.max = 20,
|
||||
}) : super('rmv/stops/nearby');
|
||||
|
||||
@override
|
||||
Map<String, String>? get queryParameters => {
|
||||
'lat': lat.toString(),
|
||||
'lon': lon.toString(),
|
||||
'radius': radiusMeters.toString(),
|
||||
'max': max.toString(),
|
||||
};
|
||||
|
||||
@override
|
||||
List<StopLocation> assemble(String raw) => (jsonDecode(raw) as List)
|
||||
.map((e) => StopLocation.fromJson(e as Map<String, dynamic>))
|
||||
.toList(growable: false);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../connect_api.dart';
|
||||
import '../rmv_models.dart';
|
||||
|
||||
class SearchStops extends ConnectApi<List<StopLocation>> {
|
||||
final String query;
|
||||
final int max;
|
||||
|
||||
SearchStops({required this.query, this.max = 10}) : super('rmv/stops');
|
||||
|
||||
@override
|
||||
Map<String, String>? get queryParameters => {
|
||||
'q': query,
|
||||
'max': max.toString(),
|
||||
};
|
||||
|
||||
@override
|
||||
List<StopLocation> assemble(String raw) => (jsonDecode(raw) as List)
|
||||
.map((e) => StopLocation.fromJson(e as Map<String, dynamic>))
|
||||
.toList(growable: false);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../connect_api.dart';
|
||||
import '../rmv_models.dart';
|
||||
import '_query_format.dart';
|
||||
|
||||
class SearchTrips extends ConnectApi<TripSearchResult> {
|
||||
final String fromStopId;
|
||||
final String toStopId;
|
||||
final DateTime? when;
|
||||
final bool searchByArrival;
|
||||
|
||||
SearchTrips({
|
||||
required this.fromStopId,
|
||||
required this.toStopId,
|
||||
this.when,
|
||||
this.searchByArrival = false,
|
||||
}) : super('rmv/trips');
|
||||
|
||||
@override
|
||||
Map<String, String>? get queryParameters => {
|
||||
'from': fromStopId,
|
||||
'to': toStopId,
|
||||
if (when != null) 'when': formatLocalDateTime(when!),
|
||||
'searchByArrival': searchByArrival.toString(),
|
||||
};
|
||||
|
||||
@override
|
||||
TripSearchResult assemble(String raw) =>
|
||||
TripSearchResult.fromJson(jsonDecode(raw) as Map<String, dynamic>);
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'iso_duration.dart';
|
||||
|
||||
part 'rmv_models.freezed.dart';
|
||||
part 'rmv_models.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class Product with _$Product {
|
||||
const factory Product({
|
||||
String? name,
|
||||
String? line,
|
||||
String? displayNumber,
|
||||
String? category,
|
||||
String? categoryCode,
|
||||
String? operator,
|
||||
}) = _Product;
|
||||
|
||||
factory Product.fromJson(Map<String, Object?> json) =>
|
||||
_$ProductFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class StopLocation with _$StopLocation {
|
||||
const factory StopLocation({
|
||||
required String id,
|
||||
String? extId,
|
||||
required String name,
|
||||
String? description,
|
||||
double? lat,
|
||||
double? lon,
|
||||
int? products,
|
||||
int? distanceMeters,
|
||||
}) = _StopLocation;
|
||||
|
||||
factory StopLocation.fromJson(Map<String, Object?> json) =>
|
||||
_$StopLocationFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class Departure with _$Departure {
|
||||
const factory Departure({
|
||||
required String stopId,
|
||||
String? stopExtId,
|
||||
required String stopName,
|
||||
required String name,
|
||||
required String direction,
|
||||
String? directionFlag,
|
||||
required DateTime scheduledTime,
|
||||
DateTime? realTime,
|
||||
int? delayMinutes,
|
||||
String? track,
|
||||
String? realTrack,
|
||||
@Default(false) bool cancelled,
|
||||
@Default(true) bool reachable,
|
||||
Product? product,
|
||||
String? journeyRef,
|
||||
}) = _Departure;
|
||||
|
||||
factory Departure.fromJson(Map<String, Object?> json) =>
|
||||
_$DepartureFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class Arrival with _$Arrival {
|
||||
const factory Arrival({
|
||||
required String stopId,
|
||||
String? stopExtId,
|
||||
required String stopName,
|
||||
required String name,
|
||||
required String origin,
|
||||
required DateTime scheduledTime,
|
||||
DateTime? realTime,
|
||||
int? delayMinutes,
|
||||
String? track,
|
||||
String? realTrack,
|
||||
@Default(false) bool cancelled,
|
||||
Product? product,
|
||||
String? journeyRef,
|
||||
}) = _Arrival;
|
||||
|
||||
factory Arrival.fromJson(Map<String, Object?> json) =>
|
||||
_$ArrivalFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TripEndpoint with _$TripEndpoint {
|
||||
const factory TripEndpoint({
|
||||
required String stopId,
|
||||
String? stopExtId,
|
||||
required String name,
|
||||
double? lat,
|
||||
double? lon,
|
||||
required DateTime scheduledTime,
|
||||
DateTime? realTime,
|
||||
int? delayMinutes,
|
||||
String? track,
|
||||
String? realTrack,
|
||||
String? type,
|
||||
}) = _TripEndpoint;
|
||||
|
||||
factory TripEndpoint.fromJson(Map<String, Object?> json) =>
|
||||
_$TripEndpointFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class JourneyStop with _$JourneyStop {
|
||||
const factory JourneyStop({
|
||||
required String id,
|
||||
String? extId,
|
||||
required String name,
|
||||
double? lat,
|
||||
double? lon,
|
||||
int? routeIdx,
|
||||
DateTime? scheduledArrival,
|
||||
DateTime? scheduledDeparture,
|
||||
DateTime? realArrival,
|
||||
DateTime? realDeparture,
|
||||
String? arrTrack,
|
||||
String? depTrack,
|
||||
String? realArrTrack,
|
||||
String? realDepTrack,
|
||||
@Default(false) bool cancelled,
|
||||
@Default(false) bool cancelledArrival,
|
||||
@Default(false) bool cancelledDeparture,
|
||||
}) = _JourneyStop;
|
||||
|
||||
factory JourneyStop.fromJson(Map<String, Object?> json) =>
|
||||
_$JourneyStopFromJson(json);
|
||||
}
|
||||
|
||||
enum LegType {
|
||||
@JsonValue('JOURNEY')
|
||||
journey,
|
||||
@JsonValue('WALK')
|
||||
walk,
|
||||
@JsonValue('TRANSFER')
|
||||
transfer,
|
||||
@JsonValue('BIKE')
|
||||
bike,
|
||||
@JsonValue('CAR')
|
||||
car,
|
||||
@JsonValue('PARK_RIDE')
|
||||
parkRide,
|
||||
@JsonValue('TAXI')
|
||||
taxi,
|
||||
@JsonValue('CHECK_IN')
|
||||
checkIn,
|
||||
@JsonValue('CHECK_OUT')
|
||||
checkOut,
|
||||
@JsonValue('DUMMY')
|
||||
dummy,
|
||||
@JsonValue('UNKNOWN')
|
||||
unknown,
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class Leg with _$Leg {
|
||||
const factory Leg({
|
||||
required String id,
|
||||
required int idx,
|
||||
@Default(LegType.unknown) LegType type,
|
||||
String? name,
|
||||
String? category,
|
||||
String? number,
|
||||
String? direction,
|
||||
required TripEndpoint origin,
|
||||
required TripEndpoint destination,
|
||||
@JsonKey(fromJson: IsoDuration.fromJson, toJson: IsoDuration.toJson)
|
||||
Duration? duration,
|
||||
@Default(false) bool cancelled,
|
||||
@Default(false) bool partCancelled,
|
||||
@Default(true) bool reachable,
|
||||
Product? product,
|
||||
String? journeyRef,
|
||||
@Default(<JourneyStop>[]) List<JourneyStop> stops,
|
||||
}) = _Leg;
|
||||
|
||||
factory Leg.fromJson(Map<String, Object?> json) => _$LegFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class Trip with _$Trip {
|
||||
const factory Trip({
|
||||
String? tripId,
|
||||
String? ctxRecon,
|
||||
String? checksum,
|
||||
@JsonKey(fromJson: IsoDuration.fromJson, toJson: IsoDuration.toJson)
|
||||
Duration? duration,
|
||||
@JsonKey(fromJson: IsoDuration.fromJson, toJson: IsoDuration.toJson)
|
||||
Duration? realDuration,
|
||||
int? transferCount,
|
||||
@Default(<Leg>[]) List<Leg> legs,
|
||||
}) = _Trip;
|
||||
|
||||
factory Trip.fromJson(Map<String, Object?> json) => _$TripFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TripSearchResult with _$TripSearchResult {
|
||||
const factory TripSearchResult({
|
||||
@Default(<Trip>[]) List<Trip> trips,
|
||||
String? scrollContextLater,
|
||||
String? scrollContextEarlier,
|
||||
}) = _TripSearchResult;
|
||||
|
||||
factory TripSearchResult.fromJson(Map<String, Object?> json) =>
|
||||
_$TripSearchResultFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class JourneyDetail with _$JourneyDetail {
|
||||
const factory JourneyDetail({
|
||||
String? journeyId,
|
||||
Product? product,
|
||||
String? direction,
|
||||
@Default(<JourneyStop>[]) List<JourneyStop> stops,
|
||||
}) = _JourneyDetail;
|
||||
|
||||
factory JourneyDetail.fromJson(Map<String, Object?> json) =>
|
||||
_$JourneyDetailFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class HimMessage with _$HimMessage {
|
||||
const factory HimMessage({
|
||||
required String id,
|
||||
String? externalId,
|
||||
String? head,
|
||||
String? lead,
|
||||
String? text,
|
||||
String? category,
|
||||
String? company,
|
||||
int? priority,
|
||||
int? products,
|
||||
DateTime? startValidity,
|
||||
DateTime? endValidity,
|
||||
DateTime? modified,
|
||||
}) = _HimMessage;
|
||||
|
||||
factory HimMessage.fromJson(Map<String, Object?> json) =>
|
||||
_$HimMessageFromJson(json);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,368 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'rmv_models.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_Product _$ProductFromJson(Map<String, dynamic> json) => _Product(
|
||||
name: json['name'] as String?,
|
||||
line: json['line'] as String?,
|
||||
displayNumber: json['displayNumber'] as String?,
|
||||
category: json['category'] as String?,
|
||||
categoryCode: json['categoryCode'] as String?,
|
||||
operator: json['operator'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ProductToJson(_Product instance) => <String, dynamic>{
|
||||
'name': instance.name,
|
||||
'line': instance.line,
|
||||
'displayNumber': instance.displayNumber,
|
||||
'category': instance.category,
|
||||
'categoryCode': instance.categoryCode,
|
||||
'operator': instance.operator,
|
||||
};
|
||||
|
||||
_StopLocation _$StopLocationFromJson(Map<String, dynamic> json) =>
|
||||
_StopLocation(
|
||||
id: json['id'] as String,
|
||||
extId: json['extId'] as String?,
|
||||
name: json['name'] as String,
|
||||
description: json['description'] as String?,
|
||||
lat: (json['lat'] as num?)?.toDouble(),
|
||||
lon: (json['lon'] as num?)?.toDouble(),
|
||||
products: (json['products'] as num?)?.toInt(),
|
||||
distanceMeters: (json['distanceMeters'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$StopLocationToJson(_StopLocation instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'extId': instance.extId,
|
||||
'name': instance.name,
|
||||
'description': instance.description,
|
||||
'lat': instance.lat,
|
||||
'lon': instance.lon,
|
||||
'products': instance.products,
|
||||
'distanceMeters': instance.distanceMeters,
|
||||
};
|
||||
|
||||
_Departure _$DepartureFromJson(Map<String, dynamic> json) => _Departure(
|
||||
stopId: json['stopId'] as String,
|
||||
stopExtId: json['stopExtId'] as String?,
|
||||
stopName: json['stopName'] as String,
|
||||
name: json['name'] as String,
|
||||
direction: json['direction'] as String,
|
||||
directionFlag: json['directionFlag'] as String?,
|
||||
scheduledTime: DateTime.parse(json['scheduledTime'] as String),
|
||||
realTime: json['realTime'] == null
|
||||
? null
|
||||
: DateTime.parse(json['realTime'] as String),
|
||||
delayMinutes: (json['delayMinutes'] as num?)?.toInt(),
|
||||
track: json['track'] as String?,
|
||||
realTrack: json['realTrack'] as String?,
|
||||
cancelled: json['cancelled'] as bool? ?? false,
|
||||
reachable: json['reachable'] as bool? ?? true,
|
||||
product: json['product'] == null
|
||||
? null
|
||||
: Product.fromJson(json['product'] as Map<String, dynamic>),
|
||||
journeyRef: json['journeyRef'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DepartureToJson(_Departure instance) =>
|
||||
<String, dynamic>{
|
||||
'stopId': instance.stopId,
|
||||
'stopExtId': instance.stopExtId,
|
||||
'stopName': instance.stopName,
|
||||
'name': instance.name,
|
||||
'direction': instance.direction,
|
||||
'directionFlag': instance.directionFlag,
|
||||
'scheduledTime': instance.scheduledTime.toIso8601String(),
|
||||
'realTime': instance.realTime?.toIso8601String(),
|
||||
'delayMinutes': instance.delayMinutes,
|
||||
'track': instance.track,
|
||||
'realTrack': instance.realTrack,
|
||||
'cancelled': instance.cancelled,
|
||||
'reachable': instance.reachable,
|
||||
'product': instance.product,
|
||||
'journeyRef': instance.journeyRef,
|
||||
};
|
||||
|
||||
_Arrival _$ArrivalFromJson(Map<String, dynamic> json) => _Arrival(
|
||||
stopId: json['stopId'] as String,
|
||||
stopExtId: json['stopExtId'] as String?,
|
||||
stopName: json['stopName'] as String,
|
||||
name: json['name'] as String,
|
||||
origin: json['origin'] as String,
|
||||
scheduledTime: DateTime.parse(json['scheduledTime'] as String),
|
||||
realTime: json['realTime'] == null
|
||||
? null
|
||||
: DateTime.parse(json['realTime'] as String),
|
||||
delayMinutes: (json['delayMinutes'] as num?)?.toInt(),
|
||||
track: json['track'] as String?,
|
||||
realTrack: json['realTrack'] as String?,
|
||||
cancelled: json['cancelled'] as bool? ?? false,
|
||||
product: json['product'] == null
|
||||
? null
|
||||
: Product.fromJson(json['product'] as Map<String, dynamic>),
|
||||
journeyRef: json['journeyRef'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ArrivalToJson(_Arrival instance) => <String, dynamic>{
|
||||
'stopId': instance.stopId,
|
||||
'stopExtId': instance.stopExtId,
|
||||
'stopName': instance.stopName,
|
||||
'name': instance.name,
|
||||
'origin': instance.origin,
|
||||
'scheduledTime': instance.scheduledTime.toIso8601String(),
|
||||
'realTime': instance.realTime?.toIso8601String(),
|
||||
'delayMinutes': instance.delayMinutes,
|
||||
'track': instance.track,
|
||||
'realTrack': instance.realTrack,
|
||||
'cancelled': instance.cancelled,
|
||||
'product': instance.product,
|
||||
'journeyRef': instance.journeyRef,
|
||||
};
|
||||
|
||||
_TripEndpoint _$TripEndpointFromJson(Map<String, dynamic> json) =>
|
||||
_TripEndpoint(
|
||||
stopId: json['stopId'] as String,
|
||||
stopExtId: json['stopExtId'] as String?,
|
||||
name: json['name'] as String,
|
||||
lat: (json['lat'] as num?)?.toDouble(),
|
||||
lon: (json['lon'] as num?)?.toDouble(),
|
||||
scheduledTime: DateTime.parse(json['scheduledTime'] as String),
|
||||
realTime: json['realTime'] == null
|
||||
? null
|
||||
: DateTime.parse(json['realTime'] as String),
|
||||
delayMinutes: (json['delayMinutes'] as num?)?.toInt(),
|
||||
track: json['track'] as String?,
|
||||
realTrack: json['realTrack'] as String?,
|
||||
type: json['type'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$TripEndpointToJson(_TripEndpoint instance) =>
|
||||
<String, dynamic>{
|
||||
'stopId': instance.stopId,
|
||||
'stopExtId': instance.stopExtId,
|
||||
'name': instance.name,
|
||||
'lat': instance.lat,
|
||||
'lon': instance.lon,
|
||||
'scheduledTime': instance.scheduledTime.toIso8601String(),
|
||||
'realTime': instance.realTime?.toIso8601String(),
|
||||
'delayMinutes': instance.delayMinutes,
|
||||
'track': instance.track,
|
||||
'realTrack': instance.realTrack,
|
||||
'type': instance.type,
|
||||
};
|
||||
|
||||
_JourneyStop _$JourneyStopFromJson(Map<String, dynamic> json) => _JourneyStop(
|
||||
id: json['id'] as String,
|
||||
extId: json['extId'] as String?,
|
||||
name: json['name'] as String,
|
||||
lat: (json['lat'] as num?)?.toDouble(),
|
||||
lon: (json['lon'] as num?)?.toDouble(),
|
||||
routeIdx: (json['routeIdx'] as num?)?.toInt(),
|
||||
scheduledArrival: json['scheduledArrival'] == null
|
||||
? null
|
||||
: DateTime.parse(json['scheduledArrival'] as String),
|
||||
scheduledDeparture: json['scheduledDeparture'] == null
|
||||
? null
|
||||
: DateTime.parse(json['scheduledDeparture'] as String),
|
||||
realArrival: json['realArrival'] == null
|
||||
? null
|
||||
: DateTime.parse(json['realArrival'] as String),
|
||||
realDeparture: json['realDeparture'] == null
|
||||
? null
|
||||
: DateTime.parse(json['realDeparture'] as String),
|
||||
arrTrack: json['arrTrack'] as String?,
|
||||
depTrack: json['depTrack'] as String?,
|
||||
realArrTrack: json['realArrTrack'] as String?,
|
||||
realDepTrack: json['realDepTrack'] as String?,
|
||||
cancelled: json['cancelled'] as bool? ?? false,
|
||||
cancelledArrival: json['cancelledArrival'] as bool? ?? false,
|
||||
cancelledDeparture: json['cancelledDeparture'] as bool? ?? false,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$JourneyStopToJson(_JourneyStop instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'extId': instance.extId,
|
||||
'name': instance.name,
|
||||
'lat': instance.lat,
|
||||
'lon': instance.lon,
|
||||
'routeIdx': instance.routeIdx,
|
||||
'scheduledArrival': instance.scheduledArrival?.toIso8601String(),
|
||||
'scheduledDeparture': instance.scheduledDeparture?.toIso8601String(),
|
||||
'realArrival': instance.realArrival?.toIso8601String(),
|
||||
'realDeparture': instance.realDeparture?.toIso8601String(),
|
||||
'arrTrack': instance.arrTrack,
|
||||
'depTrack': instance.depTrack,
|
||||
'realArrTrack': instance.realArrTrack,
|
||||
'realDepTrack': instance.realDepTrack,
|
||||
'cancelled': instance.cancelled,
|
||||
'cancelledArrival': instance.cancelledArrival,
|
||||
'cancelledDeparture': instance.cancelledDeparture,
|
||||
};
|
||||
|
||||
_Leg _$LegFromJson(Map<String, dynamic> json) => _Leg(
|
||||
id: json['id'] as String,
|
||||
idx: (json['idx'] as num).toInt(),
|
||||
type: $enumDecodeNullable(_$LegTypeEnumMap, json['type']) ?? LegType.unknown,
|
||||
name: json['name'] as String?,
|
||||
category: json['category'] as String?,
|
||||
number: json['number'] as String?,
|
||||
direction: json['direction'] as String?,
|
||||
origin: TripEndpoint.fromJson(json['origin'] as Map<String, dynamic>),
|
||||
destination: TripEndpoint.fromJson(
|
||||
json['destination'] as Map<String, dynamic>,
|
||||
),
|
||||
duration: IsoDuration.fromJson(json['duration'] as String?),
|
||||
cancelled: json['cancelled'] as bool? ?? false,
|
||||
partCancelled: json['partCancelled'] as bool? ?? false,
|
||||
reachable: json['reachable'] as bool? ?? true,
|
||||
product: json['product'] == null
|
||||
? null
|
||||
: Product.fromJson(json['product'] as Map<String, dynamic>),
|
||||
journeyRef: json['journeyRef'] as String?,
|
||||
stops:
|
||||
(json['stops'] as List<dynamic>?)
|
||||
?.map((e) => JourneyStop.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
const <JourneyStop>[],
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$LegToJson(_Leg instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'idx': instance.idx,
|
||||
'type': _$LegTypeEnumMap[instance.type]!,
|
||||
'name': instance.name,
|
||||
'category': instance.category,
|
||||
'number': instance.number,
|
||||
'direction': instance.direction,
|
||||
'origin': instance.origin,
|
||||
'destination': instance.destination,
|
||||
'duration': IsoDuration.toJson(instance.duration),
|
||||
'cancelled': instance.cancelled,
|
||||
'partCancelled': instance.partCancelled,
|
||||
'reachable': instance.reachable,
|
||||
'product': instance.product,
|
||||
'journeyRef': instance.journeyRef,
|
||||
'stops': instance.stops,
|
||||
};
|
||||
|
||||
const _$LegTypeEnumMap = {
|
||||
LegType.journey: 'JOURNEY',
|
||||
LegType.walk: 'WALK',
|
||||
LegType.transfer: 'TRANSFER',
|
||||
LegType.bike: 'BIKE',
|
||||
LegType.car: 'CAR',
|
||||
LegType.parkRide: 'PARK_RIDE',
|
||||
LegType.taxi: 'TAXI',
|
||||
LegType.checkIn: 'CHECK_IN',
|
||||
LegType.checkOut: 'CHECK_OUT',
|
||||
LegType.dummy: 'DUMMY',
|
||||
LegType.unknown: 'UNKNOWN',
|
||||
};
|
||||
|
||||
_Trip _$TripFromJson(Map<String, dynamic> json) => _Trip(
|
||||
tripId: json['tripId'] as String?,
|
||||
ctxRecon: json['ctxRecon'] as String?,
|
||||
checksum: json['checksum'] as String?,
|
||||
duration: IsoDuration.fromJson(json['duration'] as String?),
|
||||
realDuration: IsoDuration.fromJson(json['realDuration'] as String?),
|
||||
transferCount: (json['transferCount'] as num?)?.toInt(),
|
||||
legs:
|
||||
(json['legs'] as List<dynamic>?)
|
||||
?.map((e) => Leg.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
const <Leg>[],
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$TripToJson(_Trip instance) => <String, dynamic>{
|
||||
'tripId': instance.tripId,
|
||||
'ctxRecon': instance.ctxRecon,
|
||||
'checksum': instance.checksum,
|
||||
'duration': IsoDuration.toJson(instance.duration),
|
||||
'realDuration': IsoDuration.toJson(instance.realDuration),
|
||||
'transferCount': instance.transferCount,
|
||||
'legs': instance.legs,
|
||||
};
|
||||
|
||||
_TripSearchResult _$TripSearchResultFromJson(Map<String, dynamic> json) =>
|
||||
_TripSearchResult(
|
||||
trips:
|
||||
(json['trips'] as List<dynamic>?)
|
||||
?.map((e) => Trip.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
const <Trip>[],
|
||||
scrollContextLater: json['scrollContextLater'] as String?,
|
||||
scrollContextEarlier: json['scrollContextEarlier'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$TripSearchResultToJson(_TripSearchResult instance) =>
|
||||
<String, dynamic>{
|
||||
'trips': instance.trips,
|
||||
'scrollContextLater': instance.scrollContextLater,
|
||||
'scrollContextEarlier': instance.scrollContextEarlier,
|
||||
};
|
||||
|
||||
_JourneyDetail _$JourneyDetailFromJson(Map<String, dynamic> json) =>
|
||||
_JourneyDetail(
|
||||
journeyId: json['journeyId'] as String?,
|
||||
product: json['product'] == null
|
||||
? null
|
||||
: Product.fromJson(json['product'] as Map<String, dynamic>),
|
||||
direction: json['direction'] as String?,
|
||||
stops:
|
||||
(json['stops'] as List<dynamic>?)
|
||||
?.map((e) => JourneyStop.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
const <JourneyStop>[],
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$JourneyDetailToJson(_JourneyDetail instance) =>
|
||||
<String, dynamic>{
|
||||
'journeyId': instance.journeyId,
|
||||
'product': instance.product,
|
||||
'direction': instance.direction,
|
||||
'stops': instance.stops,
|
||||
};
|
||||
|
||||
_HimMessage _$HimMessageFromJson(Map<String, dynamic> json) => _HimMessage(
|
||||
id: json['id'] as String,
|
||||
externalId: json['externalId'] as String?,
|
||||
head: json['head'] as String?,
|
||||
lead: json['lead'] as String?,
|
||||
text: json['text'] as String?,
|
||||
category: json['category'] as String?,
|
||||
company: json['company'] as String?,
|
||||
priority: (json['priority'] as num?)?.toInt(),
|
||||
products: (json['products'] as num?)?.toInt(),
|
||||
startValidity: json['startValidity'] == null
|
||||
? null
|
||||
: DateTime.parse(json['startValidity'] as String),
|
||||
endValidity: json['endValidity'] == null
|
||||
? null
|
||||
: DateTime.parse(json['endValidity'] as String),
|
||||
modified: json['modified'] == null
|
||||
? null
|
||||
: DateTime.parse(json['modified'] as String),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$HimMessageToJson(_HimMessage instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'externalId': instance.externalId,
|
||||
'head': instance.head,
|
||||
'lead': instance.lead,
|
||||
'text': instance.text,
|
||||
'category': instance.category,
|
||||
'company': instance.company,
|
||||
'priority': instance.priority,
|
||||
'products': instance.products,
|
||||
'startValidity': instance.startValidity?.toIso8601String(),
|
||||
'endValidity': instance.endValidity?.toIso8601String(),
|
||||
'modified': instance.modified?.toIso8601String(),
|
||||
};
|
||||
Reference in New Issue
Block a user