Make sure we can display both Live and Static locations in ShowLocation
This commit is contained in:
@@ -40,7 +40,7 @@ class ShowLocationNode(
|
||||
}
|
||||
|
||||
private val inputs: ShowLocationEntryPoint.Inputs = inputs()
|
||||
private val presenter = presenterFactory.create(inputs.location, inputs.description)
|
||||
private val presenter = presenterFactory.create(inputs.mode)
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
|
||||
@@ -18,7 +18,7 @@ import androidx.compose.runtime.setValue
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedFactory
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.features.location.api.Location
|
||||
import io.element.android.features.location.api.ShowLocationMode
|
||||
import io.element.android.features.location.impl.common.MapDefaults
|
||||
import io.element.android.features.location.impl.common.actions.LocationActions
|
||||
import io.element.android.features.location.impl.common.permissions.PermissionsEvents
|
||||
@@ -29,15 +29,14 @@ import io.element.android.libraries.core.meta.BuildMeta
|
||||
|
||||
@AssistedInject
|
||||
class ShowLocationPresenter(
|
||||
@Assisted private val location: Location,
|
||||
@Assisted private val description: String?,
|
||||
@Assisted private val mode: ShowLocationMode,
|
||||
permissionsPresenterFactory: PermissionsPresenter.Factory,
|
||||
private val locationActions: LocationActions,
|
||||
private val buildMeta: BuildMeta,
|
||||
) : Presenter<ShowLocationState> {
|
||||
@AssistedFactory
|
||||
fun interface Factory {
|
||||
fun create(location: Location, description: String?): ShowLocationPresenter
|
||||
fun create(mode: ShowLocationMode): ShowLocationPresenter
|
||||
}
|
||||
|
||||
private val permissionsPresenter = permissionsPresenterFactory.create(MapDefaults.permissions)
|
||||
@@ -59,7 +58,16 @@ class ShowLocationPresenter(
|
||||
|
||||
fun handleEvent(event: ShowLocationEvents) {
|
||||
when (event) {
|
||||
ShowLocationEvents.Share -> locationActions.share(location, description)
|
||||
ShowLocationEvents.Share -> {
|
||||
when (mode) {
|
||||
is ShowLocationMode.Static -> {
|
||||
locationActions.share(mode.location, null)
|
||||
}
|
||||
ShowLocationMode.Live -> {
|
||||
// TODO: Handle sharing for live locations
|
||||
}
|
||||
}
|
||||
}
|
||||
is ShowLocationEvents.TrackMyLocation -> {
|
||||
if (event.enabled) {
|
||||
when {
|
||||
@@ -82,8 +90,7 @@ class ShowLocationPresenter(
|
||||
|
||||
return ShowLocationState(
|
||||
permissionDialog = permissionDialog,
|
||||
location = location,
|
||||
description = description,
|
||||
mode = mode,
|
||||
hasLocationPermission = permissionsState.isAnyGranted,
|
||||
isTrackMyLocation = isTrackMyLocation,
|
||||
appName = appName,
|
||||
|
||||
@@ -8,12 +8,11 @@
|
||||
|
||||
package io.element.android.features.location.impl.show
|
||||
|
||||
import io.element.android.features.location.api.Location
|
||||
import io.element.android.features.location.api.ShowLocationMode
|
||||
|
||||
data class ShowLocationState(
|
||||
val permissionDialog: Dialog,
|
||||
val location: Location,
|
||||
val description: String?,
|
||||
val mode: ShowLocationMode,
|
||||
val hasLocationPermission: Boolean,
|
||||
val isTrackMyLocation: Boolean,
|
||||
val appName: String,
|
||||
|
||||
@@ -10,6 +10,9 @@ package io.element.android.features.location.impl.show
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.features.location.api.Location
|
||||
import io.element.android.features.location.api.ShowLocationMode
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
||||
|
||||
private const val APP_NAME = "ApplicationName"
|
||||
|
||||
@@ -31,32 +34,47 @@ class ShowLocationStateProvider : PreviewParameterProvider<ShowLocationState> {
|
||||
isTrackMyLocation = true,
|
||||
),
|
||||
aShowLocationState(
|
||||
description = "My favourite place!",
|
||||
mode = aStaticLocationMode(senderName = "My favourite place!"),
|
||||
),
|
||||
aShowLocationState(
|
||||
description = "For some reason I decided to to write a small essay that wraps at just two lines!",
|
||||
mode = aStaticLocationMode(
|
||||
senderName = "For some reason I decided to write a small essay that wraps at just two lines!"
|
||||
),
|
||||
),
|
||||
aShowLocationState(
|
||||
description = "For some reason I decided to write a small essay in the location description. " +
|
||||
"It is so long that it will wrap onto more than two lines!",
|
||||
mode = ShowLocationMode.Live,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun aShowLocationState(
|
||||
permissionDialog: ShowLocationState.Dialog = ShowLocationState.Dialog.None,
|
||||
location: Location = Location(1.23, 2.34, 4f),
|
||||
description: String? = null,
|
||||
mode: ShowLocationMode = aStaticLocationMode(),
|
||||
hasLocationPermission: Boolean = false,
|
||||
isTrackMyLocation: Boolean = false,
|
||||
appName: String = APP_NAME,
|
||||
eventSink: (ShowLocationEvents) -> Unit = {},
|
||||
) = ShowLocationState(
|
||||
permissionDialog = permissionDialog,
|
||||
location = location,
|
||||
description = description,
|
||||
mode = mode,
|
||||
hasLocationPermission = hasLocationPermission,
|
||||
isTrackMyLocation = isTrackMyLocation,
|
||||
appName = appName,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
||||
fun aStaticLocationMode(
|
||||
location: Location = Location(1.23, 2.34, 4f),
|
||||
senderName: String = "Alice",
|
||||
senderId: UserId = UserId("@alice:matrix.org"),
|
||||
senderAvatarUrl: String? = null,
|
||||
timestamp: Long = System.currentTimeMillis(),
|
||||
assetType: AssetType? = null,
|
||||
) = ShowLocationMode.Static(
|
||||
location = location,
|
||||
senderName = senderName,
|
||||
senderId = senderId,
|
||||
senderAvatarUrl = senderAvatarUrl,
|
||||
timestamp = timestamp,
|
||||
assetType = assetType,
|
||||
)
|
||||
|
||||
@@ -11,6 +11,9 @@ package io.element.android.features.location.impl.show
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.SheetValue
|
||||
import androidx.compose.material3.rememberBottomSheetScaffoldState
|
||||
import androidx.compose.material3.rememberStandardBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -23,6 +26,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.compound.tokens.generated.TypographyTokens
|
||||
import io.element.android.features.location.api.ShowLocationMode
|
||||
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.PermissionDeniedDialog
|
||||
@@ -74,12 +78,16 @@ fun ShowLocationView(
|
||||
)
|
||||
}
|
||||
|
||||
val cameraState = rememberCameraState(
|
||||
firstPosition = CameraPosition(
|
||||
target = Position(latitude = state.location.lat, longitude = state.location.lon),
|
||||
val initialPosition = when (val mode = state.mode) {
|
||||
is ShowLocationMode.Static -> CameraPosition(
|
||||
target = Position(latitude = mode.location.lat, longitude = mode.location.lon),
|
||||
zoom = MapDefaults.DEFAULT_ZOOM
|
||||
)
|
||||
)
|
||||
ShowLocationMode.Live -> CameraPosition(
|
||||
zoom = MapDefaults.DEFAULT_ZOOM
|
||||
)
|
||||
}
|
||||
val cameraState = rememberCameraState(firstPosition = initialPosition)
|
||||
val locationProvider = if (state.hasLocationPermission) {
|
||||
rememberDefaultLocationProvider(
|
||||
updateInterval = 1.minutes,
|
||||
@@ -96,10 +104,13 @@ fun ShowLocationView(
|
||||
}
|
||||
}
|
||||
|
||||
val scaffoldState = rememberBottomSheetScaffoldState(
|
||||
bottomSheetState = rememberStandardBottomSheetState()
|
||||
)
|
||||
MapBottomSheetScaffold(
|
||||
scaffoldState = scaffoldState,
|
||||
cameraState = cameraState,
|
||||
modifier = modifier,
|
||||
sheetPeekHeight = 80.dp,
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
titleStr = stringResource(CommonStrings.screen_view_location_title),
|
||||
@@ -121,17 +132,22 @@ fun ShowLocationView(
|
||||
)
|
||||
},
|
||||
sheetContent = {
|
||||
state.description?.let {
|
||||
Text(
|
||||
text = it,
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = TypographyTokens.fontBodyMdRegular,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp),
|
||||
)
|
||||
when (val mode = state.mode) {
|
||||
is ShowLocationMode.Static -> {
|
||||
Text(
|
||||
text = mode.senderName,
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = TypographyTokens.fontBodyMdRegular,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp),
|
||||
)
|
||||
}
|
||||
ShowLocationMode.Live -> {
|
||||
// TODO: Show list of active live location sharers
|
||||
}
|
||||
}
|
||||
},
|
||||
mapContent = {
|
||||
@@ -140,22 +156,29 @@ fun ShowLocationView(
|
||||
locationState = userLocationState,
|
||||
trackUserLocation = state.isTrackMyLocation
|
||||
)
|
||||
val senderLocation = rememberGeoJsonSource(
|
||||
data = GeoJsonData.Features(
|
||||
Point(
|
||||
Position(
|
||||
latitude = state.location.lat,
|
||||
longitude = state.location.lon
|
||||
when (val mode = state.mode) {
|
||||
is ShowLocationMode.Static -> {
|
||||
val senderLocation = rememberGeoJsonSource(
|
||||
data = GeoJsonData.Features(
|
||||
Point(
|
||||
Position(
|
||||
latitude = mode.location.lat,
|
||||
longitude = mode.location.lon
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
val marker = painterResource(R.drawable.pin_small)
|
||||
SymbolLayer(
|
||||
id = "sender_location",
|
||||
source = senderLocation,
|
||||
iconImage = image(marker)
|
||||
)
|
||||
val marker = painterResource(R.drawable.pin_small)
|
||||
SymbolLayer(
|
||||
id = "sender_location",
|
||||
source = senderLocation,
|
||||
iconImage = image(marker)
|
||||
)
|
||||
}
|
||||
ShowLocationMode.Live -> {
|
||||
// TODO: Show pins for all active live location sharers
|
||||
}
|
||||
}
|
||||
},
|
||||
overlayContent = {
|
||||
LocationFloatingActionButton(
|
||||
|
||||
Reference in New Issue
Block a user