Merge pull request #6913 from element-hq/feature/user_location_state

change: replace the maplibre-compose UserLocationState to a simpler one
This commit is contained in:
ganfra
2026-06-01 21:51:38 +02:00
committed by GitHub
5 changed files with 48 additions and 30 deletions
@@ -0,0 +1,43 @@
/*
* 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
import android.annotation.SuppressLint
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalInspectionMode
import org.maplibre.compose.location.DesiredAccuracy
import org.maplibre.compose.location.Location
import org.maplibre.compose.location.rememberAndroidLocationProvider
import org.maplibre.compose.location.rememberNullLocationProvider
import org.maplibre.spatialk.units.extensions.meters
import kotlin.time.Duration.Companion.seconds
class UserLocationState(locationState: State<Location?>) {
val location: Location? by locationState
}
@SuppressLint("MissingPermission")
@Composable
fun rememberUserLocationState(hasLocationPermission: Boolean): UserLocationState {
val isPreview = LocalInspectionMode.current
val locationProvider = if (isPreview || !hasLocationPermission) {
rememberNullLocationProvider()
} else {
rememberAndroidLocationProvider(
updateInterval = 5.seconds,
desiredAccuracy = DesiredAccuracy.High,
minDistance = 5.meters,
)
}
val locationState = locationProvider.location.collectAsState()
return remember { UserLocationState(locationState) }
}
@@ -12,9 +12,9 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.snapshotFlow
import io.element.android.features.location.impl.common.UserLocationState
import kotlinx.coroutines.flow.distinctUntilChanged
import org.maplibre.compose.location.Location
import org.maplibre.compose.location.UserLocationState
import kotlin.math.abs
/**
@@ -29,7 +29,6 @@ internal fun SimpleLocationTrackingEffect(
onLocationChange: suspend (Location?) -> Unit,
) {
val latestOnLocationChange by rememberUpdatedState(onLocationChange)
LaunchedEffect(locationState, enabled) {
if (!enabled) return@LaunchedEffect
val locationStateFlow = snapshotFlow { locationState.location }
@@ -7,23 +7,15 @@
package io.element.android.features.location.impl.common.ui
import android.annotation.SuppressLint
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.features.location.impl.common.MapDefaults
import io.element.android.features.location.impl.common.UserLocationState
import org.maplibre.compose.camera.CameraState
import org.maplibre.compose.location.DesiredAccuracy
import org.maplibre.compose.location.LocationPuck
import org.maplibre.compose.location.LocationPuckColors
import org.maplibre.compose.location.LocationPuckSizes
import org.maplibre.compose.location.UserLocationState
import org.maplibre.compose.location.rememberAndroidLocationProvider
import org.maplibre.compose.location.rememberNullLocationProvider
import org.maplibre.compose.location.rememberUserLocationState
import org.maplibre.spatialk.units.extensions.meters
import kotlin.time.Duration.Companion.seconds
@Composable
fun UserLocationPuck(
@@ -65,19 +57,3 @@ fun UserLocationPuck(
)
}
}
@SuppressLint("MissingPermission")
@Composable
fun rememberUserLocationState(hasLocationPermission: Boolean): UserLocationState {
val isPreview = LocalInspectionMode.current
val locationProvider = if (isPreview || !hasLocationPermission) {
rememberNullLocationProvider()
} else {
rememberAndroidLocationProvider(
updateInterval = 5.seconds,
desiredAccuracy = DesiredAccuracy.High,
minDistance = 5.meters,
)
}
return rememberUserLocationState(locationProvider)
}
@@ -39,11 +39,12 @@ import io.element.android.features.location.api.Location
import io.element.android.features.location.api.internal.centerBottomEdge
import io.element.android.features.location.impl.R
import io.element.android.features.location.impl.common.MapDefaults
import io.element.android.features.location.impl.common.UserLocationState
import io.element.android.features.location.impl.common.rememberUserLocationState
import io.element.android.features.location.impl.common.ui.LocationConstraintsDialog
import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton
import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold
import io.element.android.features.location.impl.common.ui.UserLocationPuck
import io.element.android.features.location.impl.common.ui.rememberUserLocationState
import io.element.android.features.location.impl.share.ShareLocationEvent.StartLiveLocationShare
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.designsystem.components.LocationPin
@@ -69,7 +70,6 @@ import kotlinx.collections.immutable.ImmutableList
import org.maplibre.compose.camera.CameraMoveReason
import org.maplibre.compose.camera.CameraState
import org.maplibre.compose.camera.rememberCameraState
import org.maplibre.compose.location.UserLocationState
import kotlin.time.Duration
@OptIn(ExperimentalMaterial3Api::class)
@@ -37,13 +37,13 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.features.location.impl.common.MapDefaults
import io.element.android.features.location.impl.common.rememberUserLocationState
import io.element.android.features.location.impl.common.ui.LocationConstraintsDialog
import io.element.android.features.location.impl.common.ui.LocationFloatingActionButton
import io.element.android.features.location.impl.common.ui.LocationPinMarkers
import io.element.android.features.location.impl.common.ui.LocationShareRow
import io.element.android.features.location.impl.common.ui.MapBottomSheetScaffold
import io.element.android.features.location.impl.common.ui.UserLocationPuck
import io.element.android.features.location.impl.common.ui.rememberUserLocationState
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight