This commit is contained in:
Артём Батылкин 2023-11-28 00:20:41 +04:00
parent d3b6668a51
commit aa2c281558
18 changed files with 495 additions and 252 deletions

View File

@ -83,4 +83,9 @@ dependencies {
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2")
}

View File

@ -16,7 +16,7 @@ import com.example.todolisttask.models.model.Task
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CreateTask(navController: NavController, onSaveClick: (Task) -> Unit) {
fun CreateTask(navController: NavController, userId: Int , onSaveClick: (Task) -> Unit) {
var taskName by remember { mutableStateOf("") }
var taskDescription by remember { mutableStateOf("") }
@ -48,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(taskName, taskDescription, userId)
onSaveClick(newTask)
taskName = ""
navController.popBackStack()
}
},
modifier = Modifier.fillMaxWidth()
) {
Text("Сохранить")
}
}
}

View File

@ -1,6 +1,12 @@
package com.example.todolisttask.composeui
import android.annotation.SuppressLint
import android.os.Build.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.withContext
import androidx.annotation.RequiresApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
@ -29,17 +35,19 @@ import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
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 com.example.todolisttask.models.model.User
import com.example.todolisttask.models.model.ViewModels.TaskViewModel
import com.example.todolisttask.models.model.ViewModels.UserViewModel
import kotlinx.coroutines.coroutineScope
@RequiresApi(VERSION_CODES.O)
@OptIn(ExperimentalMaterial3Api::class)
@SuppressLint("RememberReturnType")
@Composable
fun EditTask(navController: NavController, authViewModel: AuthViewModel, taskViewModel: TaskViewModel, userViewModel: UserViewModel, taskId : Int) {
val task = (authViewModel.currentUser?.taskId ?: emptyList()).find { it.id == taskId }
var taskName by remember { mutableStateOf(task?.name ?: "") }
var taskDescriptions by remember { mutableStateOf(task?.description ?: "") }
fun EditTask(navController: NavController, authViewModel: AuthViewModel, taskViewModel: TaskViewModel, userViewModel: UserViewModel, task : Task?, onSaveClick: (Task) -> Unit) {
var taskName = remember { mutableStateOf(task?.name.orEmpty()) }
var taskDescriptions = remember { mutableStateOf(task?.description.orEmpty()) }
Column(
modifier = Modifier
@ -48,8 +56,8 @@ fun EditTask(navController: NavController, authViewModel: AuthViewModel, taskVie
horizontalAlignment = Alignment.CenterHorizontally
) {
OutlinedTextField(
value = taskName,
onValueChange = { taskName = it },
value = taskName.value,
onValueChange = { taskName.value = it },
label = { Text("Название задания") },
modifier = Modifier
.fillMaxWidth()
@ -57,8 +65,8 @@ fun EditTask(navController: NavController, authViewModel: AuthViewModel, taskVie
)
OutlinedTextField(
value = taskDescriptions,
onValueChange = { taskDescriptions = it },
value = taskDescriptions.value,
onValueChange = { taskDescriptions.value = it },
label = { Text("Описание задания") },
modifier = Modifier
.fillMaxWidth()
@ -75,11 +83,12 @@ fun EditTask(navController: NavController, authViewModel: AuthViewModel, taskVie
Button(
onClick = {
val updatedTask = task?.copy(name = taskName, description = taskDescriptions) ?: return@Button
taskViewModel.updateTask(updatedTask)
userViewModel.updateTaskOnUser(authViewModel.currentUser?.id ?: -1, updatedTask)
authViewModel.currentUser=userViewModel.getUser(authViewModel.currentUser?.id ?: -1)
val updatedTask = Task(
task?.uid ?:0,
taskName.value,
taskDescriptions.value,
task?.userId ?:0)
onSaveClick(updatedTask)
navController.popBackStack()
},
modifier = Modifier.padding(16.dp)
@ -88,4 +97,6 @@ fun EditTask(navController: NavController, authViewModel: AuthViewModel, taskVie
}
}
}

View File

@ -13,13 +13,14 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
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.ViewModels.TaskViewModel
import com.example.todolisttask.models.model.ViewModels.UserViewModel
@OptIn(ExperimentalMaterial3Api::class)
@SuppressLint("RememberReturnType")
@Composable
fun Favorite(navController: NavController, authViewModel: AuthViewModel, taskViewModel: TaskViewModel, userViewModel: UserViewModel) {
/*
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
@ -29,4 +30,6 @@ fun Favorite(navController: NavController, authViewModel: AuthViewModel, taskVie
TaskList(navController, authViewModel, taskViewModel, userViewModel, authViewModel.currentUser?.id ?: -1, showFavorites = true)
}
*/
}

View File

@ -1,6 +1,7 @@
*/
package com.example.todolisttask.composeui
import com.example.todolisttask.models.model.ViewModels.TaskViewModel
import com.example.todolisttask.models.model.ViewModels.UserViewModel
import android.annotation.SuppressLint
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@ -16,9 +17,8 @@ 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
@OptIn(ExperimentalMaterial3Api::class)
@SuppressLint("RememberReturnType")
@ -39,7 +39,7 @@ fun Home(navController: NavController, authViewModel: AuthViewModel, taskViewMod
}
Spacer(modifier = Modifier.height(16.dp))
TaskList(navController, authViewModel, taskViewModel, userViewModel, authViewModel.currentUser?.id ?: -1)
TaskList(navController, authViewModel, taskViewModel, userViewModel, authViewModel.currentUser?.value?.uid ?: -1)
}
}

View File

@ -20,18 +20,21 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewModelScope
import androidx.navigation.NavHostController
import com.example.todolisttask.composeui.navigation.Screen
import com.example.todolisttask.models.model.AuthViewModel
import com.example.todolisttask.models.model.User
import com.example.todolisttask.models.model.ViewModels.UserViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Login(
navController: NavHostController,
authViewModel: AuthViewModel,
users: List<User>
authViewModel: AuthViewModel
) {
var username by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
@ -67,12 +70,18 @@ fun Login(
Button(
onClick = {
val authenticatedUser = users.find { it.login == username && it.password == password }
authViewModel.viewModelScope.launch {
authViewModel.loginUser(username, password)
// Добавляем небольшую задержку (например, 100 мс) для обеспечения завершения операции входа в систему
delay(1000)
val authenticatedUser = authViewModel.currentUser.value
if (authenticatedUser != null) {
authViewModel.currentUser = authenticatedUser
navController.navigate(Screen.Home.route)
} else {
println("Authentication failed")
println("Аутентификация не удалась")
}
}
},
modifier = Modifier.fillMaxWidth()

View File

@ -1,4 +1,4 @@
package com.example.pmuapp.composeui
package com.example.todolisttask.composeui
import android.annotation.SuppressLint
import android.net.Uri
@ -35,7 +35,7 @@ import kotlinx.coroutines.flow.callbackFlow
@OptIn(ExperimentalMaterial3Api::class)
@SuppressLint("RememberReturnType")
@Composable
fun Profile(navController: NavController, currentUser: User?, onSaveClick: (User) -> Unit) {
fun Profile(navController: NavController,currentUser: User?, onSaveClick: (User) -> Unit) {
val nameState = remember { mutableStateOf(currentUser?.name.orEmpty()) }
val loginState = remember { mutableStateOf(currentUser?.login.orEmpty()) }
val passwordState = remember { mutableStateOf(currentUser?.password.orEmpty()) }
@ -76,12 +76,10 @@ fun Profile(navController: NavController, currentUser: User?, onSaveClick: (User
Button(
onClick = {
val updatedUser = User(
currentUser?.id ?: 0,
currentUser?.uid ?: 0,
nameState.value,
loginState.value,
passwordState.value,
currentUser?.taskId ?: emptyList(),
currentUser?.favoritetask?: emptyList()
)
onSaveClick(updatedUser)
},
@ -90,4 +88,5 @@ fun Profile(navController: NavController, currentUser: User?, onSaveClick: (User
Text("Сохранить")
}
}
}

View File

@ -2,6 +2,7 @@ package com.example.todolisttask.composeui.navigation
import CreateTask
import android.annotation.SuppressLint
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.foundation.layout.PaddingValues
@ -19,12 +20,14 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.navigation.NavDestination
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewModelScope
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
@ -34,15 +37,22 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.example.pmuapp.composeui.Profile
import com.example.todolisttask.composeui.Profile
import com.example.todolisttask.AppDatabase
import com.example.todolisttask.R
import com.example.todolisttask.composeui.EditTask
import com.example.todolisttask.composeui.Favorite
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.composeui.Login
import com.example.todolisttask.composeui.Home
import com.example.todolisttask.models.dao.TaskDao
import com.example.todolisttask.models.dao.UserDao
import com.example.todolisttask.models.model.ViewModels.TaskViewModel
import com.example.todolisttask.models.model.ViewModels.UserViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class)
@ -102,6 +112,7 @@ fun Navbar(
}
}
@SuppressLint("StateFlowValueCalledInComposition", "SuspiciousIndentation")
@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun NavHost(
@ -117,41 +128,44 @@ fun NavHost(
modifier = Modifier.padding(innerPadding)
) {
composable(Screen.Login.route) {
Login(navController, authViewModel,userViewModel.getUsers()) }
Login(navController, authViewModel) }
composable(Screen.Logout.route) {
Login(navController, authViewModel,userViewModel.getUsers()) }
Login(navController, authViewModel) }
//
composable(Screen.CreateTask.route) {
val currentUser = authViewModel.currentUser ?: userViewModel.getUsers().firstOrNull()
CreateTask ( navController, onSaveClick = { newTask ->
var adedTask = taskViewModel.createTask(newTask)
userViewModel.addPetToUser(currentUser?.id ?:0, adedTask)
authViewModel.currentUser = userViewModel.getUser(currentUser?.id ?:0)
val currentUser = authViewModel.currentUser
val id: Int = currentUser.value?.uid?.toInt() ?: 0
CreateTask ( navController, id , onSaveClick = { newTask ->
taskViewModel.createTask(newTask)
//userViewModel.addTask(currentUser?.id ?:0, adedTask)
authViewModel.updateCurrentUset(id)
}
)
}
composable(Screen.Favorite.route){
val currentUser = authViewModel.currentUser ?: userViewModel.getUsers().firstOrNull()
if (currentUser != null) {
Favorite(navController,
authViewModel,
taskViewModel,
userViewModel
)
} else {
}
}
//
// composable(Screen.Favorite.route){
// val currentUser = authViewModel.currentUser ?: userViewModel.getUsers().firstOrNull()
// if (currentUser != null) {
// Favorite(navController,
// authViewModel,
// taskViewModel,
// userViewModel
// )
// } else {
// }
//
// }
//
composable(Screen.Profile.route) {
val currentUser = authViewModel.currentUser ?: userViewModel.getUsers().firstOrNull()
val currentUser = authViewModel.currentUser.collectAsState()
if (currentUser != null) {
Profile(navController,
currentUser = currentUser,
currentUser = currentUser.value,
onSaveClick = {updatedUser ->
userViewModel.updateUser(updatedUser)
authViewModel.currentUser = updatedUser
authViewModel.updateCurrentUset(currentUser?.value?.uid ?:-1)
navController.navigate(Screen.Profile.route)
}
)
@ -160,7 +174,7 @@ fun NavHost(
}
composable(Screen.Home.route){
val currentUser = authViewModel.currentUser ?: userViewModel.getUsers().firstOrNull()
val currentUser = authViewModel.currentUser
if (currentUser != null) {
Home(navController,
authViewModel,
@ -176,10 +190,13 @@ fun NavHost(
arguments = listOf(navArgument("id") { type = NavType.IntType })
) { backStackEntry ->
val petId = backStackEntry.arguments?.getInt("id") ?: -1
EditTask(navController,authViewModel, taskViewModel, userViewModel, petId)
val task = taskViewModel.getTask(petId)
EditTask(navController,authViewModel, taskViewModel, userViewModel, task.value,
onSaveClick = {updatedTask ->
taskViewModel.viewModelScope.launch {
taskViewModel.updateTask(updatedTask)
authViewModel.updateCurrentUset(id)}})
}
}
}
@ -188,9 +205,13 @@ fun NavHost(
@Composable
fun MainNavbar() {
val navController = rememberNavController()
val authViewModel = remember { AuthViewModel() }
val userViewModel = remember {UserViewModel() }
val taskViewModel = remember {TaskViewModel()}
val context = LocalContext.current
val database: AppDatabase = AppDatabase.getInstance(context)
val userDao: UserDao = database.userDao()
val taskDao: TaskDao = database.taskDao()
val authViewModel = remember { AuthViewModel(userDao) }
val userViewModel = remember { UserViewModel(userDao) }
val taskViewModel = remember { TaskViewModel(taskDao) }
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
val currentScreen = currentDestination?.route?.let { Screen.getItem(it) }

View File

@ -1,52 +1,161 @@
package com.example.todolisttask.models.composeui
import android.annotation.SuppressLint
import android.content.res.Configuration
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
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.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.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.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
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.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewModelScope
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.Task
import com.example.todolisttask.models.model.ViewModels.TaskViewModel
import com.example.todolisttask.models.model.ViewModels.UserViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.forEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@SuppressLint("StateFlowValueCalledInComposition")
@OptIn(ExperimentalFoundationApi::class, ExperimentalLayoutApi::class)
@Composable
fun TaskList(navController: NavController?) {
val context = LocalContext.current
val tasks = remember { mutableStateListOf<Task>() }
fun TaskList(navController: NavController, authViewModel: AuthViewModel, taskViewModel: TaskViewModel, userViewModel: UserViewModel, userId: Int, showFavorites: Boolean = false) {
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
val taskList = AppDatabase.getInstance(context).taskDao().getAll()
tasks.clear()
tasks.addAll(taskList)
val currentUser by userViewModel.user.collectAsState()
taskViewModel.getTasksByUser(userId)
var tasks = taskViewModel.tasks.value
LazyColumn(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
if (userId != authViewModel.currentUser?.value?.uid ?: -1) {
item {
Text(
text = currentUser?.name + " (" + currentUser?.login + ")",
style = TextStyle(
fontSize = 24.sp,
fontWeight = FontWeight.Bold
),
modifier = Modifier.padding(16.dp)
)
}
}
Column(Modifier.padding(all = 10.dp)) {
item {
FlowColumn() {
tasks.forEach { task ->
key(task.uid) {
val taskId = Screen.Home.route.replace("{id}", task.uid.toString())
Button(
val taskName = task.name
val taskDescription = task.description
FlowRow(
modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
onClick = { navController?.navigate(taskId) }) {
Text("${task.name} ${task.description}")
.padding(8.dp)
.border(
1.dp,
Color.Black,
),
horizontalArrangement = Arrangement.SpaceBetween
) {
IconButton(
onClick = {
navController?.navigate(
Screen.EditTask.route.replace(
"{id}",
task.uid.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.viewModelScope.launch {
taskViewModel.deleteTask(task)
/* userViewModel.deleteTask(
currentUser?.id ?: 0,
task.id
)*/
authViewModel.updateCurrentUset(authViewModel.currentUser?.value?.uid ?:-1)
taskViewModel.updateTasks(taskViewModel.tasks.value)
}
}
) {
Icon(
imageVector = Icons.Default.Delete,
contentDescription = "Удалить"
)
}
/* IconButton(
onClick = {
userViewModel.addFavoriteTaskToUser(userId, task)
}
) {
Icon(
imageVector = Icons.Default.Favorite,
contentDescription = "Добавить в избранное"
)
}*/
}
}
}
}

View File

@ -1,83 +0,0 @@
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<TaskWithUser?>(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))
}
)
}
}
}

View File

@ -1,55 +0,0 @@
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.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
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.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.example.todolisttask.AppDatabase
import com.example.todolisttask.composeui.navigation.Screen
import com.example.todolisttask.models.model.Task
import com.example.todolisttask.models.model.User
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun UserList(navController: NavController?) {
val context = LocalContext.current
val users = remember { mutableStateListOf<User>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
val userList = AppDatabase.getInstance(context).userDao().getAll()
users.clear()
users.add(userList)
}
}
Column(Modifier.padding(all = 10.dp)) {
users.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.login}")
}
}
}
}
}

View File

@ -6,11 +6,13 @@ import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.todolisttask.models.model.Task
import com.example.todolisttask.models.model.User
import kotlinx.coroutines.flow.Flow
@Dao
interface TaskDao {
@Query("select * from tasks order by task_name collate nocase asc")
suspend fun getAll(): List<Task>
fun getAll(): Flow<List<Task>>
@Insert
suspend fun insert(group: Task)
@ -20,4 +22,9 @@ interface TaskDao {
@Delete
suspend fun delete(group: Task)
@Query("select * from tasks where tasks.user_id = :uid")
suspend fun getByUid(uid: Int): List<Task>
@Query("select * from tasks where tasks.uid = :uid ")
suspend fun getOne(uid: Int): Task
}

View File

@ -15,7 +15,7 @@ interface UserDao {
fun getAll(): Flow<List<User>>
@Query("select * from users left join tasks on users.uid = tasks.user_id where users.uid = :uid")
suspend fun getByUid(uid: Int): TaskWithUser
suspend fun getByUid(uid: Int): User
@Insert
suspend fun insert(user: User)
@ -26,6 +26,6 @@ interface UserDao {
@Delete
suspend fun delete(user: User)
@Query("SELECT * FROM users WHERE login = :username AND password = :password")
@Query("SELECT * FROM users WHERE users.login = :username AND users.password = :password")
suspend fun getUserByUsernameAndPassword(username: String, password: String): User?
}

View File

@ -27,13 +27,13 @@ abstract class AppDatabase : RoomDatabase() {
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)
// 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")

View File

@ -0,0 +1,41 @@
package com.example.todolisttask.models.model
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.todolisttask.models.dao.UserDao
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class AuthViewModel(private val userDao: UserDao) : ViewModel() {
private val _currentUser = MutableStateFlow<User?>(null)
val currentUser: StateFlow<User?> get() = _currentUser
fun loginUser(username: String, password: String) {
viewModelScope.launch {
try {
withContext(Dispatchers.IO) {
val user = userDao.getUserByUsernameAndPassword(username, password)
_currentUser.value = user
}
} catch (e: Exception) {
println("Error during login: ${e.message}")
}
}
}
fun updateCurrentUset(id:Int) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
val user = userDao.getByUid(id)
// Обновляем _currentUser после успешной аутентификации
_currentUser.value = user
}
}
}
}

View File

@ -3,6 +3,7 @@ package com.example.todolisttask.models.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Ignore
import androidx.room.PrimaryKey
@ -25,6 +26,13 @@ data class Task(
@ColumnInfo(name = "user_id", index = true)
val userId: Int
) {
@Ignore
constructor(
name: String,
description: String,
userId: Int
) : this(null, name, description, userId)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

View File

@ -0,0 +1,97 @@
package com.example.todolisttask.models.model.ViewModels
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.todolisttask.models.dao.TaskDao
import com.example.todolisttask.models.model.Task
import com.example.todolisttask.models.model.User
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.sql.RowId
class TaskViewModel(private val taskDao: TaskDao) : ViewModel() {
private val _task = MutableStateFlow<Task?>(null)
val task: StateFlow<Task?> get() = _task
private val _tasks = MutableStateFlow<List<Task>>(emptyList())
val tasks: StateFlow<List<Task>> get() = _tasks
// Метод для обновления списка пользователей
fun updateTasks(newUsers: List<Task>) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
_tasks.value = newUsers
}
}
}
fun updateTask(updatedTask: Task) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
Log.e("TAG", "111111111111111111111")
// Update the specific pet in the database
taskDao.update(updatedTask)
// Retrieve the updated list of pets as a Flow
val updatedTasksFlow = taskDao.getAll()
Log.e("TAG", "222222222222222222222222")
// Collect the values from the Flow and update _pets
updatedTasksFlow.collect { updatedTasks ->
// Convert java.util.List to kotlin.collections.List if needed
_tasks.value = updatedTasks.toList()
}
Log.e("TAG", "333333333333333333333333")
}
}
}
// Метод для создания новой задачи
fun createTask(task: Task) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
// Вставляем новую задачу в базу данных
taskDao.insert(task)
// Получаем актуальный список задач после вставки
val updatedTasksFlow = taskDao.getAll()
Log.e("TAG", "222222222222222222222222")
// Collect the values from the Flow and update _pets
updatedTasksFlow.collect { updatedTasks ->
// Convert java.util.List to kotlin.collections.List if needed
_tasks.value = updatedTasks.toList()
}
}
}
}
fun getTasksByUser(userId: Int) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
_tasks.value = taskDao.getByUid(userId)
}
}
}
fun getTask(Id: Int): StateFlow<Task?> {
viewModelScope.launch {
withContext(Dispatchers.IO) {
val task = taskDao.getOne(Id)
_task.value = task
}
}
return _task
}
fun deleteTask(task: Task) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
taskDao.delete(task)
}
}
}
}

View File

@ -0,0 +1,71 @@
package com.example.todolisttask.models.model.ViewModels
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.todolisttask.models.dao.UserDao
import com.example.todolisttask.models.model.User
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class UserViewModel(private val userDao: UserDao) : ViewModel() {
private val _user = MutableStateFlow<User?>(null)
val user: StateFlow<User?> get() = _user
private val _users = MutableStateFlow<List<User>>(emptyList())
val users: StateFlow<List<User>> get() = _users
// Метод для обновления списка пользователей
fun updateUsers(newUsers: List<User>) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
_users.value = newUsers
}
}
}
fun updateUser(updatedUser: User) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
Log.e("TAG", "111111111111111111111")
// Update the specific pet in the database
userDao.update(updatedUser)
// Retrieve the updated list of pets as a Flow
val updatedUsersFlow = userDao.getAll()
Log.e("TAG", "222222222222222222222222")
// Collect the values from the Flow and update _pets
updatedUsersFlow.collect { updatedUsers ->
// Convert java.util.List to kotlin.collections.List if needed
_users.value = updatedUsers.toList()
}
Log.e("TAG", "333333333333333333333333")
}
}
}
fun getUser(userId: Int): StateFlow<User?> {
viewModelScope.launch {
withContext(Dispatchers.IO) {
val user = userDao.getByUid(userId)
_user.value = user
}
}
return _user
}
// Метод для входа пользователя
fun loginUser(login: String, password: String) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
val user = userDao.getUserByUsernameAndPassword(login, password)
// Здесь должно быть обновление списка пользователей, но не _currentUser
// Также, вам, возможно, нужно вызвать метод updateUsers с обновленным списком пользователей
}
}
}
}