refactor follow me mode state handling

This commit is contained in:
stopflock
2025-08-29 11:08:50 -05:00
parent 42c03eca7d
commit c4c1505253
7 changed files with 81 additions and 103 deletions
+11 -15
View File
@@ -5,20 +5,16 @@ import 'package:geolocator/geolocator.dart';
import 'package:latlong2/latlong.dart';
import '../../dev_config.dart';
import '../../screens/home_screen.dart' show FollowMeMode;
import '../../app_state.dart' show FollowMeMode;
/// Manages GPS location tracking, follow-me modes, and location-based map animations.
/// Handles GPS permissions, position streams, and follow-me behavior.
class GpsController {
StreamSubscription<Position>? _positionSub;
LatLng? _currentLatLng;
FollowMeMode _currentFollowMeMode = FollowMeMode.off;
/// Get the current GPS location (if available)
LatLng? get currentLocation => _currentLatLng;
/// Get the current follow-me mode
FollowMeMode get currentFollowMeMode => _currentFollowMeMode;
/// Initialize GPS location tracking
Future<void> initializeLocation() async {
@@ -48,8 +44,6 @@ class GpsController {
required FollowMeMode oldMode,
required AnimatedMapController controller,
}) {
// Update the stored follow-me mode
_currentFollowMeMode = newMode;
debugPrint('[GpsController] Follow-me mode changed: $oldMode$newMode');
// Only act when follow-me is first enabled and we have a current location
@@ -84,6 +78,7 @@ class GpsController {
/// Process GPS position updates and handle follow-me animations
void processPositionUpdate({
required Position position,
required FollowMeMode followMeMode,
required AnimatedMapController controller,
required VoidCallback onLocationUpdated,
}) {
@@ -93,12 +88,12 @@ class GpsController {
// Notify that location was updated (for setState, etc.)
onLocationUpdated();
// Handle follow-me animations if enabled - use current stored mode, not parameter
if (_currentFollowMeMode != FollowMeMode.off) {
debugPrint('[GpsController] GPS position update: ${latLng.latitude}, ${latLng.longitude}, follow-me: $_currentFollowMeMode');
// Handle follow-me animations if enabled - use current mode from app state
if (followMeMode != FollowMeMode.off) {
debugPrint('[GpsController] GPS position update: ${latLng.latitude}, ${latLng.longitude}, follow-me: $followMeMode');
WidgetsBinding.instance.addPostFrameCallback((_) {
try {
if (_currentFollowMeMode == FollowMeMode.northUp) {
if (followMeMode == FollowMeMode.northUp) {
// Follow position only, keep current rotation
controller.animateTo(
dest: latLng,
@@ -106,7 +101,7 @@ class GpsController {
duration: kFollowMeAnimationDuration,
curve: Curves.easeOut,
);
} else if (_currentFollowMeMode == FollowMeMode.rotating) {
} else if (followMeMode == FollowMeMode.rotating) {
// Follow position and rotation based on heading
final heading = position.heading;
final speed = position.speed; // Speed in m/s
@@ -135,10 +130,8 @@ class GpsController {
required FollowMeMode followMeMode,
required AnimatedMapController controller,
required VoidCallback onLocationUpdated,
required FollowMeMode Function() getCurrentFollowMeMode,
}) async {
// Store the initial follow-me mode
_currentFollowMeMode = followMeMode;
final perm = await Geolocator.requestPermission();
if (perm == LocationPermission.denied ||
perm == LocationPermission.deniedForever) {
@@ -147,8 +140,11 @@ class GpsController {
}
_positionSub = Geolocator.getPositionStream().listen((Position position) {
// Get the current follow-me mode from the app state each time
final currentFollowMeMode = getCurrentFollowMeMode();
processPositionUpdate(
position: position,
followMeMode: currentFollowMeMode,
controller: controller,
onLocationUpdated: onLocationUpdated,
);
+2 -28
View File
@@ -4,9 +4,9 @@ import 'package:latlong2/latlong.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../dev_config.dart';
import '../../screens/home_screen.dart' show FollowMeMode;
/// Manages map position persistence, initial positioning, and follow-me mode storage.
/// Manages map position persistence and initial positioning.
/// Handles saving/loading last map position and moving to initial locations.
class MapPositionManager {
LatLng? _initialLocation;
@@ -89,33 +89,7 @@ class MapPositionManager {
}
}
/// Save the follow-me mode to persistent storage
static Future<void> saveFollowMeMode(FollowMeMode mode) async {
try {
final prefs = await SharedPreferences.getInstance();
await prefs.setInt(kFollowMeModeKey, mode.index);
debugPrint('[MapPositionManager] Saved follow-me mode: $mode');
} catch (e) {
debugPrint('[MapPositionManager] Failed to save follow-me mode: $e');
}
}
/// Load the follow-me mode from persistent storage
static Future<FollowMeMode> loadFollowMeMode() async {
try {
final prefs = await SharedPreferences.getInstance();
final modeIndex = prefs.getInt(kFollowMeModeKey);
if (modeIndex != null && modeIndex < FollowMeMode.values.length) {
final mode = FollowMeMode.values[modeIndex];
debugPrint('[MapPositionManager] Loaded follow-me mode: $mode');
return mode;
}
} catch (e) {
debugPrint('[MapPositionManager] Failed to load follow-me mode: $e');
}
// Default to northUp if no saved mode
return FollowMeMode.northUp;
}
/// Clear any stored map position (useful for recovery from invalid data)
static Future<void> clearStoredMapPosition() async {
+13 -7
View File
@@ -21,7 +21,7 @@ import 'map/camera_refresh_controller.dart';
import 'map/gps_controller.dart';
import 'network_status_indicator.dart';
import '../dev_config.dart';
import '../screens/home_screen.dart' show FollowMeMode;
import '../app_state.dart' show FollowMeMode;
class MapView extends StatefulWidget {
final AnimatedMapController controller;
@@ -78,6 +78,18 @@ class MapViewState extends State<MapView> {
followMeMode: widget.followMeMode,
controller: _controller,
onLocationUpdated: () => setState(() {}),
getCurrentFollowMeMode: () {
// Use mounted check to avoid calling context when widget is disposed
if (mounted) {
try {
return context.read<AppState>().followMeMode;
} catch (e) {
debugPrint('[MapView] Could not read AppState, defaulting to off: $e');
return FollowMeMode.off;
}
}
return FollowMeMode.off;
},
);
// Fetch initial cameras
@@ -111,12 +123,6 @@ class MapViewState extends State<MapView> {
}
/// Expose static methods from MapPositionManager for external access
static Future<void> saveFollowMeMode(FollowMeMode mode) =>
MapPositionManager.saveFollowMeMode(mode);
static Future<FollowMeMode> loadFollowMeMode() =>
MapPositionManager.loadFollowMeMode();
static Future<void> clearStoredMapPosition() =>
MapPositionManager.clearStoredMapPosition();