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 238a2f1f..9e6d8a06 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 @@ -18,7 +18,6 @@ package com.rtbishop.look4sat.data.repository import com.github.amsacode.predict4java.Satellite -import com.rtbishop.look4sat.data.model.Result import com.rtbishop.look4sat.data.model.SatPass import com.rtbishop.look4sat.di.DefaultDispatcher import com.rtbishop.look4sat.utility.PrefsManager @@ -36,13 +35,13 @@ class PassesRepo @Inject constructor( private val prefsManager: PrefsManager, @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher ) { - private val _passes = MutableSharedFlow>>(replay = 1) + private val _passes = MutableSharedFlow>(replay = 1) private var selectedSatellites = emptyList() - val passes: SharedFlow>> = _passes + val passes: SharedFlow> = _passes suspend fun triggerCalculation(satellites: List, refDate: Date = Date()) { if (satellites.isEmpty()) { - _passes.emit(Result.Error(Exception())) + _passes.emit(emptyList()) } else { val oldCatNums = selectedSatellites.map { it.tle.catnum } val newCatNums = satellites.map { it.tle.catnum } @@ -52,16 +51,13 @@ class PassesRepo @Inject constructor( suspend fun forceCalculation(satellites: List, refDate: Date = Date()) { if (satellites.isEmpty()) { - _passes.emit(Result.Error(Exception())) + _passes.emit(emptyList()) } 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))) + satellites.forEach { satellite -> allPasses.addAll(getPasses(satellite, refDate)) } + _passes.emit(filterPasses(allPasses, refDate)) } } } 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 747aa7e1..86ef53f2 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 @@ -42,30 +42,13 @@ class PassesAdapter(private val isUTC: Boolean, private val clickListener: Passe } } private val differ = AsyncListDiffer(this, diffCallback) - private var currentPasses = emptyList() interface PassesClickListener { fun navigateToPass(satPass: SatPass) } fun submitList(passes: List) { - currentPasses = passes - tickDiffer(System.currentTimeMillis()) - } - - fun tickDiffer(timeNow: Long) { - val copiedPasses = currentPasses.map { pass -> pass.copy() } - copiedPasses.forEach { pass -> - if (!pass.isDeepSpace) { - val timeStart = pass.aosDate.time - if (timeNow > timeStart) { - val deltaNow = timeNow.minus(timeStart).toFloat() - val deltaTotal = pass.losDate.time.minus(timeStart).toFloat() - pass.progress = ((deltaNow / deltaTotal) * 100).toInt() - } - } - } - differ.submitList(copiedPasses.filter { pass -> pass.progress < 100 }) + differ.submitList(passes) } override fun getItemCount() = differ.currentList.size diff --git a/app/src/main/java/com/rtbishop/look4sat/ui/passesScreen/PassesFragment.kt b/app/src/main/java/com/rtbishop/look4sat/ui/passesScreen/PassesFragment.kt index 621fd488..ffebbe52 100644 --- a/app/src/main/java/com/rtbishop/look4sat/ui/passesScreen/PassesFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/ui/passesScreen/PassesFragment.kt @@ -39,7 +39,6 @@ import java.util.* class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesClickListener { private val viewModel: PassesViewModel by viewModels() - private var passes = listOf() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -62,9 +61,6 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC viewModel.passes.observe(viewLifecycleOwner, { passesResult -> handleNewPasses(passesResult, passesAdapter, binding) }) - viewModel.getAppTimer().observe(viewLifecycleOwner, { timeNow -> - tickMainTimer(timeNow, passesAdapter, binding) - }) } private fun handleNewPasses( @@ -74,16 +70,15 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC ) { when (result) { is Result.Success -> { - passes = result.data - passesAdapter.submitList(passes) + passesAdapter.submitList(result.data) binding.apply { passesError.visibility = View.INVISIBLE passesProgress.visibility = View.INVISIBLE passesRecycler.visibility = View.VISIBLE } + tickMainTimer(result.data, binding) } is Result.InProgress -> { - passes = emptyList() binding.apply { passesTimer.text = 0L.formatForTimer() passesError.visibility = View.INVISIBLE @@ -92,7 +87,6 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC } } is Result.Error -> { - passes = emptyList() binding.apply { passesTimer.text = 0L.formatForTimer() passesProgress.visibility = View.INVISIBLE @@ -103,12 +97,9 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC } } - private fun tickMainTimer( - timeNow: Long, - passesAdapter: PassesAdapter, - binding: FragmentPassesBinding - ) { + private fun tickMainTimer(passes: List, binding: FragmentPassesBinding) { if (passes.isNotEmpty()) { + val timeNow = System.currentTimeMillis() try { val nextPass = passes.first { it.aosDate.time.minus(timeNow) > 0 } val millisBeforeStart = nextPass.aosDate.time.minus(timeNow) @@ -118,7 +109,6 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC val millisBeforeEnd = lastPass.losDate.time.minus(timeNow) binding.passesTimer.text = millisBeforeEnd.formatForTimer() } - passesAdapter.tickDiffer(timeNow) } else { binding.passesTimer.text = 0L.formatForTimer() } diff --git a/app/src/main/java/com/rtbishop/look4sat/ui/passesScreen/PassesViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/ui/passesScreen/PassesViewModel.kt index 21f0d82b..7d15824e 100644 --- a/app/src/main/java/com/rtbishop/look4sat/ui/passesScreen/PassesViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/ui/passesScreen/PassesViewModel.kt @@ -17,16 +17,18 @@ */ package com.rtbishop.look4sat.ui.passesScreen +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import androidx.lifecycle.asLiveData -import androidx.lifecycle.liveData import androidx.lifecycle.viewModelScope +import com.rtbishop.look4sat.data.model.Result +import com.rtbishop.look4sat.data.model.SatPass import com.rtbishop.look4sat.data.repository.PassesRepo import com.rtbishop.look4sat.data.repository.SatelliteRepo import com.rtbishop.look4sat.utility.PrefsManager import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch +import kotlinx.coroutines.* +import kotlinx.coroutines.flow.collect import javax.inject.Inject @HiltViewModel @@ -36,28 +38,52 @@ class PassesViewModel @Inject constructor( private val passesRepo: PassesRepo ) : ViewModel() { - val passes = passesRepo.passes.asLiveData(viewModelScope.coroutineContext) + private val _passes = MutableLiveData>>(Result.InProgress) + private var passesProcessing: Job? = null + val passes: LiveData>> = _passes init { viewModelScope.launch { + _passes.postValue(Result.InProgress) passesRepo.triggerCalculation(satelliteRepo.getSelectedSatellites()) } + viewModelScope.launch { + passesRepo.passes.collect { passes -> + passesProcessing?.cancelAndJoin() + passesProcessing = viewModelScope.launch { tickPasses(passes) } + } + } } fun forceCalculation() { viewModelScope.launch { + _passes.postValue(Result.InProgress) + passesProcessing?.cancelAndJoin() passesRepo.forceCalculation(satelliteRepo.getSelectedSatellites()) } } - fun getAppTimer() = liveData { - while (true) { - emit(System.currentTimeMillis()) - delay(1000) - } - } - fun shouldUseUTC(): Boolean { return prefsManager.shouldUseUTC() } + + private suspend fun tickPasses(passes: List) = withContext(Dispatchers.Default) { + var currentPasses = passes + while (isActive) { + val timeNow = System.currentTimeMillis() + currentPasses.forEach { pass -> + if (!pass.isDeepSpace) { + val timeStart = pass.aosDate.time + if (timeNow > timeStart) { + val deltaNow = timeNow.minus(timeStart).toFloat() + val deltaTotal = pass.losDate.time.minus(timeStart).toFloat() + pass.progress = ((deltaNow / deltaTotal) * 100).toInt() + } + } + } + currentPasses = currentPasses.filter { it.progress < 100 } + _passes.postValue(Result.Success(currentPasses.map { it.copy() })) + delay(1000) + } + } } 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 83ce0831..44e9dfbb 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 @@ -18,7 +18,6 @@ package com.rtbishop.look4sat.ui.polarScreen import androidx.lifecycle.* -import com.rtbishop.look4sat.data.model.Result import com.rtbishop.look4sat.data.repository.PassesRepo import com.rtbishop.look4sat.data.repository.SatelliteRepo import com.rtbishop.look4sat.utility.PrefsManager @@ -48,10 +47,8 @@ class PolarViewModel @Inject constructor( fun getPass(catNum: Int, aosTime: Long) = liveData { passesRepo.passes.collect { passes -> - if (passes is Result.Success) { - val pass = passes.data.find { it.catNum == catNum && it.aosDate.time == aosTime } - pass?.let { emit(it) } - } + val pass = passes.find { it.catNum == catNum && it.aosDate.time == aosTime } + pass?.let { emit(it) } } }