diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt
index 1ae4fa2182..188f8129f8 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/LocationConstraintsDialog.kt
@@ -8,17 +8,11 @@
package io.element.android.features.location.impl.common.ui
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
import androidx.compose.ui.res.stringResource
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.libraries.ui.strings.CommonStrings
-sealed interface LocationConstraintsDialogState {
- data object None : LocationConstraintsDialogState
- data object PermissionRationale : LocationConstraintsDialogState
- data object PermissionDenied : LocationConstraintsDialogState
- data object LocationServiceDisabled : LocationConstraintsDialogState
-}
-
@Composable
fun LocationConstraintsDialog(
state: LocationConstraintsDialogState,
@@ -53,3 +47,11 @@ fun LocationConstraintsDialog(
)
}
}
+
+@Immutable
+sealed interface LocationConstraintsDialogState {
+ data object None : LocationConstraintsDialogState
+ data object PermissionRationale : LocationConstraintsDialogState
+ data object PermissionDenied : LocationConstraintsDialogState
+ data object LocationServiceDisabled : LocationConstraintsDialogState
+}
diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt
index 33726de6e8..09c5067e1a 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/MapBottomSheetScaffold.kt
@@ -60,15 +60,16 @@ import kotlin.math.roundToInt
* - Updating camera position padding based on sheet height
* - Rendering the MaplibreMap with proper ornament positioning
*
- * @param cameraState The camera state for the map
- * @param topBar The top app bar content
- * @param sheetContent The content to display in the bottom sheet
* @param modifier Modifier for the root layout
* @param scaffoldState State for the bottom sheet scaffold
+ * @param cameraState The camera state for the map
+ * @param mapOptions The options to configure the map
* @param sheetPeekHeight The height of the sheet when collapsed
* @param sheetDragHandle Optional drag handle for the sheet
* @param sheetSwipeEnabled Whether the sheet can be swiped
+ * @param topBar The top app bar content
* @param snackbarHost The snackbar host content
+ * @param sheetContent The content to display in the bottom sheet
* @param mapContent The content inside the MaplibreMap (layers, location pucks, etc.)
* @param overlayContent Content to overlay on top of the map (FAB, pin icons, etc.)
*/
diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt
index f014debe08..8b89f77be4 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/ui/UserLocationPuck.kt
@@ -7,6 +7,7 @@
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
@@ -63,6 +64,7 @@ fun UserLocationPuck(
}
}
+@SuppressLint("MissingPermission")
@Composable
fun rememberUserLocationState(hasLocationPermission: Boolean): UserLocationState {
val isPreview = LocalInspectionMode.current
diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt
index ec5414de77..56b7b073d9 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt
@@ -126,7 +126,7 @@ class ShareLocationPresenter(
dialogState = dialogState,
trackUserLocation = trackUserPosition,
hasLocationPermission = permissionsState.isAnyGranted,
- canShareLiveLocation = false,
+ canShareLiveLocation = isLiveLocationSharingEnabled,
appName = appName,
eventSink = ::handleEvent,
)
diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt
index f562647bc9..ecb4cf9dd4 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationView.kt
@@ -8,11 +8,13 @@
package io.element.android.features.location.impl.share
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.SheetValue
import androidx.compose.material3.rememberBottomSheetScaffoldState
@@ -20,9 +22,12 @@ import androidx.compose.material3.rememberStandardBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
@@ -36,11 +41,14 @@ import io.element.android.features.location.impl.common.ui.LocationFloatingActio
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.androidutils.system.toast
import io.element.android.libraries.designsystem.components.LocationPin
import io.element.android.libraries.designsystem.components.PinVariant
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.button.BackButton
+import io.element.android.libraries.designsystem.components.dialogs.ListDialog
import io.element.android.libraries.designsystem.components.list.ListItemContent
+import io.element.android.libraries.designsystem.components.list.RadioButtonListItem
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.IconSource
@@ -62,6 +70,7 @@ fun ShareLocationView(
navigateUp: () -> Unit,
modifier: Modifier = Modifier,
) {
+ val context = LocalContext.current
when (val dialogState = state.dialogState) {
ShareLocationState.Dialog.None -> Unit
is ShareLocationState.Dialog.Constraints -> LocationConstraintsDialog(
@@ -75,6 +84,7 @@ fun ShareLocationView(
ShareLocationState.Dialog.LiveLocationDuration -> LiveLocationDurationDialog(
onSelectDuration = { duration ->
state.eventSink(ShareLocationEvent.StartLiveLocationShare(duration))
+ context.toast("Not implemented yet!")
navigateUp()
},
onDismiss = { state.eventSink(ShareLocationEvent.DismissDialog) },
@@ -129,7 +139,7 @@ fun ShareLocationView(
.padding(sheetPadding)
) {
val variant = if (state.trackUserLocation) {
- PinVariant.UserLocation(isLive = false, avatarData = state.currentUser.getAvatarData(AvatarSize.SelectedUser))
+ PinVariant.UserLocation(isLive = false, avatarData = state.currentUser.getAvatarData(AvatarSize.LocationPin))
} else {
PinVariant.PinnedLocation
}
@@ -243,7 +253,6 @@ private fun LiveLocationDurationDialog(
onSelectDuration: (Duration) -> Unit,
onDismiss: () -> Unit,
) {
- /*
var selectedIndex by remember { mutableIntStateOf(0) }
ListDialog(
title = "Choose how long to share your live location.",
@@ -263,7 +272,6 @@ private fun LiveLocationDurationDialog(
)
}
}
- */
}
@PreviewsDayNight
diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt
index 7289ec000c..9bbd818f1a 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationStateProvider.kt
@@ -68,7 +68,7 @@ fun aShowLocationState(
id = mode.senderId.value,
name = mode.senderName,
url = mode.senderAvatarUrl,
- size = AvatarSize.UserListItem,
+ size = AvatarSize.LocationPin,
),
isLive = true,
)
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt
index fce44debd2..aa9fb6b71e 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemLocationContent.kt
@@ -49,8 +49,7 @@ data class TimelineItemLocationContent(
senderId.value,
name = senderProfile.getDisplayName(),
url = senderProfile.getAvatarUrl(),
- // Size is irrelevant as the PinMarker will override anyway.
- size = AvatarSize.TimelineSender
+ size = AvatarSize.LocationPin
)
sealed interface Mode {
diff --git a/features/messages/impl/src/main/res/values/localazy.xml b/features/messages/impl/src/main/res/values/localazy.xml
index e8f4d4e6e5..f5629f5e2d 100644
--- a/features/messages/impl/src/main/res/values/localazy.xml
+++ b/features/messages/impl/src/main/res/values/localazy.xml
@@ -35,7 +35,7 @@
"Record video"
"Attachment"
"Photo & Video Library"
- "Location"
+ "Share location"
"Poll"
"Text Formatting"
"Message history is currently unavailable."
diff --git a/features/networkmonitor/impl/src/main/kotlin/io/element/android/features/networkmonitor/impl/DefaultNetworkMonitor.kt b/features/networkmonitor/impl/src/main/kotlin/io/element/android/features/networkmonitor/impl/DefaultNetworkMonitor.kt
index 949db720ce..7cffa057bc 100644
--- a/features/networkmonitor/impl/src/main/kotlin/io/element/android/features/networkmonitor/impl/DefaultNetworkMonitor.kt
+++ b/features/networkmonitor/impl/src/main/kotlin/io/element/android/features/networkmonitor/impl/DefaultNetworkMonitor.kt
@@ -15,6 +15,7 @@ import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
+import android.os.Build
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.SingleIn
@@ -83,7 +84,9 @@ class DefaultNetworkMonitor(
if (network.networkHandle == connectivityManager.activeNetwork?.networkHandle) {
// If the network doesn't have the NET_CAPABILITY_VALIDATED capability, it means that the network is not able to reach the internet
// (according to Google), which is a common case in air-gapped environments.
- isInAirGappedEnvironment.value = !networkCapabilities.capabilities.contains(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ isInAirGappedEnvironment.value = !networkCapabilities.capabilities.contains(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
+ }
}
}
diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt
index 9fc0d1d27e..af8e29d518 100644
--- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt
+++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LocationPin.kt
@@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
@@ -60,6 +61,7 @@ private val STROKE_WIDTH = 1.dp
/**
* Variants of location pin markers.
*/
+@Immutable
sealed interface PinVariant {
data class UserLocation(
val avatarData: AvatarData,
diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt
index 8407445394..cd29773a5b 100644
--- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt
+++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt
@@ -75,6 +75,6 @@ enum class AvatarSize(val dp: Dp) {
SpaceMember(24.dp),
LeaveSpaceRoom(32.dp),
SelectParentSpace(32.dp),
-
AccountItem(32.dp),
+ LocationPin(32.dp)
}