Add loading indicator
This commit is contained in:
		@@ -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(
 | 
				
			||||||
@@ -85,6 +90,7 @@ fun PokeSearch(pokeSearchViewModel: PokeSearchViewModel) {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -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) {}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user