feat: Add profile photo menu and avatar menu functionality in ProfileScreen
This commit is contained in:
@@ -741,3 +741,69 @@ private fun KebabMenuItem(
|
|||||||
contentPadding = PaddingValues(horizontal = 12.dp, vertical = 12.dp)
|
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)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -152,6 +152,10 @@ fun ProfileScreen(
|
|||||||
biometricAvailable = biometricManager.isBiometricAvailable()
|
biometricAvailable = biometricManager.isBiometricAvailable()
|
||||||
isBiometricEnabled = biometricPrefs.isBiometricEnabled.first()
|
isBiometricEnabled = biometricPrefs.isBiometricEnabled.first()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Состояние меню аватара для установки фото профиля
|
||||||
|
var showAvatarMenu by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
// Цвета в зависимости от темы
|
// Цвета в зависимости от темы
|
||||||
val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF)
|
val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF)
|
||||||
val surfaceColor = if (isDarkTheme) Color(0xFF2C2C2E) else Color(0xFFF2F2F7)
|
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
|
// 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,
|
onBack: () -> Unit,
|
||||||
hasChanges: Boolean,
|
hasChanges: Boolean,
|
||||||
onSave: () -> Unit,
|
onSave: () -> Unit,
|
||||||
isDarkTheme: Boolean
|
isDarkTheme: Boolean,
|
||||||
|
showAvatarMenu: Boolean,
|
||||||
|
onAvatarMenuChange: (Boolean) -> Unit
|
||||||
) {
|
) {
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
val configuration = LocalConfiguration.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
|
// 👤 AVATAR - shrinks and moves up
|
||||||
// ═══════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════
|
||||||
|
|||||||
Reference in New Issue
Block a user