|
@@ -1,7 +1,15 @@
|
|
package com.example.mystictale.Screen
|
|
package com.example.mystictale.Screen
|
|
|
|
|
|
|
|
+import android.content.Context
|
|
|
|
+import android.graphics.Bitmap
|
|
|
|
+import android.graphics.BitmapFactory
|
|
|
|
+import android.net.Uri
|
|
|
|
+import android.os.Build
|
|
|
|
+import android.widget.Toast
|
|
|
|
+import androidx.activity.compose.rememberLauncherForActivityResult
|
|
|
|
+import androidx.activity.result.contract.ActivityResultContracts
|
|
|
|
+import androidx.annotation.RequiresApi
|
|
import androidx.compose.animation.AnimatedVisibility
|
|
import androidx.compose.animation.AnimatedVisibility
|
|
-import androidx.compose.foundation.Image
|
|
|
|
import androidx.compose.foundation.clickable
|
|
import androidx.compose.foundation.clickable
|
|
import androidx.compose.foundation.gestures.detectTapGestures
|
|
import androidx.compose.foundation.gestures.detectTapGestures
|
|
import androidx.compose.foundation.layout.Arrangement
|
|
import androidx.compose.foundation.layout.Arrangement
|
|
@@ -17,9 +25,11 @@ import androidx.compose.foundation.layout.width
|
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
import androidx.compose.material3.Button
|
|
import androidx.compose.material3.Button
|
|
import androidx.compose.material3.ButtonColors
|
|
import androidx.compose.material3.ButtonColors
|
|
|
|
+import androidx.compose.material3.CircularProgressIndicator
|
|
import androidx.compose.material3.Icon
|
|
import androidx.compose.material3.Icon
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.Composable
|
|
|
|
+import androidx.compose.runtime.derivedStateOf
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.runtime.mutableStateOf
|
|
import androidx.compose.runtime.mutableStateOf
|
|
import androidx.compose.runtime.remember
|
|
import androidx.compose.runtime.remember
|
|
@@ -27,8 +37,11 @@ import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.draw.paint
|
|
import androidx.compose.ui.draw.paint
|
|
import androidx.compose.ui.graphics.Color
|
|
import androidx.compose.ui.graphics.Color
|
|
|
|
+import androidx.compose.ui.graphics.ImageBitmap
|
|
|
|
+import androidx.compose.ui.graphics.asImageBitmap
|
|
import androidx.compose.ui.input.pointer.pointerInput
|
|
import androidx.compose.ui.input.pointer.pointerInput
|
|
import androidx.compose.ui.layout.ContentScale
|
|
import androidx.compose.ui.layout.ContentScale
|
|
|
|
+import androidx.compose.ui.platform.LocalContext
|
|
import androidx.compose.ui.platform.LocalFocusManager
|
|
import androidx.compose.ui.platform.LocalFocusManager
|
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
|
import androidx.compose.ui.res.painterResource
|
|
import androidx.compose.ui.res.painterResource
|
|
@@ -37,43 +50,101 @@ import androidx.compose.ui.text.input.KeyboardType
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.compose.ui.unit.sp
|
|
import androidx.compose.ui.unit.sp
|
|
import androidx.navigation.NavController
|
|
import androidx.navigation.NavController
|
|
|
|
+import coil.compose.AsyncImagePainter
|
|
|
|
+import coil.compose.rememberAsyncImagePainter
|
|
|
|
+import coil.request.ImageRequest
|
|
import com.example.mystictale.R
|
|
import com.example.mystictale.R
|
|
import com.example.mystictale.ViewModels.AuthViewModel
|
|
import com.example.mystictale.ViewModels.AuthViewModel
|
|
|
|
+import com.example.mystictale.models.UserState
|
|
import com.example.mystictale.resources.components.ChooseGenderForProfile
|
|
import com.example.mystictale.resources.components.ChooseGenderForProfile
|
|
|
|
+import com.example.mystictale.resources.components.ImageForBitmap
|
|
|
|
+import com.example.mystictale.resources.components.ImagePainter
|
|
import com.example.mystictale.resources.components.Loading
|
|
import com.example.mystictale.resources.components.Loading
|
|
import com.example.mystictale.resources.components.ProfileTextField
|
|
import com.example.mystictale.resources.components.ProfileTextField
|
|
|
|
+import com.example.mystictale.resources.components.dateComponents.DateOfBirthTextFieldForProfile
|
|
|
|
+import com.example.mystictale.resources.components.dateComponents.FormattingDateForDatabase
|
|
|
|
+import com.example.mystictale.resources.components.dateComponents.FormattingDateForProfile
|
|
|
|
+import com.example.mystictale.resources.components.dateComponents.ValidationDate
|
|
|
|
+import com.example.mystictale.resources.components.dateComponents.isDateValid
|
|
import com.example.mystictale.ui.theme.DarkPurple
|
|
import com.example.mystictale.ui.theme.DarkPurple
|
|
import com.example.mystictale.ui.theme.Grey
|
|
import com.example.mystictale.ui.theme.Grey
|
|
import com.example.mystictale.ui.theme.OpenSans
|
|
import com.example.mystictale.ui.theme.OpenSans
|
|
|
|
+import com.vanpra.composematerialdialogs.MaterialDialog
|
|
|
|
+import com.vanpra.composematerialdialogs.datetime.date.datepicker
|
|
|
|
+import com.vanpra.composematerialdialogs.rememberMaterialDialogState
|
|
|
|
+import java.io.ByteArrayOutputStream
|
|
|
|
+import java.text.SimpleDateFormat
|
|
|
|
+import java.time.LocalDate
|
|
|
|
+import java.time.ZoneId
|
|
|
|
+import java.time.format.DateTimeFormatter
|
|
|
|
+import java.util.Locale
|
|
|
|
|
|
|
|
+@RequiresApi(Build.VERSION_CODES.O)
|
|
@Composable
|
|
@Composable
|
|
fun Profile(navController: NavController, viewModel: AuthViewModel) {
|
|
fun Profile(navController: NavController, viewModel: AuthViewModel) {
|
|
|
|
|
|
val user by viewModel.user
|
|
val user by viewModel.user
|
|
|
|
+ val userState by viewModel.userState
|
|
val focusManager = LocalFocusManager.current
|
|
val focusManager = LocalFocusManager.current
|
|
|
|
+ val context = LocalContext.current
|
|
val keyboardController = LocalSoftwareKeyboardController.current
|
|
val keyboardController = LocalSoftwareKeyboardController.current
|
|
val isEnabled = remember { mutableStateOf(false) }
|
|
val isEnabled = remember { mutableStateOf(false) }
|
|
val flagName = remember { mutableStateOf(false) }
|
|
val flagName = remember { mutableStateOf(false) }
|
|
val flag = remember { mutableStateOf(true) }
|
|
val flag = remember { mutableStateOf(true) }
|
|
|
|
+ val flag1 = remember { mutableStateOf(false) }
|
|
|
|
+ val flag2 = remember { mutableStateOf(false) }
|
|
|
|
+ val nameFlag = remember { mutableStateOf(false) }
|
|
|
|
+ val dateOfBirthFlag = remember { mutableStateOf(false) }
|
|
|
|
+
|
|
|
|
+ val dateDialogState = rememberMaterialDialogState()
|
|
|
|
+
|
|
|
|
+
|
|
if (flag.value) {
|
|
if (flag.value) {
|
|
viewModel.selectProfile()
|
|
viewModel.selectProfile()
|
|
flag.value = false
|
|
flag.value = false
|
|
}
|
|
}
|
|
if (user.isNotEmpty()) {
|
|
if (user.isNotEmpty()) {
|
|
-
|
|
|
|
-
|
|
|
|
- viewModel.name = user.last().name
|
|
|
|
- viewModel.dateOfBirth = user.last().date_of_birth
|
|
|
|
- viewModel.gender = user.last().id_gender
|
|
|
|
|
|
+ val newAvatar = remember { mutableStateOf(byteArrayOf()) }
|
|
|
|
+ val avatarFrombase = rememberAsyncImagePainter(
|
|
|
|
+ model = ImageRequest.Builder(LocalContext.current).data(user.last().avatar)
|
|
|
|
+ .size(100, 100).build()
|
|
|
|
+ ).state
|
|
|
|
+ val newAvatarBitmap = remember { mutableStateOf<ImageBitmap?>(null) }
|
|
|
|
+ val name = remember { mutableStateOf(user.last().name) }
|
|
|
|
+ val dateOfBirth =
|
|
|
|
+ remember { mutableStateOf(FormattingDateForProfile(user.last().date_of_birth)) }
|
|
|
|
+ val formatForScreen = SimpleDateFormat("ddMMyyyy", Locale.getDefault())
|
|
|
|
+ val formatter = DateTimeFormatter.ofPattern("ddMMyyyy")
|
|
|
|
+ val date =
|
|
|
|
+ FormattingDateForProfile(user.last().date_of_birth)!!.let { formatForScreen.parse(it) }
|
|
|
|
+ val dateForDatePicker = remember {
|
|
|
|
+ mutableStateOf(
|
|
|
|
+ date!!.toInstant()
|
|
|
|
+ .atZone(ZoneId.systemDefault())
|
|
|
|
+ .toLocalDate()
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+ val formattedDate by remember {
|
|
|
|
+ derivedStateOf {
|
|
|
|
+ DateTimeFormatter.ofPattern("ddMMyyyy").format(dateForDatePicker.value)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ val dateForBase = FormattingDateForDatabase(dateOfBirth.value!!)
|
|
val gender = remember {
|
|
val gender = remember {
|
|
mutableStateOf(
|
|
mutableStateOf(
|
|
- if (viewModel.gender == 1) {
|
|
|
|
|
|
+ if (user.last().id_gender == 1) {
|
|
"Женский"
|
|
"Женский"
|
|
} else {
|
|
} else {
|
|
"Мужской"
|
|
"Мужской"
|
|
}
|
|
}
|
|
)
|
|
)
|
|
}
|
|
}
|
|
|
|
+ val launcher =
|
|
|
|
+ rememberLauncherForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
|
|
|
|
+ if (uri == null) return@rememberLauncherForActivityResult
|
|
|
|
+ newAvatar.value = bitmapToByteArray(context, uri)
|
|
|
|
+
|
|
|
|
+ }
|
|
Column(
|
|
Column(
|
|
Modifier
|
|
Modifier
|
|
.fillMaxSize()
|
|
.fillMaxSize()
|
|
@@ -88,7 +159,7 @@ fun Profile(navController: NavController, viewModel: AuthViewModel) {
|
|
})
|
|
})
|
|
}
|
|
}
|
|
.padding(10.dp)
|
|
.padding(10.dp)
|
|
- .padding(top = 40.dp),
|
|
|
|
|
|
+ .padding(top = 50.dp),
|
|
verticalArrangement = Arrangement.Top,
|
|
verticalArrangement = Arrangement.Top,
|
|
horizontalAlignment = Alignment.CenterHorizontally
|
|
horizontalAlignment = Alignment.CenterHorizontally
|
|
) {
|
|
) {
|
|
@@ -114,14 +185,15 @@ fun Profile(navController: NavController, viewModel: AuthViewModel) {
|
|
Icon(
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.update),
|
|
painter = painterResource(id = R.drawable.update),
|
|
contentDescription = "update your profile",
|
|
contentDescription = "update your profile",
|
|
- tint = Grey,
|
|
|
|
|
|
+ tint = if (!isEnabled.value) Grey else Color.Transparent,
|
|
|
|
+
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
.padding(end = 5.dp)
|
|
.padding(end = 5.dp)
|
|
.height(21.dp)
|
|
.height(21.dp)
|
|
.width(21.dp)
|
|
.width(21.dp)
|
|
.clickable {
|
|
.clickable {
|
|
- isEnabled.value = !isEnabled.value
|
|
|
|
if (!isEnabled.value) {
|
|
if (!isEnabled.value) {
|
|
|
|
+ isEnabled.value = !isEnabled.value
|
|
if (viewModel.gender == 1) {
|
|
if (viewModel.gender == 1) {
|
|
gender.value = "Женский"
|
|
gender.value = "Женский"
|
|
} else {
|
|
} else {
|
|
@@ -129,12 +201,56 @@ fun Profile(navController: NavController, viewModel: AuthViewModel) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Spacer(modifier = Modifier.height(20.dp))
|
|
Spacer(modifier = Modifier.height(20.dp))
|
|
- Image(painter = painterResource(id = R.drawable.girl), contentDescription = "")
|
|
|
|
- Spacer(modifier = Modifier.height(20.dp))
|
|
|
|
|
|
+ if (newAvatar.value.isEmpty()) {
|
|
|
|
+ if (avatarFrombase is AsyncImagePainter.State.Success) {
|
|
|
|
+ ImagePainter(
|
|
|
|
+ isEnabled = isEnabled.value,
|
|
|
|
+ image = avatarFrombase.painter,
|
|
|
|
+ launcher = launcher
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+ if (avatarFrombase is AsyncImagePainter.State.Loading) {
|
|
|
|
+ Box(
|
|
|
|
+ modifier = Modifier
|
|
|
|
+ .fillMaxWidth()
|
|
|
|
+ .height(200.dp),
|
|
|
|
+ contentAlignment = Alignment.Center
|
|
|
|
+ ) {
|
|
|
|
+ CircularProgressIndicator()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (avatarFrombase is AsyncImagePainter.State.Error) {
|
|
|
|
+
|
|
|
|
+ if (user.last().id_gender == 1) {
|
|
|
|
+ ImagePainter(
|
|
|
|
+ isEnabled = isEnabled.value,
|
|
|
|
+ image = painterResource(R.drawable.girl),
|
|
|
|
+ launcher = launcher
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ ImagePainter(
|
|
|
|
+ isEnabled = isEnabled.value,
|
|
|
|
+ image = painterResource(R.drawable.girl),
|
|
|
|
+ launcher = launcher
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ newAvatarBitmap.value = ByteArrayImage(newAvatar.value)
|
|
|
|
+ ImageForBitmap(
|
|
|
|
+ isEnabled = isEnabled.value,
|
|
|
|
+ image = newAvatarBitmap.value!!,
|
|
|
|
+ launcher = launcher
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ Spacer(modifier = Modifier.height(10.dp))
|
|
Column(
|
|
Column(
|
|
Modifier
|
|
Modifier
|
|
.fillMaxWidth()
|
|
.fillMaxWidth()
|
|
@@ -147,16 +263,29 @@ fun Profile(navController: NavController, viewModel: AuthViewModel) {
|
|
fontSize = 14.sp,
|
|
fontSize = 14.sp,
|
|
color = Grey
|
|
color = Grey
|
|
)
|
|
)
|
|
- Spacer(modifier = Modifier.height(10.dp))
|
|
|
|
|
|
+ Spacer(modifier = Modifier.height(5.dp))
|
|
ProfileTextField(
|
|
ProfileTextField(
|
|
- value = viewModel.name!!,
|
|
|
|
- onValue = { viewModel.name = it }, placeholder = "Имя",
|
|
|
|
|
|
+ value = name.value,
|
|
|
|
+ onValue = {
|
|
|
|
+ name.value = it
|
|
|
|
+ nameFlag.value = false
|
|
|
|
+ }, placeholder = "Имя",
|
|
keyboardType = KeyboardType.Text,
|
|
keyboardType = KeyboardType.Text,
|
|
isEnable = isEnabled.value,
|
|
isEnable = isEnabled.value,
|
|
- flag = flagName.value
|
|
|
|
|
|
+ flag = flagName.value,
|
|
|
|
+ date = false
|
|
)
|
|
)
|
|
|
|
+ if (nameFlag.value) {
|
|
|
|
+ Text(
|
|
|
|
+ "Введите имя",
|
|
|
|
+ fontWeight = FontWeight.Light,
|
|
|
|
+ fontFamily = OpenSans,
|
|
|
|
+ fontSize = 13.sp,
|
|
|
|
+ color = Color.Red
|
|
|
|
+ )
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- Spacer(modifier = Modifier.height(15.dp))
|
|
|
|
|
|
+ Spacer(modifier = Modifier.height(10.dp))
|
|
Column(
|
|
Column(
|
|
Modifier
|
|
Modifier
|
|
.fillMaxWidth()
|
|
.fillMaxWidth()
|
|
@@ -169,17 +298,56 @@ fun Profile(navController: NavController, viewModel: AuthViewModel) {
|
|
fontSize = 14.sp,
|
|
fontSize = 14.sp,
|
|
color = Grey
|
|
color = Grey
|
|
)
|
|
)
|
|
- Spacer(modifier = Modifier.height(10.dp))
|
|
|
|
- ProfileTextField(
|
|
|
|
- value = viewModel.dateOfBirth!!,
|
|
|
|
- onValue = { viewModel.dateOfBirth = it },
|
|
|
|
- placeholder = "Дата рождения",
|
|
|
|
- keyboardType = KeyboardType.Text,
|
|
|
|
- isEnable = isEnabled.value,
|
|
|
|
- flag = flagName.value
|
|
|
|
|
|
+ Spacer(modifier = Modifier.height(5.dp))
|
|
|
|
+
|
|
|
|
+ DateOfBirthTextFieldForProfile(
|
|
|
|
+ dateOfBirth = dateOfBirth.value!!,
|
|
|
|
+ onValue = { dob ->
|
|
|
|
+ dateOfBirth.value = dob.filter { it.isDigit() }.take(8)
|
|
|
|
+ dateOfBirthFlag.value = false
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ dateDialogState = dateDialogState,
|
|
|
|
+ flag = dateOfBirthFlag.value,
|
|
|
|
+ enabled = isEnabled.value
|
|
)
|
|
)
|
|
|
|
+ if (dateOfBirthFlag.value) {
|
|
|
|
+ if (dateOfBirth.value!!.isEmpty()) {
|
|
|
|
+ Text(
|
|
|
|
+ "Введите дату рождения",
|
|
|
|
+ fontWeight = FontWeight.Light,
|
|
|
|
+ fontFamily = OpenSans,
|
|
|
|
+ fontSize = 13.sp,
|
|
|
|
+ color = Color.Red
|
|
|
|
+ )
|
|
|
|
+ } else if (dateOfBirth.value!!.length < 8) {
|
|
|
|
+ Text(
|
|
|
|
+ "Неверная дата рождения",
|
|
|
|
+ fontWeight = FontWeight.Light,
|
|
|
|
+ fontFamily = OpenSans,
|
|
|
|
+ fontSize = 13.sp,
|
|
|
|
+ color = Color.Red
|
|
|
|
+ )
|
|
|
|
+ } else if (!isDateValid(dateOfBirth.value!!)) {
|
|
|
|
+ Text(
|
|
|
|
+ "Неверная дата рождения",
|
|
|
|
+ fontWeight = FontWeight.Light,
|
|
|
|
+ fontFamily = OpenSans,
|
|
|
|
+ fontSize = 13.sp,
|
|
|
|
+ color = Color.Red
|
|
|
|
+ )
|
|
|
|
+ } else if (LocalDate.parse(dateOfBirth.value, formatter) > LocalDate.now()) {
|
|
|
|
+ Text(
|
|
|
|
+ "Неверная дата рождения",
|
|
|
|
+ fontWeight = FontWeight.Light,
|
|
|
|
+ fontFamily = OpenSans,
|
|
|
|
+ fontSize = 13.sp,
|
|
|
|
+ color = Color.Red
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- Spacer(modifier = Modifier.height(15.dp))
|
|
|
|
|
|
+ Spacer(modifier = Modifier.height(5.dp))
|
|
Column(
|
|
Column(
|
|
Modifier
|
|
Modifier
|
|
.fillMaxWidth()
|
|
.fillMaxWidth()
|
|
@@ -192,24 +360,44 @@ fun Profile(navController: NavController, viewModel: AuthViewModel) {
|
|
fontSize = 14.sp,
|
|
fontSize = 14.sp,
|
|
color = Grey
|
|
color = Grey
|
|
)
|
|
)
|
|
- Spacer(modifier = Modifier.height(10.dp))
|
|
|
|
- if (isEnabled.value) {
|
|
|
|
- ChooseGenderForProfile(viewModel = viewModel, gender = gender.value)
|
|
|
|
- } else {
|
|
|
|
- ProfileTextField(
|
|
|
|
- value = gender.value,
|
|
|
|
- onValue = { gender.value = it },
|
|
|
|
- placeholder = "Дата рождения",
|
|
|
|
- keyboardType = KeyboardType.Text,
|
|
|
|
- isEnable = isEnabled.value,
|
|
|
|
- flag = flagName.value
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
|
|
+ Spacer(modifier = Modifier.height(5.dp))
|
|
|
|
+
|
|
|
|
+ ChooseGenderForProfile(
|
|
|
|
+ viewModel = viewModel,
|
|
|
|
+ gender = gender.value,
|
|
|
|
+ isEnabled = isEnabled.value
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
AnimatedVisibility(visible = isEnabled.value, Modifier.padding(40.dp)) {
|
|
AnimatedVisibility(visible = isEnabled.value, Modifier.padding(40.dp)) {
|
|
Button(
|
|
Button(
|
|
onClick = {
|
|
onClick = {
|
|
|
|
+ if (ValidationDate(
|
|
|
|
+ dateOfBirth.value!!,
|
|
|
|
+ formatter
|
|
|
|
+ ) || name.value.isEmpty()
|
|
|
|
+ ) {
|
|
|
|
+ if (ValidationDate(dateOfBirth.value!!, formatter)) {
|
|
|
|
+ dateOfBirthFlag.value = true
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ if (name.value.isEmpty()) {
|
|
|
|
+ nameFlag.value = true
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ viewModel.name = name.value
|
|
|
|
+ viewModel.dateOfBirth = dateForBase
|
|
|
|
+ viewModel.gender = if (gender.value == "Женский") {
|
|
|
|
+ 1
|
|
|
|
+ } else {
|
|
|
|
+ 2
|
|
|
|
+ }
|
|
|
|
+ viewModel.addAvatar(newAvatar.value)
|
|
|
|
+ flag1.value = true
|
|
|
|
+ }
|
|
|
|
+
|
|
},
|
|
},
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.fillMaxWidth()
|
|
@@ -223,13 +411,33 @@ fun Profile(navController: NavController, viewModel: AuthViewModel) {
|
|
disabledContainerColor = DarkPurple
|
|
disabledContainerColor = DarkPurple
|
|
)
|
|
)
|
|
) {
|
|
) {
|
|
- Text("Далее", fontSize = 20.sp, fontWeight = FontWeight.Bold)
|
|
|
|
|
|
+ Text("Сохранить", fontSize = 20.sp, fontWeight = FontWeight.Bold)
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
+ MaterialDialog(
|
|
|
|
+ dialogState = dateDialogState,
|
|
|
|
+ buttons = {
|
|
|
|
+ positiveButton(text = "Ok")
|
|
|
|
+ negativeButton("cancel")
|
|
|
|
+ })
|
|
|
|
+ {
|
|
|
|
+ datepicker(
|
|
|
|
+ initialDate = dateForDatePicker.value,
|
|
|
|
+ allowedDateValidator = {
|
|
|
|
+ it <= LocalDate.now()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ ) {
|
|
|
|
+ dateForDatePicker.value = it
|
|
|
|
+ dateOfBirth.value = formattedDate.toString()
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
Box(
|
|
Box(
|
|
Modifier
|
|
Modifier
|
|
@@ -242,5 +450,89 @@ fun Profile(navController: NavController, viewModel: AuthViewModel) {
|
|
Loading()
|
|
Loading()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ if (flag1.value) {
|
|
|
|
+ when (userState) {
|
|
|
|
+ is UserState.Loading -> {
|
|
|
|
+ Loading()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ is UserState.Success -> {
|
|
|
|
+ val message = (userState as UserState.Success).message
|
|
|
|
+ viewModel.updateProfile()
|
|
|
|
+ flag1.value = false
|
|
|
|
+ flag2.value = true
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ is UserState.Error -> {
|
|
|
|
+ val message = (userState as UserState.Error).message
|
|
|
|
+ Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
|
|
|
+ flag1.value = false
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (flag2.value) {
|
|
|
|
+ when (userState) {
|
|
|
|
+ is UserState.Loading -> {
|
|
|
|
+ Loading()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ is UserState.Success -> {
|
|
|
|
+ Toast.makeText(context, "Изменения сохранены", Toast.LENGTH_SHORT).show()
|
|
|
|
+ isEnabled.value = false
|
|
|
|
+ flag2.value = false
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ is UserState.Error -> {
|
|
|
|
+ val message = (userState as UserState.Error).message
|
|
|
|
+ Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
|
|
|
+ flag2.value = false
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+fun bitmapToByteArray(context: Context, uri: Uri): ByteArray {
|
|
|
|
+ val inputStream = context.contentResolver.openInputStream(uri)
|
|
|
|
+ val bitmap = BitmapFactory.decodeStream(inputStream)
|
|
|
|
+ val baos = ByteArrayOutputStream()
|
|
|
|
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos)
|
|
|
|
+ return baos.toByteArray()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+fun ByteArrayImage(byteArray: ByteArray): ImageBitmap {
|
|
|
|
+ // Конвертируем массив байтов в Bitmap с уменьшением масштаба
|
|
|
|
+ val options = BitmapFactory.Options().apply {
|
|
|
|
+ inJustDecodeBounds = true // Сначала считываем только размеры изображения
|
|
|
|
+ }
|
|
|
|
+ BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size, options)
|
|
|
|
+
|
|
|
|
+ // Рассчитываем inSampleSize для уменьшения изображения
|
|
|
|
+ options.inSampleSize = calculateInSampleSize(options, reqWidth = 300, reqHeight = 200)
|
|
|
|
+ options.inJustDecodeBounds = false // Теперь декодируем само изображение
|
|
|
|
+
|
|
|
|
+ // Декодируем уменьшенное изображение
|
|
|
|
+ val bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size, options)
|
|
|
|
+
|
|
|
|
+ // Преобразуем Bitmap в ImageBitmap
|
|
|
|
+ return bitmap.asImageBitmap()
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
|
|
|
|
+ val (height: Int, width: Int) = options.outHeight to options.outWidth
|
|
|
|
+ var inSampleSize = 1
|
|
|
|
+
|
|
|
|
+ if (height > reqHeight || width > reqWidth) {
|
|
|
|
+ val halfHeight: Int = height / 2
|
|
|
|
+ val halfWidth: Int = width / 2
|
|
|
|
+
|
|
|
|
+ while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) {
|
|
|
|
+ inSampleSize *= 2
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return inSampleSize
|
|
}
|
|
}
|