package profiles.presentation import android.net.Uri import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.PickVisualMediaRequest import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState 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.CameraAlt import androidx.compose.material.icons.filled.Check import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.platform.LocalContext import coil.compose.AsyncImage import core.presentation.components.AppAvatar import core.presentation.theme.SoftSquareShape import ru.knot.messager.R import android.app.Activity import android.content.Intent import com.yalantis.ucrop.UCrop import core.utils.ImageCropper import java.io.File import java.util.UUID @OptIn(ExperimentalMaterial3Api::class) @Composable fun EditProfileScreen( currentDisplayName: String?, currentUsername: String, currentBio: String?, currentAvatarUrl: String?, onSave: (displayName: String, bio: String, avatarUri: Uri?) -> Unit, onBack: () -> Unit ) { val context = LocalContext.current var displayName by remember { mutableStateOf(currentDisplayName ?: "") } var bio by remember { mutableStateOf(currentBio ?: "") } var selectedImageUri by remember { mutableStateOf(null) } // Лаунчер для результата кропа val cropLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.StartActivityForResult(), onResult = { result -> if (result.resultCode == Activity.RESULT_OK && result.data != null) { selectedImageUri = UCrop.getOutput(result.data!!) } } ) // Лаунчер для выбора фото из галереи val photoPickerLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.PickVisualMedia(), onResult = { uri -> if (uri != null) { // После выбора фото запускаем UCrop val destinationUri = Uri.fromFile(File(context.cacheDir, "${UUID.randomUUID()}.jpg")) val cropIntent = ImageCropper.getCropIntent(context, uri, destinationUri).getIntent(context) cropLauncher.launch(cropIntent) } } ) Scaffold( topBar = { TopAppBar( title = { Text(stringResource(R.string.edit_profile)) }, 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) } } ) } ) { paddingValues -> Column( modifier = Modifier .fillMaxSize() .padding(paddingValues) .verticalScroll(rememberScrollState()) .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { // Смена фото Box( modifier = Modifier .size(120.dp) .clip(SoftSquareShape) .background(MaterialTheme.colorScheme.surfaceVariant) .clickable { photoPickerLauncher.launch( PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly) ) }, contentAlignment = Alignment.Center ) { if (selectedImageUri != null) { AsyncImage( model = selectedImageUri, contentDescription = null, modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Crop ) } else { AppAvatar( url = currentAvatarUrl, name = currentUsername, size = 120.dp ) } // Overlay Box( modifier = Modifier .fillMaxSize() .background(Color.Black.copy(alpha = 0.3f)), contentAlignment = Alignment.Center ) { Icon( Icons.Default.CameraAlt, contentDescription = stringResource(R.string.change_photo), tint = Color.White ) } } TextButton( onClick = { photoPickerLauncher.launch( PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly) ) }, modifier = Modifier.padding(top = 8.dp) ) { Text(stringResource(R.string.change_photo)) } Spacer(modifier = Modifier.height(32.dp)) // Поля ввода OutlinedTextField( value = displayName, onValueChange = { displayName = it }, label = { Text(stringResource(R.string.display_name)) }, modifier = Modifier.fillMaxWidth(), singleLine = true, shape = SoftSquareShape ) Spacer(modifier = Modifier.height(16.dp)) OutlinedTextField( value = "@$currentUsername", onValueChange = {}, label = { Text(stringResource(R.string.username_label)) }, modifier = Modifier.fillMaxWidth(), enabled = false, // Обычно username меняется отдельно или вообще не меняется shape = SoftSquareShape, colors = OutlinedTextFieldDefaults.colors( disabledBorderColor = MaterialTheme.colorScheme.outlineVariant, disabledLabelColor = MaterialTheme.colorScheme.onSurfaceVariant ) ) Spacer(modifier = Modifier.height(16.dp)) OutlinedTextField( value = bio, onValueChange = { bio = it }, label = { Text(stringResource(R.string.bio)) }, modifier = Modifier .fillMaxWidth() .heightIn(min = 100.dp), shape = SoftSquareShape, maxLines = 5 ) Spacer(modifier = Modifier.height(32.dp)) Button( onClick = { onSave(displayName, bio, selectedImageUri) }, modifier = Modifier.fillMaxWidth(), shape = SoftSquareShape ) { Text(stringResource(R.string.save)) } } } }