diff --git a/README.md b/README.md index 692406f..b32e9ea 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ cp lib/keys.dart.example lib/keys.dart ### Needed Bugfixes - Upload queue processing is dook -- Node fetch network indicator claims timeout too early; need to wait for split requests and backoffs to resolve + - Ensure GPS/follow-me works after recent revamp (loses lock? have to move map for button state to update?) - Clean cache when nodes have been deleted by others - Are offline areas preferred for fast loading even when online? Check working. diff --git a/assets/changelog.json b/assets/changelog.json index a83281a..3937173 100644 --- a/assets/changelog.json +++ b/assets/changelog.json @@ -1,4 +1,11 @@ { + "2.2.1": { + "content": [ + "• Fixed network status indicator timing out prematurely while split requests were still loading", + "• Network status now accurately shows 'taking a while' when requests split or backoff, and only shows 'timed out' for actual network failures", + "• Removed artificial timeout timers in favor of reporting actual request status events" + ] + }, "2.2.0": { "content": [ "• Fixed follow-me sync issues where tracking would sometimes stop working after mode changes", diff --git a/lib/services/map_data_submodules/nodes_from_overpass.dart b/lib/services/map_data_submodules/nodes_from_overpass.dart index 99f9380..e8ed9af 100644 --- a/lib/services/map_data_submodules/nodes_from_overpass.dart +++ b/lib/services/map_data_submodules/nodes_from_overpass.dart @@ -78,6 +78,11 @@ Future> _fetchOverpassNodesWithSplitting({ // Rate limits should NOT be split - just fail with extended backoff debugPrint('[fetchOverpassNodes] Rate limited - using extended backoff, not splitting'); + // Report slow progress when backing off + if (reportStatus) { + NetworkStatus.instance.reportSlowProgress(); + } + // Wait longer for rate limits before giving up entirely await Future.delayed(const Duration(seconds: 30)); return []; // Return empty rather than rethrowing - let caller handle error reporting @@ -88,6 +93,11 @@ Future> _fetchOverpassNodesWithSplitting({ return []; // Return empty - let caller handle error reporting } + // Report slow progress when we start splitting (only at the top level) + if (reportStatus) { + NetworkStatus.instance.reportSlowProgress(); + } + // Split the bounds into 4 quadrants and try each separately debugPrint('[fetchOverpassNodes] Splitting area into quadrants (depth: $splitDepth)'); final quadrants = _splitBounds(bounds); diff --git a/lib/services/network_status.dart b/lib/services/network_status.dart index fd7db81..e930bde 100644 --- a/lib/services/network_status.dart +++ b/lib/services/network_status.dart @@ -19,7 +19,6 @@ class NetworkStatus extends ChangeNotifier { bool _hasSuccess = false; int _recentOfflineMisses = 0; Timer? _overpassRecoveryTimer; - Timer? _waitingTimer; Timer? _noDataResetTimer; Timer? _successResetTimer; // Getters @@ -72,7 +71,25 @@ class NetworkStatus extends ChangeNotifier { } } - /// Set waiting status (show when loading tiles/cameras) + /// Report that requests are taking longer than usual (splitting, backoffs, etc.) + void reportSlowProgress() { + if (!_overpassHasIssues) { + _overpassHasIssues = true; + _isWaitingForData = false; // Transition from waiting to slow progress + notifyListeners(); + debugPrint('[NetworkStatus] Surveillance data requests taking longer than usual'); + } + + // Reset recovery timer - we'll clear this when the operation actually completes + _overpassRecoveryTimer?.cancel(); + _overpassRecoveryTimer = Timer(const Duration(minutes: 2), () { + _overpassHasIssues = false; + notifyListeners(); + debugPrint('[NetworkStatus] Slow progress status cleared'); + }); + } + + /// Set waiting status (show when loading surveillance data) void setWaiting() { // Clear any previous timeout/no-data state when starting new wait _isTimedOut = false; @@ -83,17 +100,7 @@ class NetworkStatus extends ChangeNotifier { if (!_isWaitingForData) { _isWaitingForData = true; notifyListeners(); - // Don't log routine waiting - only log if we stay waiting too long } - - // Set timeout for genuine network issues (not 404s) - _waitingTimer?.cancel(); - _waitingTimer = Timer(const Duration(seconds: 8), () { - _isWaitingForData = false; - _isTimedOut = true; - debugPrint('[NetworkStatus] Request timed out - likely network issues'); - notifyListeners(); - }); } /// Show success status briefly when data loads @@ -103,7 +110,6 @@ class NetworkStatus extends ChangeNotifier { _hasNoData = false; _hasSuccess = true; _recentOfflineMisses = 0; - _waitingTimer?.cancel(); _noDataResetTimer?.cancel(); notifyListeners(); @@ -123,7 +129,6 @@ class NetworkStatus extends ChangeNotifier { _isTimedOut = false; _hasSuccess = false; _hasNoData = true; - _waitingTimer?.cancel(); _successResetTimer?.cancel(); notifyListeners(); @@ -145,7 +150,6 @@ class NetworkStatus extends ChangeNotifier { _hasNoData = false; _hasSuccess = false; _recentOfflineMisses = 0; - _waitingTimer?.cancel(); _noDataResetTimer?.cancel(); _successResetTimer?.cancel(); notifyListeners(); @@ -158,7 +162,6 @@ class NetworkStatus extends ChangeNotifier { _isTimedOut = true; _hasNoData = false; _hasSuccess = false; - _waitingTimer?.cancel(); _noDataResetTimer?.cancel(); _successResetTimer?.cancel(); notifyListeners(); @@ -179,7 +182,6 @@ class NetworkStatus extends ChangeNotifier { _isTimedOut = false; _hasNoData = false; _hasSuccess = false; - _waitingTimer?.cancel(); _noDataResetTimer?.cancel(); _successResetTimer?.cancel(); @@ -200,7 +202,6 @@ class NetworkStatus extends ChangeNotifier { _isWaitingForData = false; _isTimedOut = false; _hasNoData = true; - _waitingTimer?.cancel(); notifyListeners(); debugPrint('[NetworkStatus] No offline data available for this area'); } @@ -217,7 +218,6 @@ class NetworkStatus extends ChangeNotifier { @override void dispose() { _overpassRecoveryTimer?.cancel(); - _waitingTimer?.cancel(); _noDataResetTimer?.cancel(); _successResetTimer?.cancel(); super.dispose(); diff --git a/pubspec.yaml b/pubspec.yaml index 82f0dd3..77bf249 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: deflockapp description: Map public surveillance infrastructure with OpenStreetMap publish_to: "none" -version: 2.2.0+36 # The thing after the + is the version code, incremented with each release +version: 2.2.1+37 # 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+