mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Now sorting sat items list via LiveData switchMap
This commit is contained in:
1 parent
aef560942f
commit
2044ea273b
5 files changed
+48
-68
No files matched your search
@@ -34,7 +34,7 @@ interface SatelliteDao {
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT catNum, name, isSelected FROM entries ORDER BY name ASC")
|
||||
suspend fun getAllSatItems(): List<SatItem>
|
||||
fun getItemsFlow(): Flow<List<SatItem>>
|
||||
|
||||
@Query("SELECT tle FROM entries WHERE isSelected = 1")
|
||||
suspend fun getSelectedSatellites(): List<Satellite>
|
||||
|
||||
@@ -52,8 +52,8 @@ class SatelliteRepo @Inject constructor(
|
||||
return satelliteDao.getTransmittersByCatNum(catNum)
|
||||
}
|
||||
|
||||
suspend fun getAllSatItems(): List<SatItem> {
|
||||
return satelliteDao.getAllSatItems()
|
||||
fun getItemsFlow(): Flow<List<SatItem>> {
|
||||
return satelliteDao.getItemsFlow()
|
||||
}
|
||||
|
||||
suspend fun getSelectedSatellites(): List<Satellite> {
|
||||
|
||||
@@ -24,7 +24,6 @@ import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.rtbishop.look4sat.data.model.SatItem
|
||||
import com.rtbishop.look4sat.databinding.ItemSatEntryBinding
|
||||
import java.util.*
|
||||
|
||||
class EntriesAdapter : RecyclerView.Adapter<EntriesAdapter.SatItemHolder>() {
|
||||
|
||||
@@ -67,36 +66,10 @@ class EntriesAdapter : RecyclerView.Adapter<EntriesAdapter.SatItemHolder>() {
|
||||
shouldSelectAll = !shouldSelectAll
|
||||
}
|
||||
|
||||
fun filterItems(query: String) {
|
||||
if (query.isEmpty()) {
|
||||
submitCurrentItems(allItems)
|
||||
} else {
|
||||
try {
|
||||
filterByCatNum(query.toInt())
|
||||
} catch (e: NumberFormatException) {
|
||||
filterByName(query)
|
||||
}
|
||||
}
|
||||
shouldSelectAll = true
|
||||
}
|
||||
|
||||
private fun submitCurrentItems(items: List<SatItem>) {
|
||||
listDiffer.submitList(items)
|
||||
}
|
||||
|
||||
private fun filterByCatNum(catNum: Int) {
|
||||
submitCurrentItems(allItems.filter { it.catNum == catNum })
|
||||
}
|
||||
|
||||
private fun filterByName(name: String) {
|
||||
val satName = name.toLowerCase(Locale.getDefault())
|
||||
val filteredItems = allItems.filter { item ->
|
||||
val itemName = item.name.toLowerCase(Locale.getDefault())
|
||||
itemName.contains(satName)
|
||||
}
|
||||
submitCurrentItems(filteredItems)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = listDiffer.currentList.size
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SatItemHolder {
|
||||
@@ -114,7 +87,6 @@ class EntriesAdapter : RecyclerView.Adapter<EntriesAdapter.SatItemHolder>() {
|
||||
binding.satItemCheckbox.text = item.name
|
||||
binding.satItemCheckbox.isChecked = item.isSelected
|
||||
itemView.setOnClickListener {
|
||||
item.isSelected = item.isSelected.not()
|
||||
listener.updateSelection(listOf(item.catNum), item.isSelected.not())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,14 +137,13 @@ class EntriesFragment : Fragment(R.layout.fragment_entries), SearchView.OnQueryT
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String): Boolean {
|
||||
entriesAdapter?.filterItems(newText)
|
||||
binding?.entriesRecycler?.scrollToPosition(0)
|
||||
viewModel.setNewQuery(newText)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
entriesAdapter = null
|
||||
binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,7 @@ package com.rtbishop.look4sat.ui.entriesScreen
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.*
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.data.model.Result
|
||||
@@ -31,9 +29,10 @@ import com.rtbishop.look4sat.data.model.TleSource
|
||||
import com.rtbishop.look4sat.data.repository.PrefsRepo
|
||||
import com.rtbishop.look4sat.data.repository.SatelliteRepo
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
@@ -43,55 +42,39 @@ class EntriesViewModel @Inject constructor(
|
||||
private val satelliteRepo: SatelliteRepo
|
||||
) : ViewModel(), EntriesAdapter.EntriesClickListener {
|
||||
|
||||
private var allSatItems = listOf<SatItem>()
|
||||
private val satDataState = MutableStateFlow<Result<List<SatItem>>>(Result.InProgress)
|
||||
val satData = satDataState.asLiveData(viewModelScope.coroutineContext)
|
||||
|
||||
init {
|
||||
loadAndFilterData()
|
||||
private val transModes = MutableLiveData(prefsRepo.loadModesSelection())
|
||||
private val currentQuery = MutableLiveData(String())
|
||||
private val itemsWithModes = transModes.switchMap { modes ->
|
||||
liveData { satelliteRepo.getItemsFlow().collect { emit(filterByModes(it, modes)) } }
|
||||
}
|
||||
|
||||
private fun loadAndFilterData() {
|
||||
viewModelScope.launch {
|
||||
allSatItems = satelliteRepo.getAllSatItems()
|
||||
filterByModes(prefsRepo.loadModesSelection())
|
||||
}
|
||||
private val itemsWithQuery = currentQuery.switchMap { query ->
|
||||
itemsWithModes.map { items -> Result.Success(filterByQuery(items, query)) }
|
||||
}
|
||||
|
||||
private fun filterByModes(modes: List<String>) {
|
||||
if (modes.isEmpty()) {
|
||||
satDataState.value = Result.Success(allSatItems)
|
||||
} else {
|
||||
val itemsWithModes = allSatItems.filter { item ->
|
||||
item.modes.any { mode -> mode in modes }
|
||||
}
|
||||
satDataState.value = Result.Success(itemsWithModes)
|
||||
}
|
||||
prefsRepo.saveModesSelection(modes)
|
||||
private val _satData = MediatorLiveData<Result<List<SatItem>>>().apply {
|
||||
addSource(itemsWithQuery) { value -> this.value = value }
|
||||
}
|
||||
val satData: LiveData<Result<List<SatItem>>> = _satData
|
||||
|
||||
fun importSatDataFromFile(uri: Uri) {
|
||||
viewModelScope.launch {
|
||||
satDataState.value = Result.InProgress
|
||||
_satData.value = Result.InProgress
|
||||
try {
|
||||
satelliteRepo.importSatDataFromFile(uri)
|
||||
loadAndFilterData()
|
||||
} catch (exception: Exception) {
|
||||
satDataState.value = Result.Error(exception)
|
||||
_satData.value = Result.Error(exception)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun importSatDataFromSources(sources: List<TleSource> = prefsRepo.loadDefaultSources()) {
|
||||
viewModelScope.launch {
|
||||
satDataState.value = Result.InProgress
|
||||
_satData.value = Result.InProgress
|
||||
val updateMillis = measureTimeMillis {
|
||||
try {
|
||||
prefsRepo.saveTleSources(sources)
|
||||
satelliteRepo.importSatDataFromWeb(sources)
|
||||
loadAndFilterData()
|
||||
} catch (exception: Exception) {
|
||||
satDataState.value = Result.Error(exception)
|
||||
_satData.value = Result.Error(exception)
|
||||
}
|
||||
}
|
||||
Timber.d("Update from WEB took $updateMillis ms")
|
||||
@@ -118,7 +101,7 @@ class EntriesViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
setPositiveButton(context.getString(android.R.string.ok)) { _, _ ->
|
||||
filterByModes(selectedModes)
|
||||
setNewModes(selectedModes)
|
||||
}
|
||||
setNeutralButton(context.getString(android.R.string.cancel)) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
@@ -127,6 +110,32 @@ class EntriesViewModel @Inject constructor(
|
||||
return dialogBuilder.create()
|
||||
}
|
||||
|
||||
fun setNewQuery(newQuery: String) {
|
||||
currentQuery.value = newQuery
|
||||
}
|
||||
|
||||
private fun setNewModes(newModes: List<String>) {
|
||||
transModes.value = newModes
|
||||
prefsRepo.saveModesSelection(newModes)
|
||||
}
|
||||
|
||||
private fun filterByModes(items: List<SatItem>, modes: List<String>): List<SatItem> {
|
||||
if (modes.isEmpty()) return items
|
||||
return items.filter { item -> item.modes.any { mode -> mode in modes } }
|
||||
}
|
||||
|
||||
private fun filterByQuery(items: List<SatItem>, query: String): List<SatItem> {
|
||||
if (query.isBlank()) return items
|
||||
return try {
|
||||
items.filter { it.catNum == query.toInt() }
|
||||
} catch (e: Exception) {
|
||||
items.filter { item ->
|
||||
val itemName = item.name.toLowerCase(Locale.getDefault())
|
||||
itemName.contains(query.toLowerCase(Locale.getDefault()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateSelection(catNums: List<Int>, isSelected: Boolean) {
|
||||
viewModelScope.launch {
|
||||
satelliteRepo.updateEntriesSelection(catNums, isSelected)
|
||||
|
||||
Reference in new issue
Block a user