mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-06-08 07:53:55 +02:00
ternary follow me
This commit is contained in:
@@ -10,6 +10,12 @@ import '../widgets/add_camera_sheet.dart';
|
||||
import '../widgets/camera_provider_with_cache.dart';
|
||||
import '../widgets/download_area_dialog.dart';
|
||||
|
||||
enum FollowMeMode {
|
||||
off, // No following
|
||||
northUp, // Follow position, keep north up
|
||||
rotating, // Follow position and rotation
|
||||
}
|
||||
|
||||
class HomeScreen extends StatefulWidget {
|
||||
const HomeScreen({super.key});
|
||||
|
||||
@@ -21,11 +27,44 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
final GlobalKey<MapViewState> _mapViewKey = GlobalKey<MapViewState>();
|
||||
final MapController _mapController = MapController();
|
||||
bool _followMe = true;
|
||||
FollowMeMode _followMeMode = FollowMeMode.northUp;
|
||||
|
||||
String _getFollowMeTooltip() {
|
||||
switch (_followMeMode) {
|
||||
case FollowMeMode.off:
|
||||
return 'Enable follow-me (north up)';
|
||||
case FollowMeMode.northUp:
|
||||
return 'Enable follow-me (rotating)';
|
||||
case FollowMeMode.rotating:
|
||||
return 'Disable follow-me';
|
||||
}
|
||||
}
|
||||
|
||||
IconData _getFollowMeIcon() {
|
||||
switch (_followMeMode) {
|
||||
case FollowMeMode.off:
|
||||
return Icons.gps_off;
|
||||
case FollowMeMode.northUp:
|
||||
return Icons.gps_fixed;
|
||||
case FollowMeMode.rotating:
|
||||
return Icons.navigation;
|
||||
}
|
||||
}
|
||||
|
||||
FollowMeMode _getNextFollowMeMode() {
|
||||
switch (_followMeMode) {
|
||||
case FollowMeMode.off:
|
||||
return FollowMeMode.northUp;
|
||||
case FollowMeMode.northUp:
|
||||
return FollowMeMode.rotating;
|
||||
case FollowMeMode.rotating:
|
||||
return FollowMeMode.off;
|
||||
}
|
||||
}
|
||||
|
||||
void _openAddCameraSheet() {
|
||||
// Disable follow-me when adding a camera so the map doesn't jump around
|
||||
setState(() => _followMe = false);
|
||||
setState(() => _followMeMode = FollowMeMode.off);
|
||||
|
||||
final appState = context.read<AppState>();
|
||||
appState.startAddSession();
|
||||
@@ -50,12 +89,14 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
title: const Text('Flock Map'),
|
||||
actions: [
|
||||
IconButton(
|
||||
tooltip: _followMe ? 'Disable follow‑me' : 'Enable follow‑me',
|
||||
icon: Icon(_followMe ? Icons.gps_fixed : Icons.gps_off),
|
||||
tooltip: _getFollowMeTooltip(),
|
||||
icon: Icon(_getFollowMeIcon()),
|
||||
onPressed: () {
|
||||
setState(() => _followMe = !_followMe);
|
||||
setState(() {
|
||||
_followMeMode = _getNextFollowMeMode();
|
||||
});
|
||||
// If enabling follow-me, retry location init in case permission was granted
|
||||
if (_followMe) {
|
||||
if (_followMeMode != FollowMeMode.off) {
|
||||
_mapViewKey.currentState?.retryLocationInit();
|
||||
}
|
||||
},
|
||||
@@ -71,9 +112,11 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
MapView(
|
||||
key: _mapViewKey,
|
||||
controller: _mapController,
|
||||
followMe: _followMe,
|
||||
followMeMode: _followMeMode,
|
||||
onUserGesture: () {
|
||||
if (_followMe) setState(() => _followMe = false);
|
||||
if (_followMeMode != FollowMeMode.off) {
|
||||
setState(() => _followMeMode = FollowMeMode.off);
|
||||
}
|
||||
},
|
||||
),
|
||||
Align(
|
||||
|
||||
+24
-13
@@ -22,16 +22,18 @@ import 'map/map_overlays.dart';
|
||||
import 'network_status_indicator.dart';
|
||||
import '../dev_config.dart';
|
||||
|
||||
import '../screens/home_screen.dart' show FollowMeMode;
|
||||
|
||||
class MapView extends StatefulWidget {
|
||||
final MapController controller;
|
||||
const MapView({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.followMe,
|
||||
required this.followMeMode,
|
||||
required this.onUserGesture,
|
||||
});
|
||||
|
||||
final bool followMe;
|
||||
final FollowMeMode followMeMode;
|
||||
final VoidCallback onUserGesture;
|
||||
|
||||
@override
|
||||
@@ -135,12 +137,16 @@ class MapViewState extends State<MapView> {
|
||||
@override
|
||||
void didUpdateWidget(covariant MapView oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.followMe && !oldWidget.followMe && _currentLatLng != null) {
|
||||
if (widget.followMeMode != FollowMeMode.off &&
|
||||
oldWidget.followMeMode == FollowMeMode.off &&
|
||||
_currentLatLng != null) {
|
||||
// Use smooth animation when follow me is first enabled
|
||||
_controller.animatedMove(
|
||||
_currentLatLng!,
|
||||
_controller.camera.zoom,
|
||||
);
|
||||
if (widget.followMeMode == FollowMeMode.northUp) {
|
||||
_controller.move(_currentLatLng!, _controller.camera.zoom);
|
||||
} else if (widget.followMeMode == FollowMeMode.rotating) {
|
||||
// When switching to rotating mode, reset to north-up first, then let GPS handle rotation
|
||||
_controller.moveAndRotate(_currentLatLng!, _controller.camera.zoom, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,15 +166,20 @@ class MapViewState extends State<MapView> {
|
||||
Geolocator.getPositionStream(locationSettings: locationSettings).listen((Position position) {
|
||||
final latLng = LatLng(position.latitude, position.longitude);
|
||||
setState(() => _currentLatLng = latLng);
|
||||
if (widget.followMe) {
|
||||
|
||||
if (widget.followMeMode != FollowMeMode.off) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
try {
|
||||
// Use smooth animation instead of instant jump
|
||||
_controller.animatedMove(
|
||||
latLng,
|
||||
_controller.camera.zoom,
|
||||
);
|
||||
if (widget.followMeMode == FollowMeMode.northUp) {
|
||||
// Follow position only, keep current rotation
|
||||
_controller.move(latLng, _controller.camera.zoom);
|
||||
} else if (widget.followMeMode == FollowMeMode.rotating) {
|
||||
// Follow position and rotation based on heading
|
||||
final heading = position.heading;
|
||||
final rotation = heading.isNaN ? 0.0 : -heading; // Convert to map rotation
|
||||
_controller.moveAndRotate(latLng, _controller.camera.zoom, rotation);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('MapController not ready yet: $e');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user