commit 83aabb521f9fc0c7cb0ae3ea2b76bfbf8e2ece84 Author: Alina Batylkina Date: Tue Oct 31 09:54:49 2023 +0400 lab2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b589d56 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..ae388c2 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..44ca2d9 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,41 @@ + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..0fc3113 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..8978d23 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..f29e9f7 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,73 @@ +plugins { + id("com.android.application") + id("org.jetbrains.kotlin.android") +} + +android { + namespace = "com.example.todolisttask" + compileSdk = 34 + + defaultConfig { + applicationId = "com.example.todolisttask" + minSdk = 24 + targetSdk = 34 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary = true + } + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } + buildFeatures { + compose = true + } + composeOptions { + kotlinCompilerExtensionVersion = "1.4.3" + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } +} + +dependencies { + implementation ("io.coil-kt:coil-compose:1.4.0") + 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(platform("androidx.compose:compose-bom:2023.03.00")) + implementation("androidx.navigation:navigation-compose:2.6.0") + implementation("androidx.compose.ui:ui") + 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") + testImplementation("junit:junit:4.13.2") + androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") + androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00")) + androidTestImplementation("androidx.compose.ui:ui-test-junit4") + debugImplementation("androidx.compose.ui:ui-tooling") + debugImplementation("androidx.compose.ui:ui-test-manifest") +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/todolisttask/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/todolisttask/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..c3b4b80 --- /dev/null +++ b/app/src/androidTest/java/com/example/todolisttask/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.example.todolisttask + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.example.todolisttask", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..3bc85c9 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/MainActivity.kt b/app/src/main/java/com/example/todolisttask/MainActivity.kt new file mode 100644 index 0000000..4af0f2a --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/MainActivity.kt @@ -0,0 +1,48 @@ +package com.example.todolisttask + +import android.os.Build +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.annotation.RequiresApi +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.example.todolisttask.composeui.navigation.MainNavbar +import com.example.todolisttask.ui.theme.ToDoListTaskTheme + +class MainActivity : ComponentActivity() { + @RequiresApi(Build.VERSION_CODES.O) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + ToDoListTaskTheme { + // A surface container using the 'background' color from the theme + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + MainNavbar() + } + } + } + } +} + + +@RequiresApi(Build.VERSION_CODES.O) +@Preview(showBackground = true) +@Composable +fun GreetingPreview() { + ToDoListTaskTheme { + Surface( + color = MaterialTheme.colorScheme.background + ) { + MainNavbar() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/composeui/CreateTask.kt b/app/src/main/java/com/example/todolisttask/composeui/CreateTask.kt new file mode 100644 index 0000000..ecbb094 --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/composeui/CreateTask.kt @@ -0,0 +1,67 @@ +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.material3.Button +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.runtime.* +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) +@Composable +fun CreateTask(navController: NavController, onSaveClick: (Task) -> Unit) { + var taskName by remember { mutableStateOf("") } + var taskDescription by remember { mutableStateOf("") } + + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp) + ) { + Spacer(modifier = Modifier.height(16.dp)) + + OutlinedTextField( + value = taskName, + onValueChange = { taskName = it }, + label = { Text("Название задания") }, + modifier = Modifier.fillMaxWidth() + ) + + OutlinedTextField( + value = taskDescription, + onValueChange = { taskDescription = it }, + label = { Text("Описание задания") }, + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp) + .heightIn(max = 200.dp) + .padding(16.dp), + readOnly = false + ) + + 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("Сохранить") + } + } +} diff --git a/app/src/main/java/com/example/todolisttask/composeui/EditTask.kt b/app/src/main/java/com/example/todolisttask/composeui/EditTask.kt new file mode 100644 index 0000000..bbf8741 --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/composeui/EditTask.kt @@ -0,0 +1,91 @@ +package com.example.todolisttask.composeui + +import android.os.Build.* +import androidx.annotation.RequiresApi +import androidx.compose.foundation.Image +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.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.dp +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 + +@RequiresApi(VERSION_CODES.O) +@OptIn(ExperimentalMaterial3Api::class) +@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 ?: "") } + + Column( + modifier = Modifier + .fillMaxSize() + .padding(10.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + OutlinedTextField( + value = taskName, + onValueChange = { taskName = it }, + label = { Text("Название задания") }, + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp) + ) + + OutlinedTextField( + value = taskDescriptions, + onValueChange = { taskDescriptions = it }, + label = { Text("Описание задания") }, + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp) + .heightIn(max = 200.dp) + .padding(16.dp), + readOnly = false + ) + + Spacer(modifier = Modifier.weight(1f)) + + + // val editedTaskId = Screen.PlayTask.route.replace("{id}", task?.id.toString()) + + 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) + navController.popBackStack() + }, + modifier = Modifier.padding(16.dp) + ) { + 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 new file mode 100644 index 0000000..99ef643 --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/composeui/Favorite.kt @@ -0,0 +1,36 @@ +package com.example.todolisttask.composeui + +import android.annotation.SuppressLint +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.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 + +@OptIn(ExperimentalMaterial3Api::class) +@SuppressLint("RememberReturnType") +@Composable +fun Favorite(navController: NavController, authViewModel: AuthViewModel, taskViewModel: TaskViewModel, userViewModel: UserViewModel) { + Column( + modifier = Modifier.fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Spacer(modifier = Modifier.height(16.dp)) + + TaskList(navController, authViewModel, taskViewModel, userViewModel, authViewModel.currentUser?.id ?: -1, showFavorites = true) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/composeui/Home.kt b/app/src/main/java/com/example/todolisttask/composeui/Home.kt new file mode 100644 index 0000000..4b80573 --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/composeui/Home.kt @@ -0,0 +1,57 @@ +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") +@Composable +fun Home(navController: NavController, authViewModel: AuthViewModel, taskViewModel: TaskViewModel, userViewModel: UserViewModel) { + + Column( + modifier = Modifier.fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Button( + onClick = { + navController.navigate(Screen.CreateTask.route) + } + ) { + Text("Создать задачу") + } + Spacer(modifier = Modifier.height(16.dp)) + + TaskList(navController, authViewModel, taskViewModel, userViewModel, authViewModel.currentUser?.id ?: -1) + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/composeui/Login.kt b/app/src/main/java/com/example/todolisttask/composeui/Login.kt new file mode 100644 index 0000000..9e3f83b --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/composeui/Login.kt @@ -0,0 +1,84 @@ +package com.example.todolisttask.composeui + +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.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +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.navigation.NavHostController +import com.example.todolisttask.composeui.navigation.Screen +import com.example.todolisttask.models.model.AuthViewModel +import com.example.todolisttask.models.model.User + + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun Login( + navController: NavHostController, + authViewModel: AuthViewModel, + users: List +) { + var username by remember { mutableStateOf("") } + var password by remember { mutableStateOf("") } + + + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + TextField( + value = username, + onValueChange = { username = it }, + label = { Text("Username") }, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 16.dp) + ) + + TextField( + value = password, + onValueChange = { password = it }, + label = { Text("Password") }, + visualTransformation = PasswordVisualTransformation(), + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 16.dp) + ) + + Spacer(modifier = Modifier.height(16.dp)) + + Button( + onClick = { + val authenticatedUser = users.find { it.login == username && it.password == password } + if (authenticatedUser != null) { + authViewModel.currentUser = authenticatedUser + navController.navigate(Screen.Home.route) + } else { + println("Authentication failed") + } + }, + modifier = Modifier.fillMaxWidth() + ) { + Text("Login") + } + + } +} diff --git a/app/src/main/java/com/example/todolisttask/composeui/Profile.kt b/app/src/main/java/com/example/todolisttask/composeui/Profile.kt new file mode 100644 index 0000000..e48509a --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/composeui/Profile.kt @@ -0,0 +1,94 @@ +package com.example.pmuapp.composeui + +import android.annotation.SuppressLint +import android.net.Uri +import androidx.activity.OnBackPressedCallback +import androidx.activity.OnBackPressedDispatcher +import androidx.activity.compose.BackHandler +import androidx.activity.compose.LocalOnBackPressedDispatcherOwner +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.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.verticalScroll +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.DisposableEffect +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +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 + +@OptIn(ExperimentalMaterial3Api::class) +@SuppressLint("RememberReturnType") +@Composable +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()) } + + + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp) + ) { + TextField( + value = nameState.value, + onValueChange = { nameState.value = it }, + label = { Text("Name") }, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 16.dp) + ) + + TextField( + value = loginState.value, + onValueChange = { loginState.value = it }, + label = { Text("Login") }, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 16.dp) + ) + + TextField( + value = passwordState.value, + onValueChange = { passwordState.value = it }, + label = { Text("Password") }, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 16.dp) + ) + + Button( + onClick = { + val updatedUser = User( + currentUser?.id ?: 0, + nameState.value, + loginState.value, + passwordState.value, + currentUser?.taskId ?: emptyList(), + currentUser?.favoritetask?: emptyList() + ) + onSaveClick(updatedUser) + }, + modifier = Modifier.fillMaxWidth() + ) { + Text("Сохранить") + } + } +} 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 new file mode 100644 index 0000000..e201288 --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/composeui/navigation/MyPage.kt @@ -0,0 +1,227 @@ +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 +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +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 + +import androidx.navigation.NavDestination.Companion.hierarchy +import androidx.navigation.NavGraph.Companion.findStartDestination +import androidx.navigation.NavHostController +import androidx.navigation.NavType +import androidx.navigation.compose.NavHost +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.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 +import com.example.todolisttask.composeui.Login +import com.example.todolisttask.composeui.Home + + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun Topbar( + navController: NavHostController, + currentScreen: Screen? +) { + TopAppBar( + colors = TopAppBarDefaults.smallTopAppBarColors( + containerColor = MaterialTheme.colorScheme.primary, + titleContentColor = MaterialTheme.colorScheme.onPrimary, + ), + title = { + Text(stringResource(currentScreen?.resourceId ?: R.string.app_name)) + }, + navigationIcon = { + if ( + navController.previousBackStackEntry != null + && (currentScreen == null || !currentScreen.showInBottomBar) + ) { + IconButton(onClick = { navController.navigateUp() }) { + Icon( + imageVector = Icons.Default.ArrowBack, + contentDescription = "Back", + tint = MaterialTheme.colorScheme.onPrimary + ) + } + } + } + ) +} + +@Composable +fun Navbar( + navController: NavHostController, + currentDestination: NavDestination?, + modifier: Modifier = Modifier +) { + NavigationBar(modifier) { + Screen.bottomBarItems.forEach { screen -> + NavigationBarItem( + icon = { Icon(screen.icon, contentDescription = null) }, + label = { Text(stringResource(screen.resourceId)) }, + selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true, + onClick = { + navController.navigate(screen.route) { + popUpTo(navController.graph.findStartDestination().id) { + saveState = true + } + launchSingleTop = true + restoreState = true + } + } + ) + } + } +} + +@RequiresApi(Build.VERSION_CODES.O) +@Composable +fun NavHost( + navController: NavHostController, + innerPadding: PaddingValues, + authViewModel: AuthViewModel, + userViewModel: UserViewModel, + taskViewModel: TaskViewModel +) { + NavHost( + navController = navController, + startDestination = Screen.Login.route, + modifier = Modifier.padding(innerPadding) + ) { + composable(Screen.Login.route) { + Login(navController, authViewModel,userViewModel.getUsers()) } + composable(Screen.Logout.route) { + Login(navController, authViewModel,userViewModel.getUsers()) } + 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) + } + ) + + } + + 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() + if (currentUser != null) { + Profile(navController, + currentUser = currentUser, + onSaveClick = {updatedUser -> + userViewModel.updateUser(updatedUser) + authViewModel.currentUser = updatedUser + navController.navigate(Screen.Profile.route) + } + ) + } else { + } + } + + composable(Screen.Home.route){ + val currentUser = authViewModel.currentUser ?: userViewModel.getUsers().firstOrNull() + if (currentUser != null) { + Home(navController, + authViewModel, + taskViewModel, + userViewModel + ) + } else { + } + + } + composable( + Screen.EditTask.route, + arguments = listOf(navArgument("id") { type = NavType.IntType }) + ) { backStackEntry -> + val petId = backStackEntry.arguments?.getInt("id") ?: -1 + EditTask(navController,authViewModel, taskViewModel, userViewModel, petId) + + } + + } +} + +@RequiresApi(Build.VERSION_CODES.O) +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MainNavbar() { + val navController = rememberNavController() + val authViewModel = remember { AuthViewModel() } + val userViewModel = remember {UserViewModel() } + val taskViewModel = remember {TaskViewModel()} + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentDestination = navBackStackEntry?.destination + val currentScreen = currentDestination?.route?.let { Screen.getItem(it) } + + Scaffold( + topBar = { + Topbar(navController, currentScreen) + }, + bottomBar = { + if ((currentScreen == null || currentScreen.showInBottomBar) && currentScreen != Screen.Login && currentScreen != Screen.Logout) { + Navbar(navController, currentDestination) + } + } + ) { innerPadding -> + NavHost(navController, innerPadding, authViewModel, userViewModel, taskViewModel ) + } +} + +//@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) +//@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +//@Composable +//fun MainNavbarPreview() { +// PMUappTheme { +// Surface( +// color = MaterialTheme.colorScheme.background +// ) { +// MainNavbar() +// } +// } +//} \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/composeui/navigation/Screen.kt b/app/src/main/java/com/example/todolisttask/composeui/navigation/Screen.kt new file mode 100644 index 0000000..279b042 --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/composeui/navigation/Screen.kt @@ -0,0 +1,56 @@ +package com.example.todolisttask.composeui.navigation + +import androidx.annotation.StringRes +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ExitToApp +import androidx.compose.material.icons.filled.Favorite +import androidx.compose.material.icons.filled.Home +import androidx.compose.material.icons.filled.List +import androidx.compose.material.icons.filled.Person +import androidx.compose.ui.graphics.vector.ImageVector +import com.example.todolisttask.R + + +enum class Screen( + val route: String, + @StringRes val resourceId: Int, + val icon: ImageVector = Icons.Filled.Favorite, + val showInBottomBar: Boolean = true +) { + Home( + "home", R.string.home_title, Icons.Filled.Home + ), + Login( + "login", R.string.login_title, showInBottomBar = false + ), + Profile( + "profile", R.string.user_my_title, Icons.Filled.Person + ), + Favorite( + "favorite", R.string.favorite_task_title, Icons.Filled.Favorite + ), + Logout( + "logout", R.string.logout_title, Icons.Filled.ExitToApp + ), + CreateTask( + "createtask", R.string.create_task_title, showInBottomBar = false + ), + EditTask( + "edittask/{id}", R.string.edit_task_title,showInBottomBar = false + ); + + + companion object { + val bottomBarItems = listOf( + Home, + Favorite, + Profile, + Logout + ) + + fun getItem(route: String): Screen? { + val findRoute = route.split("/").first() + return values().find { value -> value.route.startsWith(findRoute) } + } + } +} \ No newline at end of file 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 new file mode 100644 index 0000000..b3a3f9c --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/models/composeui/TaskList.kt @@ -0,0 +1,143 @@ +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 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.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.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +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.unit.dp +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 + +@OptIn(ExperimentalFoundationApi::class, ExperimentalLayoutApi::class) +@Composable +fun TaskList(navController: NavController, authViewModel: AuthViewModel, taskViewModel: TaskViewModel, userViewModel: UserViewModel, userId: Int, showFavorites: Boolean = false) { + + 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 = "Добавить в избранное" + ) + } + } + } + } + } + } +} 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 new file mode 100644 index 0000000..86d46ec --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/models/composeui/UserList.kt @@ -0,0 +1,36 @@ +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/model/AuthViewModel.kt b/app/src/main/java/com/example/todolisttask/models/model/AuthViewModel.kt new file mode 100644 index 0000000..b9ebdab --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/models/model/AuthViewModel.kt @@ -0,0 +1,10 @@ +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 new file mode 100644 index 0000000..b645265 --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/models/model/Task.kt @@ -0,0 +1,43 @@ +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 + +data class Task( + var id: Int, + val name: String, + val description: String +) : Serializable + +class TaskViewModel : ViewModel() { + var tasks: MutableState> = mutableStateOf( + emptyList() + ) + + fun createTask(newTask: Task): Task { + newTask.id = tasks.value.size.toInt() + val updatedTasks = tasks.value.toMutableList() + updatedTasks.add(newTask) + tasks.value = updatedTasks + return newTask + } + + 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 + } + } +} \ 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 new file mode 100644 index 0000000..9293782 --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/models/model/User.kt @@ -0,0 +1,127 @@ +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 + +data class User( + val id: Int, + val name: String, + val login: String, + val password: String, + val taskId: List, + val favoritetask: List +) : Serializable + + +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 + } + } + + 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 + } + } + + + 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 + } + } +} diff --git a/app/src/main/java/com/example/todolisttask/ui/theme/Color.kt b/app/src/main/java/com/example/todolisttask/ui/theme/Color.kt new file mode 100644 index 0000000..2c5ebbe --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/ui/theme/Color.kt @@ -0,0 +1,11 @@ +package com.example.todolisttask.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) +val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/ui/theme/Theme.kt b/app/src/main/java/com/example/todolisttask/ui/theme/Theme.kt new file mode 100644 index 0000000..98822ee --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/ui/theme/Theme.kt @@ -0,0 +1,70 @@ +package com.example.todolisttask.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun ToDoListTaskTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colorScheme.primary.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + } + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/todolisttask/ui/theme/Type.kt b/app/src/main/java/com/example/todolisttask/ui/theme/Type.kt new file mode 100644 index 0000000..b200829 --- /dev/null +++ b/app/src/main/java/com/example/todolisttask/ui/theme/Type.kt @@ -0,0 +1,34 @@ +package com.example.todolisttask.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..6fcadd3 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,15 @@ + + Задачник + Имя + Логин + Пароль + Пользователи + Профиль пользователя + Мой дом + Мой профиль + Авторизация + Выход + Создание задачи + Изменение задачи + Избранные + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..44baaf9 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +