From 0e97bb74441bc278a72fc6079264ee12c8520ad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=90=D0=BB=D0=B5=D0=B9?= =?UTF-8?q?=D0=BA=D0=B8=D0=BD?= Date: Sat, 9 Dec 2023 00:55:08 +0400 Subject: [PATCH] =?UTF-8?q?3-=D0=B0=D1=8F=20=D0=BD=D0=B5=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D1=82=20=D0=BF=D0=BE=D0=BA=D0=B0?= =?UTF-8?q?=20=D1=87=D1=82=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/kotlinc.xml | 2 +- app/build.gradle.kts | 21 +- .../myapplication/database/ImageConverter.kt | 20 + .../myapplication/database/MobileDatabase.kt | 69 ++++ .../myapplication/database/dao/CardDao.kt | 31 ++ .../myapplication/database/dao/UserDao.kt | 32 ++ .../myapplication/database/entities/Card.kt | 42 ++ .../myapplication/database/entities/User.kt | 19 + .../myapplication/screens/authorization.kt | 20 + .../myapplication/screens/mainScreen.kt | 382 +++++++++++++----- build.gradle.kts | 1 + 11 files changed, 540 insertions(+), 99 deletions(-) create mode 100644 app/src/main/java/com/example/myapplication/database/ImageConverter.kt create mode 100644 app/src/main/java/com/example/myapplication/database/MobileDatabase.kt create mode 100644 app/src/main/java/com/example/myapplication/database/dao/CardDao.kt create mode 100644 app/src/main/java/com/example/myapplication/database/dao/UserDao.kt create mode 100644 app/src/main/java/com/example/myapplication/database/entities/Card.kt create mode 100644 app/src/main/java/com/example/myapplication/database/entities/User.kt diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index 0fc3113..69e8615 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 5ede827..1d8c1b2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,11 +1,12 @@ plugins { id("com.android.application") id("org.jetbrains.kotlin.android") + id("com.google.devtools.ksp") } android { namespace = "com.example.myapplication" - compileSdk = 33 + compileSdk = 34 defaultConfig { applicationId = "com.example.myapplication" @@ -30,17 +31,17 @@ android { } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = "17" } buildFeatures { compose = true } composeOptions { - kotlinCompilerExtensionVersion = "1.4.3" + kotlinCompilerExtensionVersion = "1.4.5" } packaging { resources { @@ -53,7 +54,7 @@ dependencies { implementation("androidx.core:core-ktx:1.9.0") implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") - implementation("androidx.activity:activity-compose:1.7.2") + implementation("androidx.activity:activity-compose:1.8.1") implementation(platform("androidx.compose:compose-bom:2023.03.00")) implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui-graphics") @@ -67,4 +68,12 @@ dependencies { androidTestImplementation("androidx.compose.ui:ui-test-junit4") debugImplementation("androidx.compose.ui:ui-tooling") debugImplementation("androidx.compose.ui:ui-test-manifest") + + // Room + val room_version = "2.5.2" + implementation("androidx.room:room-runtime:$room_version") + annotationProcessor("androidx.room:room-compiler:$room_version") + ksp("androidx.room:room-compiler:$room_version") + implementation("androidx.room:room-ktx:$room_version") + implementation("androidx.room:room-paging:$room_version") } \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/database/ImageConverter.kt b/app/src/main/java/com/example/myapplication/database/ImageConverter.kt new file mode 100644 index 0000000..6a498ec --- /dev/null +++ b/app/src/main/java/com/example/myapplication/database/ImageConverter.kt @@ -0,0 +1,20 @@ +package com.example.myapplication.database + +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import androidx.room.TypeConverter +import java.io.ByteArrayOutputStream + +class ImageConverter { + @TypeConverter + fun fromBitmap(bitmap: Bitmap) : ByteArray { + val outputStream = ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream) + return outputStream.toByteArray() + } + + @TypeConverter + fun toBitmap(byteArray: ByteArray): Bitmap { + return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/database/MobileDatabase.kt b/app/src/main/java/com/example/myapplication/database/MobileDatabase.kt new file mode 100644 index 0000000..737aeda --- /dev/null +++ b/app/src/main/java/com/example/myapplication/database/MobileDatabase.kt @@ -0,0 +1,69 @@ +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.drawable.BitmapDrawable +import androidx.room.Database +import androidx.room.Room +import androidx.room.RoomDatabase +import androidx.room.TypeConverters +import androidx.sqlite.db.SupportSQLiteDatabase +import com.example.myapplication.R +import com.example.myapplication.database.ImageConverter +import com.example.myapplication.database.dao.CardDao +import com.example.myapplication.database.dao.UserDao +import com.example.myapplication.database.entities.Card +import com.example.myapplication.database.entities.User +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +@Database(entities = [User::class, Card::class], version = 1, exportSchema = false) +@TypeConverters(ImageConverter::class) +abstract class MobileAppDataBase : RoomDatabase() { + abstract fun userDao(): UserDao + abstract fun cardDao(): CardDao + + companion object{ + private const val DB_NAME: String = "my-db" + + @Volatile + private var INSTANCE: MobileAppDataBase? = null + + suspend fun initialDataBase(appContext: Context){ + INSTANCE?.let { database -> + val userDao = database.userDao() + userDao.insert(User(id = 1, login = "Иван", password = "1234",)) + userDao.insert(User(id = 2, login = "Леонель Месси", password = "4321",)) + + val cardDao = database.cardDao() + cardDao.insert(Card(name = "Феррари Имба", location = "г. Ульяновск", + image = BitmapFactory.decodeResource(appContext.resources, R.drawable.ferrari_laferrari_car2), mileage = 7322, price = 125000, userId = 1) + ) + cardDao.insert(Card(name = "Москоувич", location = "г. Москва", + image = BitmapFactory.decodeResource(appContext.resources, R.drawable.moscowich_car3), mileage = 156771, price = 1000, userId = 1) + ) + } + } + + fun getInstance(appContext: Context): MobileAppDataBase { + return INSTANCE ?: synchronized(this) { + Room.databaseBuilder( + appContext, + MobileAppDataBase::class.java, + DB_NAME + ) + .addCallback(object : Callback() { + override fun onCreate(db: SupportSQLiteDatabase) { + super.onCreate(db) + CoroutineScope(Dispatchers.IO).launch { + initialDataBase(appContext) + } + } + }) + .fallbackToDestructiveMigration() + .build() + .also { INSTANCE = it } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/database/dao/CardDao.kt b/app/src/main/java/com/example/myapplication/database/dao/CardDao.kt new file mode 100644 index 0000000..dd3ff98 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/database/dao/CardDao.kt @@ -0,0 +1,31 @@ +package com.example.myapplication.database.dao + +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import androidx.room.Update +import com.example.myapplication.database.entities.Card +import kotlinx.coroutines.flow.Flow + +@Dao +interface CardDao { + @Query("select * from cards") + fun getAll(): Flow> + + @Query("select * from cards where cards.id = :id") + fun getById(id: Int): Card? + + @Query("select * from cards where cards.user_id = :userId") + fun getByUserId(userId: Int): Flow> + + @Insert(onConflict = OnConflictStrategy.IGNORE) + suspend fun insert(card: Card) + + @Update + suspend fun update(card: Card) + + @Delete + suspend fun delete(card: Card) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/database/dao/UserDao.kt b/app/src/main/java/com/example/myapplication/database/dao/UserDao.kt new file mode 100644 index 0000000..c092ae7 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/database/dao/UserDao.kt @@ -0,0 +1,32 @@ +package com.example.myapplication.database.dao + +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Embedded +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import androidx.room.Relation +import androidx.room.Transaction +import androidx.room.Update +import com.example.myapplication.database.entities.Card +import com.example.myapplication.database.entities.User +import kotlinx.coroutines.flow.Flow + +@Dao +interface UserDao { + @Query("select * from users") + fun getAll(): Flow> + + @Query("select * from users where users.id = :id") + fun getById(id: Int): User? + + @Insert(onConflict = OnConflictStrategy.IGNORE) + suspend fun insert(user: User) + + @Update + suspend fun update(user: User) + + @Delete + suspend fun delete(user: User) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/database/entities/Card.kt b/app/src/main/java/com/example/myapplication/database/entities/Card.kt new file mode 100644 index 0000000..d66ba95 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/database/entities/Card.kt @@ -0,0 +1,42 @@ +package com.example.myapplication.database.entities + +import android.graphics.Bitmap +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.PrimaryKey +import androidx.room.TypeConverters +import com.example.myapplication.database.ImageConverter + +@Entity( + tableName = "cards", + foreignKeys = [ + ForeignKey( + entity = User::class, + parentColumns = ["id"], + childColumns = ["user_id"], + onDelete = ForeignKey.RESTRICT, + onUpdate = ForeignKey.RESTRICT + ) + ] +) +data class Card( + @PrimaryKey(autoGenerate = true) + val id: Int? = null, + @ColumnInfo(name = "name") + val name: String, + @ColumnInfo(name = "location") + val location: String, + @ColumnInfo(name = "mileage") + val mileage: Int, + @ColumnInfo(name = "price") + val price: Int, + @ColumnInfo(name = "image") + val image: Bitmap, + @ColumnInfo(name="user_id") + val userId: Int +){ + override fun hashCode(): Int { + return id ?: -1 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/database/entities/User.kt b/app/src/main/java/com/example/myapplication/database/entities/User.kt new file mode 100644 index 0000000..dd77675 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/database/entities/User.kt @@ -0,0 +1,19 @@ +package com.example.myapplication.database.entities + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "users") +data class User( + @PrimaryKey(autoGenerate = true) + val id: Int? = null, + @ColumnInfo(name = "login") + val login: String, + @ColumnInfo(name = "password") + val password: String, +){ + override fun hashCode(): Int { + return id ?: -1 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/screens/authorization.kt b/app/src/main/java/com/example/myapplication/screens/authorization.kt index f7d34ad..3791806 100644 --- a/app/src/main/java/com/example/myapplication/screens/authorization.kt +++ b/app/src/main/java/com/example/myapplication/screens/authorization.kt @@ -12,10 +12,14 @@ import androidx.compose.foundation.layout.size import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateListOf +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.layout.ContentScale +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp @@ -26,9 +30,25 @@ import com.example.myapplication.R import com.example.myapplication.components.LoginField import com.example.myapplication.components.PasswordField import com.example.myapplication.components.navButton +import com.example.myapplication.database.entities.Card +import com.example.myapplication.database.entities.User +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext @Composable fun Authorization(navController: NavHostController){ + val context = LocalContext.current + val users = remember { mutableStateListOf() } + + LaunchedEffect(Unit) { + withContext(Dispatchers.IO) { + MobileAppDataBase.getInstance(context).userDao().getAll().collect { data -> + users.clear() + users.addAll(data) + } + } + } + Column ( modifier = Modifier .fillMaxSize() diff --git a/app/src/main/java/com/example/myapplication/screens/mainScreen.kt b/app/src/main/java/com/example/myapplication/screens/mainScreen.kt index ecc4a9f..3610497 100644 --- a/app/src/main/java/com/example/myapplication/screens/mainScreen.kt +++ b/app/src/main/java/com/example/myapplication/screens/mainScreen.kt @@ -4,130 +4,119 @@ import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Button -import androidx.compose.material3.Card -import androidx.compose.material3.CardDefaults -import androidx.compose.material3.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.draw.clip import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController import com.example.myapplication.components.navBar +import com.example.myapplication.database.entities.Card import com.example.myapplication.ui.theme.SkyBlue +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.requiredHeight +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.sp +import com.example.myapplication.R +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext @Composable fun MainScreen(navController: NavHostController) { - Column { - Box(modifier = Modifier - .padding(horizontal = 10.dp) - .fillMaxHeight(0.9f)) { - Column( - modifier = Modifier.verticalScroll(rememberScrollState()) - ) { - ListItem( - name = "Ламборджини Авентадор 2010", - mileage = 4765, - location = "Россия, г. Ульяновск", - price = 5000000, - imageResourceId = com.example.myapplication.R.drawable.lambo_car1, - navController = navController - ) - ListItem( - name = "Оранжевый Москвич 1983", - mileage = 522011, - location = "Россия, г. Москва", - price = 125000, - imageResourceId = com.example.myapplication.R.drawable.moscowich_car3, - navController = navController - ) - ListItem( - name = "Феррари Лаферрари 2013", - mileage = 17698, - location = "Италия, г. Неаполь", - price = 1249990, - imageResourceId = com.example.myapplication.R.drawable.ferrari_laferrari_car2, - navController = navController - ) - ListItem( - name = "Оранжевый Москвич 1983", - mileage = 522011, - location = "Россия, г. Москва", - price = 125000, - imageResourceId = com.example.myapplication.R.drawable.moscowich_car3, - navController = navController - ) - ListItem( - name = "Феррари Лаферрари 2013", - mileage = 17698, - location = "Италия, г. Неаполь", - price = 1249990, - imageResourceId = com.example.myapplication.R.drawable.ferrari_laferrari_car2, - navController = navController - ) + val context = LocalContext.current + val cards = remember { mutableStateListOf() } + + LaunchedEffect(Unit) { + withContext(Dispatchers.IO) { + MobileAppDataBase.getInstance(context).cardDao().getAll().collect { data -> + cards.clear() + cards.addAll(data) } } - Column(modifier = Modifier + } + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + ) { + DataListScroll(navController, cards) + } + + Column( + modifier = Modifier .fillMaxSize() .background(SkyBlue), - verticalArrangement = Arrangement.Center) { - navBar(navController = navController) - } + verticalArrangement = Arrangement.Center + ) { + navBar(navController = navController) } } -@Composable -private fun ListItem(name: String, - mileage: Int, - location: String, - price: Int, - imageResourceId: Int, - navController: NavHostController) { - var borderColor = remember { mutableStateOf(Color.Gray) } +/*@Composable +private fun ListItem( + card: Card, + navController: NavHostController +) { + val bitmap = remember(card) { + BitmapFactory.decodeByteArray(card.image, 0, card.image.size) + } + + val imageBitmap = remember(bitmap) { + bitmap.asImageBitmap() + } Card( modifier = Modifier .fillMaxWidth() .padding(10.dp) - .border(2.dp, borderColor.value, RoundedCornerShape(15.dp)) - .clickable { borderColor.value = Color.LightGray }, + .border(2.dp, Color.Gray, RoundedCornerShape(15.dp)), shape = RoundedCornerShape(15.dp), elevation = CardDefaults.cardElevation(defaultElevation = 5.dp), - ){ - Box() { - Row(verticalAlignment = Alignment.CenterVertically){ + ) { + Box { + Row(verticalAlignment = Alignment.CenterVertically) { Image( - painter = painterResource(id = imageResourceId), + painter = remember { + BitmapPainter(imageBitmap) + }, contentDescription = "image", contentScale = ContentScale.Crop, - modifier = Modifier.size(128.dp)) - Column ( - modifier = Modifier.padding(5.dp)) { - Text(text = name, fontFamily = FontFamily.SansSerif, fontWeight = FontWeight.Bold) - Text(text = "Пробег: " + mileage) - Text(text = "Расположение: " + location) - Text(text = "Цена: " + price) + modifier = Modifier.size(128.dp) + ) + Column( + modifier = Modifier.padding(5.dp) + ) { + Text(text = card.name, fontWeight = FontWeight.Bold) + Text(text = "Пробег: ${card.mileage}") + Text(text = "Расположение: ${card.location}") + Text(text = "Цена: ${card.price}") Button(onClick = { navController.navigate("editCard") }) { Text("Изменить") } @@ -136,7 +125,216 @@ private fun ListItem(name: String, } } } - } } -} \ No newline at end of file +}*/ + +@Composable +fun DataListScroll(navController: NavHostController, dataList: List){ + LazyColumn( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .fillMaxWidth() + ){ + item { + when { + dataList.isListOf() -> addNewListItem(navController, "editcard") + + } + } + items(dataList){ item -> + when(item){ + is Card -> CardListItem(item = item, navController = navController) + } + } + } +} + +inline fun List<*>.isListOf(): Boolean { + return isNotEmpty() && all { it is T } +} + + +@Composable +fun CardListItem(item: Card, navController: NavHostController){ + val context = LocalContext.current + + val isExpanded = remember { + mutableStateOf(false) + } + + val showDialog = remember { + mutableStateOf(false) + } + + val delete = remember { + mutableStateOf(false) + } + + Card( + modifier = Modifier + .fillMaxWidth() + .padding(10.dp) + .border(2.dp, Color.Gray, RoundedCornerShape(15.dp)), + shape = RoundedCornerShape(15.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 5.dp) + ) { + Column( + modifier = Modifier.fillMaxSize() + ) { + Row( + verticalAlignment = Alignment.Top + ){ + Image(bitmap = item.image.asImageBitmap(), + contentDescription = item.name, + contentScale = ContentScale.Crop, + modifier = Modifier + .width(128.dp) + .height(256.dp)) + Column ( + modifier = Modifier.padding(8.dp) + ){ + Text( + text = "${item.name} | ${item.location} | ${item.mileage} | ${item.price}", + fontSize = 20.sp, + fontWeight = FontWeight.Bold + ) + } + } + AnimatedVisibility( + visible = isExpanded.value, + modifier = Modifier.fillMaxWidth() + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.End + ){ + DataListItemButton("Изменить", Color.Yellow, Color.White, onClickAction = { + navController.navigate("editstory/${item.id}") + }) + DataListItemButton("Удалить", Color.Red, Color.White, onClickAction = { + showDialog.value = !showDialog.value + }) + } + } + } + } + + if(showDialog.value) { + DialogWindow(label = "Подтверждение", + message = "Вы уверены что хотите удалить запись?", onConfirmAction = { + delete.value = !delete.value + showDialog.value = !showDialog.value + }, onDismissAction = { + showDialog.value = !showDialog.value + }) + } + + if(delete.value) { + LaunchedEffect(Unit){ + withContext(Dispatchers.IO){ + MobileAppDataBase.getInstance(context).cardDao().delete(item) + } + } + delete.value = !delete.value + navController.navigate("story") + } +} + + +@Composable +fun DataListItemButton(label: String, backgroundColor: Color, textColor: Color, onClickAction: () -> Unit){ + Button( + onClick = onClickAction, + modifier = Modifier.requiredHeight(64.dp), + shape = RoundedCornerShape(10.dp), + colors = ButtonDefaults.buttonColors( + containerColor = backgroundColor + ) + ) { + Text( + text = label, + color = textColor, + fontSize = 18.sp, + ) + } +} + +@Composable +fun DialogWindow(label: String, message: String, onConfirmAction: () -> Unit, onDismissAction: () -> Unit){ + AlertDialog(onDismissRequest = onDismissAction, + title = { + Text(text = label, + fontSize = 20.sp, + fontWeight = FontWeight.Bold) + }, + text = { + Text(text = message) + }, + confirmButton = { + Button( + onClick = onConfirmAction, + colors = ButtonDefaults.buttonColors( + containerColor = Color.Green + ), + shape = RoundedCornerShape(5.dp) + ) { + Text(text = "Подтвердить", + color = Color.White) + } + }, + dismissButton = { + Button( + onClick = onDismissAction, + colors = ButtonDefaults.buttonColors( + containerColor = Color.Red + ), + shape = RoundedCornerShape(5.dp) + ) { + Text(text = "Отмена", + color = Color.Black) + } + } + ) +} + +@Composable +fun addNewListItem(navController: NavHostController, destination: String){ + Card( + modifier = Modifier + .fillMaxWidth() + .padding(start = 18.dp, top = 8.dp, end = 18.dp, bottom = 8.dp) + .clickable { + navController.navigate(destination) + }, + shape = RoundedCornerShape(15.dp), + colors = CardDefaults.cardColors( + containerColor = Color.Magenta + ), + elevation = CardDefaults.cardElevation( + defaultElevation = 8.dp + ) + ) { + Column( + modifier = Modifier.fillMaxSize() + ) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ){ + Image(painter = painterResource(id = R.drawable.login), + contentDescription = "additem", + contentScale = ContentScale.Crop, + modifier = Modifier + .size(96.dp) + .padding(8.dp)) + Text( + text = "Добавить", + fontSize = 28.sp, + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(start = 32.dp)) + } + } + } +} + diff --git a/build.gradle.kts b/build.gradle.kts index 9861456..bd1eb8a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,4 +2,5 @@ plugins { id("com.android.application") version "8.1.1" apply false id("org.jetbrains.kotlin.android") version "1.8.10" apply false + id("com.google.devtools.ksp") version "1.8.20-1.0.11" apply false } \ No newline at end of file