Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ dependencies {
// Jetpack Compose
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.lifecycle.viewmodel.ktx)
implementation(libs.androidx.fragment.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.runtime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ class SingleWebViewActivity : ComponentActivity() {
) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
// TODO("Add contentDescription)
contentDescription = ""
contentDescription = getString(R.string.back)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
label.setSelected(!label.isSelected());
holder.placeTypeLayout.setSelected(label.isSelected());

NearbyFilterState.setSelectedLabels(new ArrayList<>(selectedLabels));
callback.filterByMarkerType(selectedLabels, 0, false, false);
});
}
Expand Down Expand Up @@ -153,7 +152,6 @@ public void setRecyclerViewAdapterItemsGreyedOut() {
label.setSelected(false);
selectedLabels.remove(label);
}
NearbyFilterState.setSelectedLabels(new ArrayList<>(selectedLabels));
notifyDataSetChanged();
}

Expand All @@ -165,7 +163,6 @@ public void setRecyclerViewAdapterAllSelected() {
selectedLabels.add(label);
}
}
NearbyFilterState.setSelectedLabels(new ArrayList<>(selectedLabels));
notifyDataSetChanged();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package fr.free.nrw.commons.nearby

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

/**
* ViewModel to manage the state of nearby place type filters.
*/
class NearbyFilterViewModel : ViewModel() {

private val _selectedLabels = MutableLiveData<ArrayList<Label>>(ArrayList())
val selectedLabels: LiveData<ArrayList<Label>> = _selectedLabels

/**
* Updates the selected labels list.
* @param labels The new list of selected labels
*/
fun setSelectedLabels(labels: ArrayList<Label>) {
_selectedLabels.value = labels
}

/**
* Clears all selected labels.
*/
fun clearSelectedLabels() {
_selectedLabels.value = ArrayList()
}

/**
* Selects all available labels.
*/
fun selectAllLabels(allLabels: List<Label>) {
_selectedLabels.value = ArrayList(allLabels)
}

/**
* Gets the current selected labels as an ArrayList.
* @return The current selected labels
*/
fun getSelectedLabels(): ArrayList<Label> {
return ArrayList(_selectedLabels.value ?: ArrayList())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.GridLayoutManager
Expand Down Expand Up @@ -84,6 +85,7 @@ import fr.free.nrw.commons.nearby.MarkerPlaceGroup
import fr.free.nrw.commons.nearby.NearbyController
import fr.free.nrw.commons.nearby.NearbyFilterSearchRecyclerViewAdapter
import fr.free.nrw.commons.nearby.NearbyFilterState
import fr.free.nrw.commons.nearby.NearbyFilterViewModel
import fr.free.nrw.commons.nearby.NearbyUtil
import fr.free.nrw.commons.nearby.Place
import fr.free.nrw.commons.nearby.PlacesRepository
Expand Down Expand Up @@ -264,6 +266,7 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),
private var searchable = false

private val nearbyLegend: ConstraintLayout? = null
private lateinit var filterViewModel: NearbyFilterViewModel

private var gridLayoutManager: GridLayoutManager? = null
private var dataList: MutableList<BottomSheetItem>? = null
Expand Down Expand Up @@ -446,6 +449,28 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

// Initialize the ViewModel for filter state using ViewModelProvider
filterViewModel = ViewModelProvider(this)[NearbyFilterViewModel::class.java]

// Observe selected labels changes from ViewModel
filterViewModel.selectedLabels.observe(viewLifecycleOwner) { labels ->
nearbyFilterSearchRecyclerViewAdapter?.let { adapter ->
adapter.selectedLabels.clear()
adapter.selectedLabels.addAll(labels)
adapter.notifyDataSetChanged()
// Apply the filter when labels change
if (NearbyController.currentLocation != null) {
presenter?.filterByMarkerType(
labels,
binding?.nearbyFilterList?.checkboxTriStates?.state ?: CheckBoxTriStates.UNKNOWN,
true,
false
)
}
}
}

// Initialize the launcher in the appropriate lifecycle method (e.g., onViewCreated)
inAppCameraLocationPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result ->
Expand Down Expand Up @@ -923,6 +948,8 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),
selectedLabels: ArrayList<Label>, i: Int,
b: Boolean, b1: Boolean
) {
// Save to ViewModel to survive configuration changes
filterViewModel.setSelectedLabels(selectedLabels)
presenter!!.filterByMarkerType(selectedLabels, i, b, b1)
}

Expand Down Expand Up @@ -951,17 +978,15 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),

private fun restoreStoredFilterSelection() {
val adapter = nearbyFilterSearchRecyclerViewAdapter ?: return
val savedLabels = ArrayList(NearbyFilterState.getInstance().selectedLabels)
// Restore from ViewModel instead of singleton to survive configuration changes
val savedLabels = filterViewModel.getSelectedLabels()
adapter.selectedLabels.clear()
adapter.selectedLabels.addAll(savedLabels)
val savedSet = savedLabels.toSet()
Label.valuesAsList().forEach { label ->
val isSelected = savedSet.contains(label)
label.setSelected(isSelected)
if (isSelected) {
adapter.selectedLabels.add(label)
}
}
NearbyFilterState.setSelectedLabels(ArrayList(adapter.selectedLabels))
adapter.notifyDataSetChanged()
}

Expand Down Expand Up @@ -1754,6 +1779,8 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),
&& NearbyController.currentLocation != null
) {
nearbyFilterSearchRecyclerViewAdapter!!.setRecyclerViewAdapterAllSelected()
// Update ViewModel to survive configuration changes
filterViewModel.selectAllLabels(Label.valuesAsList())
}
}

Expand All @@ -1762,6 +1789,8 @@ class NearbyParentFragment : CommonsDaggerSupportFragment(),
&& NearbyController.currentLocation != null
) {
nearbyFilterSearchRecyclerViewAdapter!!.setRecyclerViewAdapterItemsGreyedOut()
// Update ViewModel to survive configuration changes
filterViewModel.clearSelectedLabels()
}
}

Expand Down
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dexterVersion = "5.0.0"
espresso = "3.6.1"
exifinterface = "1.3.7"
fragmentTesting = "1.6.2"
fragmentKtx = "1.6.2"
frescoVersion = "3.6.0"
commonsLang3Version = "3.8.1"
glide = "4.12.0"
Expand Down Expand Up @@ -85,6 +86,7 @@ androidx-exifinterface = { module = "androidx.exifinterface:exifinterface", vers
androidx-foundation = { module = "androidx.compose.foundation:foundation" }
androidx-foundation-layout = { module = "androidx.compose.foundation:foundation-layout" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-runner = { module = "androidx.test:runner", version.ref = "runner" }
androidx-test-ext-junit = { module = "androidx.test.ext:junit", version.ref = "androidxJunitVersion" }
Expand Down Expand Up @@ -144,6 +146,7 @@ androidx-espresso-contrib = { module = "androidx.test.espresso:espresso-contrib"
androidx-espresso-intents = { module = "androidx.test.espresso:espresso-intents", version.ref = "espresso" }
androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" }
androidx-fragment-testing = { module = "androidx.fragment:fragment-testing", version.ref = "fragmentTesting" }
androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "fragmentKtx" }
androidx-uiautomator = { module = "androidx.test.uiautomator:uiautomator", version.ref = "uiautomator" }
commons-io = { module = "commons-io:commons-io", version.ref = "commonsIo" }
junit = { module = "junit:junit", version.ref = "junit" }
Expand Down