add timed out status indicator

This commit is contained in:
stopflock
2025-08-23 19:49:19 -05:00
parent f45279ecfe
commit f11bd6e238
5 changed files with 96 additions and 19 deletions
+46
View File
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'dart:async';
enum NetworkIssueType { osmTiles, overpassApi, both }
enum NetworkStatusType { waiting, issues, timedOut, ready }
class NetworkStatus extends ChangeNotifier {
static final NetworkStatus instance = NetworkStatus._();
@@ -9,13 +10,25 @@ class NetworkStatus extends ChangeNotifier {
bool _osmTilesHaveIssues = false;
bool _overpassHasIssues = false;
bool _isWaitingForData = false;
bool _isTimedOut = false;
Timer? _osmRecoveryTimer;
Timer? _overpassRecoveryTimer;
Timer? _waitingTimer;
// Getters
bool get hasAnyIssues => _osmTilesHaveIssues || _overpassHasIssues;
bool get osmTilesHaveIssues => _osmTilesHaveIssues;
bool get overpassHasIssues => _overpassHasIssues;
bool get isWaitingForData => _isWaitingForData;
bool get isTimedOut => _isTimedOut;
NetworkStatusType get currentStatus {
if (hasAnyIssues) return NetworkStatusType.issues;
if (_isWaitingForData) return NetworkStatusType.waiting;
if (_isTimedOut) return NetworkStatusType.timedOut;
return NetworkStatusType.ready;
}
NetworkIssueType? get currentIssueType {
if (_osmTilesHaveIssues && _overpassHasIssues) return NetworkIssueType.both;
@@ -78,10 +91,43 @@ class NetworkStatus extends ChangeNotifier {
}
}
/// Set waiting status (show when loading tiles/cameras)
void setWaiting() {
// Clear any previous timeout state when starting new wait
_isTimedOut = false;
if (!_isWaitingForData) {
_isWaitingForData = true;
notifyListeners();
debugPrint('[NetworkStatus] Waiting for data...');
}
// Set timeout to show "timed out" status after reasonable time
_waitingTimer?.cancel();
_waitingTimer = Timer(const Duration(seconds: 10), () {
_isWaitingForData = false;
_isTimedOut = true;
notifyListeners();
debugPrint('[NetworkStatus] Data request timed out');
});
}
/// Clear waiting/timeout status when data arrives
void clearWaiting() {
if (_isWaitingForData || _isTimedOut) {
_isWaitingForData = false;
_isTimedOut = false;
_waitingTimer?.cancel();
notifyListeners();
debugPrint('[NetworkStatus] Waiting/timeout status cleared - data arrived');
}
}
@override
void dispose() {
_osmRecoveryTimer?.cancel();
_overpassRecoveryTimer?.cancel();
_waitingTimer?.cancel();
super.dispose();
}
}
+10 -1
View File
@@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart';
import '../app_state.dart';
import 'map_data_provider.dart';
import 'network_status.dart';
/// Simple HTTP client that routes tile requests through the centralized MapDataProvider.
/// This ensures all tile fetching (offline/online routing, retries, etc.) is in one place.
@@ -47,6 +48,9 @@ class SimpleTileHttpClient extends http.BaseClient {
debugPrint('[SimpleTileService] Serving tile $z/$x/$y from offline storage');
// Clear waiting status - we got data
NetworkStatus.instance.clearWaiting();
// Serve offline tile with proper cache headers
return http.StreamedResponse(
Stream.value(localTileBytes),
@@ -76,7 +80,12 @@ class SimpleTileHttpClient extends http.BaseClient {
// We're online - try OSM with proper error handling
debugPrint('[SimpleTileService] Online mode - trying OSM for $z/$x/$y');
try {
return await _inner.send(http.Request('GET', Uri.parse('https://tile.openstreetmap.org/$z/$x/$y.png')));
final response = await _inner.send(http.Request('GET', Uri.parse('https://tile.openstreetmap.org/$z/$x/$y.png')));
// Clear waiting status on successful network tile
if (response.statusCode == 200) {
NetworkStatus.instance.clearWaiting();
}
return response;
} catch (networkError) {
debugPrint('[SimpleTileService] OSM request failed for $z/$x/$y: $networkError');
// Return 404 instead of throwing - let flutter_map handle gracefully