mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-02-12 16:52:51 +00:00
bump ver, get rid of buggy north-lock
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"1.2.6": {
|
||||
"1.2.7": {
|
||||
"content": "• NEW: Compass indicator shows map orientation and enables north-lock mode\n• Smart area caching: Loads 3x larger areas and refreshes data every 60 seconds for much faster browsing\n• Enhanced tile loading: Increased retry attempts with faster delays - tiles load much more reliably\n• Better network status: Simplified loading indicator logic\n• Instant node display: Surveillance devices now appear immediately when data finishes loading\n• Node limit alerts: Get notified when some nodes are not drawn"
|
||||
},
|
||||
"1.2.4": {
|
||||
|
||||
@@ -130,7 +130,7 @@ class AppState extends ChangeNotifier {
|
||||
int get maxCameras => _settingsState.maxCameras;
|
||||
UploadMode get uploadMode => _settingsState.uploadMode;
|
||||
FollowMeMode get followMeMode => _settingsState.followMeMode;
|
||||
bool get northLockEnabled => _settingsState.northLockEnabled;
|
||||
|
||||
bool get proximityAlertsEnabled => _settingsState.proximityAlertsEnabled;
|
||||
int get proximityAlertDistance => _settingsState.proximityAlertDistance;
|
||||
bool get networkStatusIndicatorEnabled => _settingsState.networkStatusIndicatorEnabled;
|
||||
@@ -411,10 +411,6 @@ class AppState extends ChangeNotifier {
|
||||
await _settingsState.setFollowMeMode(mode);
|
||||
}
|
||||
|
||||
Future<void> setNorthLockEnabled(bool enabled) async {
|
||||
await _settingsState.setNorthLockEnabled(enabled);
|
||||
}
|
||||
|
||||
/// Set proximity alerts enabled/disabled
|
||||
Future<void> setProximityAlertsEnabled(bool enabled) async {
|
||||
await _settingsState.setProximityAlertsEnabled(enabled);
|
||||
|
||||
@@ -69,8 +69,7 @@ const double kPreFetchAreaExpansionMultiplier = 3.0; // Expand visible bounds by
|
||||
const int kPreFetchZoomLevel = 10; // Always pre-fetch at this zoom level for consistent area sizes
|
||||
const int kMaxPreFetchSplitDepth = 3; // Maximum recursive splits when hitting Overpass node limit
|
||||
|
||||
// North lock configuration
|
||||
const double kNorthLockDisableThresholdDegrees = 10.0; // Rotation threshold to disable north lock (degrees)
|
||||
// Data refresh configuration
|
||||
const int kDataRefreshIntervalSeconds = 60; // Refresh cached data after this many seconds
|
||||
|
||||
// Follow-me mode smooth transitions
|
||||
|
||||
@@ -24,7 +24,6 @@ class SettingsState extends ChangeNotifier {
|
||||
static const String _selectedTileTypePrefsKey = 'selected_tile_type';
|
||||
static const String _legacyTestModePrefsKey = 'test_mode';
|
||||
static const String _followMeModePrefsKey = 'follow_me_mode';
|
||||
static const String _northLockEnabledPrefsKey = 'north_lock_enabled';
|
||||
static const String _proximityAlertsEnabledPrefsKey = 'proximity_alerts_enabled';
|
||||
static const String _proximityAlertDistancePrefsKey = 'proximity_alert_distance';
|
||||
static const String _networkStatusIndicatorEnabledPrefsKey = 'network_status_indicator_enabled';
|
||||
@@ -34,7 +33,6 @@ class SettingsState extends ChangeNotifier {
|
||||
int _maxCameras = 250;
|
||||
UploadMode _uploadMode = kEnableDevelopmentModes ? UploadMode.simulate : UploadMode.production;
|
||||
FollowMeMode _followMeMode = FollowMeMode.follow;
|
||||
bool _northLockEnabled = false;
|
||||
bool _proximityAlertsEnabled = false;
|
||||
int _proximityAlertDistance = kProximityAlertDefaultDistance;
|
||||
bool _networkStatusIndicatorEnabled = false;
|
||||
@@ -47,7 +45,6 @@ class SettingsState extends ChangeNotifier {
|
||||
int get maxCameras => _maxCameras;
|
||||
UploadMode get uploadMode => _uploadMode;
|
||||
FollowMeMode get followMeMode => _followMeMode;
|
||||
bool get northLockEnabled => _northLockEnabled;
|
||||
bool get proximityAlertsEnabled => _proximityAlertsEnabled;
|
||||
int get proximityAlertDistance => _proximityAlertDistance;
|
||||
bool get networkStatusIndicatorEnabled => _networkStatusIndicatorEnabled;
|
||||
@@ -100,9 +97,6 @@ class SettingsState extends ChangeNotifier {
|
||||
_maxCameras = prefs.getInt(_maxCamerasPrefsKey) ?? 250;
|
||||
}
|
||||
|
||||
// Load north lock enabled setting
|
||||
_northLockEnabled = prefs.getBool(_northLockEnabledPrefsKey) ?? false;
|
||||
|
||||
// Load proximity alerts settings
|
||||
_proximityAlertsEnabled = prefs.getBool(_proximityAlertsEnabledPrefsKey) ?? false;
|
||||
_proximityAlertDistance = prefs.getInt(_proximityAlertDistancePrefsKey) ?? kProximityAlertDefaultDistance;
|
||||
@@ -298,29 +292,12 @@ class SettingsState extends ChangeNotifier {
|
||||
if (_followMeMode != mode) {
|
||||
_followMeMode = mode;
|
||||
|
||||
// Disable north lock when switching to rotating mode (incompatible)
|
||||
if (mode == FollowMeMode.rotating && _northLockEnabled) {
|
||||
_northLockEnabled = false;
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setBool(_northLockEnabledPrefsKey, false);
|
||||
}
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setInt(_followMeModePrefsKey, mode.index);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
/// Set north lock enabled/disabled
|
||||
Future<void> setNorthLockEnabled(bool enabled) async {
|
||||
if (_northLockEnabled != enabled) {
|
||||
_northLockEnabled = enabled;
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setBool(_northLockEnabledPrefsKey, enabled);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
/// Set proximity alerts enabled/disabled
|
||||
Future<void> setProximityAlertsEnabled(bool enabled) async {
|
||||
if (_proximityAlertsEnabled != enabled) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:provider/provider.dart';
|
||||
|
||||
import '../app_state.dart';
|
||||
|
||||
/// A compass indicator widget that shows the current map rotation and allows tapping to enable/disable north lock.
|
||||
/// A compass indicator widget that shows the current map rotation and allows tapping to animate to north.
|
||||
/// The compass appears in the top-right corner of the map and is disabled (non-interactive) when in follow+rotate mode.
|
||||
class CompassIndicator extends StatefulWidget {
|
||||
final AnimatedMapController mapController;
|
||||
@@ -21,8 +21,6 @@ class CompassIndicator extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _CompassIndicatorState extends State<CompassIndicator> {
|
||||
double _lastRotation = 0.0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<AppState>(
|
||||
@@ -40,38 +38,23 @@ class _CompassIndicatorState extends State<CompassIndicator> {
|
||||
|
||||
// Check if we're in follow+rotate mode (compass should be disabled)
|
||||
final isDisabled = appState.followMeMode == FollowMeMode.rotating;
|
||||
final northLockEnabled = appState.northLockEnabled;
|
||||
|
||||
// Force rebuild when north lock changes by comparing rotation
|
||||
if (northLockEnabled && rotationDegrees != _lastRotation) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) setState(() {});
|
||||
});
|
||||
}
|
||||
_lastRotation = rotationDegrees;
|
||||
|
||||
return Positioned(
|
||||
top: (appState.uploadMode == UploadMode.sandbox || appState.uploadMode == UploadMode.simulate) ? 60 : 18,
|
||||
right: 16,
|
||||
child: GestureDetector(
|
||||
onTap: isDisabled ? null : () {
|
||||
// Toggle north lock (but not when in follow+rotate mode)
|
||||
final newNorthLockEnabled = !northLockEnabled;
|
||||
appState.setNorthLockEnabled(newNorthLockEnabled);
|
||||
|
||||
// If enabling north lock, animate to north-up orientation
|
||||
if (newNorthLockEnabled) {
|
||||
try {
|
||||
widget.mapController.animateTo(
|
||||
dest: widget.mapController.mapController.camera.center,
|
||||
zoom: widget.mapController.mapController.camera.zoom,
|
||||
rotation: 0.0,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
curve: Curves.easeOut,
|
||||
);
|
||||
} catch (_) {
|
||||
// Controller not ready, ignore
|
||||
}
|
||||
// Animate to north-up orientation
|
||||
try {
|
||||
widget.mapController.animateTo(
|
||||
dest: widget.mapController.mapController.camera.center,
|
||||
zoom: widget.mapController.mapController.camera.zoom,
|
||||
rotation: 0.0,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
curve: Curves.easeOut,
|
||||
);
|
||||
} catch (_) {
|
||||
// Controller not ready, ignore
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
@@ -85,10 +68,8 @@ class _CompassIndicatorState extends State<CompassIndicator> {
|
||||
border: Border.all(
|
||||
color: isDisabled
|
||||
? Colors.grey.shade400
|
||||
: (northLockEnabled
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Colors.grey.shade300),
|
||||
width: northLockEnabled ? 3.0 : 2.0,
|
||||
: Colors.grey.shade300,
|
||||
width: 2.0,
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
@@ -128,9 +109,7 @@ class _CompassIndicatorState extends State<CompassIndicator> {
|
||||
size: 20,
|
||||
color: isDisabled
|
||||
? Colors.grey.shade600
|
||||
: (northLockEnabled
|
||||
? Colors.red.shade700
|
||||
: Colors.red.shade600),
|
||||
: Colors.red.shade600,
|
||||
),
|
||||
),
|
||||
// Small 'N' label
|
||||
@@ -141,9 +120,7 @@ class _CompassIndicatorState extends State<CompassIndicator> {
|
||||
fontWeight: FontWeight.bold,
|
||||
color: isDisabled
|
||||
? Colors.grey.shade600
|
||||
: (northLockEnabled
|
||||
? Colors.red.shade700
|
||||
: Colors.red.shade600),
|
||||
: Colors.red.shade600,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -89,8 +89,7 @@ class GpsController {
|
||||
int proximityAlertDistance = 200,
|
||||
List<OsmNode> nearbyNodes = const [],
|
||||
List<NodeProfile> enabledProfiles = const [],
|
||||
// Optional parameter for north lock functionality
|
||||
bool northLockEnabled = false,
|
||||
|
||||
}) {
|
||||
final latLng = LatLng(position.latitude, position.longitude);
|
||||
_currentLatLng = latLng;
|
||||
@@ -114,12 +113,11 @@ class GpsController {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
try {
|
||||
if (followMeMode == FollowMeMode.follow) {
|
||||
// Follow position only, keep current rotation (unless north lock is enabled)
|
||||
final rotation = northLockEnabled ? 0.0 : controller.mapController.camera.rotation;
|
||||
// Follow position only, keep current rotation
|
||||
controller.animateTo(
|
||||
dest: latLng,
|
||||
zoom: controller.mapController.camera.zoom,
|
||||
rotation: rotation,
|
||||
rotation: controller.mapController.camera.rotation,
|
||||
duration: kFollowMeAnimationDuration,
|
||||
curve: Curves.easeOut,
|
||||
);
|
||||
@@ -157,7 +155,7 @@ class GpsController {
|
||||
required int Function() getProximityAlertDistance,
|
||||
required List<OsmNode> Function() getNearbyNodes,
|
||||
required List<NodeProfile> Function() getEnabledProfiles,
|
||||
required bool Function() getNorthLockEnabled,
|
||||
|
||||
}) async {
|
||||
final perm = await Geolocator.requestPermission();
|
||||
if (perm == LocationPermission.denied ||
|
||||
@@ -173,8 +171,6 @@ class GpsController {
|
||||
final proximityAlertDistance = getProximityAlertDistance();
|
||||
final nearbyNodes = getNearbyNodes();
|
||||
final enabledProfiles = getEnabledProfiles();
|
||||
final northLockEnabled = getNorthLockEnabled();
|
||||
|
||||
processPositionUpdate(
|
||||
position: position,
|
||||
followMeMode: currentFollowMeMode,
|
||||
@@ -184,7 +180,6 @@ class GpsController {
|
||||
proximityAlertDistance: proximityAlertDistance,
|
||||
nearbyNodes: nearbyNodes,
|
||||
enabledProfiles: enabledProfiles,
|
||||
northLockEnabled: northLockEnabled,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -74,8 +74,7 @@ class MapViewState extends State<MapView> {
|
||||
// Track map center to clear queue on significant panning
|
||||
LatLng? _lastCenter;
|
||||
|
||||
// Track rotation to detect intentional vs accidental rotation
|
||||
double? _lastRotation;
|
||||
|
||||
|
||||
// State for proximity alert banner
|
||||
bool _showProximityBanner = false;
|
||||
@@ -181,17 +180,7 @@ class MapViewState extends State<MapView> {
|
||||
}
|
||||
return [];
|
||||
},
|
||||
getNorthLockEnabled: () {
|
||||
if (mounted) {
|
||||
try {
|
||||
return context.read<AppState>().northLockEnabled;
|
||||
} catch (e) {
|
||||
debugPrint('[MapView] Could not read north lock enabled: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
);
|
||||
|
||||
// Fetch initial cameras
|
||||
@@ -561,41 +550,7 @@ class MapViewState extends State<MapView> {
|
||||
if (gesture) {
|
||||
widget.onUserGesture();
|
||||
|
||||
// Handle north lock: prevent rotation or disable lock if user rotates significantly
|
||||
if (appState.northLockEnabled) {
|
||||
try {
|
||||
final currentRotation = pos.rotation;
|
||||
if (_lastRotation != null) {
|
||||
// Calculate rotation change since last gesture
|
||||
final rotationChange = (currentRotation - _lastRotation!).abs();
|
||||
// If user tries to rotate significantly, disable north lock and allow it
|
||||
if (rotationChange > kNorthLockDisableThresholdDegrees) {
|
||||
appState.setNorthLockEnabled(false);
|
||||
// Allow this rotation to proceed
|
||||
} else {
|
||||
// Small rotation or zoom gesture - force map back to north (0°)
|
||||
if (currentRotation.abs() > 0.1) { // Only correct if actually rotated
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
try {
|
||||
_controller.animateTo(
|
||||
dest: pos.center,
|
||||
zoom: pos.zoom,
|
||||
rotation: 0.0,
|
||||
duration: const Duration(milliseconds: 100), // Quick snap back
|
||||
curve: Curves.easeOut,
|
||||
);
|
||||
} catch (_) {
|
||||
// Controller not ready, ignore
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
_lastRotation = currentRotation;
|
||||
} catch (_) {
|
||||
// Controller not ready, ignore
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (session != null) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: deflockapp
|
||||
description: Map public surveillance infrastructure with OpenStreetMap
|
||||
publish_to: "none"
|
||||
version: 1.2.6+5 # The thing after the + is the version code, incremented with each release
|
||||
version: 1.2.7+6 # The thing after the + is the version code, incremented with each release
|
||||
|
||||
environment:
|
||||
sdk: ">=3.5.0 <4.0.0" # oauth2_client 4.x needs Dart 3.5+
|
||||
|
||||
Reference in New Issue
Block a user