Feature: refactor project with di

This commit is contained in:
ArtemEmelyanov 2023-11-10 18:05:33 +04:00
parent f61608f10f
commit a78c75ef07
22 changed files with 98 additions and 77 deletions

View File

@ -18,12 +18,13 @@ import com.example.android_programming.composeui.Screens.ProfileScreen.Profile.P
import com.example.android_programming.composeui.Screens.ProfileScreen.SignIn.LoginScreen
import com.example.android_programming.composeui.Screens.ProfileScreen.SignUp.SignUpScreen
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.OrderViewModel
import com.google.gson.Gson
@Composable
fun NavController(navController: NavHostController){
var orderViewModel: OrderViewModel = viewModel(factory = OrderViewModel.factory)
var orderViewModel: OrderViewModel = viewModel(factory = AppViewModelProvider.Factory)
NavHost(
navController = navController,
startDestination = NavItem.Home.route
@ -35,7 +36,7 @@ fun NavController(navController: NavHostController){
MyOrderScreen(orderViewModel)
}
composable(NavItem.Order.route){
OrderScreen(orderViewModel, navController)
OrderScreen(navController, orderViewModel)
}
composable(NavItem.Profile.route){
ProfileScreen(navController)

View File

@ -35,10 +35,11 @@ import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.android_programming.R
import com.example.android_programming.model.PhotoManager
import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.SneakerViewModel
@Composable
fun AddPanel(sneakerViewModel: SneakerViewModel = viewModel(factory = SneakerViewModel.factory)){
fun AddPanel(sneakerViewModel: SneakerViewModel = viewModel(factory = AppViewModelProvider.Factory)){
val photoManager = PhotoManager()
Row(
modifier = Modifier

View File

@ -30,11 +30,12 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.example.android_programming.R
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.SneakerViewModel
import com.google.gson.Gson
@Composable
fun CardSneakerForChange(item: Sneaker, navController: NavHostController, sneakerViewModel: SneakerViewModel = viewModel(factory = SneakerViewModel.factory)) {
fun CardSneakerForChange(item: Sneaker, navController: NavHostController, sneakerViewModel: SneakerViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
Row(
modifier = Modifier
.fillMaxWidth()

View File

@ -14,10 +14,11 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.SneakerViewModel
@Composable
fun ChangePanel(navHostController: NavHostController, sneakerViewModel: SneakerViewModel = viewModel(factory = SneakerViewModel.factory)) {
fun ChangePanel(navHostController: NavHostController, sneakerViewModel: SneakerViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
val list = sneakerViewModel.SneakerList.collectAsState(initial = emptyList()).value
Column(
modifier = Modifier

View File

@ -43,10 +43,11 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.android_programming.R
import com.example.android_programming.model.PhotoManager
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.SneakerViewModel
@Composable
fun ChangeSneaker(sneaker: Sneaker, onBackClick: () -> Unit, sneakerViewModel: SneakerViewModel = viewModel(factory = SneakerViewModel.factory)) {
fun ChangeSneaker(sneaker: Sneaker, onBackClick: () -> Unit, sneakerViewModel: SneakerViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
val brand = remember {mutableStateOf(sneaker.brand)}
val model = remember{mutableStateOf(sneaker.model)}
val description = remember{mutableStateOf(sneaker.description)}

View File

@ -17,11 +17,13 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.example.android_programming.composeui.Screens.HomeScreen.FilterByBrand.FilterByBrand
import com.example.android_programming.composeui.Screens.HomeScreen.SearchField.SearchField
import com.example.android_programming.composeui.Screens.HomeScreen.SneakerRecyclerView.RecyclerView
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.OrderViewModel
@Composable

View File

@ -12,11 +12,12 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.OrderViewModel
import com.example.android_programming.vmodel.SneakerViewModel
@Composable
fun RecyclerView(navHostController : NavHostController, orderViewModel: OrderViewModel, sneakerViewModel: SneakerViewModel = viewModel(factory = SneakerViewModel.factory)) {
fun RecyclerView(navHostController : NavHostController, orderViewModel: OrderViewModel, sneakerViewModel: SneakerViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
Column(
modifier = Modifier
.fillMaxSize()

View File

@ -11,21 +11,25 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.android_programming.GlobalUser
import com.example.android_programming.model.Order
import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.OrderViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@Composable
fun MyOrderScreen(orderViewModel: OrderViewModel) {
val userWithOrder by orderViewModel.database.userDao().getUserOrders(GlobalUser.getInstance().getUser()?.userId!!).collectAsState(null)
/*val userWithOrder by orderViewModel.database.userDao().getUserOrders(GlobalUser.getInstance().getUser()?.userId!!).collectAsState(null)*/
val userId = GlobalUser.getInstance().getUser()?.userId
val userWithOrder = orderViewModel.getOrderList(userId!!).collectAsState(null).value?.orders
val orderList: List<Order>? = userWithOrder?.orders
println()
Column(
modifier = Modifier
.padding(bottom = 50.dp)
@ -46,8 +50,8 @@ fun MyOrderScreen(orderViewModel: OrderViewModel) {
modifier = Modifier
.fillMaxSize()
) {
if (orderList != null) {
for (item in orderList) {
if (userWithOrder != null) {
for (item in userWithOrder) {
OrderCard(item, orderViewModel)
}
}

View File

@ -31,11 +31,8 @@ import java.util.Date
@Composable
fun OrderCard(order: Order, orderViewModel: OrderViewModel){
val SneakerList = order.orderId?.let {
orderViewModel.database.orderDao().getOrderWithSneakers(
it
)
}
val SneakerList = order?.orderId?.let { orderViewModel.getOrderWithSneakers(it) }
val sneakerWithOrder by SneakerList!!.collectAsState(null)
val sneakerList: List<Sneaker>? = sneakerWithOrder?.sneakers

View File

@ -15,14 +15,16 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.example.android_programming.GlobalUser
import com.example.android_programming.R
import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.OrderViewModel
@Composable
fun OrderScreen(orderViewModel: OrderViewModel, navHostController: NavHostController) {
fun OrderScreen(navHostController: NavHostController, orderViewModel: OrderViewModel) {
Column(
modifier = Modifier
.fillMaxSize()

View File

@ -38,10 +38,11 @@ import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.example.android_programming.R
import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.UserViewModel
@Composable
fun SignInCard(navController: NavHostController, userViewModel: UserViewModel = viewModel(factory = UserViewModel.factory)) {
fun SignInCard(navController: NavHostController, userViewModel: UserViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
Row(
modifier = Modifier
.fillMaxWidth()

View File

@ -32,10 +32,11 @@ import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.example.android_programming.R
import com.example.android_programming.vmodel.AppViewModelProvider
import com.example.android_programming.vmodel.UserViewModel
@Composable
fun SignUpCard(navHostController: NavHostController, userViewModel: UserViewModel = viewModel(factory = UserViewModel.factory)) {
fun SignUpCard(navHostController: NavHostController, userViewModel: UserViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
Row(
modifier = Modifier
.fillMaxWidth()

View File

@ -7,6 +7,7 @@ import androidx.room.Query
import com.example.android_programming.model.Order
import com.example.android_programming.model.OrderSneaker
import com.example.android_programming.model.OrderWithSneakers
import com.example.android_programming.model.UserWithOrder
import kotlinx.coroutines.flow.Flow
@Dao
@ -26,4 +27,7 @@ interface OrderDao {
@Delete
suspend fun delete(order: Order)
@Query("SELECT * FROM users WHERE userId =:id")
fun getUserOrders(id: Int) : Flow<UserWithOrder>
}

View File

@ -25,7 +25,4 @@ interface UserDao {
@Query("SELECT * FROM users WHERE email = :email")
suspend fun getUserByEmail(email: String): User
@Query("SELECT * FROM users WHERE userId =:id")
fun getUserOrders(id: Int) : Flow<UserWithOrder>
}

View File

@ -4,6 +4,7 @@ import com.example.android_programming.dao.OrderDao
import com.example.android_programming.model.Order
import com.example.android_programming.model.OrderSneaker
import com.example.android_programming.model.OrderWithSneakers
import com.example.android_programming.model.UserWithOrder
import kotlinx.coroutines.flow.Flow
class OrderRepoImpl(private val orderDao: OrderDao) : OrderRepository {
@ -17,4 +18,6 @@ class OrderRepoImpl(private val orderDao: OrderDao) : OrderRepository {
override fun getOrderWithSneakers(id: Int): Flow<OrderWithSneakers> = orderDao.getOrderWithSneakers(id)
override fun getAllOrder(): Flow<List<Order>> = orderDao.getAllOrder()
override fun getUserOrders(id: Int): Flow<UserWithOrder> = orderDao.getUserOrders(id)
}

View File

@ -3,6 +3,7 @@ package com.example.android_programming.repository
import com.example.android_programming.model.Order
import com.example.android_programming.model.OrderSneaker
import com.example.android_programming.model.OrderWithSneakers
import com.example.android_programming.model.UserWithOrder
import kotlinx.coroutines.flow.Flow
interface OrderRepository {
@ -11,4 +12,5 @@ interface OrderRepository {
suspend fun delete(order: Order)
fun getOrderWithSneakers(id: Int): Flow<OrderWithSneakers>
fun getAllOrder(): Flow<List<Order>>
fun getUserOrders(id: Int) : Flow<UserWithOrder>
}

View File

@ -16,6 +16,4 @@ class UserRepoImpl(private val userDao: UserDao) : UserRepository {
override suspend fun getUserById(id: Int): User = userDao.getUserById(id)
override suspend fun getUserByEmail(email: String): User = userDao.getUserByEmail(email)
override fun getUserOrders(id: Int): Flow<UserWithOrder> = userDao.getUserOrders(id)
}

View File

@ -10,5 +10,4 @@ interface UserRepository {
suspend fun deleteUser(user: User)
suspend fun getUserById(id: Int): User
suspend fun getUserByEmail(email: String): User
fun getUserOrders(id: Int) : Flow<UserWithOrder>
}

View File

@ -0,0 +1,24 @@
package com.example.android_programming.vmodel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.example.android_programming.App
object AppViewModelProvider {
val Factory = viewModelFactory {
initializer {
SneakerViewModel(app().container.sneakerRepo)
}
initializer {
UserViewModel(app().container.userRepo)
}
initializer {
OrderViewModel(app().container.orderRepo)
}
}
}
fun CreationExtras.app(): App =
(this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as App)

View File

@ -1,6 +1,8 @@
package com.example.android_programming.vmodel
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
@ -10,11 +12,17 @@ import com.example.android_programming.GlobalUser
import com.example.android_programming.database.AppDatabase
import com.example.android_programming.model.Order
import com.example.android_programming.model.OrderSneaker
import com.example.android_programming.model.OrderWithSneakers
import com.example.android_programming.model.Sneaker
import com.example.android_programming.model.UserWithOrder
import com.example.android_programming.repository.OrderRepository
import com.example.android_programming.repository.SneakerRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import java.util.Date
class OrderViewModel(val database: AppDatabase) : ViewModel() {
class OrderViewModel(private val orderRepository: OrderRepository) : ViewModel() {
private var _selectedItems = mutableStateOf<List<Sneaker>>(emptyList())
val selectedItems get() = _selectedItems.value
var city = mutableStateOf("")
@ -26,11 +34,11 @@ class OrderViewModel(val database: AppDatabase) : ViewModel() {
}
fun deleteOrder(order: Order) = viewModelScope.launch {
database.orderDao().delete(order)
orderRepository.delete(order)
}
fun getOrderList(id: Int) = viewModelScope.launch {
database.userDao().getUserOrders(id)
fun getOrderList(id: Int) : Flow<UserWithOrder> {
return orderRepository.getUserOrders(id)
}
fun removeSelectedItem(item: Sneaker) {
@ -39,6 +47,10 @@ class OrderViewModel(val database: AppDatabase) : ViewModel() {
_selectedItems.value = updatedItems
}
fun getOrderWithSneakers(id: Int) : Flow<OrderWithSneakers> {
return orderRepository.getOrderWithSneakers(id)
}
fun createOrder() = viewModelScope.launch {
val order = Order(
date = Date().time,
@ -51,11 +63,12 @@ class OrderViewModel(val database: AppDatabase) : ViewModel() {
creatorUserId = GlobalUser.getInstance().getUser()?.userId!!
)
val orderId = database.orderDao().createOrder(order)
val orderId = orderRepository.createOrder(order)
for (sneaker in selectedItems) {
val orderSneaker = OrderSneaker( orderId.toInt(), sneaker.sneakerId!!)
database.orderDao().insertOrderSneaker(orderSneaker)
orderRepository.insertOrderSneaker(orderSneaker)
}
city.value = ""
street.value = ""
@ -66,16 +79,4 @@ class OrderViewModel(val database: AppDatabase) : ViewModel() {
fun getSubTotal(): Double {
return selectedItems.sumOf { it.price }
}
companion object{
val factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory{
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras
): T {
val database = (checkNotNull(extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY]) as App).database
return OrderViewModel(database) as T
}
}
}
}

View File

@ -10,15 +10,16 @@ import com.example.android_programming.App
import com.example.android_programming.R
import com.example.android_programming.database.AppDatabase
import com.example.android_programming.model.Sneaker
import com.example.android_programming.repository.SneakerRepository
import kotlinx.coroutines.launch
class SneakerViewModel(val database: AppDatabase): ViewModel() {
class SneakerViewModel(private val sneakerRepository: SneakerRepository): ViewModel() {
var brand = mutableStateOf("")
val model = mutableStateOf("")
val description = mutableStateOf("")
val price = mutableStateOf("")
val photo = mutableStateOf(R.drawable.img)
val SneakerList = database.sneakerDao().getAllSneakers()
val SneakerList = sneakerRepository.getAllSneakers()
var sneaker: Sneaker? = null
fun insertSneaker() = viewModelScope.launch {
@ -29,29 +30,18 @@ class SneakerViewModel(val database: AppDatabase): ViewModel() {
price = price.value.toDouble(),
photo = photo.value
)
database.sneakerDao().insert(sneaker)
sneakerRepository.insertSneaker(sneaker)
}
fun deleteSneaker(sneaker : Sneaker) = viewModelScope.launch {
database.sneakerDao().delete(sneaker)
sneakerRepository.deleteSneaker(sneaker)
}
fun getSneakerById(id: Int) = viewModelScope.launch {
database.sneakerDao().getSneakerById(id)
sneakerRepository.getSneakerById(id)
}
fun UpdateSneaker(sneaker: Sneaker) = viewModelScope.launch {
database.sneakerDao().update(sneaker)
}
companion object{
val factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory{
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras): T {
val database = (checkNotNull(extras[APPLICATION_KEY]) as App).database
return SneakerViewModel(database) as T
}
}
sneakerRepository.updateSneaker(sneaker)
}
}

View File

@ -10,9 +10,11 @@ import com.example.android_programming.GlobalUser
import com.example.android_programming.database.AppDatabase
import com.example.android_programming.model.RoleEnum
import com.example.android_programming.model.User
import com.example.android_programming.repository.SneakerRepository
import com.example.android_programming.repository.UserRepository
import kotlinx.coroutines.launch
class UserViewModel(val database: AppDatabase): ViewModel() {
class UserViewModel(private val userRepository: UserRepository): ViewModel() {
var name = mutableStateOf("")
val surname = mutableStateOf("")
@ -26,10 +28,10 @@ class UserViewModel(val database: AppDatabase): ViewModel() {
password = password.value,
role = RoleEnum.User
)
database.userDao().createUser(user)
userRepository.createUser(user)
}
fun authUser() = viewModelScope.launch {
val user = database.userDao().getUserByEmail(email.value)
val user = userRepository.getUserByEmail(email.value)
if (password.value != "" && user.password == password.value) {
val globalUser = GlobalUser.getInstance()
globalUser.setUser(user)
@ -39,16 +41,4 @@ class UserViewModel(val database: AppDatabase): ViewModel() {
fun isValidEmail(email: String): Boolean {
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
}
companion object{
val factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory{
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras
): T {
val database = (checkNotNull(extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY]) as App).database
return UserViewModel(database) as T
}
}
}
}