feat: Add profile photo menu and avatar menu functionality in ProfileScreen

This commit is contained in:
k1ngsterr1
2026-01-22 18:17:31 +05:00
parent ad69af9fd3
commit 5cd6968b06
2 changed files with 111 additions and 2 deletions

View File

@@ -741,3 +741,69 @@ private fun KebabMenuItem(
contentPadding = PaddingValues(horizontal = 12.dp, vertical = 12.dp)
)
}
/** Profile photo menu for avatar */
@Composable
fun ProfilePhotoMenu(
expanded: Boolean,
onDismiss: () -> Unit,
isDarkTheme: Boolean,
onSetPhotoClick: () -> Unit
) {
DropdownMenu(
expanded = expanded,
onDismissRequest = onDismiss,
modifier = Modifier.width(220.dp),
properties = PopupProperties(
focusable = true,
dismissOnBackPress = true,
dismissOnClickOutside = true
)
) {
ProfilePhotoMenuItem(
icon = Icons.Default.AddAPhoto,
text = "Set Profile Photo",
onClick = onSetPhotoClick,
tintColor = PrimaryBlue,
textColor = if (isDarkTheme) Color.White else Color.Black
)
}
}
@Composable
private fun ProfilePhotoMenuItem(
icon: ImageVector,
text: String,
onClick: () -> Unit,
tintColor: Color,
textColor: Color
) {
val interactionSource = remember { MutableInteractionSource() }
DropdownMenuItem(
text = {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Icon(
imageVector = icon,
contentDescription = null,
tint = tintColor,
modifier = Modifier.size(24.dp)
)
Spacer(modifier = Modifier.width(14.dp))
Text(
text = text,
color = textColor,
fontSize = 16.sp,
fontWeight = FontWeight.Medium
)
}
},
onClick = onClick,
modifier = Modifier.fillMaxWidth().padding(horizontal = 4.dp),
interactionSource = interactionSource,
contentPadding = PaddingValues(horizontal = 12.dp, vertical = 12.dp)
)
}

View File

@@ -152,6 +152,10 @@ fun ProfileScreen(
biometricAvailable = biometricManager.isBiometricAvailable()
isBiometricEnabled = biometricPrefs.isBiometricEnabled.first()
}
// Состояние меню аватара для установки фото профиля
var showAvatarMenu by remember { mutableStateOf(false) }
// Цвета в зависимости от темы
val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF)
val surfaceColor = if (isDarkTheme) Color(0xFF2C2C2E) else Color(0xFFF2F2F7)
@@ -396,7 +400,9 @@ fun ProfileScreen(
)
// Note: Local update happens in LaunchedEffect when saveSuccess is true
},
isDarkTheme = isDarkTheme
isDarkTheme = isDarkTheme,
showAvatarMenu = showAvatarMenu,
onAvatarMenuChange = { showAvatarMenu = it }
)
}
}
@@ -414,7 +420,9 @@ private fun CollapsingProfileHeader(
onBack: () -> Unit,
hasChanges: Boolean,
onSave: () -> Unit,
isDarkTheme: Boolean
isDarkTheme: Boolean,
showAvatarMenu: Boolean,
onAvatarMenuChange: (Boolean) -> Unit
) {
val density = LocalDensity.current
val configuration = LocalConfiguration.current
@@ -489,6 +497,41 @@ private fun CollapsingProfileHeader(
}
}
// ═══════════════════════════════════════════════════════════
// ⋮ MENU BUTTON (top right corner)
// ═══════════════════════════════════════════════════════════
Box(
modifier = Modifier
.align(Alignment.TopEnd)
.padding(top = statusBarHeight)
.padding(end = 4.dp, top = 4.dp)
.size(48.dp),
contentAlignment = Alignment.Center
) {
IconButton(
onClick = { onAvatarMenuChange(true) },
modifier = Modifier.size(48.dp)
) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = "Profile menu",
tint = Color.White,
modifier = Modifier.size(24.dp)
)
}
// Меню для установки фото профиля
com.rosetta.messenger.ui.chats.components.ProfilePhotoMenu(
expanded = showAvatarMenu,
onDismiss = { onAvatarMenuChange(false) },
isDarkTheme = isDarkTheme,
onSetPhotoClick = {
onAvatarMenuChange(false)
// TODO: Реализовать выбор фото профиля
}
)
}
// ═══════════════════════════════════════════════════════════
// 👤 AVATAR - shrinks and moves up
// ═══════════════════════════════════════════════════════════