Check user power level before sharing live location.
This commit is contained in:
parent
b0237a4e22
commit
e2cd75284f
@ -23,5 +23,6 @@ sealed class LocationSharingAction : VectorViewModelAction {
|
|||||||
data class PinnedLocationSharing(val locationData: LocationData?) : LocationSharingAction()
|
data class PinnedLocationSharing(val locationData: LocationData?) : LocationSharingAction()
|
||||||
data class LocationTargetChange(val locationData: LocationData) : LocationSharingAction()
|
data class LocationTargetChange(val locationData: LocationData) : LocationSharingAction()
|
||||||
object ZoomToUserLocation : LocationSharingAction()
|
object ZoomToUserLocation : LocationSharingAction()
|
||||||
|
object LiveLocationSharingRequested : LocationSharingAction()
|
||||||
data class StartLiveLocationSharing(val durationMillis: Long) : LocationSharingAction()
|
data class StartLiveLocationSharing(val durationMillis: Long) : LocationSharingAction()
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,9 @@ class LocationSharingFragment @Inject constructor(
|
|||||||
LocationSharingViewEvents.LocationNotAvailableError -> handleLocationNotAvailableError()
|
LocationSharingViewEvents.LocationNotAvailableError -> handleLocationNotAvailableError()
|
||||||
is LocationSharingViewEvents.ZoomToUserLocation -> handleZoomToUserLocationEvent(it)
|
is LocationSharingViewEvents.ZoomToUserLocation -> handleZoomToUserLocationEvent(it)
|
||||||
is LocationSharingViewEvents.StartLiveLocationService -> handleStartLiveLocationService(it)
|
is LocationSharingViewEvents.StartLiveLocationService -> handleStartLiveLocationService(it)
|
||||||
|
LocationSharingViewEvents.ChooseLiveLocationDuration -> handleChooseLiveLocationDuration()
|
||||||
|
LocationSharingViewEvents.ShowLabsFlagPromotion -> handleShowLabsFlagPromotion()
|
||||||
|
LocationSharingViewEvents.LiveLocationSharingNotEnoughPermission -> handleLiveLocationSharingNotEnoughPermission()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,6 +171,16 @@ class LocationSharingFragment @Inject constructor(
|
|||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleLiveLocationSharingNotEnoughPermission() {
|
||||||
|
MaterialAlertDialogBuilder(requireActivity())
|
||||||
|
.setTitle(R.string.live_location_not_enough_permission_dialog_title)
|
||||||
|
.setMessage(R.string.live_location_not_enough_permission_dialog_description)
|
||||||
|
.setPositiveButton(R.string.ok) { dialogInterface, _ ->
|
||||||
|
dialogInterface.dismiss()
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
private fun initLocateButton() {
|
private fun initLocateButton() {
|
||||||
views.mapView.locateButton.setOnClickListener {
|
views.mapView.locateButton.setOnClickListener {
|
||||||
viewModel.handle(LocationSharingAction.ZoomToUserLocation)
|
viewModel.handle(LocationSharingAction.ZoomToUserLocation)
|
||||||
@ -201,7 +214,7 @@ class LocationSharingFragment @Inject constructor(
|
|||||||
viewModel.handle(LocationSharingAction.CurrentUserLocationSharing)
|
viewModel.handle(LocationSharingAction.CurrentUserLocationSharing)
|
||||||
}
|
}
|
||||||
views.shareLocationOptionsPicker.optionUserLive.debouncedClicks {
|
views.shareLocationOptionsPicker.optionUserLive.debouncedClicks {
|
||||||
tryStartLiveLocationSharing()
|
viewModel.handle(LocationSharingAction.LiveLocationSharingRequested)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,13 +225,13 @@ class LocationSharingFragment @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryStartLiveLocationSharing() {
|
private fun handleChooseLiveLocationDuration() {
|
||||||
if (vectorPreferences.labsEnableLiveLocation()) {
|
startLiveLocationSharing()
|
||||||
startLiveLocationSharing()
|
}
|
||||||
} else {
|
|
||||||
LiveLocationLabsFlagPromotionBottomSheet.newInstance()
|
private fun handleShowLabsFlagPromotion() {
|
||||||
.show(requireActivity().supportFragmentManager, "DISPLAY_LIVE_LOCATION_LABS_FLAG_PROMOTION")
|
LiveLocationLabsFlagPromotionBottomSheet.newInstance()
|
||||||
}
|
.show(requireActivity().supportFragmentManager, "DISPLAY_LIVE_LOCATION_LABS_FLAG_PROMOTION")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val foregroundLocationResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
private val foregroundLocationResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||||
|
@ -23,4 +23,7 @@ sealed class LocationSharingViewEvents : VectorViewEvents {
|
|||||||
object LocationNotAvailableError : LocationSharingViewEvents()
|
object LocationNotAvailableError : LocationSharingViewEvents()
|
||||||
data class ZoomToUserLocation(val userLocation: LocationData) : LocationSharingViewEvents()
|
data class ZoomToUserLocation(val userLocation: LocationData) : LocationSharingViewEvents()
|
||||||
data class StartLiveLocationService(val sessionId: String, val roomId: String, val durationMillis: Long) : LocationSharingViewEvents()
|
data class StartLiveLocationService(val sessionId: String, val roomId: String, val durationMillis: Long) : LocationSharingViewEvents()
|
||||||
|
object ChooseLiveLocationDuration : LocationSharingViewEvents()
|
||||||
|
object ShowLabsFlagPromotion : LocationSharingViewEvents()
|
||||||
|
object LiveLocationSharingNotEnoughPermission : LocationSharingViewEvents()
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,8 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
|
|||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider
|
import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider
|
||||||
import im.vector.app.features.location.domain.usecase.CompareLocationsUseCase
|
import im.vector.app.features.location.domain.usecase.CompareLocationsUseCase
|
||||||
|
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
|
||||||
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.lastOrNull
|
import kotlinx.coroutines.flow.lastOrNull
|
||||||
@ -36,8 +38,10 @@ import kotlinx.coroutines.flow.sample
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
import org.matrix.android.sdk.api.session.getUser
|
import org.matrix.android.sdk.api.session.getUser
|
||||||
|
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
@ -52,6 +56,7 @@ class LocationSharingViewModel @AssistedInject constructor(
|
|||||||
private val locationPinProvider: LocationPinProvider,
|
private val locationPinProvider: LocationPinProvider,
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val compareLocationsUseCase: CompareLocationsUseCase,
|
private val compareLocationsUseCase: CompareLocationsUseCase,
|
||||||
|
private val vectorPreferences: VectorPreferences,
|
||||||
) : VectorViewModel<LocationSharingViewState, LocationSharingAction, LocationSharingViewEvents>(initialState), LocationTracker.Callback {
|
) : VectorViewModel<LocationSharingViewState, LocationSharingAction, LocationSharingViewEvents>(initialState), LocationTracker.Callback {
|
||||||
|
|
||||||
private val room = session.getRoom(initialState.roomId)!!
|
private val room = session.getRoom(initialState.roomId)!!
|
||||||
@ -70,6 +75,22 @@ class LocationSharingViewModel @AssistedInject constructor(
|
|||||||
setUserItem()
|
setUserItem()
|
||||||
updatePin()
|
updatePin()
|
||||||
compareTargetAndUserLocation()
|
compareTargetAndUserLocation()
|
||||||
|
checkPowerLevelsForLiveLocationSharing()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkPowerLevelsForLiveLocationSharing() {
|
||||||
|
PowerLevelsFlowFactory(room).createFlow()
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.onEach {
|
||||||
|
val powerLevelsHelper = PowerLevelsHelper(it)
|
||||||
|
val canShareLiveLocation = EventType.STATE_ROOM_BEACON_INFO
|
||||||
|
.map { beaconInfoType ->
|
||||||
|
powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, beaconInfoType)
|
||||||
|
}
|
||||||
|
.all { isUserAllowed -> isUserAllowed }
|
||||||
|
|
||||||
|
setState { copy(canShareLiveLocation = canShareLiveLocation) }
|
||||||
|
}.launchIn(viewModelScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initLocationTracking() {
|
private fun initLocationTracking() {
|
||||||
@ -130,10 +151,21 @@ class LocationSharingViewModel @AssistedInject constructor(
|
|||||||
is LocationSharingAction.PinnedLocationSharing -> handlePinnedLocationSharingAction(action)
|
is LocationSharingAction.PinnedLocationSharing -> handlePinnedLocationSharingAction(action)
|
||||||
is LocationSharingAction.LocationTargetChange -> handleLocationTargetChangeAction(action)
|
is LocationSharingAction.LocationTargetChange -> handleLocationTargetChangeAction(action)
|
||||||
LocationSharingAction.ZoomToUserLocation -> handleZoomToUserLocationAction()
|
LocationSharingAction.ZoomToUserLocation -> handleZoomToUserLocationAction()
|
||||||
|
LocationSharingAction.LiveLocationSharingRequested -> handleLiveLocationSharingRequestedAction()
|
||||||
is LocationSharingAction.StartLiveLocationSharing -> handleStartLiveLocationSharingAction(action.durationMillis)
|
is LocationSharingAction.StartLiveLocationSharing -> handleStartLiveLocationSharingAction(action.durationMillis)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleLiveLocationSharingRequestedAction() = withState { state ->
|
||||||
|
if (!state.canShareLiveLocation) {
|
||||||
|
_viewEvents.post(LocationSharingViewEvents.LiveLocationSharingNotEnoughPermission)
|
||||||
|
} else if (vectorPreferences.labsEnableLiveLocation()) {
|
||||||
|
_viewEvents.post(LocationSharingViewEvents.ChooseLiveLocationDuration)
|
||||||
|
} else {
|
||||||
|
_viewEvents.post(LocationSharingViewEvents.ShowLabsFlagPromotion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleCurrentUserLocationSharingAction() = withState { state ->
|
private fun handleCurrentUserLocationSharingAction() = withState { state ->
|
||||||
shareLocation(state.lastKnownUserLocation, isUserLocation = true)
|
shareLocation(state.lastKnownUserLocation, isUserLocation = true)
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,8 @@ data class LocationSharingViewState(
|
|||||||
val userItem: MatrixItem.UserItem? = null,
|
val userItem: MatrixItem.UserItem? = null,
|
||||||
val areTargetAndUserLocationEqual: Boolean? = null,
|
val areTargetAndUserLocationEqual: Boolean? = null,
|
||||||
val lastKnownUserLocation: LocationData? = null,
|
val lastKnownUserLocation: LocationData? = null,
|
||||||
val locationTargetDrawable: Drawable? = null
|
val locationTargetDrawable: Drawable? = null,
|
||||||
|
val canShareLiveLocation: Boolean = false,
|
||||||
) : MavericksState {
|
) : MavericksState {
|
||||||
|
|
||||||
constructor(locationSharingArgs: LocationSharingArgs) : this(
|
constructor(locationSharingArgs: LocationSharingArgs) : this(
|
||||||
|
@ -3054,6 +3054,8 @@
|
|||||||
<!-- TODO remove key -->
|
<!-- TODO remove key -->
|
||||||
<string name="live_location_bottom_sheet_stop_sharing" tools:ignore="UnusedResources">Stop sharing</string>
|
<string name="live_location_bottom_sheet_stop_sharing" tools:ignore="UnusedResources">Stop sharing</string>
|
||||||
<string name="live_location_bottom_sheet_last_updated_at">Updated %1$s ago</string>
|
<string name="live_location_bottom_sheet_last_updated_at">Updated %1$s ago</string>
|
||||||
|
<string name="live_location_not_enough_permission_dialog_title">You don’t have permission to share locations</string>
|
||||||
|
<string name="live_location_not_enough_permission_dialog_description">You need to have the right permissions in order to share locations in this room.</string>
|
||||||
|
|
||||||
<string name="message_bubbles">Show Message bubbles</string>
|
<string name="message_bubbles">Show Message bubbles</string>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user