Some ugly code..., it works
This commit is contained in:
parent
93b4d04587
commit
e0a40a548e
@ -1,11 +1,11 @@
|
||||
package com.ti.mobpo
|
||||
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.createSavedStateHandle
|
||||
import androidx.lifecycle.viewmodel.CreationExtras
|
||||
import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import com.ti.mobpo.ui.pokesearch.PokeSearchViewModel
|
||||
import com.ti.mobpo.ui.viewmodels.FavouritesViewModel
|
||||
import com.ti.mobpo.ui.viewmodels.PokeSearchViewModel
|
||||
|
||||
object AppViewModelProvider {
|
||||
val Factory = viewModelFactory {
|
||||
@ -13,9 +13,17 @@ object AppViewModelProvider {
|
||||
PokeSearchViewModel(
|
||||
pokesearchApplication().appContainer.favouritesRepository
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
initializer {
|
||||
FavouritesViewModel(
|
||||
pokesearchApplication().appContainer.favouritesRepository, pokesearchApplication().featureManager
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun CreationExtras.pokesearchApplication(): PokeSearch =
|
||||
(this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as PokeSearch)
|
||||
|
||||
|
@ -3,17 +3,26 @@ package com.ti.mobpo
|
||||
import android.app.Application
|
||||
import com.ti.mobpo.data.AppContainer
|
||||
import com.ti.mobpo.data.AppDataContainer
|
||||
import com.ti.mobpo.ui.util.FeatureManager
|
||||
|
||||
class PokeSearch : Application() {
|
||||
lateinit var appContainer: AppContainer
|
||||
private set
|
||||
|
||||
lateinit var featureManager: FeatureManager
|
||||
private set
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
appContainer = createAppContainer()
|
||||
featureManager = createFeatrureManager()
|
||||
}
|
||||
|
||||
private fun createAppContainer(): AppContainer {
|
||||
return AppDataContainer(this)
|
||||
}
|
||||
|
||||
private fun createFeatrureManager(): FeatureManager {
|
||||
return FeatureManager(this)
|
||||
}
|
||||
}
|
||||
|
@ -20,18 +20,16 @@ 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.ui.screens.Favourites
|
||||
import com.ti.mobpo.ui.screens.FavoritesScreen
|
||||
import com.ti.mobpo.ui.screens.PokeSearchScreen
|
||||
|
||||
@Composable
|
||||
@ -108,7 +106,7 @@ fun Navigation() {
|
||||
}
|
||||
composable(
|
||||
route = Screen.Favourites.route) {
|
||||
Favourites()
|
||||
FavoritesScreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
package com.ti.mobpo.ui.pokesearch
|
||||
|
||||
data class PokeSearchUiState(val searchQuery: String = "")
|
@ -18,6 +18,8 @@ import com.ti.mobpo.ui.viewmodels.FavouritesViewModel
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
@Composable
|
||||
@ -27,8 +29,11 @@ fun FavoritesScreen(viewModel: FavouritesViewModel = viewModel(factory = AppView
|
||||
|
||||
@Composable
|
||||
fun Favorites(favoritesViewModel: FavouritesViewModel) {
|
||||
LaunchedEffect(Unit) {
|
||||
favoritesViewModel.loadFavourites()
|
||||
}
|
||||
|
||||
val favorites by favoritesViewModel.pokemonDetails.collectAsState()
|
||||
favoritesViewModel.loadFavourites()
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.Top,
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.ti.mobpo.ui.screens
|
||||
|
||||
import com.ti.mobpo.ui.pokesearch.PokeSearchViewModel
|
||||
import com.ti.mobpo.ui.viewmodels.PokeSearchViewModel
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@ -26,9 +26,6 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
@ -94,7 +91,6 @@ fun PokeSearch(pokeSearchViewModel: PokeSearchViewModel) {
|
||||
|
||||
@Composable
|
||||
fun PokemonCard(pokemon: PokemonDetails, toggleFavorite: (Int) -> Unit) {
|
||||
var isFavourite by remember { mutableStateOf(false) }
|
||||
Card(
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 8.dp),
|
||||
|
18
app/src/main/java/com/ti/mobpo/ui/util/FeatureManager.kt
Normal file
18
app/src/main/java/com/ti/mobpo/ui/util/FeatureManager.kt
Normal file
@ -0,0 +1,18 @@
|
||||
package com.ti.mobpo.ui.util
|
||||
|
||||
import android.content.Context
|
||||
|
||||
class FeatureManager(private val context: Context) {
|
||||
private val PREFS_NAME = "FeaturePrefs"
|
||||
private val KEY_PAID_FEATURE_ENABLED = "paid_feature_enabled"
|
||||
|
||||
fun hasAccessToPaidFeature(): Boolean {
|
||||
val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
||||
return prefs.getBoolean(KEY_PAID_FEATURE_ENABLED, false)
|
||||
}
|
||||
|
||||
fun setPaidFeatureEnabled(enabled: Boolean) {
|
||||
val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
||||
prefs.edit().putBoolean(KEY_PAID_FEATURE_ENABLED, enabled).apply()
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package com.ti.mobpo.ui.viewmodels
|
||||
|
||||
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 com.ti.mobpo.ui.util.FeatureManager
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.IOException
|
||||
|
||||
class FavouritesViewModel(private val favouritesRepository: FavouritesRepository, featureManager: FeatureManager) : ViewModel() {
|
||||
private val service = PokeApi.retrofitService;
|
||||
|
||||
private val _pokemonDetails = MutableStateFlow<List<PokemonDetails>?>(null)
|
||||
val pokemonDetails: StateFlow<List<PokemonDetails>?> = _pokemonDetails.asStateFlow()
|
||||
|
||||
fun loadFavourites() {
|
||||
// Ugly workaround to make sure all the favourites are loaded before displaying them
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val favouritesList: StateFlow<FavouriteUiState> =
|
||||
favouritesRepository.getAllItems().map { FavouriteUiState(it) }
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(5_000L),
|
||||
initialValue = FavouriteUiState()
|
||||
)
|
||||
favouritesList.collect { state ->
|
||||
val detailsList = mutableListOf<PokemonDetails>()
|
||||
for (favourite in state.favourites) {
|
||||
val details = service.getPokemonDetails(favourite.id)
|
||||
detailsList.add(details.copy(isFavorite = true))
|
||||
}
|
||||
_pokemonDetails.value = detailsList
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
/* Handle error */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fun toggleFavorite(pokemonId: Int) {
|
||||
_pokemonDetails.value = _pokemonDetails.value?.map { pokemon ->
|
||||
if (pokemon.id == pokemonId) {
|
||||
pokemon.copy(isFavorite = !pokemon.isFavorite)
|
||||
} else {
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class FavouriteUiState(val favourites: List<Favourite> = listOf())
|
@ -1,4 +1,4 @@
|
||||
package com.ti.mobpo.ui.pokesearch
|
||||
package com.ti.mobpo.ui.viewmodels
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
Loading…
x
Reference in New Issue
Block a user