implemented RMV commute integration in the timetable, added Nominatim geocoding for home station lookup, created CommuteCubit for daily trip management with TTL caching, and introduced specialized timetable tiles, detail sheets, and settings for transit connections and walking buffers

This commit is contained in:
2026-05-20 22:50:57 +02:00
parent 067012cc84
commit 46d6b3410e
20 changed files with 1513 additions and 20 deletions
@@ -0,0 +1,40 @@
import '../../../../../api/connect/rmv/queries/search_stops.dart';
import '../../../../../api/connect/rmv/rmv_models.dart';
import '../../../../../state/app/modules/rmv/repository/rmv_repository.dart';
class CommuteRepository {
final RmvRepository _rmv = RmvRepository();
/// Trip search wrapper. Morning runs use `byArrival=true` with the latest
/// acceptable arrival time; evening runs use `byArrival=false` with the
/// earliest acceptable departure time.
Future<List<Trip>> findTrips({
required StopLocation from,
required StopLocation to,
required DateTime when,
required bool byArrival,
int max = 3,
}) async {
final result = await _rmv.searchTrips(
fromStopId: from.id,
toStopId: to.id,
when: when,
searchByArrival: byArrival,
);
if (result.trips.length <= max) return result.trips;
return result.trips.sublist(0, max);
}
/// Best-effort default school station lookup. Used the first time the user
/// activates the commute toggle, before they've had a chance to pick one
/// manually. Returns the first hit whose name contains "Marianum", or
/// just the first hit, or `null` if the search returned nothing.
Future<StopLocation?> resolveDefaultSchoolStation() async {
final results = await SearchStops(query: 'Marianum Fulda', max: 5).run();
if (results.isEmpty) return null;
final marianum = results.where(
(s) => s.name.toLowerCase().contains('marianum'),
);
return marianum.isNotEmpty ? marianum.first : results.first;
}
}