diff --git a/app/src/main/java/com/ti/mobpo/model/FavouriteUiState.kt b/app/src/main/java/com/ti/mobpo/model/FavouriteUiState.kt new file mode 100644 index 0000000..69f5cd1 --- /dev/null +++ b/app/src/main/java/com/ti/mobpo/model/FavouriteUiState.kt @@ -0,0 +1,5 @@ +package com.ti.mobpo.model + +import com.ti.mobpo.data.Favourite + +data class FavouriteUiState(val favourites: List = listOf()) \ No newline at end of file diff --git a/app/src/main/java/com/ti/mobpo/ui/Navigation.kt b/app/src/main/java/com/ti/mobpo/ui/Navigation.kt index 3fb9343..e763f24 100644 --- a/app/src/main/java/com/ti/mobpo/ui/Navigation.kt +++ b/app/src/main/java/com/ti/mobpo/ui/Navigation.kt @@ -20,17 +20,22 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController +import com.ti.mobpo.AppViewModelProvider import com.ti.mobpo.ui.screens.FavoritesScreen import com.ti.mobpo.ui.screens.PokeSearchScreen +import com.ti.mobpo.ui.viewmodels.FavouritesViewModel +import com.ti.mobpo.ui.viewmodels.PokeSearchViewModel @Composable fun Navigation() { @@ -59,6 +64,9 @@ fun Navigation() { val updatedSelectedIndex = items.indexOfFirst { it.route == currentRoute } selectedItemIndex = rememberUpdatedState(updatedSelectedIndex).value + val pokeSearchVM = viewModel(factory = AppViewModelProvider.Factory) + val favoritesVM = viewModel(factory = AppViewModelProvider.Factory) + Scaffold ( bottomBar = { NavigationBar { @@ -102,11 +110,11 @@ fun Navigation() { ExitTransition.None }) { composable(route = Screen.PokeSearch.route) { - PokeSearchScreen() + PokeSearchScreen(pokeSearchVM) } composable( route = Screen.Favourites.route) { - FavoritesScreen() + FavoritesScreen(favoritesVM) } } } @@ -120,6 +128,6 @@ fun Navigation() { @Composable fun NavigationPreview() { Surface { - PokeSearchScreen() + PokeSearchScreen(viewModel(factory = AppViewModelProvider.Factory)) } } \ No newline at end of file diff --git a/app/src/main/java/com/ti/mobpo/ui/screens/Favourites.kt b/app/src/main/java/com/ti/mobpo/ui/screens/Favourites.kt index fe9d851..bbee671 100644 --- a/app/src/main/java/com/ti/mobpo/ui/screens/Favourites.kt +++ b/app/src/main/java/com/ti/mobpo/ui/screens/Favourites.kt @@ -23,7 +23,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier @Composable -fun FavoritesScreen(viewModel: FavouritesViewModel = viewModel(factory = AppViewModelProvider.Factory)) { +fun FavoritesScreen(viewModel: FavouritesViewModel) { Favorites(viewModel) } diff --git a/app/src/main/java/com/ti/mobpo/ui/screens/PokeSearch.kt b/app/src/main/java/com/ti/mobpo/ui/screens/PokeSearch.kt index cc238cb..27c0a1a 100644 --- a/app/src/main/java/com/ti/mobpo/ui/screens/PokeSearch.kt +++ b/app/src/main/java/com/ti/mobpo/ui/screens/PokeSearch.kt @@ -47,7 +47,7 @@ import com.ti.mobpo.capitalizeFirstLetterAfterHyphens import com.ti.mobpo.ui.theme.MobileSecurityTheme @Composable -fun PokeSearchScreen(viewModel: PokeSearchViewModel = viewModel(factory = AppViewModelProvider.Factory)) { +fun PokeSearchScreen(viewModel: PokeSearchViewModel) { PokeSearch(viewModel) } diff --git a/app/src/main/java/com/ti/mobpo/ui/viewmodels/FavouritesViewModel.kt b/app/src/main/java/com/ti/mobpo/ui/viewmodels/FavouritesViewModel.kt index b829db6..a318f12 100644 --- a/app/src/main/java/com/ti/mobpo/ui/viewmodels/FavouritesViewModel.kt +++ b/app/src/main/java/com/ti/mobpo/ui/viewmodels/FavouritesViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.ti.mobpo.data.Favourite import com.ti.mobpo.data.FavouritesRepository +import com.ti.mobpo.model.FavouriteUiState import com.ti.mobpo.model.PokemonDetails import com.ti.mobpo.network.PokeApi import com.ti.mobpo.ui.util.FeatureManager @@ -47,9 +48,6 @@ class FavouritesViewModel(private val favouritesRepository: FavouritesRepository } } - - - fun toggleFavorite(pokemonId: Int) { _pokemonDetails.value = _pokemonDetails.value?.map { pokemon -> if (pokemon.id == pokemonId) { @@ -72,5 +70,3 @@ class FavouritesViewModel(private val favouritesRepository: FavouritesRepository } } } - -data class FavouriteUiState(val favourites: List = listOf()) diff --git a/app/src/main/java/com/ti/mobpo/ui/viewmodels/PokeSearchViewModel.kt b/app/src/main/java/com/ti/mobpo/ui/viewmodels/PokeSearchViewModel.kt index cd1888a..8146c7f 100644 --- a/app/src/main/java/com/ti/mobpo/ui/viewmodels/PokeSearchViewModel.kt +++ b/app/src/main/java/com/ti/mobpo/ui/viewmodels/PokeSearchViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope import com.ti.mobpo.data.Favourite import com.ti.mobpo.data.FavouritesRepository import com.ti.mobpo.model.PokemonDetails +import com.ti.mobpo.model.PokemonSpecies import com.ti.mobpo.network.PokeApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -13,23 +14,41 @@ import kotlinx.coroutines.launch import java.io.IOException - +private const val SHOW_LIMIT = 20; class PokeSearchViewModel(private val favouritesRepository: FavouritesRepository) : ViewModel() { private val service = PokeApi.retrofitService; private val _pokemonDetails = MutableStateFlow?>(null) val pokemonDetails: StateFlow?> = _pokemonDetails.asStateFlow() + private val _initialPokemonList = MutableStateFlow?>(null) + init { + fetchPokemonSpecies() + } + + private fun fetchPokemonSpecies() { + viewModelScope.launch { + try { + val response = service.getPokemon() + _initialPokemonList.value = response.results + } catch (e: IOException) { + /*TODO*/ + } + } + } + + fun search(query: String) { viewModelScope.launch { try { - val response = service.getPokemon() - val filteredList = response.results.filter { it.name.contains(query, ignoreCase = true) } + val filteredList = _initialPokemonList.value?.filter { it.name.contains(query, ignoreCase = true) } val detailsList = mutableListOf() - for (pokemonSpecies in filteredList) { - val details = service.getPokemonDetails(extractPokemonId(pokemonSpecies.url)) - val isFavorite = favouritesRepository.isFavourite(details.id) - detailsList.add(details.copy(isFavorite = isFavorite)) + if (filteredList != null) { + for (pokemonSpecies in filteredList.take(SHOW_LIMIT)) { + val details = service.getPokemonDetails(extractPokemonId(pokemonSpecies.url)) + val isFavorite = favouritesRepository.isFavourite(details.id) + detailsList.add(details.copy(isFavorite = isFavorite)) + } } _pokemonDetails.value = detailsList } catch (e: IOException) {