From 77d70569629b196f48304cff34c39f2223ea7bdb Mon Sep 17 00:00:00 2001 From: Joren Date: Mon, 29 Apr 2024 23:19:14 +0200 Subject: [PATCH] Implement view model provider, local database --- app/src/main/AndroidManifest.xml | 1 + .../java/com/ti/mobpo/AppViewModelProvider.kt | 21 +++++++++++++++++++ app/src/main/java/com/ti/mobpo/PokeSearch.kt | 19 +++++++++++++++++ .../java/com/ti/mobpo/data/FavouriteDao.kt | 3 +++ .../com/ti/mobpo/data/FavouritesRepository.kt | 6 ++++++ .../mobpo/data/OfflineFavouritesRepository.kt | 4 ++++ .../main/java/com/ti/mobpo/ui/Navigation.kt | 9 +++----- .../ui/pokesearch/PokeSearchViewModel.kt | 19 +++++++++++++++-- .../com/ti/mobpo/ui/screens/PokeSearch.kt | 5 +++-- 9 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/com/ti/mobpo/AppViewModelProvider.kt create mode 100644 app/src/main/java/com/ti/mobpo/PokeSearch.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8df0ded..9a329ab 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ > + + @Query("SELECT EXISTS(SELECT 1 FROM favourites WHERE id = :id LIMIT 1)") + suspend fun isFavourite(id: Int): Boolean } diff --git a/app/src/main/java/com/ti/mobpo/data/FavouritesRepository.kt b/app/src/main/java/com/ti/mobpo/data/FavouritesRepository.kt index 316a2c4..4083c1b 100644 --- a/app/src/main/java/com/ti/mobpo/data/FavouritesRepository.kt +++ b/app/src/main/java/com/ti/mobpo/data/FavouritesRepository.kt @@ -20,4 +20,10 @@ interface FavouritesRepository { * Delete item from the data source */ suspend fun deleteItem(item: Favourite) + + /** + * Check if the item is a favourite + */ + + suspend fun isFavourite(id: Int): Boolean } diff --git a/app/src/main/java/com/ti/mobpo/data/OfflineFavouritesRepository.kt b/app/src/main/java/com/ti/mobpo/data/OfflineFavouritesRepository.kt index 62a98a8..6f4b000 100644 --- a/app/src/main/java/com/ti/mobpo/data/OfflineFavouritesRepository.kt +++ b/app/src/main/java/com/ti/mobpo/data/OfflineFavouritesRepository.kt @@ -13,4 +13,8 @@ class OfflineFavouritesRepository(private val favouriteDao: FavouriteDao) : Favo override suspend fun deleteItem(item: Favourite) { favouriteDao.delete(item) } + + override suspend fun isFavourite(id: Int): Boolean { + return favouriteDao.isFavourite(id) + } } 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 3510682..e09a3c7 100644 --- a/app/src/main/java/com/ti/mobpo/ui/Navigation.kt +++ b/app/src/main/java/com/ti/mobpo/ui/Navigation.kt @@ -20,6 +20,7 @@ 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 @@ -30,7 +31,6 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController -import com.ti.mobpo.ui.pokesearch.PokeSearchViewModel import com.ti.mobpo.ui.screens.Favourites import com.ti.mobpo.ui.screens.PokeSearchScreen @@ -61,8 +61,6 @@ fun Navigation() { val updatedSelectedIndex = items.indexOfFirst { it.route == currentRoute } selectedItemIndex = rememberUpdatedState(updatedSelectedIndex).value - val pokeSearchViewModel: PokeSearchViewModel = viewModel() - Scaffold ( bottomBar = { NavigationBar { @@ -106,7 +104,7 @@ fun Navigation() { ExitTransition.None }) { composable(route = Screen.PokeSearch.route) { - PokeSearchScreen(pokeSearchViewModel) + PokeSearchScreen() } composable( route = Screen.Favourites.route) { @@ -124,7 +122,6 @@ fun Navigation() { @Composable fun NavigationPreview() { Surface { - val pokeSearchViewModel: PokeSearchViewModel = viewModel() - PokeSearchScreen(pokeSearchViewModel) + PokeSearchScreen() } } \ No newline at end of file diff --git a/app/src/main/java/com/ti/mobpo/ui/pokesearch/PokeSearchViewModel.kt b/app/src/main/java/com/ti/mobpo/ui/pokesearch/PokeSearchViewModel.kt index febd8b3..5bdc5a6 100644 --- a/app/src/main/java/com/ti/mobpo/ui/pokesearch/PokeSearchViewModel.kt +++ b/app/src/main/java/com/ti/mobpo/ui/pokesearch/PokeSearchViewModel.kt @@ -2,6 +2,8 @@ package com.ti.mobpo.ui.pokesearch 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.PokemonDetails import com.ti.mobpo.network.PokeApi import kotlinx.coroutines.flow.MutableStateFlow @@ -12,7 +14,7 @@ import java.io.IOException -class PokeSearchViewModel : ViewModel() { +class PokeSearchViewModel(private val favouritesRepository: FavouritesRepository) : ViewModel() { private val service = PokeApi.retrofitService; private val _pokemonDetails = MutableStateFlow?>(null) @@ -26,7 +28,8 @@ class PokeSearchViewModel : ViewModel() { val detailsList = mutableListOf() for (pokemonSpecies in filteredList) { val details = service.getPokemonDetails(extractPokemonId(pokemonSpecies.url)) - detailsList.add(details) + val isFavorite = favouritesRepository.isFavourite(details.id) + detailsList.add(details.copy(isFavorite = isFavorite)) } _pokemonDetails.value = detailsList } catch (e: IOException) { @@ -48,5 +51,17 @@ class PokeSearchViewModel : ViewModel() { pokemon } } + viewModelScope.launch { + if (_pokemonDetails.value != null) { + val pokemon = _pokemonDetails.value!!.find { it.id == pokemonId } + pokemon?.let { + if (it.isFavorite) { + favouritesRepository.insertItem(Favourite(it.id, it.name)) + } else { + favouritesRepository.deleteItem(Favourite(it.id, it.name)) + } + } + } + } } } 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 511ba28..a2aa2a7 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 @@ -45,12 +45,13 @@ import androidx.lifecycle.viewmodel.compose.viewModel import com.ti.mobpo.model.PokemonDetails import coil.compose.AsyncImage import coil.request.ImageRequest +import com.ti.mobpo.AppViewModelProvider import com.ti.mobpo.capitalizeFirstLetterAfterHyphens import com.ti.mobpo.ui.theme.MobileSecurityTheme @Composable -fun PokeSearchScreen(pokeSearchViewModel: PokeSearchViewModel) { - PokeSearch(pokeSearchViewModel) +fun PokeSearchScreen(viewModel: PokeSearchViewModel = viewModel(factory = AppViewModelProvider.Factory)) { + PokeSearch(viewModel) } @Composable