Updating location target drawable dynamically

This commit is contained in:
Maxime Naturel 2022-03-07 14:55:50 +01:00
parent 6fc6bf1c7d
commit 93c397d492
3 changed files with 25 additions and 19 deletions

View File

@ -53,7 +53,6 @@ class LocationSharingFragment @Inject constructor(
private var mapView: WeakReference<MapView>? = null private var mapView: WeakReference<MapView>? = null
private var hasRenderedUserAvatar = false private var hasRenderedUserAvatar = false
private var hasUpdatedPin = false
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLocationSharingBinding { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLocationSharingBinding {
return FragmentLocationSharingBinding.inflate(inflater, container, false) return FragmentLocationSharingBinding.inflate(inflater, container, false)
@ -125,9 +124,8 @@ class LocationSharingFragment @Inject constructor(
override fun invalidate() = withState(viewModel) { state -> override fun invalidate() = withState(viewModel) { state ->
updateMap(state) updateMap(state)
updateUserAvatar(state.userItem) updateUserAvatar(state.userItem)
if (!hasUpdatedPin && state.pinDrawable != null) { if (state.locationTargetDrawable != null) {
hasUpdatedPin = true updateLocationTargetPin(state.locationTargetDrawable)
updateStaticPin(state.pinDrawable)
} }
views.shareLocationGpsLoading.isGone = state.lastKnownUserLocation != null views.shareLocationGpsLoading.isGone = state.lastKnownUserLocation != null
} }
@ -145,10 +143,8 @@ class LocationSharingFragment @Inject constructor(
private fun initOptionsPicker() { private fun initOptionsPicker() {
// TODO // TODO
// create a useCase to compare 2 locations
// update options menu dynamically
// move pin creation into the Fragment? => need to ask other's opinions
// reset map to user location when clicking on reset icon // reset map to user location when clicking on reset icon
// unit tests
// need changes in the event sent when this is a pin drop location? // need changes in the event sent when this is a pin drop location?
// need changes in the parsing of events when receiving pin drop location?: should it be shown with user avatar or with pin? // need changes in the parsing of events when receiving pin drop location?: should it be shown with user avatar or with pin?
// set no option at start // set no option at start
@ -196,7 +192,7 @@ class LocationSharingFragment @Inject constructor(
} }
} }
private fun updateStaticPin(drawable: Drawable) { private fun updateLocationTargetPin(drawable: Drawable) {
views.shareLocationPin.setImageDrawable(drawable) views.shareLocationPin.setImageDrawable(drawable)
} }
} }

View File

@ -16,6 +16,7 @@
package im.vector.app.features.location package im.vector.app.features.location
import android.graphics.drawable.Drawable
import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.MavericksViewModelFactory
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
@ -60,7 +61,7 @@ class LocationSharingViewModel @AssistedInject constructor(
init { init {
locationTracker.start(this) locationTracker.start(this)
setUserItem() setUserItem()
createPin() updatePin()
compareTargetAndUserLocation() compareTargetAndUserLocation()
} }
@ -68,23 +69,33 @@ class LocationSharingViewModel @AssistedInject constructor(
setState { copy(userItem = session.getUser(session.myUserId)?.toMatrixItem()) } setState { copy(userItem = session.getUser(session.myUserId)?.toMatrixItem()) }
} }
private fun createPin() { private fun updatePin(isUserPin: Boolean? = true) {
locationPinProvider.create(session.myUserId) { if (isUserPin == true) {
locationPinProvider.create(userId = session.myUserId) {
updatePinDrawableInState(it)
}
} else {
locationPinProvider.create(userId = null) {
updatePinDrawableInState(it)
}
}
}
private fun updatePinDrawableInState(drawable: Drawable) {
setState { setState {
copy( copy(
pinDrawable = it locationTargetDrawable = drawable
) )
} }
} }
}
private fun compareTargetAndUserLocation() { private fun compareTargetAndUserLocation() {
locationTargetFlow locationTargetFlow
.sample(TARGET_LOCATION_CHANGE_SAMPLING_PERIOD_IN_MS) .sample(TARGET_LOCATION_CHANGE_SAMPLING_PERIOD_IN_MS)
.map { compareTargetLocation(it) } .map { compareTargetLocation(it) }
.distinctUntilChanged() .distinctUntilChanged()
// TODO change the pin dynamically depending on the current chosen location: cf. LocationPinProvider
.onEach { setState { copy(areTargetAndUserLocationEqual = it) } } .onEach { setState { copy(areTargetAndUserLocationEqual = it) } }
.onEach { updatePin(isUserPin = it) }
.launchIn(viewModelScope) .launchIn(viewModelScope)
} }

View File

@ -33,8 +33,7 @@ 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,
// TODO move pin drawable creation into the view? val locationTargetDrawable: Drawable? = null
val pinDrawable: Drawable? = null
) : MavericksState { ) : MavericksState {
constructor(locationSharingArgs: LocationSharingArgs) : this( constructor(locationSharingArgs: LocationSharingArgs) : this(
@ -47,5 +46,5 @@ fun LocationSharingViewState.toMapState() = MapState(
zoomOnlyOnce = true, zoomOnlyOnce = true,
userLocationData = lastKnownUserLocation, userLocationData = lastKnownUserLocation,
pinId = DEFAULT_PIN_ID, pinId = DEFAULT_PIN_ID,
pinDrawable = pinDrawable pinDrawable = locationTargetDrawable
) )