Make sure code doesnt get fetched multiple times, share the same vm over the whole session

This commit is contained in:
Joren 2024-04-30 01:40:33 +02:00
parent e0a40a548e
commit 2f1c6604ba
Signed by untrusted user who does not match committer: Joren
GPG Key ID: 280E33DFBC0F1B55
6 changed files with 45 additions and 17 deletions

View File

@ -0,0 +1,5 @@
package com.ti.mobpo.model
import com.ti.mobpo.data.Favourite
data class FavouriteUiState(val favourites: List<Favourite> = listOf())

View File

@ -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<PokeSearchViewModel>(factory = AppViewModelProvider.Factory)
val favoritesVM = viewModel<FavouritesViewModel>(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))
}
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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<Favourite> = listOf())

View File

@ -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,24 +14,42 @@ 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<List<PokemonDetails>?>(null)
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) {
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<PokemonDetails>()
for (pokemonSpecies in filteredList) {
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) {
/* Handle error */