Make sure code doesnt get fetched multiple times, share the same vm over the whole session
This commit is contained in:
parent
e0a40a548e
commit
2f1c6604ba
5
app/src/main/java/com/ti/mobpo/model/FavouriteUiState.kt
Normal file
5
app/src/main/java/com/ti/mobpo/model/FavouriteUiState.kt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package com.ti.mobpo.model
|
||||||
|
|
||||||
|
import com.ti.mobpo.data.Favourite
|
||||||
|
|
||||||
|
data class FavouriteUiState(val favourites: List<Favourite> = listOf())
|
@ -20,17 +20,22 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberUpdatedState
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.ti.mobpo.AppViewModelProvider
|
||||||
import com.ti.mobpo.ui.screens.FavoritesScreen
|
import com.ti.mobpo.ui.screens.FavoritesScreen
|
||||||
import com.ti.mobpo.ui.screens.PokeSearchScreen
|
import com.ti.mobpo.ui.screens.PokeSearchScreen
|
||||||
|
import com.ti.mobpo.ui.viewmodels.FavouritesViewModel
|
||||||
|
import com.ti.mobpo.ui.viewmodels.PokeSearchViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Navigation() {
|
fun Navigation() {
|
||||||
@ -59,6 +64,9 @@ fun Navigation() {
|
|||||||
val updatedSelectedIndex = items.indexOfFirst { it.route == currentRoute }
|
val updatedSelectedIndex = items.indexOfFirst { it.route == currentRoute }
|
||||||
selectedItemIndex = rememberUpdatedState(updatedSelectedIndex).value
|
selectedItemIndex = rememberUpdatedState(updatedSelectedIndex).value
|
||||||
|
|
||||||
|
val pokeSearchVM = viewModel<PokeSearchViewModel>(factory = AppViewModelProvider.Factory)
|
||||||
|
val favoritesVM = viewModel<FavouritesViewModel>(factory = AppViewModelProvider.Factory)
|
||||||
|
|
||||||
Scaffold (
|
Scaffold (
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
NavigationBar {
|
NavigationBar {
|
||||||
@ -102,11 +110,11 @@ fun Navigation() {
|
|||||||
ExitTransition.None
|
ExitTransition.None
|
||||||
}) {
|
}) {
|
||||||
composable(route = Screen.PokeSearch.route) {
|
composable(route = Screen.PokeSearch.route) {
|
||||||
PokeSearchScreen()
|
PokeSearchScreen(pokeSearchVM)
|
||||||
}
|
}
|
||||||
composable(
|
composable(
|
||||||
route = Screen.Favourites.route) {
|
route = Screen.Favourites.route) {
|
||||||
FavoritesScreen()
|
FavoritesScreen(favoritesVM)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,6 +128,6 @@ fun Navigation() {
|
|||||||
@Composable
|
@Composable
|
||||||
fun NavigationPreview() {
|
fun NavigationPreview() {
|
||||||
Surface {
|
Surface {
|
||||||
PokeSearchScreen()
|
PokeSearchScreen(viewModel(factory = AppViewModelProvider.Factory))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,7 +23,7 @@ import androidx.compose.runtime.LaunchedEffect
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun FavoritesScreen(viewModel: FavouritesViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
|
fun FavoritesScreen(viewModel: FavouritesViewModel) {
|
||||||
Favorites(viewModel)
|
Favorites(viewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ import com.ti.mobpo.capitalizeFirstLetterAfterHyphens
|
|||||||
import com.ti.mobpo.ui.theme.MobileSecurityTheme
|
import com.ti.mobpo.ui.theme.MobileSecurityTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PokeSearchScreen(viewModel: PokeSearchViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
|
fun PokeSearchScreen(viewModel: PokeSearchViewModel) {
|
||||||
PokeSearch(viewModel)
|
PokeSearch(viewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel
|
|||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.ti.mobpo.data.Favourite
|
import com.ti.mobpo.data.Favourite
|
||||||
import com.ti.mobpo.data.FavouritesRepository
|
import com.ti.mobpo.data.FavouritesRepository
|
||||||
|
import com.ti.mobpo.model.FavouriteUiState
|
||||||
import com.ti.mobpo.model.PokemonDetails
|
import com.ti.mobpo.model.PokemonDetails
|
||||||
import com.ti.mobpo.network.PokeApi
|
import com.ti.mobpo.network.PokeApi
|
||||||
import com.ti.mobpo.ui.util.FeatureManager
|
import com.ti.mobpo.ui.util.FeatureManager
|
||||||
@ -47,9 +48,6 @@ class FavouritesViewModel(private val favouritesRepository: FavouritesRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun toggleFavorite(pokemonId: Int) {
|
fun toggleFavorite(pokemonId: Int) {
|
||||||
_pokemonDetails.value = _pokemonDetails.value?.map { pokemon ->
|
_pokemonDetails.value = _pokemonDetails.value?.map { pokemon ->
|
||||||
if (pokemon.id == pokemonId) {
|
if (pokemon.id == pokemonId) {
|
||||||
@ -72,5 +70,3 @@ class FavouritesViewModel(private val favouritesRepository: FavouritesRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class FavouriteUiState(val favourites: List<Favourite> = listOf())
|
|
||||||
|
@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope
|
|||||||
import com.ti.mobpo.data.Favourite
|
import com.ti.mobpo.data.Favourite
|
||||||
import com.ti.mobpo.data.FavouritesRepository
|
import com.ti.mobpo.data.FavouritesRepository
|
||||||
import com.ti.mobpo.model.PokemonDetails
|
import com.ti.mobpo.model.PokemonDetails
|
||||||
|
import com.ti.mobpo.model.PokemonSpecies
|
||||||
import com.ti.mobpo.network.PokeApi
|
import com.ti.mobpo.network.PokeApi
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
@ -13,24 +14,42 @@ import kotlinx.coroutines.launch
|
|||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
|
|
||||||
|
private const val SHOW_LIMIT = 20;
|
||||||
class PokeSearchViewModel(private val favouritesRepository: FavouritesRepository) : ViewModel() {
|
class PokeSearchViewModel(private val favouritesRepository: FavouritesRepository) : ViewModel() {
|
||||||
private val service = PokeApi.retrofitService;
|
private val service = PokeApi.retrofitService;
|
||||||
|
|
||||||
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)
|
||||||
|
init {
|
||||||
|
fetchPokemonSpecies()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchPokemonSpecies() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
try {
|
||||||
|
val response = service.getPokemon()
|
||||||
|
_initialPokemonList.value = response.results
|
||||||
|
} catch (e: IOException) {
|
||||||
|
/*TODO*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun search(query: String) {
|
fun search(query: String) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
val response = service.getPokemon()
|
val filteredList = _initialPokemonList.value?.filter { it.name.contains(query, ignoreCase = true) }
|
||||||
val filteredList = response.results.filter { it.name.contains(query, ignoreCase = true) }
|
|
||||||
val detailsList = mutableListOf<PokemonDetails>()
|
val detailsList = mutableListOf<PokemonDetails>()
|
||||||
for (pokemonSpecies in filteredList) {
|
if (filteredList != null) {
|
||||||
|
for (pokemonSpecies in filteredList.take(SHOW_LIMIT)) {
|
||||||
val details = service.getPokemonDetails(extractPokemonId(pokemonSpecies.url))
|
val details = service.getPokemonDetails(extractPokemonId(pokemonSpecies.url))
|
||||||
val isFavorite = favouritesRepository.isFavourite(details.id)
|
val isFavorite = favouritesRepository.isFavourite(details.id)
|
||||||
detailsList.add(details.copy(isFavorite = isFavorite))
|
detailsList.add(details.copy(isFavorite = isFavorite))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
_pokemonDetails.value = detailsList
|
_pokemonDetails.value = detailsList
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
/* Handle error */
|
/* Handle error */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user