maps/mobile/lib/features/routing/providers/routing_provider.dart
2026-03-31 21:01:08 +02:00

137 lines
3.5 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../data/routing_repository.dart';
class RoutingState {
final double? originLat;
final double? originLon;
final String originName;
final double? destLat;
final double? destLon;
final String destName;
final String profile; // driving, walking, cycling
final List<RouteData> routes;
final int selectedRouteIndex;
final bool isLoading;
final String? error;
const RoutingState({
this.originLat,
this.originLon,
this.originName = 'My Location',
this.destLat,
this.destLon,
this.destName = '',
this.profile = 'driving',
this.routes = const [],
this.selectedRouteIndex = 0,
this.isLoading = false,
this.error,
});
RoutingState copyWith({
double? originLat,
double? originLon,
String? originName,
double? destLat,
double? destLon,
String? destName,
String? profile,
List<RouteData>? routes,
int? selectedRouteIndex,
bool? isLoading,
String? error,
bool clearError = false,
}) {
return RoutingState(
originLat: originLat ?? this.originLat,
originLon: originLon ?? this.originLon,
originName: originName ?? this.originName,
destLat: destLat ?? this.destLat,
destLon: destLon ?? this.destLon,
destName: destName ?? this.destName,
profile: profile ?? this.profile,
routes: routes ?? this.routes,
selectedRouteIndex: selectedRouteIndex ?? this.selectedRouteIndex,
isLoading: isLoading ?? this.isLoading,
error: clearError ? null : (error ?? this.error),
);
}
RouteData? get selectedRoute =>
routes.isNotEmpty && selectedRouteIndex < routes.length
? routes[selectedRouteIndex]
: null;
}
class RoutingNotifier extends Notifier<RoutingState> {
late RoutingRepository _repository;
@override
RoutingState build() {
_repository = ref.watch(routingRepositoryProvider);
return const RoutingState();
}
void setOrigin(double lat, double lon, String name) {
state = state.copyWith(
originLat: lat,
originLon: lon,
originName: name,
routes: [],
);
}
void setDestination(double lat, double lon, String name) {
state = state.copyWith(
destLat: lat,
destLon: lon,
destName: name,
routes: [],
);
}
void setProfile(String profile) {
state = state.copyWith(profile: profile, routes: []);
}
void selectRoute(int index) {
state = state.copyWith(selectedRouteIndex: index);
}
Future<void> calculateRoute() async {
if (state.originLat == null ||
state.originLon == null ||
state.destLat == null ||
state.destLon == null) {
state = state.copyWith(error: 'Please set both origin and destination.');
return;
}
state = state.copyWith(isLoading: true, clearError: true, routes: []);
try {
final routes = await _repository.getRoute(
profile: state.profile,
originLat: state.originLat!,
originLon: state.originLon!,
destLat: state.destLat!,
destLon: state.destLon!,
);
state = state.copyWith(
routes: routes,
selectedRouteIndex: 0,
isLoading: false,
);
} catch (e) {
state = state.copyWith(
isLoading: false,
error: 'Could not calculate route. Please try again.',
);
}
}
}
final routingProvider =
NotifierProvider.autoDispose<RoutingNotifier, RoutingState>(
RoutingNotifier.new,
);