feat: Add public key handling for avatar display and enhance paste functionality in seed phrase confirmation
This commit is contained in:
@@ -205,11 +205,13 @@ fun MainScreen(
|
|||||||
val accountPhone = account?.publicKey?.take(16)?.let {
|
val accountPhone = account?.publicKey?.take(16)?.let {
|
||||||
"+${it.take(1)} ${it.substring(1, 4)} ${it.substring(4, 7)}${it.substring(7)}"
|
"+${it.take(1)} ${it.substring(1, 4)} ${it.substring(4, 7)}${it.substring(7)}"
|
||||||
} ?: "+7 775 9932587"
|
} ?: "+7 775 9932587"
|
||||||
|
val accountPublicKey = account?.publicKey ?: "04c266b98ae5"
|
||||||
|
|
||||||
ChatsListScreen(
|
ChatsListScreen(
|
||||||
isDarkTheme = isDarkTheme,
|
isDarkTheme = isDarkTheme,
|
||||||
accountName = accountName,
|
accountName = accountName,
|
||||||
accountPhone = accountPhone,
|
accountPhone = accountPhone,
|
||||||
|
accountPublicKey = accountPublicKey,
|
||||||
onToggleTheme = onToggleTheme,
|
onToggleTheme = onToggleTheme,
|
||||||
onProfileClick = {
|
onProfileClick = {
|
||||||
// TODO: Navigate to profile
|
// TODO: Navigate to profile
|
||||||
|
|||||||
@@ -140,30 +140,11 @@ fun ConfirmSeedPhraseScreen(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(4.dp),
|
.padding(4.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
|
||||||
) {
|
) {
|
||||||
IconButton(onClick = onBack) {
|
IconButton(onClick = onBack) {
|
||||||
Icon(Icons.Default.ArrowBack, "Back", tint = textColor)
|
Icon(Icons.Default.ArrowBack, "Back", tint = textColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paste button
|
|
||||||
OutlinedButton(
|
|
||||||
onClick = handlePaste,
|
|
||||||
modifier = Modifier.height(40.dp),
|
|
||||||
colors = ButtonDefaults.outlinedButtonColors(
|
|
||||||
contentColor = PrimaryBlue
|
|
||||||
),
|
|
||||||
border = BorderStroke(1.dp, PrimaryBlue)
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
Icons.Default.ContentPaste,
|
|
||||||
contentDescription = "Paste",
|
|
||||||
modifier = Modifier.size(18.dp)
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.width(6.dp))
|
|
||||||
Text("Paste", fontSize = 14.sp)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
@@ -318,6 +299,38 @@ fun ConfirmSeedPhraseScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(20.dp))
|
||||||
|
|
||||||
|
// Paste button
|
||||||
|
AnimatedVisibility(
|
||||||
|
visible = visible,
|
||||||
|
enter = fadeIn(tween(500, delayMillis = 400))
|
||||||
|
) {
|
||||||
|
OutlinedButton(
|
||||||
|
onClick = handlePaste,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(48.dp),
|
||||||
|
colors = ButtonDefaults.outlinedButtonColors(
|
||||||
|
contentColor = PrimaryBlue
|
||||||
|
),
|
||||||
|
border = BorderStroke(1.dp, PrimaryBlue),
|
||||||
|
shape = RoundedCornerShape(12.dp)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Default.ContentPaste,
|
||||||
|
contentDescription = "Paste",
|
||||||
|
modifier = Modifier.size(20.dp)
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
Text(
|
||||||
|
text = "Paste from Clipboard",
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Error message
|
// Error message
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = showError,
|
visible = showError,
|
||||||
|
|||||||
@@ -112,6 +112,11 @@ fun getInitials(name: String): String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get avatar text from public key (first 2 chars)
|
||||||
|
fun getAvatarText(publicKey: String): String {
|
||||||
|
return publicKey.take(2).uppercase()
|
||||||
|
}
|
||||||
|
|
||||||
// Drawer menu item
|
// Drawer menu item
|
||||||
data class DrawerMenuItem(
|
data class DrawerMenuItem(
|
||||||
val icon: ImageVector,
|
val icon: ImageVector,
|
||||||
@@ -126,6 +131,7 @@ fun ChatsListScreen(
|
|||||||
isDarkTheme: Boolean,
|
isDarkTheme: Boolean,
|
||||||
accountName: String,
|
accountName: String,
|
||||||
accountPhone: String,
|
accountPhone: String,
|
||||||
|
accountPublicKey: String,
|
||||||
onToggleTheme: () -> Unit,
|
onToggleTheme: () -> Unit,
|
||||||
onProfileClick: () -> Unit,
|
onProfileClick: () -> Unit,
|
||||||
onNewGroupClick: () -> Unit,
|
onNewGroupClick: () -> Unit,
|
||||||
@@ -242,6 +248,10 @@ fun ChatsListScreen(
|
|||||||
var titleClickCount by remember { mutableStateOf(0) }
|
var titleClickCount by remember { mutableStateOf(0) }
|
||||||
var lastClickTime by remember { mutableStateOf(0L) }
|
var lastClickTime by remember { mutableStateOf(0L) }
|
||||||
|
|
||||||
|
// Search state
|
||||||
|
var isSearchExpanded by remember { mutableStateOf(false) }
|
||||||
|
var searchQuery by remember { mutableStateOf("") }
|
||||||
|
|
||||||
var visible by remember { mutableStateOf(false) }
|
var visible by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
@@ -401,19 +411,20 @@ fun ChatsListScreen(
|
|||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.Top
|
verticalAlignment = Alignment.Top
|
||||||
) {
|
) {
|
||||||
// Avatar with initials
|
// Avatar with public key
|
||||||
|
val avatarColors = getAvatarColor(accountName, isDarkTheme)
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(64.dp)
|
.size(64.dp)
|
||||||
.clip(CircleShape)
|
.clip(CircleShape)
|
||||||
.background(PrimaryBlue),
|
.background(avatarColors.backgroundColor),
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = getInitials(accountName),
|
text = getAvatarText(accountPublicKey),
|
||||||
fontSize = 24.sp,
|
fontSize = 24.sp,
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
color = Color.White
|
color = avatarColors.textColor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,7 +567,56 @@ fun ChatsListScreen(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
title = {
|
title = {
|
||||||
// Stories / Title area - Triple click to open dev console
|
// Search field or Stories / Title area
|
||||||
|
AnimatedContent(
|
||||||
|
targetState = isSearchExpanded,
|
||||||
|
transitionSpec = {
|
||||||
|
fadeIn(tween(200)) togetherWith fadeOut(tween(200))
|
||||||
|
},
|
||||||
|
label = "searchAnimation"
|
||||||
|
) { expanded ->
|
||||||
|
if (expanded) {
|
||||||
|
// Search TextField
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
isSearchExpanded = false
|
||||||
|
searchQuery = ""
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Default.ArrowBack,
|
||||||
|
contentDescription = "Close search",
|
||||||
|
tint = textColor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
TextField(
|
||||||
|
value = searchQuery,
|
||||||
|
onValueChange = { searchQuery = it },
|
||||||
|
placeholder = {
|
||||||
|
Text(
|
||||||
|
"Search...",
|
||||||
|
color = secondaryTextColor
|
||||||
|
)
|
||||||
|
},
|
||||||
|
colors = TextFieldDefaults.colors(
|
||||||
|
focusedContainerColor = Color.Transparent,
|
||||||
|
unfocusedContainerColor = Color.Transparent,
|
||||||
|
focusedTextColor = textColor,
|
||||||
|
unfocusedTextColor = textColor,
|
||||||
|
cursorColor = textColor,
|
||||||
|
focusedIndicatorColor = Color.Transparent,
|
||||||
|
unfocusedIndicatorColor = Color.Transparent
|
||||||
|
),
|
||||||
|
singleLine = true,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Triple click to open dev console
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier.clickable {
|
modifier = Modifier.clickable {
|
||||||
@@ -573,41 +633,22 @@ fun ChatsListScreen(
|
|||||||
lastClickTime = currentTime
|
lastClickTime = currentTime
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
// User story avatar placeholder
|
// User avatar
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.size(36.dp)
|
|
||||||
.clip(CircleShape)
|
|
||||||
.background(
|
|
||||||
brush = androidx.compose.ui.graphics.Brush.linearGradient(
|
|
||||||
colors = listOf(
|
|
||||||
Color(0xFF405DE6),
|
|
||||||
Color(0xFFC13584),
|
|
||||||
Color(0xFFFD1D1D)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.padding(2.dp)
|
|
||||||
.clip(CircleShape)
|
|
||||||
.background(backgroundColor),
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
val avatarColors = getAvatarColor(accountName, isDarkTheme)
|
val avatarColors = getAvatarColor(accountName, isDarkTheme)
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(30.dp)
|
.size(36.dp)
|
||||||
.clip(CircleShape)
|
.clip(CircleShape)
|
||||||
.background(avatarColors.backgroundColor),
|
.background(avatarColors.backgroundColor),
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = getInitials(accountName),
|
text = getAvatarText(accountPublicKey),
|
||||||
fontSize = 12.sp,
|
fontSize = 14.sp,
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
color = avatarColors.textColor
|
color = avatarColors.textColor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(12.dp))
|
Spacer(modifier = Modifier.width(12.dp))
|
||||||
|
|
||||||
@@ -633,15 +674,23 @@ fun ChatsListScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
IconButton(onClick = onSearchClick) {
|
if (!isSearchExpanded) {
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
isSearchExpanded = true
|
||||||
|
}
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.Search,
|
Icons.Default.Search,
|
||||||
contentDescription = "Search",
|
contentDescription = "Search",
|
||||||
tint = textColor
|
tint = textColor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
colors = TopAppBarDefaults.topAppBarColors(
|
colors = TopAppBarDefaults.topAppBarColors(
|
||||||
containerColor = backgroundColor,
|
containerColor = backgroundColor,
|
||||||
@@ -833,7 +882,7 @@ fun ChatItem(
|
|||||||
val dividerColor = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE8E8E8)
|
val dividerColor = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE8E8E8)
|
||||||
|
|
||||||
val avatarColors = getAvatarColor(chat.name, isDarkTheme)
|
val avatarColors = getAvatarColor(chat.name, isDarkTheme)
|
||||||
val initials = getInitials(chat.name)
|
val avatarText = getAvatarText(chat.publicKey)
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
Row(
|
Row(
|
||||||
@@ -852,7 +901,7 @@ fun ChatItem(
|
|||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = initials,
|
text = avatarText,
|
||||||
fontSize = 20.sp,
|
fontSize = 20.sp,
|
||||||
fontWeight = FontWeight.SemiBold,
|
fontWeight = FontWeight.SemiBold,
|
||||||
color = avatarColors.textColor
|
color = avatarColors.textColor
|
||||||
|
|||||||
Reference in New Issue
Block a user