diff --git a/app/src/main/java/com/example/mobileapp/api/ApiStatus.kt b/app/src/main/java/com/example/mobileapp/api/ApiStatus.kt new file mode 100644 index 0000000..fcec8cc --- /dev/null +++ b/app/src/main/java/com/example/mobileapp/api/ApiStatus.kt @@ -0,0 +1,5 @@ +package com.example.mobileapp.api + +enum class ApiStatus { + LOADING, ERROR, DONE, NONE +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mobileapp/api/model/RemoteConverters.kt b/app/src/main/java/com/example/mobileapp/api/model/RemoteConverters.kt index cdc6f2d..157c9b4 100644 --- a/app/src/main/java/com/example/mobileapp/api/model/RemoteConverters.kt +++ b/app/src/main/java/com/example/mobileapp/api/model/RemoteConverters.kt @@ -13,9 +13,11 @@ class RemoteConverters { fun fromBitmap(bitmap: Bitmap): String { val outputStream = ByteArrayOutputStream() + val extendedBitmap = scaleRatioBitmap(bitmap) + // Сжимаем изображение до указанного максимального размера - val quality = calculateQuality(bitmap) - bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream) + val quality = calculateQuality(extendedBitmap) + extendedBitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream) val byteArray = outputStream.toByteArray() return Base64.encodeToString(byteArray, Base64.NO_WRAP) @@ -28,8 +30,6 @@ class RemoteConverters { private fun calculateQuality(bitmap: Bitmap): Int { val outputStream = ByteArrayOutputStream() - /*bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream) - val initialSize = outputStream.size()*/ // Уменьшаем качество изображения, пока его размер не станет меньше максимального var quality = 100 @@ -42,5 +42,21 @@ class RemoteConverters { // Возвращаем качество, при котором размер изображения удовлетворяет ограничению return if (quality < 0) 0 else quality } + + private fun scaleRatioBitmap(bitmap: Bitmap): Bitmap { + val maxWidth = 990 + val maxHeight = 990 + if (bitmap.width > maxWidth || bitmap.height > maxHeight) { + // Если размер превышает максимальный, масштабируем изображение + val ratio = Math.min(maxWidth.toFloat() / bitmap.width, + maxHeight.toFloat() / bitmap.height) + + val width = (ratio * bitmap.width).toInt() + val height = (ratio * bitmap.height).toInt() + + return Bitmap.createScaledBitmap(bitmap, width, height, true) + } + return bitmap + } } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mobileapp/components/ListContent.kt b/app/src/main/java/com/example/mobileapp/components/ListContent.kt index 3cb6809..4737b5e 100644 --- a/app/src/main/java/com/example/mobileapp/components/ListContent.kt +++ b/app/src/main/java/com/example/mobileapp/components/ListContent.kt @@ -352,16 +352,3 @@ fun DialogWindow(label: String, message: String, onConfirmAction: () -> Unit, on } ) } - -@Composable -fun LoadingScreen() { - Column( - modifier = Modifier - .fillMaxSize() - .padding(16.dp), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { - CircularProgressIndicator() - } -} diff --git a/app/src/main/java/com/example/mobileapp/database/viewmodels/CustomViewModel.kt b/app/src/main/java/com/example/mobileapp/database/viewmodels/CustomViewModel.kt new file mode 100644 index 0000000..97b9c22 --- /dev/null +++ b/app/src/main/java/com/example/mobileapp/database/viewmodels/CustomViewModel.kt @@ -0,0 +1,75 @@ +package com.example.mobileapp.database.viewmodels + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.mobileapp.api.ApiStatus +import kotlinx.coroutines.launch +import retrofit2.HttpException +import java.io.IOException + +open class CustomViewModel : ViewModel() { + var apiStatus by mutableStateOf(ApiStatus.NONE) + private set + + var apiError by mutableStateOf("") + private set + + fun runInScope( + actionSuccess: suspend () -> Unit, + actionError: suspend () -> Unit + ) { + viewModelScope.launch { + apiStatus = ApiStatus.LOADING + runCatching { + actionSuccess() + apiStatus = ApiStatus.DONE + apiError = "" + }.onFailure { e: Throwable -> + when (e) { + is IOException, + is HttpException -> { + actionError() + apiStatus = ApiStatus.ERROR + apiError = e.localizedMessage ?: e.toString() + } + else -> throw e + } + } + } + } + + fun runInScope(actionSuccess: suspend () -> Unit) { + runInScope(actionSuccess, actionError = {}) + } + + fun clearStatus(){ + apiStatus = ApiStatus.NONE + } +} + +@Composable +fun LoadingScreen(color: Color) { + Box( + modifier = Modifier + .fillMaxSize() + .padding(16.dp), + contentAlignment = Alignment.Center + ) { + CircularProgressIndicator( + color = color, + strokeWidth = 6.dp + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mobileapp/database/viewmodels/UserViewModel.kt b/app/src/main/java/com/example/mobileapp/database/viewmodels/UserViewModel.kt index aaaa61a..e8c9819 100644 --- a/app/src/main/java/com/example/mobileapp/database/viewmodels/UserViewModel.kt +++ b/app/src/main/java/com/example/mobileapp/database/viewmodels/UserViewModel.kt @@ -11,7 +11,7 @@ import com.example.mobileapp.database.repositories.UserRepository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.launch -class UserViewModel(private val userRepository: UserRepository): ViewModel() { +class UserViewModel(private val userRepository: UserRepository): CustomViewModel() { //val getAllUsers = userRepository.getAllUsers() suspend fun getUser(id: Int): User? = userRepository.getUser(id) @@ -28,8 +28,12 @@ class UserViewModel(private val userRepository: UserRepository): ViewModel() { if (user.password.isEmpty()){ return@launch } - userRepository.updateUser(user) - GlobalUser.getInstance().setUser(user) + runInScope( + actionSuccess = { + userRepository.updateUser(user) + GlobalUser.getInstance().setUser(user) + } + ) } fun deleteUser(user: User) = viewModelScope.launch { @@ -44,18 +48,38 @@ class UserViewModel(private val userRepository: UserRepository): ViewModel() { if(user.email.isEmpty() || !isValidEmail(user.email)){ return@launch } - userRepository.insertUser(user) + runInScope( + actionSuccess = { + userRepository.insertUser(user) + GlobalUser.getInstance().setUser(userRepository.getUserByLogin( + UserRemoteSignIn(user.login, user.password))) + } + ) + /*userRepository.insertUser(user) GlobalUser.getInstance().setUser(userRepository.getUserByLogin( - UserRemoteSignIn(user.login, user.password))) + UserRemoteSignIn(user.login, user.password)))*/ } fun authUser(user: User) = viewModelScope.launch { - val globalUser = userRepository.getUserByLogin(UserRemoteSignIn(user.login, user.password)) + runInScope( + actionSuccess = { + val globalUser = userRepository.getUserByLogin(UserRemoteSignIn(user.login, user.password)) + globalUser?.let { + if (user.password.isNotEmpty() && user.password == globalUser.password){ + GlobalUser.getInstance().setUser(globalUser) + } + } + }, + actionError = { + GlobalUser.getInstance().setUser(null) + } + ) + /*val globalUser = userRepository.getUserByLogin(UserRemoteSignIn(user.login, user.password)) globalUser?.let { if (user.password.isNotEmpty() && user.password == globalUser.password){ GlobalUser.getInstance().setUser(globalUser) } - } + }*/ } private fun isValidEmail(email: String): Boolean { diff --git a/app/src/main/java/com/example/mobileapp/screens/Authorization.kt b/app/src/main/java/com/example/mobileapp/screens/Authorization.kt index ca044dc..c7a88b2 100644 --- a/app/src/main/java/com/example/mobileapp/screens/Authorization.kt +++ b/app/src/main/java/com/example/mobileapp/screens/Authorization.kt @@ -1,5 +1,6 @@ package com.example.mobileapp.screens +import android.widget.Toast import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -23,12 +24,14 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import com.example.mobileapp.GlobalUser import com.example.mobileapp.R +import com.example.mobileapp.api.ApiStatus import com.example.mobileapp.components.ActiveButton import com.example.mobileapp.components.NavigationButton import com.example.mobileapp.components.PasswordInputField import com.example.mobileapp.components.PlaceholderInputField import com.example.mobileapp.database.MobileAppDataBase import com.example.mobileapp.database.entities.User +import com.example.mobileapp.database.viewmodels.LoadingScreen import com.example.mobileapp.database.viewmodels.MobileAppViewModelProvider import com.example.mobileapp.database.viewmodels.UserViewModel import com.example.mobileapp.ui.theme.ButtonColor1 @@ -41,49 +44,63 @@ fun Authorization(navController: NavHostController, userViewModel: UserViewModel = viewModel( factory = MobileAppViewModelProvider.Factory )) { - val isAuthorizated = remember { mutableStateOf(false) } + val context = LocalContext.current - if(GlobalUser.getInstance().getUser() != null && !isAuthorizated.value) { - isAuthorizated.value = !isAuthorizated.value - navController.navigate("main") + when(userViewModel.apiStatus){ + ApiStatus.DONE -> { + navController.navigate("main") + userViewModel.clearStatus() + } + ApiStatus.LOADING -> LoadingScreen(ButtonColor2) + ApiStatus.ERROR -> Toast.makeText(context, "Не верные данные или пользователя не существует: " + + userViewModel.apiError, Toast.LENGTH_SHORT).show() + else -> {} } val login = remember { mutableStateOf("") } val password = remember { mutableStateOf("") } - Column( - modifier = Modifier - .fillMaxSize() - .padding(bottom = 8.dp), - verticalArrangement = Arrangement.Bottom - ) { - Image( - painter = painterResource(id = R.drawable.login), - contentDescription = "login", - contentScale = ContentScale.Crop, + if(userViewModel.apiStatus != ApiStatus.LOADING) { + Column( modifier = Modifier - .size(448.dp) - .padding(8.dp) - .align(Alignment.CenterHorizontally)) - PlaceholderInputField(label = "Логин", isSingleLine = true, onTextChanged = {newlogin -> - login.value = newlogin - }) - PasswordInputField(label = "Пароль", onPasswordChanged = {newpassword -> - password.value = newpassword - }) - ActiveButton(label = "Вход", backgroundColor = ButtonColor2, - textColor = Color.White, onClickAction = { - if (login.value.isNotEmpty() && password.value.isNotEmpty()) { - userViewModel.authUser( - User( - login = login.value, - password = password.value, - email = String() + .fillMaxSize() + .padding(bottom = 8.dp), + verticalArrangement = Arrangement.Bottom + ) { + Image( + painter = painterResource(id = R.drawable.login), + contentDescription = "login", + contentScale = ContentScale.Crop, + modifier = Modifier + .size(448.dp) + .padding(8.dp) + .align(Alignment.CenterHorizontally) + ) + PlaceholderInputField( + label = "Логин", + isSingleLine = true, + onTextChanged = { newlogin -> + login.value = newlogin + }) + PasswordInputField(label = "Пароль", onPasswordChanged = { newpassword -> + password.value = newpassword + }) + ActiveButton(label = "Вход", backgroundColor = ButtonColor2, + textColor = Color.White, onClickAction = { + if (login.value.isNotEmpty() && password.value.isNotEmpty()) { + userViewModel.authUser( + User( + login = login.value, + password = password.value, + email = String() + ) ) - ) - } - }) - NavigationButton(navController = navController, destination = "registration", label = "Регистрация", - backgroundColor = ButtonColor1, textColor = Color.Black) + } + }) + NavigationButton( + navController = navController, destination = "registration", label = "Регистрация", + backgroundColor = ButtonColor1, textColor = Color.Black + ) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/mobileapp/screens/EditScreens.kt b/app/src/main/java/com/example/mobileapp/screens/EditScreens.kt index 351dbff..5d5175e 100644 --- a/app/src/main/java/com/example/mobileapp/screens/EditScreens.kt +++ b/app/src/main/java/com/example/mobileapp/screens/EditScreens.kt @@ -6,6 +6,7 @@ import android.graphics.ImageDecoder import android.net.Uri import android.os.Build import android.provider.MediaStore +import android.widget.Toast import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.BorderStroke @@ -44,12 +45,14 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import com.example.mobileapp.GlobalUser import com.example.mobileapp.R +import com.example.mobileapp.api.ApiStatus import com.example.mobileapp.components.ActiveButton import com.example.mobileapp.components.NavigationButton import com.example.mobileapp.components.PlaceholderInputField import com.example.mobileapp.database.entities.Mail import com.example.mobileapp.database.entities.Story import com.example.mobileapp.database.entities.User +import com.example.mobileapp.database.viewmodels.LoadingScreen import com.example.mobileapp.database.viewmodels.MailViewModel import com.example.mobileapp.database.viewmodels.MobileAppViewModelProvider import com.example.mobileapp.database.viewmodels.StoryViewModel @@ -207,6 +210,16 @@ fun EditUserScreen(navController: NavHostController, factory = MobileAppViewModelProvider.Factory )) { val context = LocalContext.current + when(userViewModel.apiStatus){ + ApiStatus.DONE -> { + navController.navigate("settings") + userViewModel.clearStatus() + } + ApiStatus.LOADING -> LoadingScreen(ButtonColor2) + ApiStatus.ERROR -> Toast.makeText(context, "Не удалось обновить данные пользователя: " + + userViewModel.apiError, Toast.LENGTH_SHORT).show() + else -> {} + } var userId = remember { mutableStateOf(0) } val photo = remember { mutableStateOf(BitmapFactory.decodeResource(context.resources, R.drawable.photoplaceholder)) } @@ -241,65 +254,76 @@ fun EditUserScreen(navController: NavHostController, } } - Column( - modifier = Modifier - .fillMaxSize() - .padding(bottom = 8.dp) - .verticalScroll(rememberScrollState()), - verticalArrangement = Arrangement.Bottom - ) { - Box( + if(userViewModel.apiStatus != ApiStatus.LOADING) { + Column( modifier = Modifier - .size(512.dp), - contentAlignment = Alignment.Center + .fillMaxSize() + .padding(bottom = 8.dp) + .verticalScroll(rememberScrollState()), + verticalArrangement = Arrangement.Bottom ) { - Image( - bitmap = photo.value.asImageBitmap(), - contentDescription = "Background Image", - contentScale = ContentScale.Crop, + Box( modifier = Modifier - .size(512.dp) - .blur(12.dp), - colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) })) - Image( - bitmap = photo.value.asImageBitmap(), - contentDescription = "editplaceholder", - contentScale = ContentScale.Crop, - modifier = Modifier - .padding(8.dp) - .clip(CircleShape) - .size(384.dp)) - } - ActiveButton(label = "Выбрать фото", backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = { - launcher.launch("image/*") - }) - PlaceholderInputField(label = "Никнейм", isSingleLine = true, - startValue = login.value, onTextChanged = { newLogin -> - login.value = newLogin - }) - PlaceholderInputField(label = "Пароль", isSingleLine = true, - startValue = password.value, onTextChanged = { newPassword -> - password.value = newPassword - }) - PlaceholderInputField(label = "Почта", isSingleLine = true, - startValue = email.value, onTextChanged = { newEmail -> - email.value = newEmail - }) - ActiveButton(label = "Сохранить", backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = { - userViewModel.updateUser( - User( - id = userId.value, - login = login.value, - password = password.value, - email = email.value, - photo = photo.value + .size(512.dp), + contentAlignment = Alignment.Center + ) { + Image( + bitmap = photo.value.asImageBitmap(), + contentDescription = "Background Image", + contentScale = ContentScale.Crop, + modifier = Modifier + .size(512.dp) + .blur(12.dp), + colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) }) ) - ) - navController.navigate("settings") - }) - ActiveButton(label = "Назад", backgroundColor = ButtonColor2, textColor = Color.White, - onClickAction = { - navController.navigate("settings") - }) + Image( + bitmap = photo.value.asImageBitmap(), + contentDescription = "editplaceholder", + contentScale = ContentScale.Crop, + modifier = Modifier + .padding(8.dp) + .clip(CircleShape) + .size(384.dp) + ) + } + ActiveButton( + label = "Выбрать фото", + backgroundColor = ButtonColor1, + textColor = Color.Black, + onClickAction = { + launcher.launch("image/*") + }) + PlaceholderInputField(label = "Никнейм", isSingleLine = true, + startValue = login.value, onTextChanged = { newLogin -> + login.value = newLogin + }) + PlaceholderInputField(label = "Пароль", isSingleLine = true, + startValue = password.value, onTextChanged = { newPassword -> + password.value = newPassword + }) + PlaceholderInputField(label = "Почта", isSingleLine = true, + startValue = email.value, onTextChanged = { newEmail -> + email.value = newEmail + }) + ActiveButton( + label = "Сохранить", + backgroundColor = ButtonColor1, + textColor = Color.Black, + onClickAction = { + userViewModel.updateUser( + User( + id = userId.value, + login = login.value, + password = password.value, + email = email.value, + photo = photo.value + ) + ) + }) + ActiveButton(label = "Назад", backgroundColor = ButtonColor2, textColor = Color.White, + onClickAction = { + navController.navigate("settings") + }) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/mobileapp/screens/Registration.kt b/app/src/main/java/com/example/mobileapp/screens/Registration.kt index 48c102b..30071c5 100644 --- a/app/src/main/java/com/example/mobileapp/screens/Registration.kt +++ b/app/src/main/java/com/example/mobileapp/screens/Registration.kt @@ -1,5 +1,6 @@ package com.example.mobileapp.screens +import android.widget.Toast import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -13,17 +14,20 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import com.example.mobileapp.GlobalUser import com.example.mobileapp.R +import com.example.mobileapp.api.ApiStatus import com.example.mobileapp.components.ActiveButton import com.example.mobileapp.components.NavigationButton import com.example.mobileapp.components.PasswordInputField import com.example.mobileapp.components.PlaceholderInputField import com.example.mobileapp.database.entities.User +import com.example.mobileapp.database.viewmodels.LoadingScreen import com.example.mobileapp.database.viewmodels.MobileAppViewModelProvider import com.example.mobileapp.database.viewmodels.UserViewModel import com.example.mobileapp.ui.theme.ButtonColor1 @@ -34,11 +38,15 @@ fun Registration(navController: NavHostController, userViewModel: UserViewModel = viewModel( factory = MobileAppViewModelProvider.Factory )) { - val isRegistrated = remember { mutableStateOf(false) } - - if(GlobalUser.getInstance().getUser() != null && !isRegistrated.value) { - isRegistrated.value = !isRegistrated.value - navController.navigate("main") + val context = LocalContext.current + when(userViewModel.apiStatus){ + ApiStatus.DONE -> { + navController.navigate("main") + userViewModel.clearStatus() + } + ApiStatus.LOADING -> LoadingScreen(ButtonColor2) + ApiStatus.ERROR -> Toast.makeText(context, "Не удалось создать пользователя: " + userViewModel.apiError, Toast.LENGTH_SHORT).show() + else -> {} } val login = remember { mutableStateOf("") } @@ -46,45 +54,56 @@ fun Registration(navController: NavHostController, val password = remember { mutableStateOf("") } val repeatepassword = remember { mutableStateOf("") } - Column( - modifier = Modifier - .fillMaxSize() - .padding(bottom = 8.dp), - verticalArrangement = Arrangement.Bottom - ) { - Image( - painter = painterResource(id = R.drawable.registration), - contentDescription = "registration", - contentScale = ContentScale.Crop, + if(userViewModel.apiStatus != ApiStatus.LOADING) { + Column( modifier = Modifier - .size(320.dp) - .padding(8.dp) - .align(Alignment.CenterHorizontally)) - PlaceholderInputField(label = "Логин", isSingleLine = true, onTextChanged = {newlogin -> - login.value = newlogin - }) - PlaceholderInputField(label = "Email", isSingleLine = true, onTextChanged = {newemail -> - email.value = newemail - }) - PasswordInputField(label = "Пароль", onPasswordChanged = {newpassword -> - password.value = newpassword - }) - PasswordInputField(label = "Пароль ещё раз", onPasswordChanged = {newpassword -> - repeatepassword.value = newpassword - }) - ActiveButton(label = "Зарегистрироваться", backgroundColor = ButtonColor2, - textColor = Color.White, onClickAction = { - if (password.value == repeatepassword.value){ - userViewModel.regUser( - User( - login = login.value, - password = password.value, - email = email.value + .fillMaxSize() + .padding(bottom = 8.dp), + verticalArrangement = Arrangement.Bottom + ) { + Image( + painter = painterResource(id = R.drawable.registration), + contentDescription = "registration", + contentScale = ContentScale.Crop, + modifier = Modifier + .size(320.dp) + .padding(8.dp) + .align(Alignment.CenterHorizontally) + ) + PlaceholderInputField( + label = "Логин", + isSingleLine = true, + onTextChanged = { newlogin -> + login.value = newlogin + }) + PlaceholderInputField( + label = "Email", + isSingleLine = true, + onTextChanged = { newemail -> + email.value = newemail + }) + PasswordInputField(label = "Пароль", onPasswordChanged = { newpassword -> + password.value = newpassword + }) + PasswordInputField(label = "Пароль ещё раз", onPasswordChanged = { newpassword -> + repeatepassword.value = newpassword + }) + ActiveButton(label = "Зарегистрироваться", backgroundColor = ButtonColor2, + textColor = Color.White, onClickAction = { + if (password.value == repeatepassword.value) { + userViewModel.regUser( + User( + login = login.value, + password = password.value, + email = email.value + ) ) - ) - } - }) - NavigationButton(navController = navController, destination = "authorization", - label = "Назад", backgroundColor = ButtonColor1, textColor = Color.Black) + } + }) + NavigationButton( + navController = navController, destination = "authorization", + label = "Назад", backgroundColor = ButtonColor1, textColor = Color.Black + ) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/mobileapp/screens/ReportScreen.kt b/app/src/main/java/com/example/mobileapp/screens/ReportScreen.kt index b3bb7ff..72ecd43 100644 --- a/app/src/main/java/com/example/mobileapp/screens/ReportScreen.kt +++ b/app/src/main/java/com/example/mobileapp/screens/ReportScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel @@ -37,6 +38,18 @@ fun ReportScreen( .fillMaxWidth(), verticalArrangement = Arrangement.Center ) { + Column( + modifier = Modifier + .fillMaxWidth(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text(text = "Отчёт по публикациям:", + fontSize = 28.sp, + fontWeight = FontWeight.Bold, + modifier = Modifier + .padding(top = 16.dp, bottom = 16.dp, start = 8.dp, end = 8.dp)) + } if(reportViewModel.report.value == null) { DatePicker(startValue = dateFrom.value, onDateSelected = { newDateFrom -> dateFrom.value = newDateFrom @@ -50,13 +63,9 @@ fun ReportScreen( }) } else{ - Text(text = "Отчёт по публикациям иллюстраций", - fontSize = 28.sp, - fontWeight = FontWeight.Bold, - modifier = Modifier - .padding(8.dp)) Text(text = "Дата с ${dateFormat.format(reportViewModel.report.value?.dateFrom?.let { Date(it) })}", fontSize = 20.sp, + textAlign = TextAlign.Center, fontWeight = FontWeight.Bold, modifier = Modifier .padding(8.dp))