Switched to SatItems in Entries recycler Adapter

This commit is contained in:
Arty Bishop committed 2021-03-06 15:42:35 +00:00
1 parent 8df2334cd6
commit ab811e4ead
6 files changed
+136 -111

No files matched your search

@@ -0,0 +1,22 @@
/*******************************************************************************
Look4Sat. Amateur radio satellite tracker and pass predictor.
Copyright (C) 2019, 2020 Arty Bishop (bishop.arty@gmail.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
******************************************************************************/
package com.rtbishop.look4sat.data
class SatItem(val catNum: Int, val name: String, var isSelected: Boolean)
@@ -1,20 +1,20 @@
/*******************************************************************************
Look4Sat. Amateur radio satellite tracker and pass predictor.
Copyright (C) 2019, 2020 Arty Bishop (bishop.arty@gmail.com)
Look4Sat. Amateur radio satellite tracker and pass predictor.
Copyright (C) 2019, 2020 Arty Bishop (bishop.arty@gmail.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
******************************************************************************/
package com.rtbishop.look4sat.repository
@@ -23,6 +23,7 @@ import android.content.ContentResolver
import android.net.Uri
import com.github.amsacode.predict4java.TLE
import com.rtbishop.look4sat.data.SatEntry
import com.rtbishop.look4sat.data.SatItem
import com.rtbishop.look4sat.data.SatTrans
import com.rtbishop.look4sat.data.TleSource
import com.rtbishop.look4sat.di.IoDispatcher
@@ -41,8 +42,12 @@ class SatelliteRepo @Inject constructor(
@IoDispatcher private val ioDispatcher: CoroutineDispatcher
) {
fun getEntries(): Flow<List<SatEntry>> {
return satelliteDao.getEntries()
fun getSatItems(): Flow<List<SatItem>> {
return satelliteDao.getSatItems()
}
suspend fun getSelectedEntries(): List<SatEntry> {
return satelliteDao.getSelectedEntries()
}
suspend fun updateEntriesSelection(catNums: List<Int>) {
@@ -1,26 +1,27 @@
/*******************************************************************************
Look4Sat. Amateur radio satellite tracker and pass predictor.
Copyright (C) 2019, 2020 Arty Bishop (bishop.arty@gmail.com)
Look4Sat. Amateur radio satellite tracker and pass predictor.
Copyright (C) 2019, 2020 Arty Bishop (bishop.arty@gmail.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
******************************************************************************/
package com.rtbishop.look4sat.repository.localData
import androidx.room.*
import com.rtbishop.look4sat.data.SatEntry
import com.rtbishop.look4sat.data.SatItem
import com.rtbishop.look4sat.data.SatTrans
import kotlinx.coroutines.flow.Flow
@@ -30,9 +31,15 @@ interface SatelliteDao {
@Query("SELECT * FROM entries ORDER BY name ASC")
fun getEntries(): Flow<List<SatEntry>>
@Query("SELECT catNum, name, isSelected FROM entries ORDER BY name ASC")
fun getSatItems(): Flow<List<SatItem>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertEntries(entries: List<SatEntry>)
@Query("SELECT * FROM entries WHERE isSelected = 1 ORDER BY name ASC")
suspend fun getSelectedEntries(): List<SatEntry>
@Query("SELECT catNum FROM entries WHERE isSelected = 1")
suspend fun getSelectedCatNums(): List<Int>
@@ -23,8 +23,8 @@ import android.net.Uri
import androidx.lifecycle.*
import com.github.amsacode.predict4java.SatelliteFactory
import com.rtbishop.look4sat.data.*
import com.rtbishop.look4sat.repository.SatelliteRepo
import com.rtbishop.look4sat.repository.PrefsRepo
import com.rtbishop.look4sat.repository.SatelliteRepo
import com.rtbishop.look4sat.utility.getPredictor
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
@@ -41,7 +41,6 @@ class SharedViewModel @Inject constructor(
private val _passes = MutableLiveData<Result<MutableList<SatPass>>>()
private val _appEvent = MutableLiveData<Event<Int>>()
private var selectedEntries = emptyList<SatEntry>()
private var shouldTriggerCalculation = true
init {
@@ -60,7 +59,7 @@ class SharedViewModel @Inject constructor(
}
fun getSources() = liveData { emit(prefsRepo.loadTleSources()) }
fun getEntries() = satelliteRepo.getEntries().asLiveData()
fun getSatItems() = satelliteRepo.getSatItems().asLiveData()
fun getPasses(): LiveData<Result<MutableList<SatPass>>> = _passes
fun getTransmittersForSat(satId: Int) =
satelliteRepo.getTransmittersForSat(satId).asLiveData()
@@ -77,16 +76,14 @@ class SharedViewModel @Inject constructor(
_passes.value = Result.InProgress
viewModelScope.launch(Dispatchers.Default) {
val passes = mutableListOf<SatPass>()
selectedEntries.forEach { passes.addAll(getPasses(it, dateNow)) }
satelliteRepo.getSelectedEntries().forEach { entry ->
passes.addAll(getPasses(entry, dateNow))
}
val filteredPasses = sortList(passes, dateNow)
_passes.postValue(Result.Success(filteredPasses))
}
}
fun setEntries(entries: List<SatEntry>) {
selectedEntries = entries.filter { it.isSelected }
}
fun updateEntriesFromFile(uri: Uri) {
postAppEvent(Event(0))
viewModelScope.launch {
@@ -110,15 +107,16 @@ class SharedViewModel @Inject constructor(
}
}
}
fun updateEntriesSelection(entries: List<SatEntry>) {
fun updateItemsSelection(items: List<SatItem>) {
_passes.value = Result.InProgress
viewModelScope.launch {
selectedEntries = entries.filter { it.isSelected }
val selectedEntries = items.filter { it.isSelected }.map { it.catNum }
satelliteRepo.updateEntriesSelection(selectedEntries)
calculatePasses()
satelliteRepo.updateEntriesSelection(selectedEntries.map { it.catNum })
}
}
private fun postAppEvent(event: Event<Int>) {
_appEvent.value = event
}
@@ -23,40 +23,47 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.SearchView
import androidx.recyclerview.widget.RecyclerView
import com.rtbishop.look4sat.data.SatEntry
import com.rtbishop.look4sat.data.SatItem
import com.rtbishop.look4sat.databinding.ItemSatEntryBinding
import java.util.*
class EntriesAdapter : RecyclerView.Adapter<EntriesAdapter.SatEntryHolder>(),
class EntriesAdapter : RecyclerView.Adapter<EntriesAdapter.SatItemHolder>(),
SearchView.OnQueryTextListener {
private val allItems = mutableListOf<SatItem>()
private val currentItems = mutableListOf<SatItem>()
private var shouldSearchAll = true
private var allEntries = mutableListOf<SatEntry>()
private var currentEntries = mutableListOf<SatEntry>()
fun getEntries(): MutableList<SatEntry> {
return allEntries
fun getItems(): List<SatItem> {
return allItems
}
fun setEntries(list: MutableList<SatEntry>) {
allEntries = list
currentEntries = list
fun setItems(items: List<SatItem>) {
allItems.clear()
allItems.addAll(items)
currentItems.clear()
currentItems.addAll(items)
notifyDataSetChanged()
}
fun selectAll() {
shouldSearchAll = if (shouldSearchAll) {
currentEntries.forEach { it.isSelected = true }
notifyDataSetChanged()
false
} else {
currentEntries.forEach { it.isSelected = false }
notifyDataSetChanged()
true
}
fun selectAllItems() {
shouldSearchAll = shouldSearchAll.not()
currentItems.forEach { it.isSelected = it.isSelected.not() }
notifyDataSetChanged()
}
private fun filterEntries(list: MutableList<SatEntry>, query: String): MutableList<SatEntry> {
override fun onQueryTextChange(newText: String): Boolean {
currentItems.clear()
currentItems.addAll(filterItems(allItems, newText).toMutableList())
notifyDataSetChanged()
return false
}
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
private fun filterItems(list: List<SatItem>, query: String): List<SatItem> {
if (query.isEmpty()) return list
return try {
filterByCatNum(list, query.toInt())
@@ -64,54 +71,42 @@ class EntriesAdapter : RecyclerView.Adapter<EntriesAdapter.SatEntryHolder>(),
filterByName(list, query)
}
}
private fun filterByCatNum(list: MutableList<SatEntry>, catNum: Int): MutableList<SatEntry> {
return list.filter { it.catNum == catNum } as MutableList
private fun filterByCatNum(list: List<SatItem>, catNum: Int): List<SatItem> {
return list.filter { it.catNum == catNum }
}
private fun filterByName(list: MutableList<SatEntry>, query: String): MutableList<SatEntry> {
private fun filterByName(list: List<SatItem>, query: String): List<SatItem> {
val defaultLocale = Locale.getDefault()
val filteredList = mutableListOf<SatEntry>()
val searchQuery = query.toLowerCase(defaultLocale)
list.forEach {
val entryName = it.name.toLowerCase(defaultLocale)
if (entryName.contains(searchQuery)) filteredList.add(it)
return list.filter { satItem ->
val lowerCaseItem = satItem.name.toLowerCase(defaultLocale)
lowerCaseItem.contains(searchQuery)
}
return filteredList
}
override fun onQueryTextChange(newText: String): Boolean {
currentEntries = filterEntries(getEntries(), newText)
notifyDataSetChanged()
return false
override fun getItemCount(): Int {
return currentItems.size
}
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SatEntryHolder {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SatItemHolder {
val binding = ItemSatEntryBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
return SatEntryHolder(binding)
return SatItemHolder(binding)
}
override fun onBindViewHolder(holder: SatEntryHolder, position: Int) {
holder.bind(currentEntries[position])
override fun onBindViewHolder(holder: SatItemHolder, position: Int) {
holder.bind(currentItems[position])
}
override fun getItemCount(): Int {
return currentEntries.size
}
inner class SatEntryHolder(private val binding: ItemSatEntryBinding) :
inner class SatItemHolder(private val binding: ItemSatEntryBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(satEntry: SatEntry) {
binding.satEntryCheckbox.text = satEntry.name
binding.satEntryCheckbox.isChecked = satEntry.isSelected
fun bind(satItem: SatItem) {
binding.satEntryCheckbox.text = satItem.name
binding.satEntryCheckbox.isChecked = satItem.isSelected
itemView.setOnClickListener {
satEntry.isSelected = binding.satEntryCheckbox.isChecked
satItem.isSelected = binding.satEntryCheckbox.isChecked
}
}
}
@@ -29,7 +29,6 @@ import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.data.SatEntry
import com.rtbishop.look4sat.databinding.FragmentEntriesBinding
import com.rtbishop.look4sat.ui.SharedViewModel
import com.rtbishop.look4sat.utility.RecyclerDivider
@@ -66,7 +65,7 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) {
}
importWeb.setOnClickListener { showImportFromWebDialog() }
importFile.setOnClickListener { filePicker.launch("*/*") }
selectAll.setOnClickListener { entriesAdapter?.selectAll() }
selectAll.setOnClickListener { entriesAdapter?.selectAllItems() }
entriesFab.setOnClickListener { navigateToPasses() }
searchBar.setOnQueryTextListener(entriesAdapter)
searchBar.clearFocus()
@@ -75,11 +74,10 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) {
private fun observeEntries() {
setLoading()
viewModel.getEntries().observe(viewLifecycleOwner, { entries ->
if (entries.isNullOrEmpty()) setError()
viewModel.getSatItems().observe(viewLifecycleOwner, { satItems ->
if (satItems.isNullOrEmpty()) setError()
else {
viewModel.setEntries(entries)
entriesAdapter?.setEntries(entries as MutableList<SatEntry>)
entriesAdapter?.setItems(satItems)
setLoaded()
}
observeEvents()
@@ -130,9 +128,9 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) {
private fun navigateToPasses() {
binding?.searchBar?.clearFocus()
entriesAdapter?.let {
val entries = it.getEntries()
if (entries.isNotEmpty()) {
viewModel.updateEntriesSelection(entries)
val satItems = it.getItems()
if (satItems.isNotEmpty()) {
viewModel.updateItemsSelection(satItems)
requireView().findNavController().navigate(R.id.action_entries_to_passes)
}
}