Hilt, DI, я схожу с ума

This commit is contained in:
Данила Мочалов 2023-11-21 00:36:30 +04:00
parent ff29494a6c
commit 32958bbbb5
12 changed files with 165 additions and 63 deletions

View File

@ -5,6 +5,9 @@ plugins {
id 'kotlin-kapt'
}
apply plugin: 'com.android.application'
apply plugin: 'com.google.dagger.hilt.android'
android {
namespace 'com.example.shawarma'
compileSdk 34
@ -75,6 +78,7 @@ dependencies {
implementation 'androidx.room:room-ktx:2.5.0' // Дополнительно для Kotlin Coroutines, Kotlin Flows
// lab4
implementation "com.google.dagger:hilt-android:2.40.5"
kapt "com.google.dagger:hilt-android-compiler:2.40.5"
implementation "com.google.dagger:hilt-android:2.42"
kapt "com.google.dagger:hilt-android-compiler:2.42"
implementation("androidx.hilt:hilt-navigation-compose:1.0.0")
}

View File

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".ShawarmaApp"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
@ -19,7 +20,6 @@
android:theme="@style/Theme.Shawarma">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

View File

@ -0,0 +1,31 @@
package com.example.shawarma
import android.app.Application
import androidx.room.Room
import com.example.shawarma.data.db.AppDatabase
import com.example.shawarma.data.repos.UserRepository
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideDatabase(app: Application) : AppDatabase {
return Room.databaseBuilder(
app,
AppDatabase::class.java,
AppDatabase.DB_NAME
).build()
}
@Provides
@Singleton
fun provideUserRepository(db: AppDatabase) : UserRepository {
return UserRepository(db.userDao())
}
}

View File

@ -11,8 +11,9 @@ import com.example.shawarma.screens.authorization.AuthorizationScreen
import com.example.shawarma.screens.registration.RegistrationScreen
import com.example.shawarma.ui.theme.MyLightYellow
import com.example.shawarma.ui.theme.ShawarmaTheme
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.HiltAndroidApp
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View File

@ -0,0 +1,11 @@
package com.example.shawarma
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class ShawarmaApp : Application() {
override fun onCreate() {
super.onCreate()
}
}

View File

@ -15,6 +15,9 @@ import com.example.shawarma.data.models.OrderProductModel
import com.example.shawarma.data.models.OrderStatus
import com.example.shawarma.data.models.ProductModel
import com.example.shawarma.data.models.UserModel
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -39,7 +42,7 @@ abstract class AppDatabase : RoomDatabase() {
abstract fun orderProductDao() : OrderProductDao
companion object {
private const val DB_NAME: String = "shawarma-db"
const val DB_NAME: String = "shawarma-db"
@Volatile
private var INSTANCE: AppDatabase? = null
@ -48,54 +51,54 @@ abstract class AppDatabase : RoomDatabase() {
INSTANCE?.let { database ->
// Users
val userDao = database.userDao()
val user1 = UserModel(1, "danya", "password", "ADMIN")
userDao.insert(user1)
// Products
val productDao = database.productDao()
val product1 = ProductModel(1, "Классик", 100, null)
val product2 = ProductModel(2, "Сырная", 120, null)
val discount1 = ProductModel(3, "Выгода", 80, 100)
val discount2 = ProductModel(4, "Кола", 50, 75)
productDao.insert(product1)
productDao.insert(product2)
productDao.insert(discount1)
productDao.insert(discount2)
// Orders
val orderDao = database.orderDao()
val order1 = OrderModel(1, OrderStatus.Готовится.toString(), 1, Date())
val order2 = OrderModel(2, OrderStatus.Неоплачено.toString(), 1, Date())
val order3 = OrderModel(3, OrderStatus.Готово.toString(), 1, Date())
val order4 = OrderModel(4, OrderStatus.Выдано.toString(), 1, Date())
orderDao.insert(order1)
orderDao.insert(order2)
orderDao.insert(order3)
orderDao.insert(order4)
// OrderProducts
val orderProductDao = database.orderProductDao()
val op1 = OrderProductModel(1, 1, 2, 200)
val op2 = OrderProductModel(1, 4, 3, 150)
val op3 = OrderProductModel(1, 3, 1, 80)
val op4 = OrderProductModel(2, 1, 2, 200)
val op5 = OrderProductModel(2, 4, 3, 150)
val op6 = OrderProductModel(2, 3, 1, 80)
val op7 = OrderProductModel(3, 1, 2, 200)
val op8 = OrderProductModel(3, 4, 3, 150)
val op9 = OrderProductModel(3, 3, 1, 80)
val op10 = OrderProductModel(4, 1, 2, 200)
val op11 = OrderProductModel(4, 4, 3, 150)
val op12 = OrderProductModel(4, 3, 1, 80)
orderProductDao.insert(op1)
orderProductDao.insert(op2)
orderProductDao.insert(op3)
orderProductDao.insert(op4)
orderProductDao.insert(op5)
orderProductDao.insert(op6)
orderProductDao.insert(op7)
orderProductDao.insert(op8)
orderProductDao.insert(op9)
orderProductDao.insert(op10)
orderProductDao.insert(op11)
orderProductDao.insert(op12)
//val user1 = UserModel(1, "danya", "password", "ADMIN")
//userDao.insert(user1)
// // Products
// val productDao = database.productDao()
// val product1 = ProductModel(1, "Классик", 100, null)
// val product2 = ProductModel(2, "Сырная", 120, null)
// val discount1 = ProductModel(3, "Выгода", 80, 100)
// val discount2 = ProductModel(4, "Кола", 50, 75)
// productDao.insert(product1)
// productDao.insert(product2)
// productDao.insert(discount1)
// productDao.insert(discount2)
// // Orders
// val orderDao = database.orderDao()
// val order1 = OrderModel(1, OrderStatus.Готовится.toString(), 1, Date())
// val order2 = OrderModel(2, OrderStatus.Неоплачено.toString(), 1, Date())
// val order3 = OrderModel(3, OrderStatus.Готово.toString(), 1, Date())
// val order4 = OrderModel(4, OrderStatus.Выдано.toString(), 1, Date())
// orderDao.insert(order1)
// orderDao.insert(order2)
// orderDao.insert(order3)
// orderDao.insert(order4)
// // OrderProducts
// val orderProductDao = database.orderProductDao()
// val op1 = OrderProductModel(1, 1, 2, 200)
// val op2 = OrderProductModel(1, 4, 3, 150)
// val op3 = OrderProductModel(1, 3, 1, 80)
// val op4 = OrderProductModel(2, 1, 2, 200)
// val op5 = OrderProductModel(2, 4, 3, 150)
// val op6 = OrderProductModel(2, 3, 1, 80)
// val op7 = OrderProductModel(3, 1, 2, 200)
// val op8 = OrderProductModel(3, 4, 3, 150)
// val op9 = OrderProductModel(3, 3, 1, 80)
// val op10 = OrderProductModel(4, 1, 2, 200)
// val op11 = OrderProductModel(4, 4, 3, 150)
// val op12 = OrderProductModel(4, 3, 1, 80)
// orderProductDao.insert(op1)
// orderProductDao.insert(op2)
// orderProductDao.insert(op3)
// orderProductDao.insert(op4)
// orderProductDao.insert(op5)
// orderProductDao.insert(op6)
// orderProductDao.insert(op7)
// orderProductDao.insert(op8)
// orderProductDao.insert(op9)
// orderProductDao.insert(op10)
// orderProductDao.insert(op11)
// orderProductDao.insert(op12)
}
}

View File

@ -6,6 +6,7 @@ import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.shawarma.data.models.UserModel
import dagger.Provides
import kotlinx.coroutines.flow.Flow
@Dao
@ -18,6 +19,8 @@ interface UserDao {
suspend fun delete(user: UserModel)
@Query("select * from users order by user_login collate nocase asc")
fun getAll(): Flow<List<UserModel>>
@Query("select * from users where users.id = :id")
fun getById(id: Int): UserModel
@Query("select * from users where id = :id")
fun getById(id: Int): Flow<UserModel>
@Query("select * from users where user_login = :login and user_password = :password limit 1")
fun login(login: String, password: String) : Flow<UserModel>
}

View File

@ -1,9 +1,9 @@
package com.example.shawarma.data.repos
import androidx.room.Dao
import com.example.shawarma.data.interfaces.dao.UserDao
import com.example.shawarma.data.models.UserModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import javax.inject.Inject
class UserRepository @Inject constructor(
@ -21,7 +21,10 @@ class UserRepository @Inject constructor(
fun getAll(): Flow<List<UserModel>> {
return userDao.getAll()
}
fun getById(id: Int): UserModel {
fun getById(id: Int): Flow<UserModel> {
return userDao.getById(id)
}
suspend fun login(login: String, password: String): Flow<UserModel> {
return userDao.login(login, password)
}
}

View File

@ -14,23 +14,31 @@ import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Card
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.zIndex
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.example.shawarma.data.db.AppDatabase
import com.example.shawarma.ui.theme.JejuFamily
import com.example.shawarma.ui.theme.MyLightRed
import com.example.shawarma.utils.ScreenPaths
import com.example.shawarma.viewmodels.UserViewModel
import com.example.shawarma.widgets.MyTextField
import com.example.shawarma.widgets.ShawarmaLogo1
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun AuthorizationScreen(navHostController: NavHostController) {
@ -44,6 +52,7 @@ fun AuthorizationScreen(navHostController: NavHostController) {
fun AuthorizationCard(navHostController: NavHostController) {
val login = remember { mutableStateOf(TextFieldValue("")) }
val password = remember { mutableStateOf(TextFieldValue("")) }
val userViewModel: UserViewModel = hiltViewModel<UserViewModel>()
Column(
horizontalAlignment = Alignment.CenterHorizontally,
@ -97,11 +106,12 @@ fun AuthorizationCard(navHostController: NavHostController) {
)
Button(
onClick = {
userViewModel.login(login.value.text, password.value.text)
navHostController.navigate(ScreenPaths.home.name) {
popUpTo(ScreenPaths.authorization.name) {
inclusive = true
}
} },
}},
colors = ButtonDefaults.buttonColors(MyLightRed, Color.White),
shape = RoundedCornerShape(20.dp),
modifier = Modifier

View File

@ -0,0 +1,33 @@
package com.example.shawarma.viewmodels
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.shawarma.ShawarmaApp
import com.example.shawarma.data.models.UserModel
import com.example.shawarma.data.repos.UserRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject
@HiltViewModel
class UserViewModel @Inject constructor(
private val userRepository: UserRepository
) : ViewModel() {
private var userModel: UserModel? = null
fun login(login: String, password: String) {
viewModelScope.launch() {
withContext(Dispatchers.IO) {
userRepository.login(login, password).collect() {
println(it)
}
}
}
}
}

View File

@ -5,27 +5,30 @@ import androidx.compose.foundation.layout.size
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.currentBackStackEntryAsState
import com.example.shawarma.utils.BottomNavItem
@Composable
fun BottomNavBar(navController: NavController) {
val items = listOf(
val adminItems = listOf(
BottomNavItem.Discount,
BottomNavItem.Home,
BottomNavItem.Cart,
BottomNavItem.Orders,
BottomNavItem.Products
)
val userItems = listOf(
BottomNavItem.Discount,
BottomNavItem.Home,
BottomNavItem.Cart
)
BottomNavigation(
backgroundColor = Color.White,
contentColor = Color.Black,
@ -33,7 +36,7 @@ fun BottomNavBar(navController: NavController) {
) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
items.forEach { item ->
adminItems.forEach { item ->
BottomNavigationItem(
icon = {
Icon(

View File

@ -7,7 +7,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.40.5'
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.42'
}
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {