Add loading indicator

This commit is contained in:
Joren 2024-04-30 02:06:14 +02:00
parent 84e801ed01
commit 7b36f08a26
Signed by untrusted user who does not match committer: Joren
GPG Key ID: 280E33DFBC0F1B55
2 changed files with 27 additions and 14 deletions

View File

@ -19,6 +19,7 @@ import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.outlined.FavoriteBorder import androidx.compose.material.icons.outlined.FavoriteBorder
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@ -53,6 +54,7 @@ fun PokeSearchScreen(viewModel: PokeSearchViewModel) {
@Composable @Composable
fun PokeSearch(pokeSearchViewModel: PokeSearchViewModel) { fun PokeSearch(pokeSearchViewModel: PokeSearchViewModel) {
val searchResults by pokeSearchViewModel.pokemonDetails.collectAsState() val searchResults by pokeSearchViewModel.pokemonDetails.collectAsState()
val isLoading by pokeSearchViewModel.isLoading.collectAsState()
Column( Column(
verticalArrangement = Arrangement.Top, verticalArrangement = Arrangement.Top,
@ -67,6 +69,9 @@ fun PokeSearch(pokeSearchViewModel: PokeSearchViewModel) {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
if(isLoading) {
CircularProgressIndicator()
} else {
searchResults?.let { results -> searchResults?.let { results ->
if (results.isNotEmpty()) { if (results.isNotEmpty()) {
LazyVerticalGrid( LazyVerticalGrid(
@ -86,6 +91,7 @@ fun PokeSearch(pokeSearchViewModel: PokeSearchViewModel) {
} }
} }
} }
}
@Composable @Composable
@ -125,7 +131,8 @@ fun PokemonCard(pokemon: PokemonDetails, toggleFavorite: (Int) -> Unit) {
) )
IconButton( IconButton(
onClick = { toggleFavorite(pokemon.id) }, onClick = { toggleFavorite(pokemon.id) },
modifier = Modifier.wrapContentSize() modifier = Modifier
.wrapContentSize()
.layout { measurable, constraints -> .layout { measurable, constraints ->
if (constraints.maxHeight == Constraints.Infinity) { if (constraints.maxHeight == Constraints.Infinity) {
layout(0, 0) {} layout(0, 0) {}

View File

@ -21,6 +21,9 @@ class PokeSearchViewModel(private val favouritesRepository: FavouritesRepository
private val _pokemonDetails = MutableStateFlow<List<PokemonDetails>?>(null) private val _pokemonDetails = MutableStateFlow<List<PokemonDetails>?>(null)
val pokemonDetails: StateFlow<List<PokemonDetails>?> = _pokemonDetails.asStateFlow() val pokemonDetails: StateFlow<List<PokemonDetails>?> = _pokemonDetails.asStateFlow()
private val _initialPokemonList = MutableStateFlow<List<PokemonSpecies>?>(null) private val _initialPokemonList = MutableStateFlow<List<PokemonSpecies>?>(null)
private val _isLoading = MutableStateFlow(false)
val isLoading: StateFlow<Boolean> = _isLoading.asStateFlow()
init { init {
fetchPokemonSpecies() fetchPokemonSpecies()
} }
@ -37,6 +40,7 @@ class PokeSearchViewModel(private val favouritesRepository: FavouritesRepository
} }
fun search(query: String) { fun search(query: String) {
_isLoading.value = true
viewModelScope.launch { viewModelScope.launch {
try { try {
val filteredList = _initialPokemonList.value?.binarySearch(query) val filteredList = _initialPokemonList.value?.binarySearch(query)
@ -52,6 +56,8 @@ class PokeSearchViewModel(private val favouritesRepository: FavouritesRepository
_pokemonDetails.value = detailsList _pokemonDetails.value = detailsList
} catch (e: IOException) { } catch (e: IOException) {
/* Handle error */ /* Handle error */
} finally {
_isLoading.value = false
} }
} }
} }