Merge pull request #6587 from vector-im/feature/ons/fix_live_location_sharing_permission

Check user power level before sharing live location (PSG-620)
This commit is contained in:
Onuray Sahin 2022-07-20 15:01:32 +03:00 committed by GitHub
commit 7f821f1285
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 59 additions and 9 deletions

1
changelog.d/6587.bugfix Normal file
View file

@ -0,0 +1 @@
Check user power level before sharing live location

View file

@ -23,5 +23,6 @@ sealed class LocationSharingAction : VectorViewModelAction {
data class PinnedLocationSharing(val locationData: LocationData?) : LocationSharingAction()
data class LocationTargetChange(val locationData: LocationData) : LocationSharingAction()
object ZoomToUserLocation : LocationSharingAction()
object LiveLocationSharingRequested : LocationSharingAction()
data class StartLiveLocationSharing(val durationMillis: Long) : LocationSharingAction()
}

View file

@ -104,6 +104,9 @@ class LocationSharingFragment @Inject constructor(
LocationSharingViewEvents.LocationNotAvailableError -> handleLocationNotAvailableError()
is LocationSharingViewEvents.ZoomToUserLocation -> handleZoomToUserLocationEvent(it)
is LocationSharingViewEvents.StartLiveLocationService -> handleStartLiveLocationService(it)
LocationSharingViewEvents.ChooseLiveLocationDuration -> handleChooseLiveLocationDuration()
LocationSharingViewEvents.ShowLabsFlagPromotion -> handleShowLabsFlagPromotion()
LocationSharingViewEvents.LiveLocationSharingNotEnoughPermission -> handleLiveLocationSharingNotEnoughPermission()
}
}
}
@ -168,6 +171,14 @@ class LocationSharingFragment @Inject constructor(
.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, null)
.show()
}
private fun initLocateButton() {
views.mapView.locateButton.setOnClickListener {
viewModel.handle(LocationSharingAction.ZoomToUserLocation)
@ -201,7 +212,7 @@ class LocationSharingFragment @Inject constructor(
viewModel.handle(LocationSharingAction.CurrentUserLocationSharing)
}
views.shareLocationOptionsPicker.optionUserLive.debouncedClicks {
tryStartLiveLocationSharing()
viewModel.handle(LocationSharingAction.LiveLocationSharingRequested)
}
}
@ -212,13 +223,13 @@ class LocationSharingFragment @Inject constructor(
}
}
private fun tryStartLiveLocationSharing() {
if (vectorPreferences.labsEnableLiveLocation()) {
startLiveLocationSharing()
} else {
LiveLocationLabsFlagPromotionBottomSheet.newInstance()
.show(requireActivity().supportFragmentManager, "DISPLAY_LIVE_LOCATION_LABS_FLAG_PROMOTION")
}
private fun handleChooseLiveLocationDuration() {
startLiveLocationSharing()
}
private fun handleShowLabsFlagPromotion() {
LiveLocationLabsFlagPromotionBottomSheet.newInstance()
.show(requireActivity().supportFragmentManager, "DISPLAY_LIVE_LOCATION_LABS_FLAG_PROMOTION")
}
private val foregroundLocationResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->

View file

@ -23,4 +23,7 @@ sealed class LocationSharingViewEvents : VectorViewEvents {
object LocationNotAvailableError : LocationSharingViewEvents()
data class ZoomToUserLocation(val userLocation: LocationData) : LocationSharingViewEvents()
data class StartLiveLocationService(val sessionId: String, val roomId: String, val durationMillis: Long) : LocationSharingViewEvents()
object ChooseLiveLocationDuration : LocationSharingViewEvents()
object ShowLabsFlagPromotion : LocationSharingViewEvents()
object LiveLocationSharingNotEnoughPermission : LocationSharingViewEvents()
}

View file

@ -26,6 +26,8 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.platform.VectorViewModel
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.powerlevel.PowerLevelsFlowFactory
import im.vector.app.features.settings.VectorPreferences
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.lastOrNull
@ -36,8 +38,10 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.extensions.orFalse
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.getUser
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.util.toMatrixItem
import timber.log.Timber
@ -52,6 +56,7 @@ class LocationSharingViewModel @AssistedInject constructor(
private val locationPinProvider: LocationPinProvider,
private val session: Session,
private val compareLocationsUseCase: CompareLocationsUseCase,
private val vectorPreferences: VectorPreferences,
) : VectorViewModel<LocationSharingViewState, LocationSharingAction, LocationSharingViewEvents>(initialState), LocationTracker.Callback {
private val room = session.getRoom(initialState.roomId)!!
@ -70,6 +75,21 @@ class LocationSharingViewModel @AssistedInject constructor(
setUserItem()
updatePin()
compareTargetAndUserLocation()
observePowerLevelsForLiveLocationSharing()
}
private fun observePowerLevelsForLiveLocationSharing() {
PowerLevelsFlowFactory(room).createFlow()
.distinctUntilChanged()
.setOnEach {
val powerLevelsHelper = PowerLevelsHelper(it)
val canShareLiveLocation = EventType.STATE_ROOM_BEACON_INFO
.all { beaconInfoType ->
powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, beaconInfoType)
}
copy(canShareLiveLocation = canShareLiveLocation)
}
}
private fun initLocationTracking() {
@ -130,10 +150,21 @@ class LocationSharingViewModel @AssistedInject constructor(
is LocationSharingAction.PinnedLocationSharing -> handlePinnedLocationSharingAction(action)
is LocationSharingAction.LocationTargetChange -> handleLocationTargetChangeAction(action)
LocationSharingAction.ZoomToUserLocation -> handleZoomToUserLocationAction()
LocationSharingAction.LiveLocationSharingRequested -> handleLiveLocationSharingRequestedAction()
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 ->
shareLocation(state.lastKnownUserLocation, isUserLocation = true)
}

View file

@ -34,7 +34,8 @@ data class LocationSharingViewState(
val userItem: MatrixItem.UserItem? = null,
val areTargetAndUserLocationEqual: Boolean? = null,
val lastKnownUserLocation: LocationData? = null,
val locationTargetDrawable: Drawable? = null
val locationTargetDrawable: Drawable? = null,
val canShareLiveLocation: Boolean = false,
) : MavericksState {
constructor(locationSharingArgs: LocationSharingArgs) : this(

View file

@ -3116,6 +3116,8 @@
<!-- TODO remove key -->
<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_not_enough_permission_dialog_title">You dont have permission to share live location</string>
<string name="live_location_not_enough_permission_dialog_description">You need to have the right permissions in order to share live location in this room.</string>
<string name="live_location_share_location_item_share">Share location</string>
<string name="message_bubbles">Show Message bubbles</string>