From 4cdb9a305cd96ab12a5bfd2d198eacdd7060ea7a Mon Sep 17 00:00:00 2001 From: Cilly Leang Date: Thu, 2 Apr 2026 02:28:10 +1100 Subject: [PATCH] fix(ui): make setting camera position work again --- .../moe/lava/banksia/ui/map/MapLibreMaps.kt | 19 +++++++++++++++++-- .../lava/banksia/ui/map/MapsPositionState.kt | 10 ++++++---- .../banksia/ui/map/mappers/CameraPosition.kt | 15 +++++++++++++++ .../lava/banksia/ui/screens/map/MapScreen.kt | 9 +++++++++ .../ui/screens/map/MapScreenViewModel.kt | 5 ----- 5 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 ui/maps/src/commonMain/kotlin/moe/lava/banksia/ui/map/mappers/CameraPosition.kt diff --git a/ui/maps/src/commonMain/kotlin/moe/lava/banksia/ui/map/MapLibreMaps.kt b/ui/maps/src/commonMain/kotlin/moe/lava/banksia/ui/map/MapLibreMaps.kt index a870653..d76c1f4 100644 --- a/ui/maps/src/commonMain/kotlin/moe/lava/banksia/ui/map/MapLibreMaps.kt +++ b/ui/maps/src/commonMain/kotlin/moe/lava/banksia/ui/map/MapLibreMaps.kt @@ -6,12 +6,15 @@ import androidx.compose.foundation.layout.add import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.safeDrawing import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp +import kotlinx.coroutines.launch import kotlinx.serialization.json.JsonObject import moe.lava.banksia.core.Constants import moe.lava.banksia.ui.map.mappers.routeColorExpression +import moe.lava.banksia.ui.map.mappers.toMapPosition import moe.lava.banksia.ui.platform.BanksiaTheme import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.rememberCameraState @@ -26,6 +29,7 @@ import org.maplibre.compose.style.BaseStyle import org.maplibre.compose.util.ClickResult import org.maplibre.spatialk.geojson.Feature import org.maplibre.spatialk.geojson.Geometry +import kotlin.time.Duration.Companion.seconds @Composable internal fun MapLibreMaps( @@ -34,7 +38,7 @@ internal fun MapLibreMaps( positionState: MapsPositionState, stops: GeoJsonData.Features?, // vehicles: GeoJsonData.Features?, - stopInnerColor: Color, + stopInnerColor: Color = BanksiaTheme.colors.surface, onStopClicked: (Feature) -> Unit, ) { val camPos = rememberCameraState( @@ -43,6 +47,17 @@ internal fun MapLibreMaps( target = MELBOURNE_POS ) ) + val scope = rememberCoroutineScope() + scope.launch { + positionState.updates.collect { + val (position, box) = it.toMapPosition() + if (box != null) { + camPos.animateTo(box, duration = 1.seconds) + } else { + camPos.animateTo(position, duration = 1.seconds) + } + } + } val variant = if (isSystemInDarkTheme()) "dark" else "light" @@ -63,7 +78,7 @@ internal fun MapLibreMaps( CircleLayer( id = "maps-stops0", source = stopsSource, - color = const(BanksiaTheme.colors.surface), + color = const(stopInnerColor), radius = const(3.dp), strokeWidth = const(2.dp), strokeColor = routeColorExpression, diff --git a/ui/maps/src/commonMain/kotlin/moe/lava/banksia/ui/map/MapsPositionState.kt b/ui/maps/src/commonMain/kotlin/moe/lava/banksia/ui/map/MapsPositionState.kt index b3dab0a..94421a7 100644 --- a/ui/maps/src/commonMain/kotlin/moe/lava/banksia/ui/map/MapsPositionState.kt +++ b/ui/maps/src/commonMain/kotlin/moe/lava/banksia/ui/map/MapsPositionState.kt @@ -7,16 +7,18 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.launch -import moe.lava.banksia.core.util.Point +import moe.lava.banksia.ui.map.util.CameraPosition class MapsPositionState internal constructor( private val scope: CoroutineScope ) { - internal val updates: SharedFlow + internal val updates: SharedFlow field = MutableSharedFlow() - fun update(position: Point) { - scope.launch { updates.emit(position) } + fun update(position: CameraPosition) { + scope.launch { + updates.emit(position) + } } } diff --git a/ui/maps/src/commonMain/kotlin/moe/lava/banksia/ui/map/mappers/CameraPosition.kt b/ui/maps/src/commonMain/kotlin/moe/lava/banksia/ui/map/mappers/CameraPosition.kt new file mode 100644 index 0000000..b463c18 --- /dev/null +++ b/ui/maps/src/commonMain/kotlin/moe/lava/banksia/ui/map/mappers/CameraPosition.kt @@ -0,0 +1,15 @@ +package moe.lava.banksia.ui.map.mappers + +import moe.lava.banksia.ui.map.util.CameraPosition +import org.maplibre.spatialk.geojson.BoundingBox +import org.maplibre.compose.camera.CameraPosition as MLCameraPosition + +internal fun CameraPosition.toMapPosition() = Pair( + MLCameraPosition(target = this.centre.toPosition(), zoom = 16.0), + this.bounds?.let { + BoundingBox( + southwest = it.southwest.toPosition(), + northeast = it.northeast.toPosition(), + ) + } +) diff --git a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreen.kt b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreen.kt index f4319be..1303bf5 100644 --- a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreen.kt +++ b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreen.kt @@ -40,6 +40,7 @@ import moe.lava.banksia.ui.layout.SheetStateWrapper import moe.lava.banksia.ui.layout.info.InfoPanel import moe.lava.banksia.ui.layout.info.InfoPanelState import moe.lava.banksia.ui.map.Maps +import moe.lava.banksia.ui.map.rememberMapsPositionState import moe.lava.banksia.ui.platform.BanksiaTheme import org.jetbrains.compose.resources.painterResource import org.koin.compose.viewmodel.koinViewModel @@ -64,6 +65,13 @@ fun MapScreen( val sheetState = SheetStateWrapper.create() var searchExpandedState by rememberSaveable { mutableStateOf(false) } + val mapsPositionState = rememberMapsPositionState() + scope.launch { + viewModel.cameraChangeEmitter.collect { + mapsPositionState.update(it.value) + } + } + LaunchedEffect(infoState) { if (infoState !is InfoPanelState.None) { sheetState.peek() @@ -80,6 +88,7 @@ fun MapScreen( SearchBarDefaults.InputFieldHeight.roundToPx() }, bottom = sheetState.bottomInset), stops = mapState.stops, + positionState = mapsPositionState, // vehicles = mapState.vehicles, onStopClicked = { stop -> viewModel.handleEvent(MapScreenEvent.SelectStop(stop)) diff --git a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreenViewModel.kt b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreenViewModel.kt index 53600f4..c4bd768 100644 --- a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreenViewModel.kt +++ b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreenViewModel.kt @@ -116,11 +116,6 @@ class MapScreenViewModel( } fun centreCameraToLocation() { - viewModelScope.launch { - log("msvm", "getting..") - val routes = routeRepository.getAll() - log("msvm", routes.joinToString("\n")) - } lastKnownLocation?.let { location -> viewModelScope.launch { log("bvm", "emitting $location")