mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-16 12:00:03 +03:00
Rendering the user location pin
This commit is contained in:
parent
d23636900f
commit
a4211d8482
6 changed files with 61 additions and 31 deletions
|
@ -47,7 +47,7 @@ data class LocationSharingViewState(
|
|||
|
||||
fun LocationSharingViewState.toMapState() = MapState(
|
||||
zoomOnlyOnce = true,
|
||||
userLocationData = lastKnownUserLocation,
|
||||
pinLocationData = lastKnownUserLocation,
|
||||
pinId = DEFAULT_PIN_ID,
|
||||
pinDrawable = null,
|
||||
// show the map pin only when target location and user location are not equal
|
||||
|
|
|
@ -21,9 +21,10 @@ import androidx.annotation.Px
|
|||
|
||||
data class MapState(
|
||||
val zoomOnlyOnce: Boolean,
|
||||
val userLocationData: LocationData? = null,
|
||||
val pinLocationData: LocationData? = null,
|
||||
val pinId: String,
|
||||
val pinDrawable: Drawable? = null,
|
||||
val showPin: Boolean = true,
|
||||
@Px val logoMarginBottom: Int = 0
|
||||
val userLocationData: LocationData? = null,
|
||||
@Px val logoMarginBottom: Int = 0,
|
||||
)
|
||||
|
|
|
@ -38,6 +38,8 @@ import im.vector.app.R
|
|||
import im.vector.app.core.utils.DimensionConverter
|
||||
import timber.log.Timber
|
||||
|
||||
private const val USER_PIN_ID = "user-pin-id"
|
||||
|
||||
class MapTilerMapView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
|
@ -173,13 +175,13 @@ class MapTilerMapView @JvmOverloads constructor(
|
|||
}
|
||||
}
|
||||
|
||||
state.userLocationData?.let { locationData ->
|
||||
safeMapRefs.symbolManager.deleteAll()
|
||||
state.pinLocationData?.let { locationData ->
|
||||
if (!initZoomDone || !state.zoomOnlyOnce) {
|
||||
zoomToLocation(locationData)
|
||||
initZoomDone = true
|
||||
}
|
||||
|
||||
safeMapRefs.symbolManager.deleteAll()
|
||||
if (pinDrawable != null && state.showPin) {
|
||||
safeMapRefs.symbolManager.create(
|
||||
SymbolOptions()
|
||||
|
@ -189,6 +191,20 @@ class MapTilerMapView @JvmOverloads constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
state.userLocationData?.let { locationData ->
|
||||
if (!safeMapRefs.style.isFullyLoaded || safeMapRefs.style.getImage(USER_PIN_ID) == null) {
|
||||
userLocationDrawable?.let { drawable ->
|
||||
safeMapRefs.style.addImage(USER_PIN_ID, drawable.toBitmap())
|
||||
}
|
||||
}
|
||||
safeMapRefs.symbolManager.create(
|
||||
SymbolOptions()
|
||||
.withLatLng(LatLng(locationData.latitude, locationData.longitude))
|
||||
.withIconImage(USER_PIN_ID)
|
||||
.withIconAnchor(Property.ICON_ANCHOR_BOTTOM)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun zoomToLocation(locationData: LocationData) {
|
||||
|
|
|
@ -37,7 +37,6 @@ import im.vector.app.core.utils.onPermissionDeniedDialog
|
|||
import im.vector.app.core.utils.openLocation
|
||||
import im.vector.app.core.utils.registerForPermissionsResult
|
||||
import im.vector.app.databinding.FragmentLocationPreviewBinding
|
||||
import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider
|
||||
import im.vector.app.features.location.DEFAULT_PIN_ID
|
||||
import im.vector.app.features.location.LocationSharingArgs
|
||||
import im.vector.app.features.location.MapState
|
||||
|
@ -46,8 +45,8 @@ import im.vector.app.features.location.showUserLocationNotAvailableErrorDialog
|
|||
import java.lang.ref.WeakReference
|
||||
import javax.inject.Inject
|
||||
|
||||
/*
|
||||
* TODO Move locationPinProvider to a ViewModel
|
||||
/**
|
||||
* Screen displaying the expanded map of a static location share.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class LocationPreviewFragment :
|
||||
|
@ -55,7 +54,6 @@ class LocationPreviewFragment :
|
|||
VectorMenuProvider {
|
||||
|
||||
@Inject lateinit var urlMapProvider: UrlMapProvider
|
||||
@Inject lateinit var locationPinProvider: LocationPinProvider
|
||||
|
||||
private val args: LocationSharingArgs by args()
|
||||
|
||||
|
@ -81,7 +79,6 @@ class LocationPreviewFragment :
|
|||
|
||||
lifecycleScope.launchWhenCreated {
|
||||
views.mapView.initialize(urlMapProvider.getMapUrl())
|
||||
loadPinDrawable()
|
||||
}
|
||||
|
||||
observeViewEvents()
|
||||
|
@ -151,12 +148,24 @@ class LocationPreviewFragment :
|
|||
|
||||
override fun invalidate() = withState(viewModel) { state ->
|
||||
views.mapPreviewLoadingError.isVisible = state.loadingMapHasFailed
|
||||
// TODO render pin for user location
|
||||
if(state.isLoadingUserLocation) {
|
||||
if (state.isLoadingUserLocation) {
|
||||
showLoadingDialog()
|
||||
} else {
|
||||
dismissLoadingDialog()
|
||||
}
|
||||
updateMap(state)
|
||||
}
|
||||
|
||||
private fun updateMap(viewState: LocationPreviewViewState) {
|
||||
views.mapView.render(
|
||||
MapState(
|
||||
zoomOnlyOnce = true,
|
||||
pinLocationData = viewState.pinLocationData,
|
||||
pinId = viewState.pinUserId ?: DEFAULT_PIN_ID,
|
||||
pinDrawable = viewState.pinDrawable,
|
||||
userLocationData = viewState.lastKnownUserLocation,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getMenuRes() = R.menu.menu_location_preview
|
||||
|
@ -176,24 +185,6 @@ class LocationPreviewFragment :
|
|||
openLocation(requireActivity(), location.latitude, location.longitude)
|
||||
}
|
||||
|
||||
private fun loadPinDrawable() {
|
||||
val location = args.initialLocationData ?: return
|
||||
val userId = args.locationOwnerId
|
||||
|
||||
locationPinProvider.create(userId) { pinDrawable ->
|
||||
lifecycleScope.launchWhenResumed {
|
||||
views.mapView.render(
|
||||
MapState(
|
||||
zoomOnlyOnce = true,
|
||||
userLocationData = location,
|
||||
pinId = args.locationOwnerId ?: DEFAULT_PIN_ID,
|
||||
pinDrawable = pinDrawable,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initLocateButton() {
|
||||
views.mapView.locateButton.setOnClickListener {
|
||||
if (checkPermissions(PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING, requireActivity(), foregroundLocationResultLauncher)) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import dagger.assisted.AssistedInject
|
|||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||
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.LocationData
|
||||
import im.vector.app.features.location.LocationTracker
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -32,6 +33,7 @@ import kotlinx.coroutines.launch
|
|||
|
||||
class LocationPreviewViewModel @AssistedInject constructor(
|
||||
@Assisted private val initialState: LocationPreviewViewState,
|
||||
private val locationPinProvider: LocationPinProvider,
|
||||
private val locationTracker: LocationTracker,
|
||||
) : VectorViewModel<LocationPreviewViewState, LocationPreviewAction, LocationPreviewViewEvents>(initialState), LocationTracker.Callback {
|
||||
|
||||
|
@ -43,9 +45,18 @@ class LocationPreviewViewModel @AssistedInject constructor(
|
|||
companion object : MavericksViewModelFactory<LocationPreviewViewModel, LocationPreviewViewState> by hiltMavericksViewModelFactory()
|
||||
|
||||
init {
|
||||
initialState.pinUserId?.let { userId ->
|
||||
initPin(userId)
|
||||
}
|
||||
initLocationTracking()
|
||||
}
|
||||
|
||||
private fun initPin(userId: String) {
|
||||
locationPinProvider.create(userId) { pinDrawable ->
|
||||
setState { copy(pinDrawable = pinDrawable) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun initLocationTracking() {
|
||||
locationTracker.addCallback(this)
|
||||
locationTracker.locations
|
||||
|
|
|
@ -16,11 +16,22 @@
|
|||
|
||||
package im.vector.app.features.location.preview
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import com.airbnb.mvrx.MavericksState
|
||||
import im.vector.app.features.location.LocationData
|
||||
import im.vector.app.features.location.LocationSharingArgs
|
||||
|
||||
data class LocationPreviewViewState(
|
||||
val pinLocationData: LocationData? = null,
|
||||
val pinUserId: String? = null,
|
||||
val pinDrawable: Drawable? = null,
|
||||
val loadingMapHasFailed: Boolean = false,
|
||||
val isLoadingUserLocation: Boolean = false,
|
||||
val lastKnownUserLocation: LocationData? = null,
|
||||
) : MavericksState
|
||||
) : MavericksState {
|
||||
|
||||
constructor(args: LocationSharingArgs): this(
|
||||
pinLocationData = args.initialLocationData,
|
||||
pinUserId = args.locationOwnerId,
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue