diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/model/Result.kt b/app/src/main/java/com/rtbishop/look4sat/framework/model/DataState.kt similarity index 77% rename from app/src/main/java/com/rtbishop/look4sat/framework/model/Result.kt rename to app/src/main/java/com/rtbishop/look4sat/framework/model/DataState.kt index 52b6cf5b..07d9d788 100644 --- a/app/src/main/java/com/rtbishop/look4sat/framework/model/Result.kt +++ b/app/src/main/java/com/rtbishop/look4sat/framework/model/DataState.kt @@ -17,8 +17,9 @@ */ package com.rtbishop.look4sat.framework.model -sealed class Result { - data class Success(val data: T) : Result() - data class Error(val exception: Throwable) : Result() - object InProgress : Result() +sealed class DataState { + data class Success(val data: T) : DataState() + data class Error(val error: Throwable) : DataState() + object Empty : DataState() + object Loading : DataState() } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragment.kt index 06ec0dd3..3a3c87b2 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragment.kt @@ -29,7 +29,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.rtbishop.look4sat.R import com.rtbishop.look4sat.data.SatItem import com.rtbishop.look4sat.databinding.FragmentEntriesBinding -import com.rtbishop.look4sat.framework.model.Result +import com.rtbishop.look4sat.framework.model.DataState import com.rtbishop.look4sat.utility.RecyclerDivider import com.rtbishop.look4sat.utility.getNavResult import com.rtbishop.look4sat.utility.navigateSafe @@ -79,21 +79,21 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) { } private fun handleSatData( - result: Result>, + dataState: DataState>, binding: FragmentEntriesBinding, entriesAdapter: EntriesAdapter ) { - when (result) { - is Result.Success -> { - entriesAdapter.submitList(result.data) + when (dataState) { + is DataState.Success -> { + entriesAdapter.submitList(dataState.data) binding.entriesProgress.visibility = View.INVISIBLE binding.entriesRecycler.visibility = View.VISIBLE } - is Result.InProgress -> { + is DataState.Loading -> { binding.entriesProgress.visibility = View.VISIBLE binding.entriesRecycler.visibility = View.INVISIBLE } - is Result.Error -> { + is DataState.Error -> { binding.entriesProgress.visibility = View.INVISIBLE binding.entriesRecycler.visibility = View.VISIBLE requireView().showSnack(getString(R.string.entries_update_error)) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt index 5dd8e267..b56b291a 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt @@ -24,10 +24,12 @@ import androidx.lifecycle.* import com.rtbishop.look4sat.data.Preferences import com.rtbishop.look4sat.data.SatelliteRepo import com.rtbishop.look4sat.data.SatItem -import com.rtbishop.look4sat.framework.model.Result +import com.rtbishop.look4sat.framework.model.DataState import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch +import timber.log.Timber import java.util.* import javax.inject.Inject @@ -38,46 +40,46 @@ class EntriesViewModel @Inject constructor( private val satelliteRepo: SatelliteRepo, ) : ViewModel(), EntriesAdapter.EntriesClickListener, SearchView.OnQueryTextListener { + private val coroutineHandler = CoroutineExceptionHandler { _, throwable -> + Timber.d(throwable) + _satData.value = DataState.Error(throwable) + } private val transModes = MutableLiveData(satelliteRepo.loadSelectedModes()) private val currentQuery = MutableLiveData(String()) private val itemsWithModes = transModes.switchMap { modes -> liveData { satelliteRepo.getSatItems().collect { emit(filterByModes(it, modes)) } } } private val itemsWithQuery = currentQuery.switchMap { query -> - itemsWithModes.map { items -> Result.Success(filterByQuery(items, query)) } + itemsWithModes.map { items -> DataState.Success(filterByQuery(items, query)) } } - private val _satData = MediatorLiveData>>().apply { + private val _satData = MediatorLiveData>>().apply { addSource(itemsWithQuery) { value -> this.value = value } } private var shouldSelectAll = true - val satData: LiveData>> = _satData + val satData: LiveData>> = _satData fun updateEntriesFromFile(uri: Uri) { - viewModelScope.launch { - _satData.value = Result.InProgress + viewModelScope.launch(coroutineHandler) { + _satData.value = DataState.Loading runCatching { resolver.openInputStream(uri)?.use { stream -> satelliteRepo.updateEntriesFromFile(stream) } - }.onFailure { _satData.value = Result.Error(it) } + }.onFailure { _satData.value = DataState.Error(it) } } } fun updateEntriesFromWeb(sources: List) { - viewModelScope.launch { - _satData.value = Result.InProgress - try { - preferences.saveTleSources(sources) - satelliteRepo.updateEntriesFromWeb(sources) - } catch (exception: Exception) { - _satData.value = Result.Error(exception) - } + viewModelScope.launch(coroutineHandler) { + _satData.value = DataState.Loading + preferences.saveTleSources(sources) + satelliteRepo.updateEntriesFromWeb(sources) } } fun selectCurrentItems() { val currentValue = _satData.value - if (currentValue is Result.Success) { + if (currentValue is DataState.Success) { updateSelection(currentValue.data.map { it.catNum }, shouldSelectAll) shouldSelectAll = shouldSelectAll.not() } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesFragment.kt index df53a288..ae02f7d0 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesFragment.kt @@ -30,7 +30,7 @@ import androidx.recyclerview.widget.SimpleItemAnimator import com.rtbishop.look4sat.R import com.rtbishop.look4sat.databinding.FragmentPassesBinding import com.rtbishop.look4sat.domain.SatPass -import com.rtbishop.look4sat.framework.model.Result +import com.rtbishop.look4sat.framework.model.DataState import com.rtbishop.look4sat.utility.RecyclerDivider import com.rtbishop.look4sat.utility.navigateSafe import com.rtbishop.look4sat.utility.toTimerString @@ -73,21 +73,21 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC } private fun handleNewPasses( - result: Result>, + dataState: DataState>, passesAdapter: PassesAdapter, binding: FragmentPassesBinding ) { - when (result) { - is Result.Success -> { - passesAdapter.submitList(result.data) + when (dataState) { + is DataState.Success -> { + passesAdapter.submitList(dataState.data) binding.apply { passesError.visibility = View.INVISIBLE passesProgress.visibility = View.INVISIBLE passesRecycler.visibility = View.VISIBLE } - tickMainTimer(result.data, binding) + tickMainTimer(dataState.data, binding) } - is Result.InProgress -> { + is DataState.Loading -> { binding.apply { passesTimer.text = 0L.toTimerString() passesError.visibility = View.INVISIBLE @@ -95,7 +95,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC passesProgress.visibility = View.VISIBLE } } - is Result.Error -> { + is DataState.Error -> { binding.apply { passesTimer.text = 0L.toTimerString() passesProgress.visibility = View.INVISIBLE diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesViewModel.kt index 83dfa2cf..8ab74768 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesViewModel.kt @@ -25,7 +25,7 @@ import com.rtbishop.look4sat.data.Preferences import com.rtbishop.look4sat.data.SatelliteRepo import com.rtbishop.look4sat.domain.Predictor import com.rtbishop.look4sat.domain.SatPass -import com.rtbishop.look4sat.framework.model.Result +import com.rtbishop.look4sat.framework.model.DataState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.* import kotlinx.coroutines.flow.collect @@ -39,16 +39,16 @@ class PassesViewModel @Inject constructor( private val preferences: Preferences ) : ViewModel() { - private val _passes = MutableLiveData>>(Result.InProgress) + private val _passes = MutableLiveData>>(DataState.Loading) private val _isFirstLaunchDone = MutableLiveData() private var passesProcessing: Job? = null - val passes: LiveData>> = _passes + val passes: LiveData>> = _passes val isFirstLaunchDone: LiveData = _isFirstLaunchDone init { if (preferences.isSetupDone()) { viewModelScope.launch { - _passes.postValue(Result.InProgress) + _passes.postValue(DataState.Loading) val dateNow = Date() val satellites = satelliteRepo.getSelectedSatellites() val stationPos = preferences.loadStationPosition() @@ -70,7 +70,7 @@ class PassesViewModel @Inject constructor( fun triggerInitialSetup() { preferences.updatePositionFromGPS() viewModelScope.launch { - _passes.postValue(Result.InProgress) + _passes.postValue(DataState.Loading) val defaultCatNums = listOf(43700, 25544, 25338, 28654, 33591, 40069, 27607, 24278) val dateNow = Date() val satellites = satelliteRepo.getSelectedSatellites() @@ -87,7 +87,7 @@ class PassesViewModel @Inject constructor( fun forceCalculation() { viewModelScope.launch { - _passes.postValue(Result.InProgress) + _passes.postValue(DataState.Loading) passesProcessing?.cancelAndJoin() val dateNow = Date() val satellites = satelliteRepo.getSelectedSatellites() @@ -117,7 +117,7 @@ class PassesViewModel @Inject constructor( } } currentPasses = currentPasses.filter { it.progress < 100 } - _passes.postValue(Result.Success(currentPasses.map { it.copy() })) + _passes.postValue(DataState.Success(currentPasses.map { it.copy() })) delay(1000) } } diff --git a/build.gradle b/build.gradle index 264db984..f1247ee1 100644 --- a/build.gradle +++ b/build.gradle @@ -5,12 +5,12 @@ buildscript { coroutines_version = '1.5.2-native-mt' material_version = '1.4.0' splash_screen_version = '1.0.0-alpha01' - constraint_layout_version = '2.1.0' + constraint_layout_version = '2.1.1' lifecycle_version = '2.3.1' navigation_version = '2.3.5' preference_version = '1.1.1' room_version = '2.3.0' - hilt_version = '2.38.1' + hilt_version = '2.39' retrofit_version = '2.9.0' osmdroid_version = '6.1.11' timber_version = '5.0.1'