Профиль, редактирование без аватара
This commit is contained in:
@@ -12,8 +12,10 @@ import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.CalendarToday
|
||||
import androidx.compose.material.icons.filled.CameraAlt
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.Clear
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -30,6 +32,10 @@ import core.presentation.components.AppAvatar
|
||||
import core.presentation.theme.SoftSquareShape
|
||||
import ru.knot.messager.R
|
||||
|
||||
import android.app.DatePickerDialog
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import com.yalantis.ucrop.UCrop
|
||||
@@ -43,14 +49,62 @@ fun EditProfileScreen(
|
||||
currentDisplayName: String?,
|
||||
currentUsername: String,
|
||||
currentBio: String?,
|
||||
currentBirthday: String?,
|
||||
currentAvatarUrl: String?,
|
||||
onSave: (displayName: String, bio: String, avatarUri: Uri?) -> Unit,
|
||||
isSaving: Boolean = false,
|
||||
error: String? = null,
|
||||
onSave: (displayName: String, bio: String, birthday: String?, avatarUri: Uri?) -> Unit,
|
||||
onBack: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
var displayName by remember { mutableStateOf(currentDisplayName ?: "") }
|
||||
var bio by remember { mutableStateOf(currentBio ?: "") }
|
||||
var displayName by remember(currentDisplayName) { mutableStateOf(currentDisplayName ?: "") }
|
||||
var bio by remember(currentBio) { mutableStateOf(currentBio ?: "") }
|
||||
var birthday by remember(currentBirthday) { mutableStateOf(currentBirthday ?: "") }
|
||||
var selectedImageUri by remember { mutableStateOf<Uri?>(null) }
|
||||
var showDatePicker by remember { mutableStateOf(false) }
|
||||
|
||||
// Парсим текущую дату для инициализации DatePicker и отображения
|
||||
val calendar = Calendar.getInstance()
|
||||
var formattedBirthday by remember { mutableStateOf("") }
|
||||
|
||||
if (birthday.isNotEmpty()) {
|
||||
try {
|
||||
// Пробуем распарсить ISO8601 формат (yyyy-MM-dd или yyyy-MM-ddTHH:mm:ss)
|
||||
val format = when {
|
||||
birthday.contains("T") -> SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault())
|
||||
birthday.length == 10 -> SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||
else -> SimpleDateFormat("dd.MM.yyyy", Locale.getDefault())
|
||||
}
|
||||
format.parse(birthday)?.let {
|
||||
calendar.time = it
|
||||
// Форматируем для отображения: ДД.ММ.ГГГГ
|
||||
formattedBirthday = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault()).format(it)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
formattedBirthday = birthday
|
||||
}
|
||||
}
|
||||
|
||||
// DatePickerDialog
|
||||
if (showDatePicker) {
|
||||
DatePickerDialog(
|
||||
context,
|
||||
{ _, year, month, dayOfMonth ->
|
||||
val selectedCalendar = Calendar.getInstance()
|
||||
selectedCalendar.set(year, month, dayOfMonth)
|
||||
// Используем ISO8601 формат для отправки на сервер
|
||||
val format = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||
birthday = format.format(selectedCalendar.time)
|
||||
},
|
||||
calendar.get(Calendar.YEAR),
|
||||
calendar.get(Calendar.MONTH),
|
||||
calendar.get(Calendar.DAY_OF_MONTH)
|
||||
).apply {
|
||||
datePicker.maxDate = System.currentTimeMillis()
|
||||
show()
|
||||
}
|
||||
showDatePicker = false
|
||||
}
|
||||
|
||||
// Лаунчер для результата кропа
|
||||
val cropLauncher = rememberLauncherForActivityResult(
|
||||
@@ -78,17 +132,28 @@ fun EditProfileScreen(
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(R.string.edit_profile)) },
|
||||
title = { Text(stringResource(R.string.edit_profile), fontWeight = FontWeight.Bold) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onBack) {
|
||||
Icon(Icons.Default.ArrowBack, contentDescription = stringResource(R.string.back))
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
IconButton(onClick = { onSave(displayName, bio, selectedImageUri) }) {
|
||||
Icon(Icons.Default.Check, contentDescription = stringResource(R.string.save), tint = MaterialTheme.colorScheme.primary)
|
||||
TextButton(
|
||||
onClick = { onSave(displayName, bio, birthday, selectedImageUri) },
|
||||
enabled = !isSaving
|
||||
) {
|
||||
Text(
|
||||
if (isSaving) stringResource(R.string.saving) else stringResource(R.string.save),
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = if (isSaving) Color.Gray else MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = Color.Transparent,
|
||||
titleContentColor = Color.White
|
||||
)
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
@@ -132,13 +197,14 @@ fun EditProfileScreen(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color.Black.copy(alpha = 0.3f)),
|
||||
.background(Color.Black.copy(alpha = 0.4f)),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.CameraAlt,
|
||||
contentDescription = stringResource(R.string.change_photo),
|
||||
tint = Color.White
|
||||
tint = Color.White.copy(alpha = 0.8f),
|
||||
modifier = Modifier.size(28.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -194,14 +260,65 @@ fun EditProfileScreen(
|
||||
maxLines = 5
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = formattedBirthday,
|
||||
onValueChange = { },
|
||||
label = { Text("Дата рождения") },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
singleLine = true,
|
||||
shape = SoftSquareShape,
|
||||
placeholder = { Text("ДД.ММ.ГГГГ") },
|
||||
trailingIcon = {
|
||||
Row {
|
||||
if (birthday.isNotEmpty()) {
|
||||
IconButton(onClick = { birthday = "" }) {
|
||||
Icon(
|
||||
Icons.Default.Clear,
|
||||
contentDescription = "Очистить",
|
||||
tint = Color.Gray
|
||||
)
|
||||
}
|
||||
}
|
||||
IconButton(onClick = { showDatePicker = true }) {
|
||||
Icon(
|
||||
Icons.Default.CalendarToday,
|
||||
contentDescription = "Выбрать дату",
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
if (error != null) {
|
||||
Text(
|
||||
text = error,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
modifier = Modifier.padding(top = 8.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
|
||||
Button(
|
||||
onClick = { onSave(displayName, bio, selectedImageUri) },
|
||||
onClick = { onSave(displayName, bio, birthday, selectedImageUri) },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = SoftSquareShape
|
||||
shape = SoftSquareShape,
|
||||
enabled = !isSaving
|
||||
) {
|
||||
Text(stringResource(R.string.save))
|
||||
if (isSaving) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(24.dp),
|
||||
color = Color.White,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(stringResource(R.string.saving))
|
||||
} else {
|
||||
Text(stringResource(R.string.save))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user