diff --git a/mobile/lib/extensions/maplibrecontroller_extensions.dart b/mobile/lib/extensions/maplibrecontroller_extensions.dart index 0c1e62e308..e01655b3a8 100644 --- a/mobile/lib/extensions/maplibrecontroller_extensions.dart +++ b/mobile/lib/extensions/maplibrecontroller_extensions.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:math'; import 'package:flutter/services.dart'; @@ -6,6 +7,8 @@ import 'package:immich_mobile/modules/map/utils/map_utils.dart'; import 'package:maplibre_gl/maplibre_gl.dart'; extension MapMarkers on MaplibreMapController { + static var _completer = Completer()..complete(); + Future addGeoJSONSourceForMarkers(List markers) async { return addSource( MapUtils.defaultSourceId, @@ -16,6 +19,12 @@ extension MapMarkers on MaplibreMapController { } Future reloadAllLayersForMarkers(List markers) async { + // Wait for previous reload to complete + if (!_completer.isCompleted) { + return _completer.future; + } + _completer = Completer(); + // !! Make sure to remove layers before sources else the native // maplibre library would crash when removing the source saying that // the source is still in use @@ -36,6 +45,8 @@ extension MapMarkers on MaplibreMapController { MapUtils.defaultHeatMapLayerId, MapUtils.defaultHeatMapLayerProperties, ); + + _completer.complete(); } Future addMarkerAtLatLng(LatLng centre) async { diff --git a/mobile/lib/modules/map/views/map_page.dart b/mobile/lib/modules/map/views/map_page.dart index 1882e32616..671e501bcc 100644 --- a/mobile/lib/modules/map/views/map_page.dart +++ b/mobile/lib/modules/map/views/map_page.dart @@ -41,6 +41,7 @@ class MapPage extends HookConsumerWidget { final bottomSheetStreamController = useStreamController(); final selectedMarker = useValueNotifier<_AssetMarkerMeta?>(null); final assetsDebouncer = useDebouncer(); + final layerDebouncer = useDebouncer(interval: const Duration(seconds: 1)); final isLoading = useProcessingOverlay(); final scrollController = useScrollController(); final markerDebouncer = @@ -77,7 +78,9 @@ class MapPage extends HookConsumerWidget { // removes all sources and layers and re-adds them with the updated markers Future reloadLayers() async { if (mapController.value != null) { - mapController.value!.reloadAllLayersForMarkers(markers.value); + layerDebouncer.run( + () => mapController.value!.reloadAllLayersForMarkers(markers.value), + ); } }