Simplify ShowLocationState

This commit is contained in:
ganfra 2026-03-13 18:41:32 +01:00
parent 9b98a47941
commit 6414d74c40
5 changed files with 37 additions and 72 deletions

View file

@ -78,7 +78,11 @@ fun LocationShareRow(
modifier = Modifier.size(16.dp), modifier = Modifier.size(16.dp),
) )
} else { } else {
val icon = if (item.assetType == AssetType.PIN) CompoundIcons.LocationNavigator() else CompoundIcons.LocationNavigatorCentred() val icon = if (item.assetType == AssetType.PIN) {
CompoundIcons.LocationNavigator()
} else {
CompoundIcons.LocationNavigatorCentred()
}
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = null, contentDescription = null,
@ -120,8 +124,8 @@ internal fun LocationShareRowPreview() = ElementPreview {
size = AvatarSize.UserListItem, size = AvatarSize.UserListItem,
), ),
formattedTimestamp = "Shared 1 min ago", formattedTimestamp = "Shared 1 min ago",
assetType = AssetType.SENDER,
isLive = true, isLive = true,
assetType = AssetType.SENDER,
location = Location(0.0, 0.0) location = Location(0.0, 0.0)
), ),
onShareClick = {}, onShareClick = {},
@ -136,9 +140,9 @@ internal fun LocationShareRowPreview() = ElementPreview {
url = null, url = null,
size = AvatarSize.UserListItem, size = AvatarSize.UserListItem,
), ),
isLive = false,
assetType = AssetType.PIN, assetType = AssetType.PIN,
formattedTimestamp = "Shared 5 hours ago", formattedTimestamp = "Shared 5 hours ago",
isLive = false,
location = Location(0.0, 0.0) location = Location(0.0, 0.0)
), ),
onShareClick = {}, onShareClick = {},

View file

@ -28,15 +28,12 @@ import io.element.android.features.location.impl.common.permissions.PermissionsP
import io.element.android.features.location.impl.common.permissions.PermissionsState import io.element.android.features.location.impl.common.permissions.PermissionsState
import io.element.android.features.location.impl.common.toDialogState import io.element.android.features.location.impl.common.toDialogState
import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState
import io.element.android.features.location.impl.common.ui.LocationMarkerData
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.dateformatter.api.DateFormatter import io.element.android.libraries.dateformatter.api.DateFormatter
import io.element.android.libraries.dateformatter.api.DateFormatterMode import io.element.android.libraries.dateformatter.api.DateFormatterMode
import io.element.android.libraries.designsystem.components.PinVariant
import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.matrix.api.room.location.AssetType
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.services.toolbox.api.strings.StringProvider import io.element.android.services.toolbox.api.strings.StringProvider
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@ -99,34 +96,6 @@ class ShowLocationPresenter(
} }
} }
val markers = remember {
when (mode) {
is ShowLocationMode.Static -> {
val pinVariant = if (mode.assetType == AssetType.PIN) {
PinVariant.PinnedLocation
} else {
PinVariant.UserLocation(
avatarData = AvatarData(
id = mode.senderId.value,
name = mode.senderName,
url = mode.senderAvatarUrl,
size = AvatarSize.UserListItem,
),
isLive = false,
)
}
persistentListOf(
LocationMarkerData(
id = mode.senderId.value,
location = mode.location,
variant = pinVariant,
)
)
}
ShowLocationMode.Live -> persistentListOf()
}
}
val locationShares = remember { val locationShares = remember {
when (mode) { when (mode) {
is ShowLocationMode.Static -> { is ShowLocationMode.Static -> {
@ -146,9 +115,9 @@ class ShowLocationPresenter(
size = AvatarSize.UserListItem, size = AvatarSize.UserListItem,
), ),
formattedTimestamp = formattedTimestamp, formattedTimestamp = formattedTimestamp,
location = mode.location,
isLive = false, isLive = false,
assetType = mode.assetType, assetType = mode.assetType,
location = mode.location,
) )
) )
} }
@ -158,7 +127,6 @@ class ShowLocationPresenter(
return ShowLocationState( return ShowLocationState(
dialogState = dialogState, dialogState = dialogState,
markers = markers,
locationShares = locationShares, locationShares = locationShares,
hasLocationPermission = permissionsState.isAnyGranted, hasLocationPermission = permissionsState.isAnyGranted,
isTrackMyLocation = isTrackMyLocation, isTrackMyLocation = isTrackMyLocation,

View file

@ -11,6 +11,7 @@ package io.element.android.features.location.impl.show
import io.element.android.features.location.api.Location import io.element.android.features.location.api.Location
import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState
import io.element.android.features.location.impl.common.ui.LocationMarkerData import io.element.android.features.location.impl.common.ui.LocationMarkerData
import io.element.android.libraries.designsystem.components.PinVariant
import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.room.location.AssetType
@ -18,7 +19,6 @@ import kotlinx.collections.immutable.ImmutableList
data class ShowLocationState( data class ShowLocationState(
val dialogState: LocationConstraintsDialogState, val dialogState: LocationConstraintsDialogState,
val markers: ImmutableList<LocationMarkerData>,
val locationShares: ImmutableList<LocationShareItem>, val locationShares: ImmutableList<LocationShareItem>,
val hasLocationPermission: Boolean, val hasLocationPermission: Boolean,
val isTrackMyLocation: Boolean, val isTrackMyLocation: Boolean,
@ -37,3 +37,19 @@ data class LocationShareItem(
val isLive: Boolean, val isLive: Boolean,
val assetType: AssetType?, val assetType: AssetType?,
) )
fun LocationShareItem.toMarkerData(): LocationMarkerData {
val pinVariant = if (assetType == AssetType.PIN) {
PinVariant.PinnedLocation
} else {
PinVariant.UserLocation(
avatarData = avatarData,
isLive = isLive,
)
}
return LocationMarkerData(
id = userId.value,
location = location,
variant = pinVariant,
)
}

View file

@ -11,16 +11,12 @@ package io.element.android.features.location.impl.show
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.location.api.Location import io.element.android.features.location.api.Location
import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState
import io.element.android.features.location.impl.common.ui.LocationMarkerData
import io.element.android.libraries.designsystem.components.PinVariant
import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.room.location.AssetType
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
private const val APP_NAME = "ApplicationName"
class ShowLocationStateProvider : PreviewParameterProvider<ShowLocationState> { class ShowLocationStateProvider : PreviewParameterProvider<ShowLocationState> {
override val values: Sequence<ShowLocationState> override val values: Sequence<ShowLocationState>
get() = sequenceOf( get() = sequenceOf(
@ -45,13 +41,10 @@ class ShowLocationStateProvider : PreviewParameterProvider<ShowLocationState> {
) )
} }
private val defaultLocation = Location(1.23, 2.34, 4f) private const val APP_NAME = "ApplicationName"
private val defaultSenderId = UserId("@alice:matrix.org")
private const val defaultSenderName = "Alice"
fun aShowLocationState( fun aShowLocationState(
constraintsDialogState: LocationConstraintsDialogState = LocationConstraintsDialogState.None, constraintsDialogState: LocationConstraintsDialogState = LocationConstraintsDialogState.None,
markers: List<LocationMarkerData> = listOf(aLocationMarkerData()),
locationShares: List<LocationShareItem> = listOf(aLocationShareItem()), locationShares: List<LocationShareItem> = listOf(aLocationShareItem()),
hasLocationPermission: Boolean = false, hasLocationPermission: Boolean = false,
isTrackMyLocation: Boolean = false, isTrackMyLocation: Boolean = false,
@ -60,7 +53,6 @@ fun aShowLocationState(
): ShowLocationState { ): ShowLocationState {
return ShowLocationState( return ShowLocationState(
dialogState = constraintsDialogState, dialogState = constraintsDialogState,
markers = markers.toImmutableList(),
locationShares = locationShares.toImmutableList(), locationShares = locationShares.toImmutableList(),
hasLocationPermission = hasLocationPermission, hasLocationPermission = hasLocationPermission,
isTrackMyLocation = isTrackMyLocation, isTrackMyLocation = isTrackMyLocation,
@ -69,35 +61,17 @@ fun aShowLocationState(
) )
} }
fun aLocationMarkerData(
id: String = defaultSenderId.value,
location: Location = defaultLocation,
variant: PinVariant = PinVariant.UserLocation(
avatarData = AvatarData(
id = defaultSenderId.value,
name = defaultSenderName,
url = null,
size = AvatarSize.LocationPin,
),
isLive = false,
),
) = LocationMarkerData(
id = id,
location = location,
variant = variant,
)
fun aLocationShareItem( fun aLocationShareItem(
userId: UserId = defaultSenderId, userId: UserId = UserId("@alice:matrix.org"),
displayName: String = defaultSenderName, displayName: String = "Alice",
avatarData: AvatarData = AvatarData( avatarData: AvatarData = AvatarData(
id = defaultSenderId.value, id = userId.value,
name = defaultSenderName, name = displayName,
url = null, url = null,
size = AvatarSize.UserListItem, size = AvatarSize.UserListItem,
), ),
formattedTimestamp: String = "Shared 1 min ago", formattedTimestamp: String = "Shared 1 min ago",
location: Location = defaultLocation, location: Location = Location(1.23, 2.34, 4f),
isLive: Boolean = false, isLive: Boolean = false,
assetType: AssetType? = null, assetType: AssetType? = null,
) = LocationShareItem( ) = LocationShareItem(

View file

@ -66,10 +66,10 @@ fun ShowLocationView(
) )
val initialPosition = remember { val initialPosition = remember {
if (state.markers.isEmpty()) { if (state.locationShares.isEmpty()) {
MapDefaults.defaultCameraPosition MapDefaults.defaultCameraPosition
} else { } else {
val firstLocation = state.markers.first().location val firstLocation = state.locationShares.first().location
CameraPosition( CameraPosition(
target = Position(latitude = firstLocation.lat, longitude = firstLocation.lon), target = Position(latitude = firstLocation.lat, longitude = firstLocation.lon),
zoom = MapDefaults.DEFAULT_ZOOM zoom = MapDefaults.DEFAULT_ZOOM
@ -147,7 +147,10 @@ fun ShowLocationView(
locationState = userLocationState, locationState = userLocationState,
trackUserLocation = state.isTrackMyLocation trackUserLocation = state.isTrackMyLocation
) )
LocationPinMarkers(state.markers) val markers = remember(state.locationShares) {
state.locationShares.map { it.toMarkerData() }
}
LocationPinMarkers(markers)
}, },
overlayContent = { overlayContent = {
LocationFloatingActionButton( LocationFloatingActionButton(