From b416011a1dc0e0ebb1be4b4bf3c1737c267f76f1 Mon Sep 17 00:00:00 2001 From: Emelyanov535 Date: Wed, 13 Dec 2023 22:51:51 +0400 Subject: [PATCH] Fix: correct update basket --- .../api/repository/RestBasketRepository.kt | 8 ++++---- .../businessLogic/repo/BasketRepository.kt | 4 ++-- .../businessLogic/vmodel/BasketViewModel.kt | 18 +++++++++++++++--- .../businessLogic/vmodel/OrderViewModel.kt | 3 +-- .../SneakerRecyclerView/CardSneaker.kt | 18 +++++++++++------- .../Screens/OrderScreen/CardSneaker.kt | 7 ++++++- .../Screens/OrderScreen/OrderScreen.kt | 15 +++++++++------ .../database/AppDatabase.kt | 6 +++--- 8 files changed, 51 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/com/example/android_programming/api/repository/RestBasketRepository.kt b/app/src/main/java/com/example/android_programming/api/repository/RestBasketRepository.kt index f0e10f8..f41c10e 100644 --- a/app/src/main/java/com/example/android_programming/api/repository/RestBasketRepository.kt +++ b/app/src/main/java/com/example/android_programming/api/repository/RestBasketRepository.kt @@ -21,14 +21,14 @@ class RestBasketRepository( service.createBasketSneaker(basketSneaker.toBasketSneakerRemote()) } - override fun getBasketWithSneakers(id: Int): Flow> = runBlocking { + override suspend fun getBasketWithSneakers(id: Int): Flow> { val sneakersRemoteList = service.getUserBasketSneakers(id) val sneakersList = sneakersRemoteList.map { it.toSneaker() } - flowOf(sneakersList.toList()) + return flowOf(sneakersList.toList()) } - override suspend fun getUserBasketId(id: Int): Int { - return service.getUserBasket(id) + override suspend fun getUserBasketId(id: Int): Flow { + return flowOf(service.getUserBasket(id)) } override suspend fun getQuantity(basketId: Int, sneakerId: Int): Int? { diff --git a/app/src/main/java/com/example/android_programming/businessLogic/repo/BasketRepository.kt b/app/src/main/java/com/example/android_programming/businessLogic/repo/BasketRepository.kt index 93129f8..09b90ed 100644 --- a/app/src/main/java/com/example/android_programming/businessLogic/repo/BasketRepository.kt +++ b/app/src/main/java/com/example/android_programming/businessLogic/repo/BasketRepository.kt @@ -11,8 +11,8 @@ import kotlinx.coroutines.flow.Flow interface BasketRepository { suspend fun insertBasketSneaker(basketSneaker: BasketSneakers) - fun getBasketWithSneakers(id: Int): Flow> - suspend fun getUserBasketId(id: Int): Int + suspend fun getBasketWithSneakers(id: Int): Flow> + suspend fun getUserBasketId(id: Int): Flow // fun getAllBasket(): Flow> // suspend fun delete(basket: Basket) // suspend fun createBasket(basket: Basket):Long diff --git a/app/src/main/java/com/example/android_programming/businessLogic/vmodel/BasketViewModel.kt b/app/src/main/java/com/example/android_programming/businessLogic/vmodel/BasketViewModel.kt index f3c4748..b8e9189 100644 --- a/app/src/main/java/com/example/android_programming/businessLogic/vmodel/BasketViewModel.kt +++ b/app/src/main/java/com/example/android_programming/businessLogic/vmodel/BasketViewModel.kt @@ -8,16 +8,20 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.example.android_programming.GlobalUser import com.example.android_programming.model.BasketSneakers import com.example.android_programming.model.BasketWithSneakers import com.example.android_programming.businessLogic.repo.BasketRepository import com.example.android_programming.model.Sneaker import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.Job import kotlinx.coroutines.async import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -25,6 +29,9 @@ class BasketViewModel(private val basketRepository: BasketRepository): ViewModel private val _quantityStateMap = mutableMapOf>() + private val _sneakerList = MutableStateFlow>(emptyList()) + val sneakerList: StateFlow> = _sneakerList + fun getQuantityState(basketId: Int, sneakerId: Int): StateFlow { val quantityStateFlow = _quantityStateMap.getOrPut(sneakerId) { MutableStateFlow(0) @@ -50,17 +57,22 @@ class BasketViewModel(private val basketRepository: BasketRepository): ViewModel basketRepository.insertBasketSneaker(basketSneakers) } } - fun getBasketSneakers(userId: Int) : Flow> { - return basketRepository.getBasketWithSneakers(userId) + fun fetchBasketSneakers(userId: Int) { + viewModelScope.launch { + basketRepository.getBasketWithSneakers(userId).collect { + _sneakerList.value = it + } + } } - suspend fun getUserBasketId(userId: Int) : Int{ + suspend fun getUserBasketId(userId: Int) : Flow{ return basketRepository.getUserBasketId(userId) } fun deleteSneakerFromBasket(basketId: Int, sneakerId: Int) = viewModelScope.launch { basketRepository.removeSneakerFromBasket(basketId, sneakerId) + fetchBasketSneakers(GlobalUser.getInstance().getUser()?.userId!!) } fun incrementQuantity(basketId: Int, sneakerId: Int) { diff --git a/app/src/main/java/com/example/android_programming/businessLogic/vmodel/OrderViewModel.kt b/app/src/main/java/com/example/android_programming/businessLogic/vmodel/OrderViewModel.kt index c48f5db..c1f2645 100644 --- a/app/src/main/java/com/example/android_programming/businessLogic/vmodel/OrderViewModel.kt +++ b/app/src/main/java/com/example/android_programming/businessLogic/vmodel/OrderViewModel.kt @@ -62,8 +62,7 @@ class OrderViewModel(private val orderRepository: OrderRepository, private val b for (sneaker in selectedItems.value.orEmpty()) { val userId = GlobalUser.getInstance().getUser()?.userId!! - val orderSneaker = basketRepository.getQuantity(userId, sneaker.sneakerId!!) - ?.let { OrderSneaker( orderId.toInt(), sneaker.sneakerId!!, it) } + val orderSneaker = OrderSneaker( orderId.toInt(), sneaker.sneakerId!!, 1) if (orderSneaker != null) { orderRepository.insertOrderSneaker(orderSneaker) } diff --git a/app/src/main/java/com/example/android_programming/composeui/Screens/HomeScreen/SneakerRecyclerView/CardSneaker.kt b/app/src/main/java/com/example/android_programming/composeui/Screens/HomeScreen/SneakerRecyclerView/CardSneaker.kt index de99854..8109cc6 100644 --- a/app/src/main/java/com/example/android_programming/composeui/Screens/HomeScreen/SneakerRecyclerView/CardSneaker.kt +++ b/app/src/main/java/com/example/android_programming/composeui/Screens/HomeScreen/SneakerRecyclerView/CardSneaker.kt @@ -18,7 +18,11 @@ import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ShoppingCart import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -37,14 +41,16 @@ import com.example.android_programming.model.Sneaker import com.example.android_programming.businessLogic.vmodel.AppViewModelProvider import com.example.android_programming.businessLogic.vmodel.BasketViewModel import com.google.gson.Gson +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @Composable fun CardSneaker(item: Sneaker, navController: NavHostController, basketViewModel: BasketViewModel = viewModel(factory = AppViewModelProvider.Factory)) { val maxWidth = (LocalConfiguration.current.screenWidthDp / 2).dp - + val coroutineScope = rememberCoroutineScope() Box( modifier = Modifier .padding(4.dp) @@ -100,12 +106,10 @@ fun CardSneaker(item: Sneaker, navController: NavHostController, basketViewModel if(user == null){ navController.navigate("login") }else{ - basketViewModel.addToBasket(BasketSneakers(1, item.sneakerId!!, 1)) -// runBlocking { -// launch(Dispatchers.Default) { -// basketViewModel.addToBasket(BasketSneakers(basketViewModel.getUserBasketId(user.userId!!), item.sneakerId!!, 1)) -// } -// } + coroutineScope.launch { + val userBasketId: Int = basketViewModel.getUserBasketId(user.userId!!).first() + basketViewModel.addToBasket(BasketSneakers(userBasketId, item.sneakerId!!, 1)) + } } }, modifier = Modifier diff --git a/app/src/main/java/com/example/android_programming/composeui/Screens/OrderScreen/CardSneaker.kt b/app/src/main/java/com/example/android_programming/composeui/Screens/OrderScreen/CardSneaker.kt index e10f76f..57ea5d8 100644 --- a/app/src/main/java/com/example/android_programming/composeui/Screens/OrderScreen/CardSneaker.kt +++ b/app/src/main/java/com/example/android_programming/composeui/Screens/OrderScreen/CardSneaker.kt @@ -24,6 +24,7 @@ import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -42,6 +43,7 @@ import com.example.android_programming.businessLogic.vmodel.BasketViewModel import com.example.android_programming.businessLogic.vmodel.OrderViewModel import com.example.android_programming.model.BasketSneakers import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -50,6 +52,7 @@ import kotlinx.coroutines.runBlocking fun CardSneakerLike(item: Sneaker, basketViewModel: BasketViewModel = viewModel(factory = AppViewModelProvider.Factory)) { val userId = GlobalUser.getInstance().getUser()?.userId!! val quantityState by basketViewModel.getQuantityState(userId, item.sneakerId!!).collectAsState() + val scope = rememberCoroutineScope() Row( modifier = Modifier .fillMaxWidth() @@ -85,7 +88,9 @@ fun CardSneakerLike(item: Sneaker, basketViewModel: BasketViewModel = viewModel( contentColor = Color.White ), onClick = { - basketViewModel.deleteSneakerFromBasket(1, item.sneakerId!!) + scope.launch { + basketViewModel.deleteSneakerFromBasket(basketViewModel.getUserBasketId(GlobalUser.getInstance().getUser()?.userId!!).first(), item.sneakerId!!) + } // runBlocking { // launch(Dispatchers.Default) { // basketViewModel.deleteSneakerFromBasket(basketViewModel.getUserBasketId(GlobalUser.getInstance().getUser()?.userId!!), item.sneakerId!!) diff --git a/app/src/main/java/com/example/android_programming/composeui/Screens/OrderScreen/OrderScreen.kt b/app/src/main/java/com/example/android_programming/composeui/Screens/OrderScreen/OrderScreen.kt index 75902b3..6677d09 100644 --- a/app/src/main/java/com/example/android_programming/composeui/Screens/OrderScreen/OrderScreen.kt +++ b/app/src/main/java/com/example/android_programming/composeui/Screens/OrderScreen/OrderScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.colorResource @@ -30,12 +31,14 @@ import com.example.android_programming.businessLogic.vmodel.BasketViewModel import com.example.android_programming.businessLogic.vmodel.OrderViewModel import com.example.android_programming.model.BasketSneakers import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @Composable fun OrderScreen(navHostController: NavHostController, basketViewModel: BasketViewModel = viewModel(factory = AppViewModelProvider.Factory), orderViewModel: OrderViewModel = viewModel(factory = AppViewModelProvider.Factory)) { + val scope = rememberCoroutineScope() Column( modifier = Modifier .fillMaxSize() @@ -46,10 +49,11 @@ fun OrderScreen(navHostController: NavHostController, basketViewModel: BasketVie DeliveryAddress(orderViewModel) val userId = GlobalUser.getInstance().getUser()?.userId if (userId != null) { - val sneakerList: List? by basketViewModel.getBasketSneakers(userId).collectAsState(null) + basketViewModel.fetchBasketSneakers(userId!!) + val sneakerList: List? = basketViewModel.sneakerList.collectAsState(null).value if (sneakerList != null) { - orderViewModel.updateSelectedItems(sneakerList!!) - ShoppingList(sneakerList!!) + orderViewModel.updateSelectedItems(sneakerList) + ShoppingList(sneakerList) SubTotal(orderViewModel) } } @@ -61,9 +65,8 @@ fun OrderScreen(navHostController: NavHostController, basketViewModel: BasketVie onClick = { if(GlobalUser.getInstance().getUser() != null){ orderViewModel.createOrder() - runBlocking { - launch(Dispatchers.Default) { - basketViewModel.deleteAllSneakerFromBasket(basketViewModel.getUserBasketId(userId!!)) } + scope.launch { + basketViewModel.deleteAllSneakerFromBasket(basketViewModel.getUserBasketId(userId!!).first()) } navHostController.navigate("home") }else{ diff --git a/app/src/main/java/com/example/android_programming/database/AppDatabase.kt b/app/src/main/java/com/example/android_programming/database/AppDatabase.kt index 4a32b34..3473af2 100644 --- a/app/src/main/java/com/example/android_programming/database/AppDatabase.kt +++ b/app/src/main/java/com/example/android_programming/database/AppDatabase.kt @@ -77,9 +77,9 @@ abstract class AppDatabase : RoomDatabase() { .addCallback(object : Callback() { override fun onCreate(db: SupportSQLiteDatabase) { super.onCreate(db) - CoroutineScope(Dispatchers.IO).launch { - populateDatabase() - } +// CoroutineScope(Dispatchers.IO).launch { +// populateDatabase() +// } } }) .fallbackToDestructiveMigration()