diff --git a/lib/app_state.dart b/lib/app_state.dart index 17df856..6a18e6a 100644 --- a/lib/app_state.dart +++ b/lib/app_state.dart @@ -309,6 +309,14 @@ class AppState extends ChangeNotifier { void startRoute() { _navigationState.startRoute(); + + // Auto-enable follow-me if user is near the start point + // We need to get user location from the GPS controller + // This will be handled in HomeScreen where we have access to MapView + } + + bool shouldAutoEnableFollowMe(LatLng? userLocation) { + return _navigationState.shouldAutoEnableFollowMe(userLocation); } void showRouteOverview() { diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 1fefa29..b918627 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -174,7 +174,9 @@ class _HomeScreenState extends State with TickerProviderStateMixin { _navigationSheetHeight = height; }); }, - child: const NavigationSheet(), + child: NavigationSheet( + onStartRoute: _onStartRoute, + ), ), ); @@ -183,9 +185,34 @@ class _HomeScreenState extends State with TickerProviderStateMixin { setState(() { _navigationSheetHeight = 0.0; }); + + // If we're in route active mode and showing overview, reset the overview flag + // This fixes the stuck route button issue + final appState = context.read(); + if (appState.isInRouteMode && appState.showingOverview) { + debugPrint('[HomeScreen] Sheet dismissed during route overview - hiding overview'); + appState.hideRouteOverview(); + } }); } + void _onStartRoute() { + final appState = context.read(); + + // Get user location from MapView GPS controller and check if we should auto-enable follow-me + try { + final userLocation = _mapViewKey.currentState?.getUserLocation(); + if (userLocation != null && appState.shouldAutoEnableFollowMe(userLocation)) { + debugPrint('[HomeScreen] Auto-enabling follow-me mode - user within 1km of start'); + appState.setFollowMeMode(FollowMeMode.northUp); + } + } catch (e) { + debugPrint('[HomeScreen] Could not get user location for auto follow-me: $e'); + } + + appState.startRoute(); + } + void _onNavigationButtonPressed() { final appState = context.read(); diff --git a/lib/state/navigation_state.dart b/lib/state/navigation_state.dart index 7bc5339..e5af71a 100644 --- a/lib/state/navigation_state.dart +++ b/lib/state/navigation_state.dart @@ -227,6 +227,17 @@ class NavigationState extends ChangeNotifier { notifyListeners(); } + /// Check if user should auto-enable follow-me (called from outside with user location) + bool shouldAutoEnableFollowMe(LatLng? userLocation) { + if (userLocation == null || _routeStart == null) return false; + + final distanceToStart = const Distance().as(LengthUnit.Meter, userLocation, _routeStart!); + final shouldEnable = distanceToStart <= 1000; // Within 1km + + debugPrint('[NavigationState] Distance to start: ${distanceToStart.toStringAsFixed(0)}m, auto follow-me: $shouldEnable'); + return shouldEnable; + } + /// Show route overview (from route button during active navigation) void showRouteOverview() { if (_mode != AppNavigationMode.routeActive) return; diff --git a/lib/widgets/map_view.dart b/lib/widgets/map_view.dart index 965e5e0..93d6942 100644 --- a/lib/widgets/map_view.dart +++ b/lib/widgets/map_view.dart @@ -203,6 +203,11 @@ class MapViewState extends State { void retryLocationInit() { _gpsController.retryLocationInit(); } + + /// Get current user location + LatLng? getUserLocation() { + return _gpsController.currentLocation; + } /// Expose static methods from MapPositionManager for external access static Future clearStoredMapPosition() => @@ -390,7 +395,7 @@ class MapViewState extends State { } // Build start/end pins for route visualization - if (appState.showingOverview || appState.isInRouteMode) { + if (appState.showingOverview || appState.isInRouteMode || appState.isSettingSecondPoint) { if (appState.routeStart != null) { centerMarkers.add( Marker( @@ -415,13 +420,15 @@ class MapViewState extends State { // Build route path visualization final routeLines = []; - if (appState.routePath != null && appState.routePath!.length > 1 && - (appState.showingOverview || appState.isInRouteMode)) { - routeLines.add(Polyline( - points: appState.routePath!, - color: Colors.blue, - strokeWidth: 4.0, - )); + if (appState.routePath != null && appState.routePath!.length > 1) { + // Show route line during overview or active route + if (appState.showingOverview || appState.isInRouteMode) { + routeLines.add(Polyline( + points: appState.routePath!, + color: Colors.blue, + strokeWidth: 4.0, + )); + } } return Stack( diff --git a/lib/widgets/navigation_sheet.dart b/lib/widgets/navigation_sheet.dart index eff872e..dafd217 100644 --- a/lib/widgets/navigation_sheet.dart +++ b/lib/widgets/navigation_sheet.dart @@ -6,7 +6,12 @@ import 'package:latlong2/latlong.dart'; import '../app_state.dart'; class NavigationSheet extends StatelessWidget { - const NavigationSheet({super.key}); + final VoidCallback? onStartRoute; + + const NavigationSheet({ + super.key, + this.onStartRoute, + }); String _formatCoordinates(LatLng coordinates) { return '${coordinates.latitude.toStringAsFixed(6)}, ${coordinates.longitude.toStringAsFixed(6)}'; @@ -207,7 +212,7 @@ class NavigationSheet extends StatelessWidget { child: ElevatedButton.icon( icon: const Icon(Icons.play_arrow), label: const Text('Start'), - onPressed: () => appState.startRoute(), + onPressed: onStartRoute ?? () => appState.startRoute(), ), ), const SizedBox(width: 12),