Adding static pin at the center of the map

This commit is contained in:
Maxime Naturel 2022-03-04 15:32:36 +01:00
parent 9256b5671b
commit a1d155df71
8 changed files with 67 additions and 17 deletions

View File

@ -123,7 +123,7 @@ class LocationPreviewFragment @Inject constructor(
views.mapView.render(
MapState(
zoomOnlyOnce = true,
pinLocationData = location,
userLocationData = location,
pinId = args.locationOwnerId ?: DEFAULT_PIN_ID,
pinDrawable = pinDrawable
)

View File

@ -16,6 +16,7 @@
package im.vector.app.features.location
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -52,6 +53,7 @@ class LocationSharingFragment @Inject constructor(
private var mapView: WeakReference<MapView>? = null
private var hasRenderedUserAvatar = false
private var hasUpdatedPin = false
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLocationSharingBinding {
return FragmentLocationSharingBinding.inflate(inflater, container, false)
@ -116,7 +118,11 @@ class LocationSharingFragment @Inject constructor(
override fun invalidate() = withState(viewModel) { state ->
updateMap(state)
updateUserAvatar(state.userItem)
views.shareLocationGpsLoading.isGone = state.lastKnownLocation != null
if(!hasUpdatedPin && state.pinDrawable != null) {
hasUpdatedPin = true
updateStaticPin(state.pinDrawable)
}
views.shareLocationGpsLoading.isGone = state.lastKnownUserLocation != null
}
private fun handleLocationNotAvailableError() {
@ -132,10 +138,14 @@ class LocationSharingFragment @Inject constructor(
private fun initOptionsPicker() {
// TODO
// move pin creation into the Fragment
// create a useCase to compare pinnedLocation and userLocation
// change the pin dynamically depending on the current chosen location: cf. LocationPinProvider
// make the pin stay at the center of the map: selected location is the center of the map
// reset map to user location when clicking on reset icon
// 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?
// set no option at start
views.shareLocationOptionsPicker.render()
views.shareLocationOptionsPicker.optionPinned.debouncedClicks {
// TODO
}
@ -148,8 +158,10 @@ class LocationSharingFragment @Inject constructor(
}
private fun updateMap(state: LocationSharingViewState) {
// first update the options view
if (state.isUserLocation) {
// first, update the options view
// TODO compute distance between userLocation and location at center of map
val isUserLocation = true
if (isUserLocation) {
// TODO activate USER_LIVE option when implemented
views.shareLocationOptionsPicker.render(
LocationSharingOption.USER_CURRENT
@ -159,10 +171,13 @@ class LocationSharingFragment @Inject constructor(
LocationSharingOption.PINNED
)
}
val mapState = state
.toMapState()
.copy(logoMarginBottom = views.shareLocationOptionsPicker.height)
views.mapView.render(mapState)
// then, update the map using the height of the options view after it has been rendered
views.shareLocationOptionsPicker.post {
val mapState = state
.toMapState()
.copy(logoMarginBottom = views.shareLocationOptionsPicker.height)
views.mapView.render(mapState)
}
}
private fun updateUserAvatar(userItem: MatrixItem.UserItem?) {
@ -174,4 +189,8 @@ class LocationSharingFragment @Inject constructor(
views.shareLocationOptionsPicker.optionUserCurrent.setIconBackgroundTint(tintColor)
}
}
private fun updateStaticPin(drawable: Drawable) {
views.shareLocationPin.setImageDrawable(drawable)
}
}

View File

@ -76,7 +76,7 @@ class LocationSharingViewModel @AssistedInject constructor(
}
private fun handleShareLocation() = withState { state ->
state.lastKnownLocation?.let { location ->
state.lastKnownUserLocation?.let { location ->
room.sendLocation(
latitude = location.latitude,
longitude = location.longitude,
@ -90,7 +90,7 @@ class LocationSharingViewModel @AssistedInject constructor(
override fun onLocationUpdate(locationData: LocationData) {
setState {
copy(lastKnownLocation = locationData)
copy(lastKnownUserLocation = locationData)
}
}

View File

@ -30,9 +30,9 @@ enum class LocationSharingMode(@StringRes val titleRes: Int) {
data class LocationSharingViewState(
val roomId: String,
val mode: LocationSharingMode,
val isUserLocation: Boolean = false,
val userItem: MatrixItem.UserItem? = null,
val lastKnownLocation: LocationData? = null,
val lastKnownUserLocation: LocationData? = null,
// TODO move pin drawable creation into the view?
val pinDrawable: Drawable? = null
) : MavericksState {
@ -44,7 +44,7 @@ data class LocationSharingViewState(
fun LocationSharingViewState.toMapState() = MapState(
zoomOnlyOnce = true,
pinLocationData = lastKnownLocation,
userLocationData = lastKnownUserLocation,
pinId = DEFAULT_PIN_ID,
pinDrawable = pinDrawable
)

View File

@ -21,7 +21,7 @@ import androidx.annotation.Px
data class MapState(
val zoomOnlyOnce: Boolean,
val pinLocationData: LocationData? = null,
val userLocationData: LocationData? = null,
val pinId: String,
val pinDrawable: Drawable? = null,
@Px val logoMarginBottom: Int = 0

View File

@ -70,6 +70,9 @@ class MapTilerMapView @JvmOverloads constructor(
safeMapRefs.map.uiSettings.setLogoMargins(0, 0, 0, state.logoMarginBottom)
// TODO display a dot pin for userLocation instead of pinDrawable
// TODO add reset to user location button
// TODO check conflict of rendering with preview location in timeline
state.pinDrawable?.let { pinDrawable ->
if (!safeMapRefs.style.isFullyLoaded ||
safeMapRefs.style.getImage(state.pinId) == null) {
@ -77,7 +80,7 @@ class MapTilerMapView @JvmOverloads constructor(
}
}
state.pinLocationData?.let { locationData ->
state.userLocationData?.let { locationData ->
if (!initZoomDone || !state.zoomOnlyOnce) {
zoomToLocation(locationData.latitude, locationData.longitude)
initZoomDone = true
@ -100,4 +103,13 @@ class MapTilerMapView @JvmOverloads constructor(
.zoom(INITIAL_MAP_ZOOM_IN_PREVIEW)
.build()
}
fun getLocationOfMapCenter(): LocationData? =
mapRefs?.map?.cameraPosition?.target?.let { target ->
LocationData(
latitude = target.latitude,
longitude = target.longitude,
uncertainty = null
)
}
}

View File

@ -10,12 +10,30 @@
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:mapbox_renderTextureMode="true"
tools:background="#4F00" />
<ImageView
android:id="@+id/shareLocationPin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/a11y_location_share_pin_on_map"
app:layout_constraintBottom_toTopOf="@id/shareLocationMapCenter"
app:layout_constraintEnd_toEndOf="@id/mapView"
app:layout_constraintStart_toStartOf="@id/mapView" />
<ViewStub
android:id="@+id/shareLocationMapCenter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@id/mapView"
app:layout_constraintEnd_toEndOf="@id/mapView"
app:layout_constraintStart_toStartOf="@id/mapView"
app:layout_constraintTop_toTopOf="@id/mapView" />
<im.vector.app.features.location.option.LocationSharingOptionPickerView
android:id="@+id/shareLocationOptionsPicker"
android:layout_width="0dp"

View File

@ -2929,6 +2929,7 @@
<string name="a11y_static_map_image">Map</string>
<!-- TODO delete -->
<string name="location_share" tools:ignore="UnusedResources">Share location</string>
<string name="a11y_location_share_pin_on_map">Pin of selected location on map</string>
<string name="location_share_option_user_current">Share my current location</string>
<string name="a11y_location_share_option_user_current_icon">Share my current location</string>
<string name="location_share_option_user_live">Share live location</string>