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.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@ -53,6 +54,7 @@ fun PokeSearchScreen(viewModel: PokeSearchViewModel) {
@Composable
fun PokeSearch(pokeSearchViewModel: PokeSearchViewModel) {
val searchResults by pokeSearchViewModel.pokemonDetails.collectAsState()
val isLoading by pokeSearchViewModel.isLoading.collectAsState()
Column(
verticalArrangement = Arrangement.Top,
@ -67,21 +69,25 @@ fun PokeSearch(pokeSearchViewModel: PokeSearchViewModel) {
Spacer(modifier = Modifier.height(16.dp))
searchResults?.let { results ->
if (results.isNotEmpty()) {
LazyVerticalGrid(
columns = GridCells.Adaptive(150.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
items(items = results, key = { pokemon -> pokemon.id }) { pokemon ->
PokemonCard(pokemon, toggleFavorite = { pokemonId ->
pokeSearchViewModel.toggleFavorite(pokemonId)
})
if(isLoading) {
CircularProgressIndicator()
} else {
searchResults?.let { results ->
if (results.isNotEmpty()) {
LazyVerticalGrid(
columns = GridCells.Adaptive(150.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
items(items = results, key = { pokemon -> pokemon.id }) { pokemon ->
PokemonCard(pokemon, toggleFavorite = { pokemonId ->
pokeSearchViewModel.toggleFavorite(pokemonId)
})
}
}
} else {
Text("No results found")
}
} else {
Text("No results found")
}
}
}
@ -125,7 +131,8 @@ fun PokemonCard(pokemon: PokemonDetails, toggleFavorite: (Int) -> Unit) {
)
IconButton(
onClick = { toggleFavorite(pokemon.id) },
modifier = Modifier.wrapContentSize()
modifier = Modifier
.wrapContentSize()
.layout { measurable, constraints ->
if (constraints.maxHeight == Constraints.Infinity) {
layout(0, 0) {}

View File

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