feat: add animated badge for top-level requests count in ChatsListScreen

This commit is contained in:
2026-02-14 00:31:05 +05:00
parent e399fd04aa
commit a46968cfff
7 changed files with 242 additions and 83 deletions

View File

@@ -494,33 +494,27 @@ fun ChatsListScreen(
)
val headerColor = avatarColors.backgroundColor
// Header с blur аватарки (fallback = голубой) или акцентным цветом (light)
// Header: avatar blur или цвет шапки chat list
Box(modifier = Modifier.fillMaxWidth()) {
if (isDarkTheme) {
if (backgroundBlurColorId == "solid_blue") {
// Голубой фон
Box(
modifier = Modifier
.matchParentSize()
.background(PrimaryBlueDark)
)
} else {
// Avatar blur (default)
BlurredAvatarBackground(
publicKey = accountPublicKey,
avatarRepository = avatarRepository,
fallbackColor = PrimaryBlueDark,
blurRadius = 40f,
alpha = 0.6f,
overlayColors = emptyList(),
isDarkTheme = isDarkTheme
)
}
if (backgroundBlurColorId == "avatar") {
// Avatar blur
BlurredAvatarBackground(
publicKey = accountPublicKey,
avatarRepository = avatarRepository,
fallbackColor = if (isDarkTheme) Color(0xFF2A2A2A) else PrimaryBlue,
blurRadius = 40f,
alpha = 0.6f,
overlayColors = null,
isDarkTheme = isDarkTheme
)
} else {
// None или любой другой — стандартный цвет шапки
Box(
modifier = Modifier
.matchParentSize()
.background(PrimaryBlue)
.background(
if (isDarkTheme) Color(0xFF2A2A2A) else PrimaryBlue
)
)
}
@@ -1102,16 +1096,48 @@ fun ChatsListScreen(
tint =
Color.White
)
if (topLevelRequestsCount > 0) {
// Badge с числом запросов
androidx.compose.animation.AnimatedVisibility(
visible = topLevelRequestsCount > 0,
enter = scaleIn(
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessMedium
)
) + fadeIn(),
exit = scaleOut() + fadeOut(),
modifier = Modifier.align(Alignment.TopEnd)
) {
val badgeText = remember(topLevelRequestsCount) {
when {
topLevelRequestsCount > 99 -> "99+"
else -> topLevelRequestsCount.toString()
}
}
val badgeBg = Color.White
val badgeShape = RoundedCornerShape(50)
Box(
modifier =
Modifier
.align(Alignment.TopEnd)
.offset(x = 4.dp, y = (-4).dp)
.size(10.dp)
.clip(CircleShape)
.background(if (isDarkTheme) Color.White else PrimaryBlue)
)
modifier = Modifier
.offset(x = 6.dp, y = (-6).dp)
.defaultMinSize(minWidth = 20.dp, minHeight = 20.dp)
.clip(badgeShape)
.background(
color = if (isDarkTheme) Color(0xFF2A2A2A) else Color(0xFF0D8CF4)
)
.padding(2.dp)
.clip(badgeShape)
.background(color = badgeBg),
contentAlignment = Alignment.Center
) {
Text(
text = badgeText,
fontSize = 10.sp,
fontWeight = FontWeight.Bold,
color = Color(0xFF0D8CF4),
lineHeight = 10.sp,
modifier = Modifier.padding(horizontal = 4.dp, vertical = 2.dp)
)
}
}
}
}
@@ -3314,11 +3340,13 @@ fun RequestsScreen(
onPin = { onTogglePin(request.opponentKey) }
)
Divider(
modifier = Modifier.padding(start = 84.dp),
color = dividerColor,
thickness = 0.5.dp
)
if (request != requests.last()) {
Divider(
modifier = Modifier.padding(start = 84.dp),
color = dividerColor,
thickness = 0.5.dp
)
}
}
}
}