mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-06 04:27:29 +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
|
package com.rtbishop.look4sat.data.repository
|
||||||
|
|
||||||
import com.github.amsacode.predict4java.Satellite
|
import com.github.amsacode.predict4java.Satellite
|
||||||
import com.rtbishop.look4sat.data.model.Result
|
|
||||||
import com.rtbishop.look4sat.data.model.SatPass
|
import com.rtbishop.look4sat.data.model.SatPass
|
||||||
import com.rtbishop.look4sat.di.DefaultDispatcher
|
import com.rtbishop.look4sat.di.DefaultDispatcher
|
||||||
import com.rtbishop.look4sat.utility.PrefsManager
|
import com.rtbishop.look4sat.utility.PrefsManager
|
||||||
@@ -36,13 +35,13 @@ class PassesRepo @Inject constructor(
|
|||||||
private val prefsManager: PrefsManager,
|
private val prefsManager: PrefsManager,
|
||||||
@DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher
|
@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>()
|
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()) {
|
suspend fun triggerCalculation(satellites: List<Satellite>, refDate: Date = Date()) {
|
||||||
if (satellites.isEmpty()) {
|
if (satellites.isEmpty()) {
|
||||||
_passes.emit(Result.Error(Exception()))
|
_passes.emit(emptyList())
|
||||||
} else {
|
} else {
|
||||||
val oldCatNums = selectedSatellites.map { it.tle.catnum }
|
val oldCatNums = selectedSatellites.map { it.tle.catnum }
|
||||||
val newCatNums = satellites.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()) {
|
suspend fun forceCalculation(satellites: List<Satellite>, refDate: Date = Date()) {
|
||||||
if (satellites.isEmpty()) {
|
if (satellites.isEmpty()) {
|
||||||
_passes.emit(Result.Error(Exception()))
|
_passes.emit(emptyList())
|
||||||
} else {
|
} else {
|
||||||
_passes.emit(Result.InProgress)
|
|
||||||
withContext(defaultDispatcher) {
|
withContext(defaultDispatcher) {
|
||||||
val allPasses = mutableListOf<SatPass>()
|
val allPasses = mutableListOf<SatPass>()
|
||||||
selectedSatellites = satellites
|
selectedSatellites = satellites
|
||||||
satellites.forEach { satellite ->
|
satellites.forEach { satellite -> allPasses.addAll(getPasses(satellite, refDate)) }
|
||||||
allPasses.addAll(getPasses(satellite, refDate))
|
_passes.emit(filterPasses(allPasses, refDate))
|
||||||
}
|
|
||||||
_passes.emit(Result.Success(filterPasses(allPasses, refDate)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,30 +42,13 @@ class PassesAdapter(private val isUTC: Boolean, private val clickListener: Passe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
private val differ = AsyncListDiffer(this, diffCallback)
|
private val differ = AsyncListDiffer(this, diffCallback)
|
||||||
private var currentPasses = emptyList<SatPass>()
|
|
||||||
|
|
||||||
interface PassesClickListener {
|
interface PassesClickListener {
|
||||||
fun navigateToPass(satPass: SatPass)
|
fun navigateToPass(satPass: SatPass)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun submitList(passes: List<SatPass>) {
|
fun submitList(passes: List<SatPass>) {
|
||||||
currentPasses = passes
|
differ.submitList(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 })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount() = differ.currentList.size
|
override fun getItemCount() = differ.currentList.size
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import java.util.*
|
|||||||
class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesClickListener {
|
class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesClickListener {
|
||||||
|
|
||||||
private val viewModel: PassesViewModel by viewModels()
|
private val viewModel: PassesViewModel by viewModels()
|
||||||
private var passes = listOf<SatPass>()
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
@@ -62,9 +61,6 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
|
|||||||
viewModel.passes.observe(viewLifecycleOwner, { passesResult ->
|
viewModel.passes.observe(viewLifecycleOwner, { passesResult ->
|
||||||
handleNewPasses(passesResult, passesAdapter, binding)
|
handleNewPasses(passesResult, passesAdapter, binding)
|
||||||
})
|
})
|
||||||
viewModel.getAppTimer().observe(viewLifecycleOwner, { timeNow ->
|
|
||||||
tickMainTimer(timeNow, passesAdapter, binding)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleNewPasses(
|
private fun handleNewPasses(
|
||||||
@@ -74,16 +70,15 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
|
|||||||
) {
|
) {
|
||||||
when (result) {
|
when (result) {
|
||||||
is Result.Success -> {
|
is Result.Success -> {
|
||||||
passes = result.data
|
passesAdapter.submitList(result.data)
|
||||||
passesAdapter.submitList(passes)
|
|
||||||
binding.apply {
|
binding.apply {
|
||||||
passesError.visibility = View.INVISIBLE
|
passesError.visibility = View.INVISIBLE
|
||||||
passesProgress.visibility = View.INVISIBLE
|
passesProgress.visibility = View.INVISIBLE
|
||||||
passesRecycler.visibility = View.VISIBLE
|
passesRecycler.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
tickMainTimer(result.data, binding)
|
||||||
}
|
}
|
||||||
is Result.InProgress -> {
|
is Result.InProgress -> {
|
||||||
passes = emptyList()
|
|
||||||
binding.apply {
|
binding.apply {
|
||||||
passesTimer.text = 0L.formatForTimer()
|
passesTimer.text = 0L.formatForTimer()
|
||||||
passesError.visibility = View.INVISIBLE
|
passesError.visibility = View.INVISIBLE
|
||||||
@@ -92,7 +87,6 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Result.Error -> {
|
is Result.Error -> {
|
||||||
passes = emptyList()
|
|
||||||
binding.apply {
|
binding.apply {
|
||||||
passesTimer.text = 0L.formatForTimer()
|
passesTimer.text = 0L.formatForTimer()
|
||||||
passesProgress.visibility = View.INVISIBLE
|
passesProgress.visibility = View.INVISIBLE
|
||||||
@@ -103,12 +97,9 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tickMainTimer(
|
private fun tickMainTimer(passes: List<SatPass>, binding: FragmentPassesBinding) {
|
||||||
timeNow: Long,
|
|
||||||
passesAdapter: PassesAdapter,
|
|
||||||
binding: FragmentPassesBinding
|
|
||||||
) {
|
|
||||||
if (passes.isNotEmpty()) {
|
if (passes.isNotEmpty()) {
|
||||||
|
val timeNow = System.currentTimeMillis()
|
||||||
try {
|
try {
|
||||||
val nextPass = passes.first { it.aosDate.time.minus(timeNow) > 0 }
|
val nextPass = passes.first { it.aosDate.time.minus(timeNow) > 0 }
|
||||||
val millisBeforeStart = nextPass.aosDate.time.minus(timeNow)
|
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)
|
val millisBeforeEnd = lastPass.losDate.time.minus(timeNow)
|
||||||
binding.passesTimer.text = millisBeforeEnd.formatForTimer()
|
binding.passesTimer.text = millisBeforeEnd.formatForTimer()
|
||||||
}
|
}
|
||||||
passesAdapter.tickDiffer(timeNow)
|
|
||||||
} else {
|
} else {
|
||||||
binding.passesTimer.text = 0L.formatForTimer()
|
binding.passesTimer.text = 0L.formatForTimer()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,18 @@
|
|||||||
*/
|
*/
|
||||||
package com.rtbishop.look4sat.ui.passesScreen
|
package com.rtbishop.look4sat.ui.passesScreen
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.asLiveData
|
|
||||||
import androidx.lifecycle.liveData
|
|
||||||
import androidx.lifecycle.viewModelScope
|
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.PassesRepo
|
||||||
import com.rtbishop.look4sat.data.repository.SatelliteRepo
|
import com.rtbishop.look4sat.data.repository.SatelliteRepo
|
||||||
import com.rtbishop.look4sat.utility.PrefsManager
|
import com.rtbishop.look4sat.utility.PrefsManager
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.flow.collect
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@@ -36,28 +38,52 @@ class PassesViewModel @Inject constructor(
|
|||||||
private val passesRepo: PassesRepo
|
private val passesRepo: PassesRepo
|
||||||
) : ViewModel() {
|
) : 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 {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
_passes.postValue(Result.InProgress)
|
||||||
passesRepo.triggerCalculation(satelliteRepo.getSelectedSatellites())
|
passesRepo.triggerCalculation(satelliteRepo.getSelectedSatellites())
|
||||||
}
|
}
|
||||||
|
viewModelScope.launch {
|
||||||
|
passesRepo.passes.collect { passes ->
|
||||||
|
passesProcessing?.cancelAndJoin()
|
||||||
|
passesProcessing = viewModelScope.launch { tickPasses(passes) }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun forceCalculation() {
|
fun forceCalculation() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
_passes.postValue(Result.InProgress)
|
||||||
|
passesProcessing?.cancelAndJoin()
|
||||||
passesRepo.forceCalculation(satelliteRepo.getSelectedSatellites())
|
passesRepo.forceCalculation(satelliteRepo.getSelectedSatellites())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAppTimer() = liveData {
|
|
||||||
while (true) {
|
|
||||||
emit(System.currentTimeMillis())
|
|
||||||
delay(1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun shouldUseUTC(): Boolean {
|
fun shouldUseUTC(): Boolean {
|
||||||
return prefsManager.shouldUseUTC()
|
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
|
package com.rtbishop.look4sat.ui.polarScreen
|
||||||
|
|
||||||
import androidx.lifecycle.*
|
import androidx.lifecycle.*
|
||||||
import com.rtbishop.look4sat.data.model.Result
|
|
||||||
import com.rtbishop.look4sat.data.repository.PassesRepo
|
import com.rtbishop.look4sat.data.repository.PassesRepo
|
||||||
import com.rtbishop.look4sat.data.repository.SatelliteRepo
|
import com.rtbishop.look4sat.data.repository.SatelliteRepo
|
||||||
import com.rtbishop.look4sat.utility.PrefsManager
|
import com.rtbishop.look4sat.utility.PrefsManager
|
||||||
@@ -48,10 +47,8 @@ class PolarViewModel @Inject constructor(
|
|||||||
|
|
||||||
fun getPass(catNum: Int, aosTime: Long) = liveData {
|
fun getPass(catNum: Int, aosTime: Long) = liveData {
|
||||||
passesRepo.passes.collect { passes ->
|
passesRepo.passes.collect { passes ->
|
||||||
if (passes is Result.Success) {
|
val pass = passes.find { it.catNum == catNum && it.aosDate.time == aosTime }
|
||||||
val pass = passes.data.find { it.catNum == catNum && it.aosDate.time == aosTime }
|
pass?.let { emit(it) }
|
||||||
pass?.let { emit(it) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user