ionic-planb-logistic-app-fl.../lib/services/navigation_session_service.dart
Jean-Philippe Brule d8bdaed63e Upgrade Flutter packages and fix breaking changes for Riverpod 3.0
Major package upgrades:
- Riverpod 2.x → 3.0.3 (breaking changes)
- flutter_appauth 7.0.0 → 11.0.0
- go_router 14.0.0 → 17.0.0
- permission_handler 11.3.0 → 12.0.1
- flutter_lints 5.0.0 → 6.0.0
- animate_do 3.1.2 → 4.2.0
- Plus 41 transitive dependency updates

Breaking changes fixed:

Riverpod 3.0 migration:
- Replace StateProvider with NotifierProvider pattern
- Update .valueOrNull to proper async value handling with .future
- Create LanguageNotifier and ThemeModeNotifier classes
- Fix all provider async value access patterns

Google Maps Navigation API updates:
- Rename GoogleMapsNavigationViewController to GoogleNavigationViewController
- Update Waypoint to NavigationWaypoint.withLatLngTarget
- Migrate controller methods to static GoogleMapsNavigator methods
- Update event listener types and callbacks

Localization system fixes:
- Update l10n.yaml synthetic-package configuration
- Fix import paths from flutter_gen to package imports
- Add errorTitle translation key for both en/fr
- Remove unnecessary null-aware operators (AppLocalizations is non-nullable)
- Regenerate localization files

iOS/macOS configuration:
- Update CocoaPods dependencies (AppAuth 1.7.5 → 2.0.0)
- Create missing Profile.xcconfig files for both platforms
- Sync Podfile.lock files with updated dependencies

Code quality:
- Fix all analyzer errors (0 errors remaining)
- Resolve deprecated API usage warnings
- Update async/await patterns for better error handling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 01:25:16 -05:00

193 lines
5.0 KiB
Dart

import 'package:google_navigation_flutter/google_navigation_flutter.dart';
class NavigationSessionService {
static final NavigationSessionService _instance =
NavigationSessionService._internal();
factory NavigationSessionService() {
return _instance;
}
NavigationSessionService._internal();
bool _isSessionInitialized = false;
GoogleNavigationViewController? _controller;
bool get isSessionInitialized => _isSessionInitialized;
Future<void> initializeSession() async {
if (_isSessionInitialized) {
return;
}
try {
await GoogleMapsNavigator.initializeNavigationSession();
_isSessionInitialized = true;
} catch (e) {
throw NavigationSessionException('Failed to initialize session: $e');
}
}
Future<void> setController(
GoogleNavigationViewController controller,
) async {
_controller = controller;
}
Future<NavigationRoute> calculateRoute({
required double startLatitude,
required double startLongitude,
required double destinationLatitude,
required double destinationLongitude,
}) async {
if (!_isSessionInitialized) {
throw NavigationSessionException('Session not initialized');
}
if (_controller == null) {
throw NavigationSessionException('Controller not set');
}
try {
final origin = LatLng(
latitude: startLatitude,
longitude: startLongitude,
);
final destination = LatLng(
latitude: destinationLatitude,
longitude: destinationLongitude,
);
final waypoint = NavigationWaypoint.withLatLngTarget(
title: 'Destination',
target: destination,
);
final destinations = Destinations(
waypoints: [waypoint],
displayOptions: NavigationDisplayOptions(showDestinationMarkers: true),
);
// Set destinations will trigger route calculation
await GoogleMapsNavigator.setDestinations(destinations);
return NavigationRoute(
startLocation: origin,
endLocation: destination,
isCalculated: true,
);
} catch (e) {
throw NavigationSessionException('Failed to calculate route: $e');
}
}
Future<void> startNavigation() async {
if (!_isSessionInitialized) {
throw NavigationSessionException('Navigation not properly initialized');
}
try {
await GoogleMapsNavigator.startGuidance();
} catch (e) {
throw NavigationSessionException('Failed to start navigation: $e');
}
}
Future<void> stopNavigation() async {
if (!_isSessionInitialized) {
return;
}
try {
await GoogleMapsNavigator.stopGuidance();
} catch (e) {
throw NavigationSessionException('Failed to stop navigation: $e');
}
}
void addLocationListener(
Function(RoadSnappedLocationUpdatedEvent event) onLocationUpdate,
) {
if (!_isSessionInitialized) {
throw NavigationSessionException('Navigation not initialized');
}
GoogleMapsNavigator.setRoadSnappedLocationUpdatedListener((event) {
onLocationUpdate(event);
});
}
void addArrivalListener(Function(OnArrivalEvent event) onArrival) {
if (!_isSessionInitialized) {
throw NavigationSessionException('Navigation not initialized');
}
GoogleMapsNavigator.setOnArrivalListener((event) {
onArrival(event);
});
}
// Note: Remaining distance listener API may vary by version
// This is a placeholder for future implementation
void addRemainingDistanceListener(
Function(dynamic event) onDistanceChange,
) {
if (!_isSessionInitialized) {
throw NavigationSessionException('Navigation not initialized');
}
// TODO: Implement when correct API is available
// GoogleMapsNavigator does not expose a public remaining distance listener
}
void clearAllListeners() {
if (!_isSessionInitialized) {
return;
}
// Clear listeners by setting them to empty callbacks
// Note: The API doesn't support null, so we use no-op callbacks
GoogleMapsNavigator.setRoadSnappedLocationUpdatedListener((_) {});
GoogleMapsNavigator.setOnArrivalListener((_) {});
}
Future<void> cleanup() async {
try {
if (_isSessionInitialized) {
await stopNavigation();
clearAllListeners();
await GoogleMapsNavigator.cleanup();
}
_isSessionInitialized = false;
_controller = null;
} catch (e) {
throw NavigationSessionException('Failed to cleanup: $e');
}
}
}
class NavigationRoute {
final LatLng startLocation;
final LatLng endLocation;
final bool isCalculated;
final int? distanceMeters;
final Duration? estimatedTime;
NavigationRoute({
required this.startLocation,
required this.endLocation,
required this.isCalculated,
this.distanceMeters,
this.estimatedTime,
});
}
class NavigationSessionException implements Exception {
final String message;
NavigationSessionException(this.message);
@override
String toString() => 'NavigationSessionException: $message';
}