mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Extracted passes ticking logic from PassesAdapter.kt
This commit is contained in:
1 parent
7b4f58dd78
commit
555c2fe626
5 files changed
+51
-59
No files matched your search
@@ -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<Result<List<SatPass>>>(replay = 1)
|
||||
private val _passes = MutableSharedFlow<List<SatPass>>(replay = 1)
|
||||
private var selectedSatellites = emptyList<Satellite>()
|
||||
val passes: SharedFlow<Result<List<SatPass>>> = _passes
|
||||
val passes: SharedFlow<List<SatPass>> = _passes
|
||||
|
||||
suspend fun triggerCalculation(satellites: List<Satellite>, 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<Satellite>, refDate: Date = Date()) {
|
||||
if (satellites.isEmpty()) {
|
||||
_passes.emit(Result.Error(Exception()))
|
||||
_passes.emit(emptyList())
|
||||
} else {
|
||||
_passes.emit(Result.InProgress)
|
||||
withContext(defaultDispatcher) {
|
||||
val allPasses = mutableListOf<SatPass>()
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,30 +42,13 @@ class PassesAdapter(private val isUTC: Boolean, private val clickListener: Passe
|
||||
}
|
||||
}
|
||||
private val differ = AsyncListDiffer(this, diffCallback)
|
||||
private var currentPasses = emptyList<SatPass>()
|
||||
|
||||
interface PassesClickListener {
|
||||
fun navigateToPass(satPass: SatPass)
|
||||
}
|
||||
|
||||
fun submitList(passes: List<SatPass>) {
|
||||
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
|
||||
|
||||
@@ -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<SatPass>()
|
||||
|
||||
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<SatPass>, 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()
|
||||
}
|
||||
|
||||
@@ -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<List<SatPass>>>(Result.InProgress)
|
||||
private var passesProcessing: Job? = null
|
||||
val passes: LiveData<Result<List<SatPass>>> = _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<SatPass>) = 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user