From c2216e49172f756605e522893a539b503a6b4dfb Mon Sep 17 00:00:00 2001 From: Arty Bishop Date: Sat, 3 Apr 2021 12:41:49 +0100 Subject: [PATCH] Fixed behaviour of passes recycler ticking and refreshing --- .../rtbishop/look4sat/data/model/SatPass.kt | 4 +- .../look4sat/data/repository/PassesRepo.kt | 35 +++++++------ .../look4sat/ui/passesScreen/PassesAdapter.kt | 49 ++++++++----------- .../ui/passesScreen/PassesFragment.kt | 35 ++++++++----- .../look4sat/ui/polarScreen/PolarFragment.kt | 13 ++--- .../look4sat/ui/polarScreen/PolarView.kt | 6 +-- .../look4sat/ui/polarScreen/PolarViewModel.kt | 7 ++- .../look4sat/utility/PassPredictor.kt | 4 +- build.gradle | 2 +- 9 files changed, 84 insertions(+), 71 deletions(-) diff --git a/app/src/main/java/com/rtbishop/look4sat/data/model/SatPass.kt b/app/src/main/java/com/rtbishop/look4sat/data/model/SatPass.kt index 59dfd83b..b66d22c3 100644 --- a/app/src/main/java/com/rtbishop/look4sat/data/model/SatPass.kt +++ b/app/src/main/java/com/rtbishop/look4sat/data/model/SatPass.kt @@ -35,10 +35,10 @@ data class SatPass( val predictor: PassPredictor, var progress: Int = 0 ) { - val startDate: Date + val aosDate: Date get() = Date(aosTime) - val endDate: Date + val losDate: Date get() = Date(losTime) val tcaDate: Date diff --git a/app/src/main/java/com/rtbishop/look4sat/data/repository/PassesRepo.kt b/app/src/main/java/com/rtbishop/look4sat/data/repository/PassesRepo.kt index 3e207d5d..238a2f1f 100644 --- a/app/src/main/java/com/rtbishop/look4sat/data/repository/PassesRepo.kt +++ b/app/src/main/java/com/rtbishop/look4sat/data/repository/PassesRepo.kt @@ -41,21 +41,28 @@ class PassesRepo @Inject constructor( val passes: SharedFlow>> = _passes suspend fun triggerCalculation(satellites: List, refDate: Date = Date()) { - if (satellites.isEmpty()) _passes.emit(Result.Error(Exception())) - val oldCatNums = selectedSatellites.map { it.tle.catnum } - val newCatNums = satellites.map { it.tle.catnum } - if (oldCatNums != newCatNums) forceCalculation(satellites, refDate) + if (satellites.isEmpty()) { + _passes.emit(Result.Error(Exception())) + } else { + val oldCatNums = selectedSatellites.map { it.tle.catnum } + val newCatNums = satellites.map { it.tle.catnum } + if (oldCatNums != newCatNums) forceCalculation(satellites, refDate) + } } suspend fun forceCalculation(satellites: List, refDate: Date = Date()) { - _passes.emit(Result.InProgress) - withContext(defaultDispatcher) { - val allPasses = mutableListOf() - selectedSatellites = satellites - satellites.forEach { satellite -> - allPasses.addAll(getPasses(satellite, refDate)) + if (satellites.isEmpty()) { + _passes.emit(Result.Error(Exception())) + } else { + _passes.emit(Result.InProgress) + withContext(defaultDispatcher) { + val allPasses = mutableListOf() + selectedSatellites = satellites + satellites.forEach { satellite -> + allPasses.addAll(getPasses(satellite, refDate)) + } + _passes.emit(Result.Success(filterPasses(allPasses, refDate))) } - _passes.emit(Result.Success(filterPasses(allPasses, refDate))) } } @@ -66,9 +73,9 @@ class PassesRepo @Inject constructor( private fun filterPasses(passes: List, refDate: Date): List { val timeFuture = Date(refDate.time + (prefsManager.getHoursAhead() * 3600 * 1000)) - return passes.filter { it.endDate.after(refDate) } - .filter { it.startDate.before(timeFuture) } + return passes.filter { it.losDate.after(refDate) } + .filter { it.aosDate.before(timeFuture) } .filter { it.maxElevation > prefsManager.getMinElevation() } - .sortedBy { it.startDate } + .sortedBy { it.aosDate } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/ui/passesScreen/PassesAdapter.kt b/app/src/main/java/com/rtbishop/look4sat/ui/passesScreen/PassesAdapter.kt index 1ab7f7a3..747aa7e1 100644 --- a/app/src/main/java/com/rtbishop/look4sat/ui/passesScreen/PassesAdapter.kt +++ b/app/src/main/java/com/rtbishop/look4sat/ui/passesScreen/PassesAdapter.kt @@ -19,8 +19,6 @@ package com.rtbishop.look4sat.ui.passesScreen import android.view.LayoutInflater import android.view.ViewGroup -import androidx.core.os.bundleOf -import androidx.navigation.findNavController import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView @@ -28,15 +26,15 @@ import com.rtbishop.look4sat.R import com.rtbishop.look4sat.data.model.SatPass import com.rtbishop.look4sat.databinding.ItemPassGeoBinding import com.rtbishop.look4sat.databinding.ItemPassLeoBinding -import com.rtbishop.look4sat.utility.navigateSafe import java.text.SimpleDateFormat import java.util.* -class PassesAdapter(private val isUTC: Boolean) : RecyclerView.Adapter() { +class PassesAdapter(private val isUTC: Boolean, private val clickListener: PassesClickListener) : + RecyclerView.Adapter() { private val diffCallback = object : DiffUtil.ItemCallback() { override fun areItemsTheSame(oldItem: SatPass, newItem: SatPass): Boolean { - return oldItem.catNum == newItem.catNum && oldItem.startDate == newItem.startDate + return oldItem.catNum == newItem.catNum && oldItem.aosDate == newItem.aosDate } override fun areContentsTheSame(oldItem: SatPass, newItem: SatPass): Boolean { @@ -44,30 +42,30 @@ class PassesAdapter(private val isUTC: Boolean) : RecyclerView.Adapter() private var currentPasses = emptyList() + interface PassesClickListener { + fun navigateToPass(satPass: SatPass) + } + fun submitList(passes: List) { - allPasses = passes.map { it.copy() } - currentPasses = passes.map { it.copy() } + currentPasses = passes tickDiffer(System.currentTimeMillis()) } fun tickDiffer(timeNow: Long) { - val list = currentPasses.map { it.copy() } - list.forEach { pass -> + val copiedPasses = currentPasses.map { pass -> pass.copy() } + copiedPasses.forEach { pass -> if (!pass.isDeepSpace) { - val timeStart = pass.startDate.time + val timeStart = pass.aosDate.time if (timeNow > timeStart) { - val timeEnd = pass.endDate.time val deltaNow = timeNow.minus(timeStart).toFloat() - val deltaTotal = timeEnd.minus(timeStart).toFloat() + val deltaTotal = pass.losDate.time.minus(timeStart).toFloat() pass.progress = ((deltaNow / deltaTotal) * 100).toInt() } } } - currentPasses = list.filter { pass -> pass.progress < 100 } - differ.submitList(currentPasses) + differ.submitList(copiedPasses.filter { pass -> pass.progress < 100 }) } override fun getItemCount() = differ.currentList.size @@ -86,11 +84,10 @@ class PassesAdapter(private val isUTC: Boolean) : RecyclerView.Adapter() + private var passes = listOf() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -44,20 +47,20 @@ class PassesFragment : Fragment(R.layout.fragment_passes) { } private fun setupComponents(view: View) { - val passesAdapter = PassesAdapter(viewModel.shouldUseUTC()) + val passesAdapter = PassesAdapter(viewModel.shouldUseUTC(), this) val binding = FragmentPassesBinding.bind(view).apply { passesRecycler.apply { setHasFixedSize(true) adapter = passesAdapter isVerticalScrollBarEnabled = false layoutManager = LinearLayoutManager(context) -// (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false + (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false addItemDecoration(RecyclerDivider(R.drawable.rec_divider_dark)) } passesRefresh.setOnClickListener { viewModel.forceCalculation() } } - viewModel.passes.observe(viewLifecycleOwner, { result -> - handleNewPasses(result, passesAdapter, binding) + viewModel.passes.observe(viewLifecycleOwner, { passesResult -> + handleNewPasses(passesResult, passesAdapter, binding) }) viewModel.getAppTimer().observe(viewLifecycleOwner, { timeNow -> tickMainTimer(timeNow, passesAdapter, binding) @@ -71,7 +74,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes) { ) { when (result) { is Result.Success -> { - passes = result.data.toMutableList() + passes = result.data passesAdapter.submitList(passes) binding.apply { passesError.visibility = View.INVISIBLE @@ -80,7 +83,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes) { } } is Result.InProgress -> { - passes.clear() + passes = emptyList() binding.apply { passesTimer.text = 0L.formatForTimer() passesError.visibility = View.INVISIBLE @@ -89,7 +92,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes) { } } is Result.Error -> { - passes.clear() + passes = emptyList() binding.apply { passesTimer.text = 0L.formatForTimer() passesProgress.visibility = View.INVISIBLE @@ -107,18 +110,24 @@ class PassesFragment : Fragment(R.layout.fragment_passes) { ) { if (passes.isNotEmpty()) { try { - val nextPass = passes.first { it.startDate.time.minus(timeNow) > 0 } - val millisBeforeStart = nextPass.startDate.time.minus(timeNow) + val nextPass = passes.first { it.aosDate.time.minus(timeNow) > 0 } + val millisBeforeStart = nextPass.aosDate.time.minus(timeNow) binding.passesTimer.text = millisBeforeStart.formatForTimer() } catch (e: NoSuchElementException) { val lastPass = passes.last() - val millisBeforeEnd = lastPass.endDate.time.minus(timeNow) + val millisBeforeEnd = lastPass.losDate.time.minus(timeNow) binding.passesTimer.text = millisBeforeEnd.formatForTimer() } -// passesAdapter.tickPasses(timeNow) passesAdapter.tickDiffer(timeNow) } else { binding.passesTimer.text = 0L.formatForTimer() } } + + override fun navigateToPass(satPass: SatPass) { + if (satPass.progress < 100) { + val bundle = bundleOf("catNum" to satPass.catNum, "aosTime" to satPass.aosDate.time) + findNavController().navigateSafe(R.id.action_passes_to_polar, bundle) + } + } } diff --git a/app/src/main/java/com/rtbishop/look4sat/ui/polarScreen/PolarFragment.kt b/app/src/main/java/com/rtbishop/look4sat/ui/polarScreen/PolarFragment.kt index 97374884..8ba57f01 100644 --- a/app/src/main/java/com/rtbishop/look4sat/ui/polarScreen/PolarFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/ui/polarScreen/PolarFragment.kt @@ -117,8 +117,9 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener { } private fun observePass() { - val passId = requireArguments().getInt("index") - viewModel.getPass(passId).observe(viewLifecycleOwner) { pass -> + val catNum = requireArguments().getInt("catNum") + val aosTime = requireArguments().getLong("aosTime") + viewModel.getPass(catNum, aosTime).observe(viewLifecycleOwner) { pass -> satPass = pass polarView = PolarView(requireContext()).apply { setPass(pass) } binding.frame.addView(polarView) @@ -171,13 +172,13 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener { binding.altitude.text = String.format(polarAlt, satPos.altitude) if (!satPass.isDeepSpace) { - if (dateNow.before(satPass.startDate)) { - val millisBeforeStart = satPass.startDate.time.minus(timeNow) + if (dateNow.before(satPass.aosDate)) { + val millisBeforeStart = satPass.aosDate.time.minus(timeNow) binding.polarTimer.text = millisBeforeStart.formatForTimer() } else { - val millisBeforeEnd = satPass.endDate.time.minus(timeNow) + val millisBeforeEnd = satPass.losDate.time.minus(timeNow) binding.polarTimer.text = millisBeforeEnd.formatForTimer() - if (dateNow.after(satPass.endDate)) { + if (dateNow.after(satPass.losDate)) { binding.polarTimer.text = 0L.formatForTimer() findNavController().popBackStack() } diff --git a/app/src/main/java/com/rtbishop/look4sat/ui/polarScreen/PolarView.kt b/app/src/main/java/com/rtbishop/look4sat/ui/polarScreen/PolarView.kt index 22d7a4c2..f6b18e80 100644 --- a/app/src/main/java/com/rtbishop/look4sat/ui/polarScreen/PolarView.kt +++ b/app/src/main/java/com/rtbishop/look4sat/ui/polarScreen/PolarView.kt @@ -92,13 +92,13 @@ class PolarView(context: Context) : View(context) { } private fun drawPassTrajectory(cvs: Canvas, satPass: SatPass) { - val startTime = satPass.startDate - val endTime = satPass.endDate + val startTime = satPass.aosDate + val endTime = satPass.losDate while (startTime.before(endTime)) { val satPos = satPass.predictor.getSatPos(startTime) val x = sph2CartX(satPos.azimuth, satPos.elevation, radius.toDouble()) val y = sph2CartY(satPos.azimuth, satPos.elevation, radius.toDouble()) - if (startTime.compareTo(satPass.startDate) == 0) { + if (startTime.compareTo(satPass.aosDate) == 0) { path.moveTo(x, -y) } else { path.lineTo(x, -y) diff --git a/app/src/main/java/com/rtbishop/look4sat/ui/polarScreen/PolarViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/ui/polarScreen/PolarViewModel.kt index a6cda624..20622aab 100644 --- a/app/src/main/java/com/rtbishop/look4sat/ui/polarScreen/PolarViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/ui/polarScreen/PolarViewModel.kt @@ -44,9 +44,12 @@ class PolarViewModel @Inject constructor( } } - fun getPass(passId: Int) = liveData { + fun getPass(catNum: Int, aosTime: Long) = liveData { passesRepo.passes.collect { passes -> - if (passes is Result.Success) emit(passes.data[passId]) + if (passes is Result.Success) { + val pass = passes.data.find { it.catNum == catNum && it.aosDate.time == aosTime } + pass?.let { emit(it) } + } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/utility/PassPredictor.kt b/app/src/main/java/com/rtbishop/look4sat/utility/PassPredictor.kt index b1b2755e..cc7c48e7 100644 --- a/app/src/main/java/com/rtbishop/look4sat/utility/PassPredictor.kt +++ b/app/src/main/java/com/rtbishop/look4sat/utility/PassPredictor.kt @@ -69,10 +69,10 @@ class PassPredictor(private val satellite: Satellite, private val qth: GroundSta do { if (count > 0) shouldWindBack = false val pass = nextNearEarthPass(startDate, shouldWindBack) - lastAosDate = pass.startDate + lastAosDate = pass.aosDate passes.add(pass) startDate = - Date(pass.endDate.time + (oneQuarterOrbitMin * 3) * 60L * 1000L) + Date(pass.losDate.time + (oneQuarterOrbitMin * 3) * 60L * 1000L) count++ } while (lastAosDate < endDate) } diff --git a/build.gradle b/build.gradle index 8ca9ed2f..9dad375e 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { gradle_plugin_version = '1.4.32' material_version = '1.3.0' constraint_layout_version = '2.0.4' - lifecycle_version = '2.3.0' + lifecycle_version = '2.3.1' navigation_version = '2.3.4' preference_version = '1.1.1' room_version = '2.2.6'