Skip to content

Commit

Permalink
Update selected job card and highlight map feature on tapping point o…
Browse files Browse the repository at this point in the history
…r polygon (#1945)

* Select feature on loi click

* Remove panning and zooming of point on click

---------

Co-authored-by: Gino Miceli <228050+gino-m@users.noreply.github.com>
  • Loading branch information
shobhitagarwal1612 and gino-m authored Oct 1, 2023
1 parent a669e2b commit c34ca12
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SnapHelper
import com.google.android.ground.R
import com.google.android.ground.coroutines.IoDispatcher
import com.google.android.ground.databinding.BasemapLayoutBinding
import com.google.android.ground.databinding.LoiCardsRecyclerViewBinding
import com.google.android.ground.databinding.MenuButtonBinding
Expand All @@ -43,6 +44,7 @@ import com.google.android.ground.ui.home.mapcontainer.cards.MapCardUiData
import com.google.android.ground.ui.map.MapFragment
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
import timber.log.Timber
Expand All @@ -54,6 +56,7 @@ class HomeScreenMapContainerFragment : Hilt_HomeScreenMapContainerFragment() {
@Inject lateinit var ephemeralPopups: EphemeralPopups
@Inject lateinit var submissionRepository: SubmissionRepository
@Inject lateinit var userRepository: UserRepository
@Inject @IoDispatcher lateinit var ioDispatcher: CoroutineDispatcher

private lateinit var mapContainerViewModel: HomeScreenMapContainerViewModel
private lateinit var homeScreenViewModel: HomeScreenViewModel
Expand All @@ -65,8 +68,6 @@ class HomeScreenMapContainerFragment : Hilt_HomeScreenMapContainerFragment() {
mapContainerViewModel = getViewModel(HomeScreenMapContainerViewModel::class.java)
homeScreenViewModel = getViewModel(HomeScreenViewModel::class.java)

lifecycleScope.launch { map.featureClicks.collect { mapContainerViewModel.onFeatureClick(it) } }

mapContainerViewModel
.getZoomThresholdCrossed()
.`as`(RxAutoDispose.autoDisposable(this))
Expand Down Expand Up @@ -94,6 +95,10 @@ class HomeScreenMapContainerFragment : Hilt_HomeScreenMapContainerFragment() {
}
.collect { (mapCards, loiCount) -> adapter.updateData(mapCards, loiCount - 1) }
}

lifecycleScope.launch(ioDispatcher) {
map.featureClicks.collect { mapContainerViewModel.onFeatureClicked(it) }
}
}

override fun onCreateView(
Expand Down Expand Up @@ -149,6 +154,16 @@ class HomeScreenMapContainerFragment : Hilt_HomeScreenMapContainerFragment() {

val helper: SnapHelper = PagerSnapHelper()
helper.attachToRecyclerView(recyclerView)

lifecycleScope.launch {
mapContainerViewModel.loiClicks.collect {
val index = it?.let { adapter.getIndex(it) } ?: -1
if (index != -1) {
recyclerView.scrollToPosition(index)
adapter.focusItemAtIndex(index)
}
}
}
}

private fun navigateToDataCollectionFragment(cardUiData: MapCardUiData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
*/
package com.google.android.ground.ui.home.mapcontainer

import androidx.lifecycle.viewModelScope
import com.google.android.ground.Config.CLUSTERING_ZOOM_THRESHOLD
import com.google.android.ground.Config.ZOOM_LEVEL_THRESHOLD
import com.google.android.ground.coroutines.IoDispatcher
import com.google.android.ground.model.geometry.Point
import com.google.android.ground.model.job.Job
import com.google.android.ground.model.locationofinterest.LocationOfInterest
import com.google.android.ground.repository.LocationOfInterestRepository
Expand All @@ -41,12 +41,16 @@ import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.reactive.asFlow
import timber.log.Timber

Expand Down Expand Up @@ -82,7 +86,10 @@ internal constructor(
* List of [LocationOfInterest] for the active survey that are present within the viewport and
* zoom level is clustering threshold or higher.
*/
val loisInViewport: Flow<List<LocationOfInterest>>
val loisInViewport: StateFlow<List<LocationOfInterest>>

/** [LocationOfInterest] clicked by the user. */
val loiClicks: MutableStateFlow<LocationOfInterest?> = MutableStateFlow(null)

/**
* List of [Job] within the active survey of `suggestLoiType` and zoom level is clustering
Expand Down Expand Up @@ -117,6 +124,7 @@ internal constructor(
if (bounds == null || survey == null || !isZoomedIn) flowOf(listOf())
else loiRepository.getWithinBoundsOnceAndStream(survey, bounds).asFlow()
}
.stateIn(viewModelScope, SharingStarted.Lazily, listOf())

suggestLoiJobs =
activeSurvey
Expand Down Expand Up @@ -151,12 +159,12 @@ internal constructor(
* Intended as a callback for when a specific map [Feature] is clicked. If the click is ambiguous,
* (list of features > 1), it chooses the first [Feature].
*/
fun onFeatureClick(features: Set<Feature>) {
// TODO: Handle polygon clicks.
fun onFeatureClicked(features: Set<Feature>) {
val geometry = features.first().geometry

if (geometry is Point) {
panAndZoomCamera(geometry.coordinates)
for (loi in loisInViewport.value) {
if (loi.geometry == geometry) {
loiClicks.value = loi
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@ class MapCardAdapter(private val canUserSubmitData: Boolean) :
}
}

/** Returns index of job card with the given [LocationOfInterest]. */
fun getIndex(loi: LocationOfInterest): Int {
for ((index, item) in itemsList.withIndex()) {
if (item is MapCardUiData.LoiCardUiData && item.loi == loi) {
return index
}
}
return -1
}

abstract class CardViewHolder(itemView: View, private val cardView: MaterialCardView) :
RecyclerView.ViewHolder(itemView) {
fun setOnClickListener(callback: () -> Unit) {
Expand Down

0 comments on commit c34ca12

Please sign in to comment.