mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-05-15 21:48:18 +02:00
more status indicator improvements
This commit is contained in:
@@ -136,15 +136,11 @@ class MapDataProvider {
|
||||
|
||||
// AUTO (default): try local first, then remote if not offline
|
||||
try {
|
||||
debugPrint('[MapDataProvider] Trying local tile $z/$x/$y (offline: $offline)');
|
||||
return await fetchLocalTile(z: z, x: x, y: y);
|
||||
} catch (e) {
|
||||
debugPrint('[MapDataProvider] Local tile $z/$x/$y failed: $e');
|
||||
} catch (_) {
|
||||
if (!offline) {
|
||||
debugPrint('[MapDataProvider] Falling back to remote for $z/$x/$y');
|
||||
return _fetchRemoteTileFromCurrentProvider(z, x, y);
|
||||
} else {
|
||||
debugPrint('[MapDataProvider] Offline mode - no fallback for $z/$x/$y');
|
||||
throw OfflineModeException("Tile $z/$x/$y not found in offline areas and offline mode is enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'dart:async';
|
||||
import '../app_state.dart';
|
||||
|
||||
enum NetworkIssueType { osmTiles, overpassApi, both }
|
||||
enum NetworkStatusType { waiting, issues, timedOut, noData, ready }
|
||||
enum NetworkStatusType { waiting, issues, timedOut, noData, ready, success }
|
||||
|
||||
class NetworkStatus extends ChangeNotifier {
|
||||
static final NetworkStatus instance = NetworkStatus._();
|
||||
@@ -15,11 +15,13 @@ class NetworkStatus extends ChangeNotifier {
|
||||
bool _isWaitingForData = false;
|
||||
bool _isTimedOut = false;
|
||||
bool _hasNoData = false;
|
||||
bool _hasSuccess = false;
|
||||
int _recentOfflineMisses = 0;
|
||||
Timer? _osmRecoveryTimer;
|
||||
Timer? _overpassRecoveryTimer;
|
||||
Timer? _waitingTimer;
|
||||
Timer? _noDataResetTimer;
|
||||
Timer? _successResetTimer;
|
||||
|
||||
// Getters
|
||||
bool get hasAnyIssues => _osmTilesHaveIssues || _overpassHasIssues;
|
||||
@@ -28,12 +30,14 @@ class NetworkStatus extends ChangeNotifier {
|
||||
bool get isWaitingForData => _isWaitingForData;
|
||||
bool get isTimedOut => _isTimedOut;
|
||||
bool get hasNoData => _hasNoData;
|
||||
bool get hasSuccess => _hasSuccess;
|
||||
|
||||
NetworkStatusType get currentStatus {
|
||||
if (hasAnyIssues) return NetworkStatusType.issues;
|
||||
if (_isWaitingForData) return NetworkStatusType.waiting;
|
||||
if (_isTimedOut) return NetworkStatusType.timedOut;
|
||||
if (_hasNoData) return NetworkStatusType.noData;
|
||||
if (_hasSuccess) return NetworkStatusType.success;
|
||||
return NetworkStatusType.ready;
|
||||
}
|
||||
|
||||
@@ -122,17 +126,59 @@ class NetworkStatus extends ChangeNotifier {
|
||||
});
|
||||
}
|
||||
|
||||
/// Clear waiting/timeout/no-data status when data arrives
|
||||
/// Show success status briefly when data loads
|
||||
void setSuccess() {
|
||||
_isWaitingForData = false;
|
||||
_isTimedOut = false;
|
||||
_hasNoData = false;
|
||||
_hasSuccess = true;
|
||||
_recentOfflineMisses = 0;
|
||||
_waitingTimer?.cancel();
|
||||
_noDataResetTimer?.cancel();
|
||||
notifyListeners();
|
||||
|
||||
// Auto-clear success status after 2 seconds
|
||||
_successResetTimer?.cancel();
|
||||
_successResetTimer = Timer(const Duration(seconds: 2), () {
|
||||
if (_hasSuccess) {
|
||||
_hasSuccess = false;
|
||||
notifyListeners();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Show no-data status briefly when tiles aren't available
|
||||
void setNoData() {
|
||||
_isWaitingForData = false;
|
||||
_isTimedOut = false;
|
||||
_hasSuccess = false;
|
||||
_hasNoData = true;
|
||||
_waitingTimer?.cancel();
|
||||
_successResetTimer?.cancel();
|
||||
notifyListeners();
|
||||
|
||||
// Auto-clear no-data status after 2 seconds
|
||||
_noDataResetTimer?.cancel();
|
||||
_noDataResetTimer = Timer(const Duration(seconds: 2), () {
|
||||
if (_hasNoData) {
|
||||
_hasNoData = false;
|
||||
notifyListeners();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Clear waiting/timeout/no-data status (legacy method for compatibility)
|
||||
void clearWaiting() {
|
||||
if (_isWaitingForData || _isTimedOut || _hasNoData) {
|
||||
if (_isWaitingForData || _isTimedOut || _hasNoData || _hasSuccess) {
|
||||
_isWaitingForData = false;
|
||||
_isTimedOut = false;
|
||||
_hasNoData = false;
|
||||
_hasSuccess = false;
|
||||
_recentOfflineMisses = 0;
|
||||
_waitingTimer?.cancel();
|
||||
_noDataResetTimer?.cancel();
|
||||
_successResetTimer?.cancel();
|
||||
notifyListeners();
|
||||
// Quietly clear waiting status - don't log routine data arrival
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,20 +48,13 @@ class SimpleTileHttpClient extends http.BaseClient {
|
||||
}
|
||||
|
||||
Future<http.StreamedResponse> _handleTileRequest(int z, int x, int y) async {
|
||||
final startTime = DateTime.now();
|
||||
final isOffline = AppState.instance.offlineMode;
|
||||
debugPrint('[SimpleTileService] Requesting tile $z/$x/$y (offline: $isOffline)');
|
||||
|
||||
try {
|
||||
// Always go through MapDataProvider - it handles offline/online routing
|
||||
// MapDataProvider will get current provider from AppState
|
||||
final tileBytes = await _mapDataProvider.getTile(z: z, x: x, y: y, source: MapSource.auto);
|
||||
|
||||
final duration = DateTime.now().difference(startTime);
|
||||
debugPrint('[SimpleTileService] SUCCESS tile $z/$x/$y in ${duration.inMilliseconds}ms');
|
||||
|
||||
// Clear waiting status - we got data
|
||||
NetworkStatus.instance.clearWaiting();
|
||||
// Show success status briefly
|
||||
NetworkStatus.instance.setSuccess();
|
||||
|
||||
// Serve tile with proper cache headers
|
||||
return http.StreamedResponse(
|
||||
@@ -76,12 +69,10 @@ class SimpleTileHttpClient extends http.BaseClient {
|
||||
);
|
||||
|
||||
} catch (e) {
|
||||
final duration = DateTime.now().difference(startTime);
|
||||
debugPrint('[SimpleTileService] FAILED tile $z/$x/$y in ${duration.inMilliseconds}ms: $e');
|
||||
debugPrint('[SimpleTileService] Could not get tile $z/$x/$y: $e');
|
||||
|
||||
// 404 means no tiles available - clear waiting status
|
||||
// This is true whether we're online or offline
|
||||
NetworkStatus.instance.clearWaiting();
|
||||
// 404 means no tiles available - show "no data" status briefly
|
||||
NetworkStatus.instance.setNoData();
|
||||
|
||||
// Return 404 and let flutter_map handle it gracefully
|
||||
return http.StreamedResponse(
|
||||
|
||||
@@ -29,10 +29,16 @@ class NetworkStatusIndicator extends StatelessWidget {
|
||||
break;
|
||||
|
||||
case NetworkStatusType.noData:
|
||||
message = 'No offline data';
|
||||
message = 'No tiles here';
|
||||
icon = Icons.cloud_off;
|
||||
color = Colors.grey;
|
||||
break;
|
||||
|
||||
case NetworkStatusType.success:
|
||||
message = 'Tiles loaded';
|
||||
icon = Icons.check_circle;
|
||||
color = Colors.green;
|
||||
break;
|
||||
|
||||
case NetworkStatusType.issues:
|
||||
switch (networkStatus.currentIssueType) {
|
||||
|
||||
Reference in New Issue
Block a user