mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Swapped SingleLiveEvent for MutableStateFlow
This commit is contained in:
1 parent
d493e3e87b
commit
8134db90d6
7 files changed
+49
-73
No files matched your search
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Look4Sat. Amateur radio satellite tracker and pass predictor.
|
||||
* Copyright (C) 2019-2021 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rtbishop.look4sat.data
|
||||
|
||||
class Event<out T>(private val content: T) {
|
||||
|
||||
private var hasBeenHandled = false
|
||||
|
||||
fun getContentIfNotHandled(): T? {
|
||||
return if (hasBeenHandled) {
|
||||
null
|
||||
} else {
|
||||
hasBeenHandled = true
|
||||
content
|
||||
}
|
||||
}
|
||||
|
||||
fun peekContent(): T = content
|
||||
}
|
||||
@@ -20,13 +20,18 @@ package com.rtbishop.look4sat.ui
|
||||
import android.net.Uri
|
||||
import androidx.lifecycle.*
|
||||
import com.github.amsacode.predict4java.Satellite
|
||||
import com.rtbishop.look4sat.data.*
|
||||
import com.rtbishop.look4sat.data.Result
|
||||
import com.rtbishop.look4sat.data.SatItem
|
||||
import com.rtbishop.look4sat.data.SatPass
|
||||
import com.rtbishop.look4sat.data.TleSource
|
||||
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
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
@@ -37,18 +42,21 @@ class SharedViewModel @Inject constructor(
|
||||
private val satelliteRepo: SatelliteRepo,
|
||||
) : ViewModel() {
|
||||
|
||||
private val _passes = MutableLiveData<Result<MutableList<SatPass>>>()
|
||||
private val _appEvent = MutableLiveData<Event<Int>>()
|
||||
private val _passes = MutableStateFlow<Result<MutableList<SatPass>>>(Result.InProgress)
|
||||
val passes: LiveData<Result<MutableList<SatPass>>> = _passes.asLiveData()
|
||||
|
||||
private val _satData = MutableStateFlow<Result<List<SatItem>>>(Result.InProgress)
|
||||
val satData: LiveData<Result<List<SatItem>>> = _satData.asLiveData()
|
||||
|
||||
init {
|
||||
if (prefsRepo.isFirstLaunch()) {
|
||||
updateDefaultSourcesAndEntries()
|
||||
prefsRepo.setFirstLaunchDone()
|
||||
}
|
||||
loadDataFromDb()
|
||||
calculatePasses()
|
||||
}
|
||||
|
||||
fun getAppEvent(): LiveData<Event<Int>> = _appEvent
|
||||
fun getAppTimer() = liveData {
|
||||
while (true) {
|
||||
emit(System.currentTimeMillis())
|
||||
@@ -57,10 +65,7 @@ class SharedViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun getSources() = prefsRepo.loadTleSources()
|
||||
fun getSatItems() = satelliteRepo.getSatItems().asLiveData()
|
||||
fun getPasses(): LiveData<Result<MutableList<SatPass>>> = _passes
|
||||
fun getTransmittersForSat(satId: Int) =
|
||||
satelliteRepo.getTransmittersForSat(satId).asLiveData()
|
||||
fun getTransmittersForSat(satId: Int) = satelliteRepo.getTransmittersForSat(satId).asLiveData()
|
||||
|
||||
fun calculatePasses(dateNow: Date = Date(System.currentTimeMillis())) {
|
||||
_passes.value = Result.InProgress
|
||||
@@ -70,30 +75,30 @@ class SharedViewModel @Inject constructor(
|
||||
passes.addAll(getPasses(satellite, dateNow))
|
||||
}
|
||||
val filteredPasses = sortList(passes, dateNow)
|
||||
_passes.postValue(Result.Success(filteredPasses))
|
||||
_passes.value = Result.Success(filteredPasses)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun updateEntriesFromFile(uri: Uri) {
|
||||
postAppEvent(Event(0))
|
||||
_satData.value = Result.InProgress
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
satelliteRepo.updateEntriesFromFile(uri)
|
||||
} catch (exception: Exception) {
|
||||
postAppEvent(Event(1))
|
||||
_satData.value = Result.Error(exception)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateEntriesFromSources(sources: List<TleSource>) {
|
||||
postAppEvent(Event(0))
|
||||
|
||||
fun updateEntriesFromSources(sources: List<TleSource> = prefsRepo.loadTleSources()) {
|
||||
_satData.value = Result.InProgress
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
prefsRepo.saveTleSources(sources)
|
||||
satelliteRepo.updateEntriesFromWeb(sources)
|
||||
satelliteRepo.updateTransmitters()
|
||||
} catch (exception: Exception) {
|
||||
postAppEvent(Event(1))
|
||||
_satData.value = Result.Error(exception)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,10 +112,6 @@ class SharedViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun postAppEvent(event: Event<Int>) {
|
||||
_appEvent.value = event
|
||||
}
|
||||
|
||||
private fun getPasses(satellite: Satellite, dateNow: Date): MutableList<SatPass> {
|
||||
val predictor = satellite.getPredictor(prefsRepo.getStationPosition())
|
||||
val passes = predictor.getPasses(dateNow, prefsRepo.getHoursAhead(), true)
|
||||
@@ -130,8 +131,19 @@ class SharedViewModel @Inject constructor(
|
||||
passes.sortBy { it.pass.startTime }
|
||||
return passes
|
||||
}
|
||||
|
||||
|
||||
private fun loadDataFromDb() {
|
||||
_satData.value = Result.InProgress
|
||||
viewModelScope.launch {
|
||||
satelliteRepo.getSatItems().collect { satItems: List<SatItem> ->
|
||||
if (satItems.isNotEmpty()) {
|
||||
_satData.value = Result.Success(satItems)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateDefaultSourcesAndEntries() {
|
||||
updateEntriesFromSources(prefsRepo.loadTleSources())
|
||||
updateEntriesFromSources()
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ 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.Result
|
||||
import com.rtbishop.look4sat.databinding.FragmentEntriesBinding
|
||||
import com.rtbishop.look4sat.ui.SharedViewModel
|
||||
import com.rtbishop.look4sat.utility.RecyclerDivider
|
||||
@@ -70,19 +71,16 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) {
|
||||
}
|
||||
|
||||
private fun setupObservers() {
|
||||
setLoading()
|
||||
viewModel.getSatItems().observe(viewLifecycleOwner, { satItems ->
|
||||
if (satItems.isNullOrEmpty()) {
|
||||
setError()
|
||||
} else {
|
||||
entriesAdapter?.setItems(satItems)
|
||||
setLoaded()
|
||||
}
|
||||
})
|
||||
viewModel.getAppEvent().observe(viewLifecycleOwner, { event ->
|
||||
event.getContentIfNotHandled()?.let { content ->
|
||||
if (content == 0) setLoading()
|
||||
else if (content == 1) {
|
||||
viewModel.satData.observe(viewLifecycleOwner, { result ->
|
||||
when (result) {
|
||||
is Result.Success -> {
|
||||
entriesAdapter?.setItems(result.data)
|
||||
setLoaded()
|
||||
}
|
||||
is Result.InProgress -> {
|
||||
setLoading()
|
||||
}
|
||||
is Result.Error -> {
|
||||
val errorMsg = getString(R.string.entries_update_error)
|
||||
Snackbar.make(requireView(), errorMsg, Snackbar.LENGTH_SHORT).show()
|
||||
entriesAdapter?.let { adapter ->
|
||||
|
||||
@@ -83,7 +83,7 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
||||
|
||||
private fun setupObservers() {
|
||||
mapViewModel.getGSP().observe(viewLifecycleOwner, { setupPosOverlay(it) })
|
||||
sharedViewModel.getPasses().observe(viewLifecycleOwner, {
|
||||
sharedViewModel.passes.observe(viewLifecycleOwner, {
|
||||
if (it is Result.Success && it.data.isNotEmpty()) {
|
||||
mapViewModel.setPasses(it.data)
|
||||
binding.fabPrev.setOnClickListener { mapViewModel.scrollSelection(true) }
|
||||
|
||||
@@ -54,7 +54,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes) {
|
||||
}
|
||||
|
||||
private fun setupObservers() {
|
||||
viewModel.getPasses().observe(viewLifecycleOwner, { result ->
|
||||
viewModel.passes.observe(viewLifecycleOwner, { result ->
|
||||
if (result is Result.Success) {
|
||||
if (result.data.isEmpty()) {
|
||||
binding?.apply {
|
||||
|
||||
@@ -97,7 +97,7 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
|
||||
}
|
||||
|
||||
private fun observePasses() {
|
||||
viewModel.getPasses().observe(viewLifecycleOwner, { result ->
|
||||
viewModel.passes.observe(viewLifecycleOwner, { result ->
|
||||
if (result is Result.Success) {
|
||||
satPass = result.data[requireArguments().getInt("index")]
|
||||
polarView = PolarView(requireContext()).apply { setPass(satPass) }
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ buildscript {
|
||||
material_version = '1.3.0'
|
||||
constraint_layout_version = '2.0.4'
|
||||
lifecycle_version = '2.3.0'
|
||||
navigation_version = '2.3.3'
|
||||
navigation_version = '2.3.4'
|
||||
preference_version = '1.1.1'
|
||||
room_version = '2.2.6'
|
||||
hilt_version = '2.33-beta'
|
||||
|
||||
Reference in new issue
Block a user