mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-05-23 16:49:55 +02:00
fixes tile re-rendering after long rate limit periods without having to zoom/pan
This commit is contained in:
@@ -63,6 +63,10 @@ class _MapViewState extends State<MapView> {
|
||||
|
||||
// Ensure initial overlays are fetched
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// Set up tile refresh callback
|
||||
final tileProvider = Provider.of<TileProviderWithCache>(context, listen: false);
|
||||
tileProvider.setOnTilesCachedCallback(_onTilesCached);
|
||||
|
||||
_refreshCamerasFromProvider();
|
||||
});
|
||||
}
|
||||
@@ -72,6 +76,15 @@ class _MapViewState extends State<MapView> {
|
||||
_positionSub?.cancel();
|
||||
_debounce.dispose();
|
||||
_cameraProvider.removeListener(_onCamerasUpdated);
|
||||
|
||||
// Clean up tile refresh callback
|
||||
try {
|
||||
final tileProvider = Provider.of<TileProviderWithCache>(context, listen: false);
|
||||
tileProvider.setOnTilesCachedCallback(null);
|
||||
} catch (e) {
|
||||
// Context might be disposed already - that's okay
|
||||
}
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -79,6 +92,14 @@ class _MapViewState extends State<MapView> {
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
|
||||
void _onTilesCached() {
|
||||
// When new tiles are cached, just trigger a widget rebuild
|
||||
// This should cause the TileLayer to re-render with cached tiles
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
void _refreshCamerasFromProvider() {
|
||||
final appState = context.read<AppState>();
|
||||
LatLngBounds? bounds;
|
||||
@@ -159,6 +180,8 @@ class _MapViewState extends State<MapView> {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final appState = context.watch<AppState>();
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../services/network_status.dart';
|
||||
|
||||
class NetworkStatusIndicator extends StatelessWidget {
|
||||
const NetworkStatusIndicator({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider.value(
|
||||
value: NetworkStatus.instance,
|
||||
child: Consumer<NetworkStatus>(
|
||||
builder: (context, networkStatus, child) {
|
||||
if (!networkStatus.hasAnyIssues) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
String message;
|
||||
IconData icon;
|
||||
Color color;
|
||||
|
||||
switch (networkStatus.currentIssueType) {
|
||||
case NetworkIssueType.osmTiles:
|
||||
message = 'OSM tiles slow';
|
||||
icon = Icons.map_outlined;
|
||||
color = Colors.orange;
|
||||
break;
|
||||
case NetworkIssueType.overpassApi:
|
||||
message = 'Camera data slow';
|
||||
icon = Icons.camera_alt_outlined;
|
||||
color = Colors.orange;
|
||||
break;
|
||||
case NetworkIssueType.both:
|
||||
message = 'Network issues';
|
||||
icon = Icons.cloud_off_outlined;
|
||||
color = Colors.red;
|
||||
break;
|
||||
default:
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return Positioned(
|
||||
top: MediaQuery.of(context).padding.top + 8,
|
||||
left: 8,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black87,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: color, width: 1),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
icon,
|
||||
size: 16,
|
||||
color: color,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
message,
|
||||
style: TextStyle(
|
||||
color: color,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,15 @@ class TileProviderWithCache extends TileProvider with ChangeNotifier {
|
||||
|
||||
bool _disposed = false;
|
||||
int _disposeCount = 0;
|
||||
VoidCallback? _onTilesCachedCallback;
|
||||
|
||||
TileProviderWithCache();
|
||||
|
||||
/// Set a callback to be called when tiles are cached (used by MapView for refresh)
|
||||
void setOnTilesCachedCallback(VoidCallback? callback) {
|
||||
_onTilesCachedCallback = callback;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_disposeCount++;
|
||||
@@ -67,6 +73,8 @@ class TileProviderWithCache extends TileProvider with ChangeNotifier {
|
||||
if (!_disposed && hasListeners) {
|
||||
notifyListeners(); // This updates any listening widgets
|
||||
}
|
||||
// Trigger map refresh callback to force tile re-rendering
|
||||
_onTilesCachedCallback?.call();
|
||||
}
|
||||
// If bytes were empty, don't cache (will re-attempt next time)
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user