Merge pull request #6891 from element-hq/renovate/org.maplibre.compose-maplibre-compose-0.x

Update dependency org.maplibre.compose:maplibre-compose to v0.13.0
This commit is contained in:
ganfra
2026-05-28 18:58:13 +02:00
committed by GitHub
7 changed files with 76 additions and 18 deletions
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.location.impl.common.ui
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.snapshotFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import org.maplibre.compose.location.Location
import org.maplibre.compose.location.UserLocationState
import kotlin.math.abs
/**
* Drop-in replacement for the library's LocationTrackingEffect.
* TODO remove once https://github.com/maplibre/maplibre-compose/issues/808 is fixed
*/
@Composable
internal fun SimpleLocationTrackingEffect(
locationState: UserLocationState,
enabled: Boolean = true,
precision: Double = 0.00001,
onLocationChange: suspend (Location?) -> Unit,
) {
val latestOnLocationChange by rememberUpdatedState(onLocationChange)
LaunchedEffect(locationState, enabled) {
if (!enabled) return@LaunchedEffect
val locationStateFlow = snapshotFlow { locationState.location }
locationStateFlow
.distinctUntilChanged { oldLocation, newLocation ->
if (oldLocation != null && newLocation != null) {
when {
abs(oldLocation.position.value.latitude - newLocation.position.value.latitude) >= precision -> false
abs(oldLocation.position.value.longitude - newLocation.position.value.longitude) >= precision -> false
else -> true
}
} else {
false
}
}
.collect { location ->
latestOnLocationChange(location)
}
}
}
@@ -18,11 +18,11 @@ import org.maplibre.compose.location.DesiredAccuracy
import org.maplibre.compose.location.LocationPuck import org.maplibre.compose.location.LocationPuck
import org.maplibre.compose.location.LocationPuckColors import org.maplibre.compose.location.LocationPuckColors
import org.maplibre.compose.location.LocationPuckSizes import org.maplibre.compose.location.LocationPuckSizes
import org.maplibre.compose.location.LocationTrackingEffect
import org.maplibre.compose.location.UserLocationState import org.maplibre.compose.location.UserLocationState
import org.maplibre.compose.location.rememberAndroidLocationProvider import org.maplibre.compose.location.rememberAndroidLocationProvider
import org.maplibre.compose.location.rememberNullLocationProvider import org.maplibre.compose.location.rememberNullLocationProvider
import org.maplibre.compose.location.rememberUserLocationState import org.maplibre.compose.location.rememberUserLocationState
import org.maplibre.spatialk.units.extensions.meters
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
@Composable @Composable
@@ -31,22 +31,24 @@ fun UserLocationPuck(
locationState: UserLocationState, locationState: UserLocationState,
trackUserLocation: Boolean, trackUserLocation: Boolean,
) { ) {
LocationTrackingEffect( SimpleLocationTrackingEffect(
locationState = locationState, locationState = locationState,
enabled = trackUserLocation, enabled = trackUserLocation,
) { ) { currentLocation ->
val finalPosition = cameraState.position.copy( val target = currentLocation?.position?.value ?: cameraState.position.target
target = currentLocation.position, val newPosition = cameraState.position.copy(
bearing = currentLocation.bearing ?: cameraState.position.bearing, target = target,
// Force pointing to NORTH
bearing = 0.0,
zoom = cameraState.position.zoom.coerceAtLeast(MapDefaults.DEFAULT_ZOOM) zoom = cameraState.position.zoom.coerceAtLeast(MapDefaults.DEFAULT_ZOOM)
) )
cameraState.animateTo(finalPosition) cameraState.animateTo(newPosition)
} }
val location = locationState.location val location = locationState.location
if (location != null) { if (location != null) {
LocationPuck( LocationPuck(
idPrefix = "user-location", idPrefix = "user-location",
locationState = locationState, location = location,
cameraState = cameraState, cameraState = cameraState,
accuracyThreshold = Float.POSITIVE_INFINITY, accuracyThreshold = Float.POSITIVE_INFINITY,
showBearingAccuracy = false, showBearingAccuracy = false,
@@ -74,7 +76,7 @@ fun rememberUserLocationState(hasLocationPermission: Boolean): UserLocationState
rememberAndroidLocationProvider( rememberAndroidLocationProvider(
updateInterval = 5.seconds, updateInterval = 5.seconds,
desiredAccuracy = DesiredAccuracy.High, desiredAccuracy = DesiredAccuracy.High,
minDistanceMeters = 5f, minDistance = 5.meters,
) )
} }
return rememberUserLocationState(locationProvider) return rememberUserLocationState(locationProvider)
@@ -36,6 +36,8 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import org.maplibre.compose.location.AndroidLocationProvider import org.maplibre.compose.location.AndroidLocationProvider
import org.maplibre.compose.location.DesiredAccuracy import org.maplibre.compose.location.DesiredAccuracy
import org.maplibre.spatialk.units.extensions.inMeters
import org.maplibre.spatialk.units.extensions.meters
import timber.log.Timber import timber.log.Timber
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
import io.element.android.features.location.api.Location as ApiLocation import io.element.android.features.location.api.Location as ApiLocation
@@ -91,7 +93,7 @@ class LiveLocationSharingService : Service() {
val locationProvider = AndroidLocationProvider( val locationProvider = AndroidLocationProvider(
context = applicationContext, context = applicationContext,
updateInterval = UPDATE_INTERVAL_IN_SECOND.seconds, updateInterval = UPDATE_INTERVAL_IN_SECOND.seconds,
minDistanceMeters = minDistanceMeters.toFloat(), minDistance = minDistanceMeters.meters,
desiredAccuracy = DesiredAccuracy.Balanced, desiredAccuracy = DesiredAccuracy.Balanced,
coroutineScope = coroutineScope coroutineScope = coroutineScope
) )
@@ -100,9 +102,9 @@ class LiveLocationSharingService : Service() {
.filterNotNull() .filterNotNull()
.map { location -> .map { location ->
ApiLocation( ApiLocation(
lat = location.position.latitude, lat = location.position.value.latitude,
lon = location.position.longitude, lon = location.position.value.longitude,
accuracy = location.accuracy.toFloat(), accuracy = location.position.accuracy?.inMeters?.toFloat(),
) )
} }
.onEach(coordinator::dispatch) .onEach(coordinator::dispatch)
@@ -100,8 +100,8 @@ class ShareLocationPresenter(
fun checkLocationConstraints() { fun checkLocationConstraints() {
// No need to check SendLiveLocationPermissions here // No need to check SendLiveLocationPermissions here
val locationConstraints = checkLocationConstraints(permissionsState, locationActions, SendLiveLocationPermissions.GRANTED) val locationConstraints = checkLocationConstraints(permissionsState, locationActions, SendLiveLocationPermissions.GRANTED)
dialogState = ShareLocationState.Dialog.Constraints(locationConstraints.toDialogState())
trackUserPosition = locationConstraints is LocationConstraintsCheck.Success trackUserPosition = locationConstraints is LocationConstraintsCheck.Success
dialogState = ShareLocationState.Dialog.Constraints(locationConstraints.toDialogState())
} }
suspend fun computeLiveLocationDialogState(): ShareLocationState.Dialog { suspend fun computeLiveLocationDialogState(): ShareLocationState.Dialog {
@@ -225,8 +225,8 @@ private fun BottomSheetContent(
state.eventSink( state.eventSink(
ShareLocationEvent.ShareStaticLocation( ShareLocationEvent.ShareStaticLocation(
location = Location( location = Location(
lat = userLocation.position.latitude, lat = userLocation.position.value.latitude,
lon = userLocation.position.longitude lon = userLocation.position.value.longitude
), ),
isPinned = false isPinned = false
) )
@@ -155,7 +155,9 @@ fun ShowLocationView(
val position = CameraPosition( val position = CameraPosition(
padding = sheetPaddings, padding = sheetPaddings,
target = Position(locationShare.location.lon, locationShare.location.lat), target = Position(locationShare.location.lon, locationShare.location.lat),
zoom = MapDefaults.DEFAULT_ZOOM // Force pointing to NORTH
bearing = 0.0,
zoom = cameraState.position.zoom.coerceAtLeast(MapDefaults.DEFAULT_ZOOM),
) )
coroutineScope.launch { coroutineScope.launch {
cameraState.animateTo(finalPosition = position) cameraState.animateTo(finalPosition = position)
+1 -1
View File
@@ -214,7 +214,7 @@ telephoto_flick = { module = "me.saket.telephoto:flick-android", version.ref = "
statemachine = "com.freeletics.flowredux:compose:1.2.2" statemachine = "com.freeletics.flowredux:compose:1.2.2"
maplibre = "org.maplibre.gl:android-sdk:13.1.0" maplibre = "org.maplibre.gl:android-sdk:13.1.0"
maplibre_ktx = "org.maplibre.gl:android-sdk-ktx-v7:3.0.2" maplibre_ktx = "org.maplibre.gl:android-sdk-ktx-v7:3.0.2"
maplibre_compose = "org.maplibre.compose:maplibre-compose:0.12.1" maplibre_compose = "org.maplibre.compose:maplibre-compose:0.13.0"
maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:3.0.2" maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:3.0.2"
opusencoder = "io.element.android:opusencoder:1.2.0" opusencoder = "io.element.android:opusencoder:1.2.0"
zxing_cpp = "io.github.zxing-cpp:android:3.0.2" zxing_cpp = "io.github.zxing-cpp:android:3.0.2"