mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Switched to SatItems in Entries recycler Adapter
This commit is contained in:
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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user