From d9a2c3aefede08de4da8b6182f442ff9a3ffc6e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=91=D0=B0=D1=82=D1=8B?= =?UTF-8?q?=D0=BB=D0=BA=D0=B8=D0=BD?= Date: Mon, 13 Nov 2023 18:49:43 +0400 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/kotlinc.xml | 2 +- .idea/misc.xml | 5 +- .idea/vcs.xml | 2 +- app/build.gradle.kts | 33 ++-- .../todolisttask/composeui/CreateTask.kt | 29 ++- .../todolisttask/composeui/Favorite.kt | 4 - .../example/todolisttask/composeui/Home.kt | 13 -- .../example/todolisttask/composeui/Profile.kt | 1 - .../composeui/navigation/MyPage.kt | 4 - .../todolisttask/models/composeui/TaskList.kt | 167 ++++-------------- .../todolisttask/models/composeui/TaskView.kt | 83 +++++++++ .../todolisttask/models/composeui/UserList.kt | 36 ---- .../todolisttask/models/dao/TaskDao.kt | 23 +++ .../todolisttask/models/dao/UserDao.kt | 28 +++ .../models/database/AppDatabase.kt | 64 +++++++ .../models/model/AuthViewModel.kt | 10 -- .../example/todolisttask/models/model/Task.kt | 64 ++++--- .../todolisttask/models/model/TaskWithUser.kt | 11 ++ .../example/todolisttask/models/model/User.kt | 143 +++------------ app/src/main/res/values/strings.xml | 2 + build.gradle.kts | 1 + 21 files changed, 348 insertions(+), 377 deletions(-) create mode 100644 app/src/main/java/com/example/todolisttask/models/composeui/TaskView.kt delete mode 100644 app/src/main/java/com/example/todolisttask/models/composeui/UserList.kt create mode 100644 app/src/main/java/com/example/todolisttask/models/dao/TaskDao.kt create mode 100644 app/src/main/java/com/example/todolisttask/models/dao/UserDao.kt create mode 100644 app/src/main/java/com/example/todolisttask/models/database/AppDatabase.kt delete mode 100644 app/src/main/java/com/example/todolisttask/models/model/AuthViewModel.kt create mode 100644 app/src/main/java/com/example/todolisttask/models/model/TaskWithUser.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/.idea/misc.xml b/.idea/misc.xml index 8978d23..ac801d8 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,9 +1,6 @@ - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f29e9f7..e31609e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,16 +1,17 @@ plugins { id("com.android.application") id("org.jetbrains.kotlin.android") + id("com.google.devtools.ksp") } android { namespace = "com.example.todolisttask" - compileSdk = 34 + compileSdk = 33 defaultConfig { applicationId = "com.example.todolisttask" minSdk = 24 - targetSdk = 34 + targetSdk = 33 versionCode = 1 versionName = "1.0" @@ -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 { @@ -48,11 +49,16 @@ android { } } } +kotlin { + jvmToolchain(17) +} dependencies { - implementation ("io.coil-kt:coil-compose:1.4.0") + // Core implementation("androidx.core:core-ktx:1.9.0") implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") + + // UI implementation("androidx.activity:activity-compose:1.7.2") implementation(platform("androidx.compose:compose-bom:2023.03.00")) implementation("androidx.navigation:navigation-compose:2.6.0") @@ -60,9 +66,16 @@ dependencies { implementation("androidx.compose.ui:ui-graphics") implementation("androidx.compose.ui:ui-tooling-preview") implementation("androidx.compose.material3:material3") - implementation("com.google.android.engage:engage-core:1.3.0") - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("androidx.compose.ui:ui-graphics-android:1.5.3") + + // 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") + + // Tests testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") diff --git a/app/src/main/java/com/example/todolisttask/composeui/CreateTask.kt b/app/src/main/java/com/example/todolisttask/composeui/CreateTask.kt index ecbb094..204c523 100644 --- a/app/src/main/java/com/example/todolisttask/composeui/CreateTask.kt +++ b/app/src/main/java/com/example/todolisttask/composeui/CreateTask.kt @@ -12,7 +12,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.example.todolisttask.models.model.AuthViewModel import com.example.todolisttask.models.model.Task @OptIn(ExperimentalMaterial3Api::class) @@ -49,19 +48,19 @@ fun CreateTask(navController: NavController, onSaveClick: (Task) -> Unit) { Spacer(modifier = Modifier.height(16.dp)) - Button( - onClick = { - if (taskName.isNotEmpty()) { - val newTask = Task(0, taskName, taskDescription) - onSaveClick(newTask) - taskName = "" - - navController.popBackStack() - } - }, - modifier = Modifier.fillMaxWidth() - ) { - Text("Сохранить") - } +// Button( +// onClick = { +// if (taskName.isNotEmpty()) { +// val newTask = Task(0, taskName, taskDescription) +// onSaveClick(newTask) +// taskName = "" +// +// navController.popBackStack() +// } +// }, +// modifier = Modifier.fillMaxWidth() +// ) { +// Text("Сохранить") +// } } } diff --git a/app/src/main/java/com/example/todolisttask/composeui/Favorite.kt b/app/src/main/java/com/example/todolisttask/composeui/Favorite.kt index 99ef643..1847a75 100644 --- a/app/src/main/java/com/example/todolisttask/composeui/Favorite.kt +++ b/app/src/main/java/com/example/todolisttask/composeui/Favorite.kt @@ -6,16 +6,12 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height -import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.example.todolisttask.composeui.navigation.Screen -import com.example.todolisttask.models.composeui.TaskList import com.example.todolisttask.models.model.AuthViewModel import com.example.todolisttask.models.model.TaskViewModel import com.example.todolisttask.models.model.UserViewModel diff --git a/app/src/main/java/com/example/todolisttask/composeui/Home.kt b/app/src/main/java/com/example/todolisttask/composeui/Home.kt index 4b80573..7902287 100644 --- a/app/src/main/java/com/example/todolisttask/composeui/Home.kt +++ b/app/src/main/java/com/example/todolisttask/composeui/Home.kt @@ -1,36 +1,23 @@ package com.example.todolisttask.composeui import android.annotation.SuppressLint -import android.net.Uri -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer 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.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text -import androidx.compose.material3.TextField import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import coil.compose.rememberImagePainter import com.example.todolisttask.composeui.navigation.Screen -import com.example.todolisttask.models.composeui.TaskList import com.example.todolisttask.models.model.AuthViewModel import com.example.todolisttask.models.model.TaskViewModel -import com.example.todolisttask.models.model.User import com.example.todolisttask.models.model.UserViewModel -import com.example.todolisttask.models.composeui.TaskList @OptIn(ExperimentalMaterial3Api::class) @SuppressLint("RememberReturnType") diff --git a/app/src/main/java/com/example/todolisttask/composeui/Profile.kt b/app/src/main/java/com/example/todolisttask/composeui/Profile.kt index e48509a..b1c7d6a 100644 --- a/app/src/main/java/com/example/todolisttask/composeui/Profile.kt +++ b/app/src/main/java/com/example/todolisttask/composeui/Profile.kt @@ -28,7 +28,6 @@ import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import coil.compose.rememberImagePainter import com.example.todolisttask.composeui.navigation.Screen import com.example.todolisttask.models.model.User import kotlinx.coroutines.flow.callbackFlow diff --git a/app/src/main/java/com/example/todolisttask/composeui/navigation/MyPage.kt b/app/src/main/java/com/example/todolisttask/composeui/navigation/MyPage.kt index e201288..22e8ba7 100644 --- a/app/src/main/java/com/example/todolisttask/composeui/navigation/MyPage.kt +++ b/app/src/main/java/com/example/todolisttask/composeui/navigation/MyPage.kt @@ -4,9 +4,7 @@ package com.example.todolisttask.composeui.navigation import CreateTask import android.os.Build import androidx.annotation.RequiresApi -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack @@ -23,7 +21,6 @@ import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.navigation.NavDestination @@ -41,7 +38,6 @@ import com.example.pmuapp.composeui.Profile import com.example.todolisttask.R import com.example.todolisttask.composeui.EditTask import com.example.todolisttask.composeui.Favorite -import com.example.todolisttask.models.composeui.TaskList import com.example.todolisttask.models.model.AuthViewModel import com.example.todolisttask.models.model.TaskViewModel import com.example.todolisttask.models.model.UserViewModel diff --git a/app/src/main/java/com/example/todolisttask/models/composeui/TaskList.kt b/app/src/main/java/com/example/todolisttask/models/composeui/TaskList.kt index b3a3f9c..ec87655 100644 --- a/app/src/main/java/com/example/todolisttask/models/composeui/TaskList.kt +++ b/app/src/main/java/com/example/todolisttask/models/composeui/TaskList.kt @@ -1,143 +1,54 @@ package com.example.todolisttask.models.composeui -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.Image -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement +import android.content.res.Configuration import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ExperimentalLayoutApi -import androidx.compose.foundation.layout.FlowColumn -import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Delete -import androidx.compose.material.icons.filled.Edit -import androidx.compose.material.icons.filled.Favorite import androidx.compose.material3.Button -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.key +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.navigation.NavController +import com.example.todolisttask.AppDatabase import com.example.todolisttask.composeui.navigation.Screen -import com.example.todolisttask.models.model.AuthViewModel -import com.example.todolisttask.models.model.TaskViewModel -import com.example.todolisttask.models.model.UserViewModel +import com.example.todolisttask.models.model.Task +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext -@OptIn(ExperimentalFoundationApi::class, ExperimentalLayoutApi::class) @Composable -fun TaskList(navController: NavController, authViewModel: AuthViewModel, taskViewModel: TaskViewModel, userViewModel: UserViewModel, userId: Int, showFavorites: Boolean = false) { +fun TaskList(navController: NavController?) { + val context = LocalContext.current + val tasks = remember { mutableStateListOf() } - val currentUser = userViewModel.getUser(userId) - var tasks = if (showFavorites) currentUser.favoritetask else currentUser.taskId - - LazyColumn( - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { - if (userId != authViewModel.currentUser?.id ?: -1) { - item { - Text( - text = currentUser?.name + " (" + currentUser.login + ")", - style = TextStyle( - fontSize = 24.sp, - fontWeight = FontWeight.Bold - ), - modifier = Modifier.padding(16.dp) - ) - } - } - - item { - FlowColumn() { - tasks.forEach { task -> - val taskName = task.name - val taskDescription = task.description - - FlowRow( - modifier = Modifier - .padding(8.dp) - .border( - 1.dp, - Color.Black, - ), - horizontalArrangement = Arrangement.SpaceBetween - ) { - IconButton( - onClick = { - navController?.navigate( - Screen.EditTask.route.replace( - "{id}", - task.id.toString() - ) - ) - }, - ) { - Icon( - imageVector = Icons.Default.Edit, - contentDescription = "Изменить" - ) - } - - Column( - modifier = Modifier.weight(1f) - .padding(top = 4.dp) - ) { - Text( - text = taskName, - style = TextStyle( - fontWeight = FontWeight.Bold - ) - ) - - if (taskDescription.isNotBlank()) { - Text( - text = taskDescription - ) - } - } - - IconButton( - onClick = { - taskViewModel.deleteTask(task) - userViewModel.deleteTask( - currentUser?.id ?: 0, - task.id - ) - authViewModel.currentUser = - userViewModel.getUser( - currentUser?.id ?: 0 - ) - } - ) { - Icon( - imageVector = Icons.Default.Delete, - contentDescription = "Удалить" - ) - } - IconButton( - onClick = { - userViewModel.addFavoriteTaskToUser(userId, task) - } - ) { - Icon( - imageVector = Icons.Default.Favorite, - contentDescription = "Добавить в избранное" - ) - } - } - } - } - } + LaunchedEffect(Unit) { + withContext(Dispatchers.IO) { + val taskList = AppDatabase.getInstance(context).taskDao().getAll() + tasks.clear() + tasks.addAll(taskList) } -} + } + + Column(Modifier.padding(all = 10.dp)) { + tasks.forEach { task -> + key(task.uid) { + val taskId = Screen.Home.route.replace("{id}", task.uid.toString()) + Button( + modifier = Modifier + .fillMaxWidth() + .padding(all = 10.dp), + onClick = { navController?.navigate(taskId) }) { + Text("${task.name} ${task.description}") + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/models/composeui/TaskView.kt b/app/src/main/java/com/example/todolisttask/models/composeui/TaskView.kt new file mode 100644 index 0000000..7c3ff20 --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/models/composeui/TaskView.kt @@ -0,0 +1,83 @@ +package com.example.todolisttask.models.composeui + +import android.content.res.Configuration +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Surface +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.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.example.todolisttask.AppDatabase +import com.example.todolisttask.R +import com.example.todolisttask.models.model.TaskWithUser +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun TaskView(id: Int) { + val context = LocalContext.current + val (taskWithUser, setTaskWithUser) = remember { mutableStateOf(null) } + + LaunchedEffect(Unit) { + withContext(Dispatchers.IO) { + setTaskWithUser(AppDatabase.getInstance(context).userDao().getByUid(id)) + } + } + + taskWithUser?.let { task -> + Column( + Modifier + .fillMaxWidth() + .padding(all = 10.dp) + ) { + OutlinedTextField( + modifier = Modifier.fillMaxWidth(), + value = task.user?.name ?: "", + onValueChange = {}, + readOnly = true, + label = { + Text(stringResource(id = R.string.user_name)) + } + ) + OutlinedTextField( + modifier = Modifier.fillMaxWidth(), + value = task.user?.login ?: "", + onValueChange = {}, + readOnly = true, + label = { + Text(stringResource(id = R.string.user_login)) + } + ) + OutlinedTextField( + modifier = Modifier.fillMaxWidth(), + value = task.taskName ?: "", + onValueChange = {}, + readOnly = true, + label = { + Text(stringResource(id = R.string.task_name)) + } + ) + OutlinedTextField( + modifier = Modifier.fillMaxWidth(), + value = task.user?.password ?: "", + onValueChange = {}, + readOnly = true, + label = { + Text(stringResource(id = R.string.password_name)) + } + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/models/composeui/UserList.kt b/app/src/main/java/com/example/todolisttask/models/composeui/UserList.kt deleted file mode 100644 index 86d46ec..0000000 --- a/app/src/main/java/com/example/todolisttask/models/composeui/UserList.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.example.todolisttask.models.composeui - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Button -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import androidx.navigation.NavController -import com.example.todolisttask.composeui.navigation.Screen -import com.example.todolisttask.models.model.UserViewModel - -/* -@Composable - -fun UserList(navController: NavController?, - userViewModel: UserViewModel -) { - val users = userViewModel.users.value - - Column(Modifier.padding(all = 10.dp)) { - users.forEachIndexed() { index, user -> - val userId = Screen.UserViewModel.route.replace("{id}", index.toString()) - Button( - modifier = Modifier - .fillMaxWidth() - .padding(all = 10.dp), - onClick = { navController?.navigate(userId) }) { - Text("${user.login}") - } - } - } -}*/ - diff --git a/app/src/main/java/com/example/todolisttask/models/dao/TaskDao.kt b/app/src/main/java/com/example/todolisttask/models/dao/TaskDao.kt new file mode 100644 index 0000000..59d8ace --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/models/dao/TaskDao.kt @@ -0,0 +1,23 @@ +package com.example.todolisttask.models.dao + +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.Query +import androidx.room.Update +import com.example.todolisttask.models.model.Task + +@Dao +interface TaskDao { + @Query("select * from tasks order by task_name collate nocase asc") + suspend fun getAll(): List + + @Insert + suspend fun insert(group: Task) + + @Update + suspend fun update(group: Task) + + @Delete + suspend fun delete(group: Task) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/models/dao/UserDao.kt b/app/src/main/java/com/example/todolisttask/models/dao/UserDao.kt new file mode 100644 index 0000000..5c4a1a5 --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/models/dao/UserDao.kt @@ -0,0 +1,28 @@ +package com.example.todolisttask.models.dao + +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.Query +import androidx.room.Update +import com.example.todolisttask.models.model.TaskWithUser +import com.example.todolisttask.models.model.User +import kotlinx.coroutines.flow.Flow + +@Dao +interface UserDao { + @Query("select * from users order by name collate nocase asc") + fun getAll(): Flow> + + @Query("select * from users left join tasks on users.uid = tasks.user_id where users.uid = :uid") + suspend fun getByUid(uid: Int): TaskWithUser + + @Insert + 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/todolisttask/models/database/AppDatabase.kt b/app/src/main/java/com/example/todolisttask/models/database/AppDatabase.kt new file mode 100644 index 0000000..d50666c --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/models/database/AppDatabase.kt @@ -0,0 +1,64 @@ +package com.example.todolisttask + +import android.content.Context +import androidx.room.Database +import androidx.room.Room +import androidx.room.RoomDatabase +import androidx.sqlite.db.SupportSQLiteDatabase +import com.example.todolisttask.models.dao.TaskDao +import com.example.todolisttask.models.dao.UserDao +import com.example.todolisttask.models.model.Task +import com.example.todolisttask.models.model.User +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +@Database(entities = [User::class, Task::class], version = 1, exportSchema = false) +abstract class AppDatabase : RoomDatabase() { + abstract fun userDao(): UserDao + abstract fun taskDao(): TaskDao + + companion object { + private const val DB_NAME: String = "pmy-db" + + @Volatile + private var INSTANCE: AppDatabase? = null + + private suspend fun populateDatabase() { + INSTANCE?.let { database -> + // Groups + val taskDao = database.taskDao() + val task1 = Task(1, "Test1", "TestDesk",1) + val task2 = Task(2, "Test2", "TestDesk",1) + val task3 = Task(3, "Test3", "TestDesk",1) + taskDao.insert(task1) + taskDao.insert(task2) + taskDao.insert(task3) + // Students + val userDao = database.userDao() + val user1 = User("Sergey", "User", "123456") + userDao.insert(user1) + } + } + + fun getInstance(appContext: Context): AppDatabase { + return INSTANCE ?: synchronized(this) { + Room.databaseBuilder( + appContext, + AppDatabase::class.java, + DB_NAME + ) + .addCallback(object : Callback() { + override fun onCreate(db: SupportSQLiteDatabase) { + super.onCreate(db) + CoroutineScope(Dispatchers.IO).launch { + populateDatabase() + } + } + }) + .build() + .also { INSTANCE = it } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/models/model/AuthViewModel.kt b/app/src/main/java/com/example/todolisttask/models/model/AuthViewModel.kt deleted file mode 100644 index b9ebdab..0000000 --- a/app/src/main/java/com/example/todolisttask/models/model/AuthViewModel.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.example.todolisttask.models.model; - -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import androidx.lifecycle.ViewModel - -class AuthViewModel : ViewModel() { - var currentUser: User? by mutableStateOf(null) -} \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/models/model/Task.kt b/app/src/main/java/com/example/todolisttask/models/model/Task.kt index b645265..272c92b 100644 --- a/app/src/main/java/com/example/todolisttask/models/model/Task.kt +++ b/app/src/main/java/com/example/todolisttask/models/model/Task.kt @@ -1,43 +1,39 @@ package com.example.todolisttask.models.model -import android.media.Image -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf -import androidx.lifecycle.ViewModel -import java.io.Serializable +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.PrimaryKey -data class Task( - var id: Int, - val name: String, - val description: String -) : Serializable -class TaskViewModel : ViewModel() { - var tasks: MutableState> = mutableStateOf( - emptyList() +@Entity(tableName = "tasks", foreignKeys = [ + ForeignKey( + entity = User::class, + parentColumns = ["uid"], + childColumns = ["user_id"], + onDelete = ForeignKey.RESTRICT, + onUpdate = ForeignKey.RESTRICT ) - - fun createTask(newTask: Task): Task { - newTask.id = tasks.value.size.toInt() - val updatedTasks = tasks.value.toMutableList() - updatedTasks.add(newTask) - tasks.value = updatedTasks - return newTask +]) +data class Task( + @PrimaryKey(autoGenerate = true) + val uid: Int?, + @ColumnInfo(name = "task_name") + val name: String, + @ColumnInfo(name = "task_description") + val description: String, + @ColumnInfo(name = "user_id", index = true) + val userId: Int +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + other as Task + if (uid != other.uid) return false + return true } - fun deleteTask(task: Task) { - val updatedTasks = tasks.value.toMutableList() - updatedTasks.remove(task) - tasks.value = updatedTasks - } - - fun updateTask(updatedTask: Task) { - val updatedTasks = tasks.value.toMutableList() - val index = updatedTasks.indexOfFirst { it.id == updatedTask.id } - - if (index != -1) { - updatedTasks[index] = updatedTask - tasks.value = updatedTasks - } + override fun hashCode(): Int { + return uid ?: -1 } } \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/models/model/TaskWithUser.kt b/app/src/main/java/com/example/todolisttask/models/model/TaskWithUser.kt new file mode 100644 index 0000000..8b9af97 --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/models/model/TaskWithUser.kt @@ -0,0 +1,11 @@ +package com.example.todolisttask.models.model + +import androidx.room.ColumnInfo +import androidx.room.Embedded + +data class TaskWithUser( + @Embedded + val user: User, + @ColumnInfo(name = "task_name") + val taskName: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/models/model/User.kt b/app/src/main/java/com/example/todolisttask/models/model/User.kt index 9293782..cc7ad01 100644 --- a/app/src/main/java/com/example/todolisttask/models/model/User.kt +++ b/app/src/main/java/com/example/todolisttask/models/model/User.kt @@ -1,127 +1,38 @@ package com.example.todolisttask.models.model -import android.net.Uri -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf -import androidx.lifecycle.ViewModel -import java.io.Serializable +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.Ignore +import androidx.room.PrimaryKey +@Entity(tableName = "users") data class User( - val id: Int, + @PrimaryKey(autoGenerate = true) + val uid: Int?, + @ColumnInfo(name = "name") val name: String, + @ColumnInfo(name = "login") val login: String, - val password: String, - val taskId: List, - val favoritetask: List -) : Serializable + @ColumnInfo(name = "password") + val password: String +) { + @Ignore + constructor( + name: String, + login: String, + password: String + ) : this(null, name, login, password) -class UserViewModel : ViewModel() { - var users: MutableState> = mutableStateOf( - listOf( - User(0, "Иван", "ivan", "111111", emptyList(), emptyList()), - User(1, "Анна", "ann", "111111", emptyList(), emptyList()), - User(2, "Лиза", "liza", "111111", emptyList(), emptyList()) - ) - ) - - fun getUsers(): List { - return users.value - } - fun getUser(id:Int): User { - return users.value.get(id) - } - fun getPets(id:Int): List { - return users.value.get(id).taskId - } - // Function to add a pet to a user - fun addPetToUser(userId: Int, newPet: Task) { - val updatedUsers = users.value.toMutableList() - val user = updatedUsers.find { it.id == userId } - - user?.let { - val updatedPets = user.taskId.toMutableList() - updatedPets.add(newPet) - val updatedUser = user.copy(taskId = updatedPets) - val userIndex = updatedUsers.indexOf(user) - updatedUsers[userIndex] = updatedUser - users.value = updatedUsers - } - } - fun deleteTask(userId: Int, taskIdToDelete: Int) { - val updatedUsers = users.value.toMutableList() - - // Найдем пользователя по userId - val user = updatedUsers.find { it.id == userId } - - user?.let { user -> - val updatedTasks = user.taskId.toMutableList() - - // Найдем питомца по petId и удалим его из списка питомцев - val taskToDelete = updatedTasks.find { it.id == taskIdToDelete } - - taskToDelete?.let { task -> - updatedTasks.remove(task) - } - - // Обновим пользователя с обновленным списком питомцев - val updatedUser = user.copy(taskId = updatedTasks) - - // Обновим список пользователей - val userIndex = updatedUsers.indexOf(user) - updatedUsers[userIndex] = updatedUser - users.value = updatedUsers - } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + other as User + if (uid != other.uid) return false + return true } - fun addFavoriteTaskToUser(userId: Int, newFavoriteTask: Task) { - val updatedUsers = users.value.toMutableList() - val user = updatedUsers.find { it.id == userId } - - user?.let { - val updatedFavoriteTasks = user.favoritetask.toMutableList() - updatedFavoriteTasks.add(newFavoriteTask) - val updatedUser = user.copy(favoritetask = updatedFavoriteTasks) - val userIndex = updatedUsers.indexOf(user) - updatedUsers[userIndex] = updatedUser - users.value = updatedUsers - } + override fun hashCode(): Int { + return uid ?: -1 } - - - fun updateTaskOnUser(userId: Int, updatedTask: Task) { - val updatedUsers = users.value.toMutableList() - - // Найдем пользователя по userId - val user = updatedUsers.find { it.id == userId } - - user?.let { user -> - val updatedTasks = user.taskId.toMutableList() - - // Найдем питомца по petId и обновим его - val taskToUpdate = updatedTasks.find { it.id == updatedTask.id } - - taskToUpdate?.let { task -> - val taskIndex = updatedTasks.indexOf(task) - updatedTasks[taskIndex] = updatedTask - } - - // Обновим пользователя с обновленным списком питомцев - val updatedUser = user.copy(taskId = updatedTasks) - - // Обновим список пользователей - val userIndex = updatedUsers.indexOf(user) - updatedUsers[userIndex] = updatedUser - users.value = updatedUsers - } - } - - fun updateUser(updatedUser: User) { - val updatedUsers = users.value.toMutableList() - val index = updatedUsers.indexOfFirst { it.login == updatedUser.login } - if (index != -1) { - updatedUsers[index] = updatedUser - users.value = updatedUsers - } - } -} +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6fcadd3..53a230b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,4 +12,6 @@ Создание задачи Изменение задачи Избранные + Название задачи + Пароль \ No newline at end of file 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