Skip to content

Commit

Permalink
Improve the structure of BreedDetails code
Browse files Browse the repository at this point in the history
  • Loading branch information
bpedryc committed Jun 16, 2023
1 parent e36923d commit aea43f6
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package co.touchlab.kampkit.android.ui

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import co.touchlab.kampkit.ui.breedDetails.BreedDetailsViewModel
import co.touchlab.kermit.Logger
Expand All @@ -13,6 +18,13 @@ fun BreedDetailsScreen(
log: Logger
) {
val state by viewModel.detailsState.collectAsStateWithLifecycle()
Box(Modifier.fillMaxSize()) {
state.error?.let { error ->
Text(error, Modifier.align(Alignment.Center), color = Color.Red)
}
if (state.error == null) {
Text(state.breed.name, Modifier.align(Alignment.Center))
}
}

Text("${state.breed?.name }")
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ package co.touchlab.kampkit.ui.breedDetails

import co.touchlab.kampkit.core.ViewModel
import co.touchlab.kampkit.data.dog.DogRepository
import co.touchlab.kampkit.db.Breed
import co.touchlab.kermit.Logger
import com.rickclephas.kmp.nativecoroutines.NativeCoroutinesState
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

Expand All @@ -26,42 +23,23 @@ class BreedDetailsViewModel(
val detailsState: StateFlow<BreedDetailsViewState> = mutableDetailsState

init {
observeDetails()
loadDetails()
}

private fun observeDetails() {
// Refresh breeds, and emit any exception that was thrown so we can handle it downstream
val refreshFlow = flow<Throwable?> {
try {
dogRepository.refreshBreedsIfStale()
emit(null)
} catch (exception: Exception) {
emit(exception)
}
}

private fun loadDetails() {
viewModelScope.launch {
combine(refreshFlow, dogRepository.getBreed(breedId)) { throwable, breed -> throwable to breed }
.collect { (error, breed) ->
mutableDetailsState.update { previousState ->
val errorMessage = if (error != null) {
"Unable to download breed details"
} else {
previousState.error
}
previousState.copy(
isLoading = false,
breed = breed,
error = errorMessage.takeIf { breed != null },
)
}
dogRepository.getBreed(breedId).collect { breed ->
mutableDetailsState.update { previousState ->
val error = if (breed == null) "Couldn't load the breed details" else null
val newBreed = breed?.toDisplayable() ?: previousState.breed
previousState.copy(
isLoading = false,
breed = newBreed,
error = error
)
}
}
}
}
}

data class BreedDetailsViewState(
val breed: Breed? = null,
val error: String? = null,
val isLoading: Boolean = false,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package co.touchlab.kampkit.ui.breedDetails

data class BreedDetailsViewState(
val breed: BreedDisplayable = BreedDisplayable(),
val error: String? = null,
val isLoading: Boolean = false,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package co.touchlab.kampkit.ui.breedDetails

import co.touchlab.kampkit.db.Breed

data class BreedDisplayable(
val id: Long = 0,
val name: String = "",
val favorite: Boolean = false
)

fun Breed.toDisplayable() = BreedDisplayable(
this.id,
this.name,
this.favorite
)

0 comments on commit aea43f6

Please sign in to comment.