From ab811e4ead3face71028f2a487a72c0ce2b877aa Mon Sep 17 00:00:00 2001 From: Arty Bishop Date: Sat, 6 Mar 2021 15:42:35 +0000 Subject: [PATCH] Switched to SatItems in Entries recycler Adapter --- .../com/rtbishop/look4sat/data/SatItem.kt | 22 ++++ .../look4sat/repository/SatelliteRepo.kt | 35 +++--- .../repository/localData/SatelliteDao.kt | 33 +++-- .../rtbishop/look4sat/ui/SharedViewModel.kt | 24 ++-- .../ui/entriesScreen/EntriesAdapter.kt | 117 +++++++++--------- .../ui/entriesScreen/EntriesFragment.kt | 16 ++- 6 files changed, 136 insertions(+), 111 deletions(-) create mode 100644 app/src/main/java/com/rtbishop/look4sat/data/SatItem.kt diff --git a/app/src/main/java/com/rtbishop/look4sat/data/SatItem.kt b/app/src/main/java/com/rtbishop/look4sat/data/SatItem.kt new file mode 100644 index 00000000..a3d5175c --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/data/SatItem.kt @@ -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) \ No newline at end of file diff --git a/app/src/main/java/com/rtbishop/look4sat/repository/SatelliteRepo.kt b/app/src/main/java/com/rtbishop/look4sat/repository/SatelliteRepo.kt index f54f3474..2c308559 100644 --- a/app/src/main/java/com/rtbishop/look4sat/repository/SatelliteRepo.kt +++ b/app/src/main/java/com/rtbishop/look4sat/repository/SatelliteRepo.kt @@ -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> { - return satelliteDao.getEntries() + fun getSatItems(): Flow> { + return satelliteDao.getSatItems() + } + + suspend fun getSelectedEntries(): List { + return satelliteDao.getSelectedEntries() } suspend fun updateEntriesSelection(catNums: List) { diff --git a/app/src/main/java/com/rtbishop/look4sat/repository/localData/SatelliteDao.kt b/app/src/main/java/com/rtbishop/look4sat/repository/localData/SatelliteDao.kt index 1360bc53..16d34bea 100644 --- a/app/src/main/java/com/rtbishop/look4sat/repository/localData/SatelliteDao.kt +++ b/app/src/main/java/com/rtbishop/look4sat/repository/localData/SatelliteDao.kt @@ -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> + @Query("SELECT catNum, name, isSelected FROM entries ORDER BY name ASC") + fun getSatItems(): Flow> + @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertEntries(entries: List) + @Query("SELECT * FROM entries WHERE isSelected = 1 ORDER BY name ASC") + suspend fun getSelectedEntries(): List + @Query("SELECT catNum FROM entries WHERE isSelected = 1") suspend fun getSelectedCatNums(): List diff --git a/app/src/main/java/com/rtbishop/look4sat/ui/SharedViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/ui/SharedViewModel.kt index b8ab8f05..5f3902fa 100644 --- a/app/src/main/java/com/rtbishop/look4sat/ui/SharedViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/ui/SharedViewModel.kt @@ -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>>() private val _appEvent = MutableLiveData>() - private var selectedEntries = emptyList() 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>> = _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() - 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) { - 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) { + + fun updateItemsSelection(items: List) { + _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) { _appEvent.value = event } diff --git a/app/src/main/java/com/rtbishop/look4sat/ui/entriesScreen/EntriesAdapter.kt b/app/src/main/java/com/rtbishop/look4sat/ui/entriesScreen/EntriesAdapter.kt index cbb2ec83..4e1430f5 100644 --- a/app/src/main/java/com/rtbishop/look4sat/ui/entriesScreen/EntriesAdapter.kt +++ b/app/src/main/java/com/rtbishop/look4sat/ui/entriesScreen/EntriesAdapter.kt @@ -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(), +class EntriesAdapter : RecyclerView.Adapter(), SearchView.OnQueryTextListener { - + + private val allItems = mutableListOf() + private val currentItems = mutableListOf() private var shouldSearchAll = true - private var allEntries = mutableListOf() - private var currentEntries = mutableListOf() - - fun getEntries(): MutableList { - return allEntries + + fun getItems(): List { + return allItems } - - fun setEntries(list: MutableList) { - allEntries = list - currentEntries = list + + fun setItems(items: List) { + 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, query: String): MutableList { + + 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, query: String): List { if (query.isEmpty()) return list return try { filterByCatNum(list, query.toInt()) @@ -64,54 +71,42 @@ class EntriesAdapter : RecyclerView.Adapter(), filterByName(list, query) } } - - private fun filterByCatNum(list: MutableList, catNum: Int): MutableList { - return list.filter { it.catNum == catNum } as MutableList + + private fun filterByCatNum(list: List, catNum: Int): List { + return list.filter { it.catNum == catNum } } - - private fun filterByName(list: MutableList, query: String): MutableList { + + private fun filterByName(list: List, query: String): List { val defaultLocale = Locale.getDefault() - val filteredList = mutableListOf() 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 } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/ui/entriesScreen/EntriesFragment.kt b/app/src/main/java/com/rtbishop/look4sat/ui/entriesScreen/EntriesFragment.kt index bbdb212b..d4f3044e 100644 --- a/app/src/main/java/com/rtbishop/look4sat/ui/entriesScreen/EntriesFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/ui/entriesScreen/EntriesFragment.kt @@ -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) + 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) } }