From 578d2d24ed5a17ecd210f89824d8ee6dfe42d4b7 Mon Sep 17 00:00:00 2001 From: Shautvast Date: Sat, 4 Apr 2026 16:04:59 +0200 Subject: [PATCH] fix: skip redundant mapController.move() on gesture-driven pans Every pan gesture updated mapProvider state, which triggered ref.listen to call _mapController.move() with the position the map was already at. This caused TileLayer to re-evaluate the viewport and cancel in-flight tile loads, producing a partially-rendered (diagonal) map. Co-Authored-By: Claude Sonnet 4.6 --- .../features/map/presentation/screens/map_screen.dart | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/mobile/lib/features/map/presentation/screens/map_screen.dart b/mobile/lib/features/map/presentation/screens/map_screen.dart index ce03ec4..b6ea8a8 100644 --- a/mobile/lib/features/map/presentation/screens/map_screen.dart +++ b/mobile/lib/features/map/presentation/screens/map_screen.dart @@ -42,9 +42,18 @@ class _MapScreenState extends ConsumerState { final styleAsync = ref.watch(mapStyleProvider(apiClient.baseUrl)); // Listen for zoom/center changes from the provider and move the map. + // Skip the move if the map controller is already at the target position + // (meaning the state change came from a user gesture via onPositionChanged). + // Without this guard, every gesture-driven pan calls _mapController.move() + // with the position the map is already at, which triggers a tile + // recalculation that cancels in-flight tile loads and produces a + // partially-rendered (diagonal) map. ref.listen(mapProvider, (previous, next) { if (previous?.center != next.center || previous?.zoom != next.zoom) { - _mapController.move(next.center, next.zoom); + final camera = _mapController.camera; + if (camera.center != next.center || camera.zoom != next.zoom) { + _mapController.move(next.center, next.zoom); + } } });