fix(ui): make setting camera position work again

This commit is contained in:
Cilly Leang 2026-04-02 02:28:10 +11:00
parent c912723c78
commit 4cdb9a305c
Signed by: cilly
GPG key ID: 6500251E087653C9
5 changed files with 47 additions and 11 deletions

View file

@ -6,12 +6,15 @@ import androidx.compose.foundation.layout.add
import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import moe.lava.banksia.core.Constants import moe.lava.banksia.core.Constants
import moe.lava.banksia.ui.map.mappers.routeColorExpression import moe.lava.banksia.ui.map.mappers.routeColorExpression
import moe.lava.banksia.ui.map.mappers.toMapPosition
import moe.lava.banksia.ui.platform.BanksiaTheme import moe.lava.banksia.ui.platform.BanksiaTheme
import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.CameraPosition
import org.maplibre.compose.camera.rememberCameraState 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.compose.util.ClickResult
import org.maplibre.spatialk.geojson.Feature import org.maplibre.spatialk.geojson.Feature
import org.maplibre.spatialk.geojson.Geometry import org.maplibre.spatialk.geojson.Geometry
import kotlin.time.Duration.Companion.seconds
@Composable @Composable
internal fun MapLibreMaps( internal fun MapLibreMaps(
@ -34,7 +38,7 @@ internal fun MapLibreMaps(
positionState: MapsPositionState, positionState: MapsPositionState,
stops: GeoJsonData.Features?, stops: GeoJsonData.Features?,
// vehicles: GeoJsonData.Features?, // vehicles: GeoJsonData.Features?,
stopInnerColor: Color, stopInnerColor: Color = BanksiaTheme.colors.surface,
onStopClicked: (Feature<Geometry, JsonObject?>) -> Unit, onStopClicked: (Feature<Geometry, JsonObject?>) -> Unit,
) { ) {
val camPos = rememberCameraState( val camPos = rememberCameraState(
@ -43,6 +47,17 @@ internal fun MapLibreMaps(
target = MELBOURNE_POS 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" val variant = if (isSystemInDarkTheme()) "dark" else "light"
@ -63,7 +78,7 @@ internal fun MapLibreMaps(
CircleLayer( CircleLayer(
id = "maps-stops0", id = "maps-stops0",
source = stopsSource, source = stopsSource,
color = const(BanksiaTheme.colors.surface), color = const(stopInnerColor),
radius = const(3.dp), radius = const(3.dp),
strokeWidth = const(2.dp), strokeWidth = const(2.dp),
strokeColor = routeColorExpression, strokeColor = routeColorExpression,

View file

@ -7,16 +7,18 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import moe.lava.banksia.core.util.Point import moe.lava.banksia.ui.map.util.CameraPosition
class MapsPositionState internal constructor( class MapsPositionState internal constructor(
private val scope: CoroutineScope private val scope: CoroutineScope
) { ) {
internal val updates: SharedFlow<Point> internal val updates: SharedFlow<CameraPosition>
field = MutableSharedFlow() field = MutableSharedFlow()
fun update(position: Point) { fun update(position: CameraPosition) {
scope.launch { updates.emit(position) } scope.launch {
updates.emit(position)
}
} }
} }

View file

@ -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(),
)
}
)

View file

@ -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.InfoPanel
import moe.lava.banksia.ui.layout.info.InfoPanelState import moe.lava.banksia.ui.layout.info.InfoPanelState
import moe.lava.banksia.ui.map.Maps import moe.lava.banksia.ui.map.Maps
import moe.lava.banksia.ui.map.rememberMapsPositionState
import moe.lava.banksia.ui.platform.BanksiaTheme import moe.lava.banksia.ui.platform.BanksiaTheme
import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.painterResource
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel
@ -64,6 +65,13 @@ fun MapScreen(
val sheetState = SheetStateWrapper.create() val sheetState = SheetStateWrapper.create()
var searchExpandedState by rememberSaveable { mutableStateOf(false) } var searchExpandedState by rememberSaveable { mutableStateOf(false) }
val mapsPositionState = rememberMapsPositionState()
scope.launch {
viewModel.cameraChangeEmitter.collect {
mapsPositionState.update(it.value)
}
}
LaunchedEffect(infoState) { LaunchedEffect(infoState) {
if (infoState !is InfoPanelState.None) { if (infoState !is InfoPanelState.None) {
sheetState.peek() sheetState.peek()
@ -80,6 +88,7 @@ fun MapScreen(
SearchBarDefaults.InputFieldHeight.roundToPx() SearchBarDefaults.InputFieldHeight.roundToPx()
}, bottom = sheetState.bottomInset), }, bottom = sheetState.bottomInset),
stops = mapState.stops, stops = mapState.stops,
positionState = mapsPositionState,
// vehicles = mapState.vehicles, // vehicles = mapState.vehicles,
onStopClicked = { stop -> onStopClicked = { stop ->
viewModel.handleEvent(MapScreenEvent.SelectStop(stop)) viewModel.handleEvent(MapScreenEvent.SelectStop(stop))

View file

@ -116,11 +116,6 @@ class MapScreenViewModel(
} }
fun centreCameraToLocation() { fun centreCameraToLocation() {
viewModelScope.launch {
log("msvm", "getting..")
val routes = routeRepository.getAll()
log("msvm", routes.joinToString("\n"))
}
lastKnownLocation?.let { location -> lastKnownLocation?.let { location ->
viewModelScope.launch { viewModelScope.launch {
log("bvm", "emitting $location") log("bvm", "emitting $location")