Релиз 1.2.0: синхронизированы статусы, скролл и UI-выравнивание
All checks were successful
Android Kernel Build / build (push) Successful in 17h2m4s

- Поднята версия приложения до 1.2.0 (versionCode 22)\n- Синхронизированы статусы отправки между чат-листом и диалогом: SENT отображается как часы до delivery, ERROR теперь стабильно приходит в открытый диалог\n- Доработан Telegram-подобный skeleton в диалоге: shimmer, геометрия пузырей, поддержка групповых аватаров\n- Добавлен плавный автоскролл к баннеру подтверждения нового устройства в чат-листе\n- Выровнены verified-галочки с именами в профилях и в сайдбаре\n- Кнопка Copy Seed Phrase в светлой теме приведена к белому тексту\n- Мелкие UI-правки в чате и компонентах ввода/эмодзи
This commit is contained in:
2026-03-16 00:02:27 +07:00
parent bae665f89d
commit b5398e2f1d
10 changed files with 252 additions and 115 deletions

View File

@@ -23,8 +23,8 @@ val gitShortSha = safeGitOutput("rev-parse", "--short", "HEAD") ?: "unknown"
// ═══════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════
// Rosetta versioning — bump here on each release // Rosetta versioning — bump here on each release
// ═══════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════
val rosettaVersionName = "1.1.9" val rosettaVersionName = "1.2.0"
val rosettaVersionCode = 21 // Increment on each release val rosettaVersionCode = 22 // Increment on each release
android { android {
namespace = "com.rosetta.messenger" namespace = "com.rosetta.messenger"

View File

@@ -600,6 +600,9 @@ class MessageRepository private constructor(private val context: Context) {
// При ошибке обновляем статус // При ошибке обновляем статус
messageDao.updateDeliveryStatus(account, messageId, DeliveryStatus.ERROR.value) messageDao.updateDeliveryStatus(account, messageId, DeliveryStatus.ERROR.value)
updateMessageStatus(dialogKey, messageId, DeliveryStatus.ERROR) updateMessageStatus(dialogKey, messageId, DeliveryStatus.ERROR)
_deliveryStatusEvents.tryEmit(
DeliveryStatusUpdate(dialogKey, messageId, DeliveryStatus.ERROR)
)
} }
} }
@@ -1140,6 +1143,9 @@ class MessageRepository private constructor(private val context: Context) {
messageDao.updateDeliveryStatus(account, entity.messageId, DeliveryStatus.ERROR.value) messageDao.updateDeliveryStatus(account, entity.messageId, DeliveryStatus.ERROR.value)
val dialogKey = getDialogKey(entity.toPublicKey) val dialogKey = getDialogKey(entity.toPublicKey)
updateMessageStatus(dialogKey, entity.messageId, DeliveryStatus.ERROR) updateMessageStatus(dialogKey, entity.messageId, DeliveryStatus.ERROR)
_deliveryStatusEvents.tryEmit(
DeliveryStatusUpdate(dialogKey, entity.messageId, DeliveryStatus.ERROR)
)
} }
} }
} }

View File

@@ -1164,7 +1164,7 @@ fun ChatDetailScreen(
Row( Row(
modifier = modifier =
Modifier.fillMaxWidth() Modifier.fillMaxWidth()
.height(56.dp) .height(64.dp)
.padding( .padding(
horizontal = horizontal =
4.dp 4.dp
@@ -1336,7 +1336,7 @@ fun ChatDetailScreen(
Row( Row(
modifier = modifier =
Modifier.fillMaxWidth() Modifier.fillMaxWidth()
.height(56.dp) .height(64.dp)
.padding( .padding(
horizontal = horizontal =
4.dp 4.dp
@@ -2310,6 +2310,7 @@ fun ChatDetailScreen(
isLoading -> { isLoading -> {
MessageSkeletonList( MessageSkeletonList(
isDarkTheme = isDarkTheme, isDarkTheme = isDarkTheme,
isGroupChat = isGroupChat,
modifier = modifier =
Modifier.fillMaxSize() Modifier.fillMaxSize()
) )

View File

@@ -425,6 +425,10 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
// Обновляем конкретное сообщение // Обновляем конкретное сообщение
updateMessageStatus(update.messageId, MessageStatus.DELIVERED) updateMessageStatus(update.messageId, MessageStatus.DELIVERED)
} }
DeliveryStatus.ERROR -> {
// Синхронизируем ошибку отправки с открытым диалогом
updateMessageStatus(update.messageId, MessageStatus.ERROR)
}
DeliveryStatus.READ -> { DeliveryStatus.READ -> {
// Помечаем все исходящие как прочитанные // Помечаем все исходящие как прочитанные
markAllOutgoingAsRead() markAllOutgoingAsRead()

View File

@@ -928,21 +928,21 @@ fun ChatsListScreen(
// Display name // Display name
if (accountName.isNotEmpty()) { if (accountName.isNotEmpty()) {
Row( Row(
verticalAlignment = Alignment.CenterVertically horizontalArrangement = Arrangement.Start
) { ) {
Text( Text(
text = accountName, text = accountName,
fontSize = 15.sp, fontSize = 15.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = Color.White color = Color.White,
modifier = Modifier.alignByBaseline()
) )
if (accountVerified > 0 || isRosettaOfficial || isFreddyOfficial) { if (accountVerified > 0 || isRosettaOfficial || isFreddyOfficial) {
Spacer( Box(
modifier = modifier =
Modifier.width( Modifier.padding(start = 2.dp)
6.dp .alignBy { (it.measuredHeight * 0.78f).toInt() }
) ) {
)
VerifiedBadge( VerifiedBadge(
verified = if (accountVerified > 0) accountVerified else 1, verified = if (accountVerified > 0) accountVerified else 1,
size = 15, size = 15,
@@ -951,6 +951,7 @@ fun ChatsListScreen(
} }
} }
} }
}
// Username // Username
if (accountUsername.isNotEmpty()) { if (accountUsername.isNotEmpty()) {
@@ -2066,8 +2067,34 @@ fun ChatsListScreen(
// Track scroll direction to hide/show Requests // Track scroll direction to hide/show Requests
val chatListState = rememberLazyListState() val chatListState = rememberLazyListState()
var isRequestsVisible by remember { mutableStateOf(true) } var isRequestsVisible by remember { mutableStateOf(true) }
var lastAutoScrolledVerificationId by remember {
mutableStateOf<String?>(null)
}
val hapticFeedback = LocalHapticFeedback.current val hapticFeedback = LocalHapticFeedback.current
// When a new device confirmation banner appears at the top,
// smoothly bring the list to top so the banner is visible.
LaunchedEffect(pendingDeviceVerification?.deviceId) {
val verificationId =
pendingDeviceVerification?.deviceId
if (verificationId.isNullOrBlank()) {
lastAutoScrolledVerificationId = null
return@LaunchedEffect
}
if (verificationId == lastAutoScrolledVerificationId) {
return@LaunchedEffect
}
val alreadyAtTop =
chatListState.firstVisibleItemIndex == 0 &&
chatListState.firstVisibleItemScrollOffset <= 2
if (!alreadyAtTop) {
chatListState.animateScrollToItem(0)
}
lastAutoScrolledVerificationId = verificationId
}
// NestedScroll — ловим направление свайпа даже без скролла // NestedScroll — ловим направление свайпа даже без скролла
// Для появления: накапливаем pull down дельту, нужен сильный жест // Для появления: накапливаем pull down дельту, нужен сильный жест
val requestsNestedScroll = remember(hapticFeedback) { val requestsNestedScroll = remember(hapticFeedback) {

View File

@@ -1903,7 +1903,7 @@ fun AnimatedMessageStatus(
MessageStatus.SENDING -> MessageStatus.SENDING ->
TelegramIcons.Clock TelegramIcons.Clock
MessageStatus.SENT -> MessageStatus.SENT ->
TelegramIcons.Done TelegramIcons.Clock
MessageStatus.DELIVERED -> MessageStatus.DELIVERED ->
TelegramIcons.Done TelegramIcons.Done
else -> TelegramIcons.Clock else -> TelegramIcons.Clock
@@ -2573,68 +2573,130 @@ private fun ForwardedImagePreview(
/** Message skeleton loader with shimmer animation */ /** Message skeleton loader with shimmer animation */
@Composable @Composable
fun MessageSkeletonList(isDarkTheme: Boolean, modifier: Modifier = Modifier) { fun MessageSkeletonList(
val skeletonColor = if (isDarkTheme) Color(0xFF3A3A3C) else Color(0xFFE0E0E0) isDarkTheme: Boolean,
isGroupChat: Boolean,
val infiniteTransition = rememberInfiniteTransition(label = "shimmer") modifier: Modifier = Modifier
val shimmerAlpha by ) {
infiniteTransition.animateFloat( val transition = rememberInfiniteTransition(label = "telegramSkeleton")
initialValue = 0.4f, val shimmerProgress by
targetValue = 0.8f, transition.animateFloat(
initialValue = -1f,
targetValue = 2f,
animationSpec = animationSpec =
infiniteRepeatable( infiniteRepeatable(
animation = tween(800, easing = FastOutSlowInEasing), animation = tween(1300, easing = LinearEasing),
repeatMode = RepeatMode.Reverse repeatMode = RepeatMode.Restart
), ),
label = "shimmerAlpha" label = "telegramSkeletonProgress"
) )
Box(modifier = modifier) { // Telegram-style deterministic pseudo-randomness.
val widthRandom = remember { floatArrayOf(0.18f, 0.74f, 0.32f, 0.61f, 0.27f, 0.84f, 0.49f, 0.12f) }
val heightRandom = remember { floatArrayOf(0.25f, 0.68f, 0.14f, 0.52f, 0.37f, 0.79f, 0.29f, 0.57f) }
val bubbleShape =
remember {
RoundedCornerShape(
topStart = TelegramBubbleSpec.bubbleRadius,
topEnd = TelegramBubbleSpec.bubbleRadius,
bottomStart = TelegramBubbleSpec.nearRadius,
bottomEnd = TelegramBubbleSpec.bubbleRadius
)
}
BoxWithConstraints(modifier = modifier.fillMaxSize()) {
val density = LocalDensity.current
val maxWidthPx = with(density) { maxWidth.toPx() }.coerceAtLeast(1f)
val gradientWidthPx = with(density) { 200.dp.toPx() }
val shimmerX = shimmerProgress * maxWidthPx
val color0 =
if (isDarkTheme) Color(0x36FFFFFF) else Color(0x1F000000)
val color1 =
if (isDarkTheme) Color(0x1CFFFFFF) else Color(0x12000000)
val outlineColor =
if (isDarkTheme) Color(0x40FFFFFF) else Color(0x24FFFFFF)
val shimmerBrush =
Brush.linearGradient(
colorStops =
arrayOf(
0f to color1,
0.4f to color0,
0.6f to color0,
1f to color1
),
start = Offset(shimmerX - gradientWidthPx, 0f),
end = Offset(shimmerX, 0f)
)
val bottomInset = 58.dp
val containerWidth = this@BoxWithConstraints.maxWidth
val bubbleMaxWidth = (containerWidth * 0.8f) - if (isGroupChat) 42.dp else 0.dp
val avatarGap = 6.dp
val availableHeight = (maxHeight - bottomInset).coerceAtLeast(0.dp)
var usedHeight = 0.dp
var rowCount = 0
while (rowCount < 24 && usedHeight < availableHeight) {
val randomHeight = heightRandom[rowCount % heightRandom.size]
usedHeight += (64.dp + (randomHeight * 64f).dp + 3.dp)
rowCount++
}
if (rowCount < 6) rowCount = 6
Column( Column(
modifier = modifier =
Modifier.align(Alignment.BottomCenter) Modifier.align(Alignment.BottomStart)
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 8.dp) .padding(start = 3.dp, end = 8.dp, bottom = bottomInset),
.padding(bottom = 80.dp), verticalArrangement = Arrangement.spacedBy(3.dp)
verticalArrangement = Arrangement.spacedBy(6.dp)
) { ) {
SkeletonBubble(true, 0.45f, skeletonColor, shimmerAlpha) repeat(rowCount) { index ->
SkeletonBubble(false, 0.55f, skeletonColor, shimmerAlpha) val lineWidth =
SkeletonBubble(true, 0.35f, skeletonColor, shimmerAlpha) minOf(
SkeletonBubble(false, 0.50f, skeletonColor, shimmerAlpha) bubbleMaxWidth,
SkeletonBubble(true, 0.60f, skeletonColor, shimmerAlpha) 42.dp +
SkeletonBubble(false, 0.40f, skeletonColor, shimmerAlpha) containerWidth *
} (0.4f +
} widthRandom[index % widthRandom.size] *
} 0.35f)
)
val lineHeight =
64.dp +
(heightRandom[index % heightRandom.size] * 64f).dp
@Composable
private fun SkeletonBubble(
isOutgoing: Boolean,
widthFraction: Float,
bubbleColor: Color,
alpha: Float
) {
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = if (isOutgoing) Arrangement.End else Arrangement.Start verticalAlignment = Alignment.Bottom
) { ) {
if (isGroupChat) {
Box( Box(
modifier = modifier =
Modifier.fillMaxWidth(widthFraction) Modifier.size(42.dp)
.defaultMinSize(minHeight = 44.dp) .clip(CircleShape)
.clip( .background(shimmerBrush)
RoundedCornerShape( .border(1.dp, outlineColor, CircleShape)
topStart = 18.dp, )
topEnd = 18.dp, Spacer(modifier = Modifier.width(avatarGap))
bottomStart = }
if (isOutgoing) 18.dp else 6.dp,
bottomEnd = if (isOutgoing) 6.dp else 18.dp Box(
modifier =
Modifier.width(lineWidth)
.height(lineHeight)
.clip(bubbleShape)
.background(shimmerBrush)
.border(
width = 1.dp,
color = outlineColor,
shape = bubbleShape
) )
) )
.background(bubbleColor.copy(alpha = alpha)) }
.padding(horizontal = 14.dp, vertical = 10.dp) }
) }
} }
} }

View File

@@ -4,7 +4,9 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.graphics.Paint
import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.net.Uri import android.net.Uri
import android.text.Editable import android.text.Editable
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
@@ -12,6 +14,7 @@ import android.text.TextPaint
import android.text.TextWatcher import android.text.TextWatcher
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan import android.text.style.ClickableSpan
import android.text.style.DynamicDrawableSpan
import android.text.style.ForegroundColorSpan import android.text.style.ForegroundColorSpan
import android.text.style.ImageSpan import android.text.style.ImageSpan
import android.util.AttributeSet import android.util.AttributeSet
@@ -32,6 +35,43 @@ import androidx.compose.foundation.background
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import java.util.regex.Pattern import java.util.regex.Pattern
private class TelegramLikeEmojiSpan(
emojiDrawable: Drawable,
private var sourceFontMetrics: Paint.FontMetricsInt?
) : ImageSpan(emojiDrawable, DynamicDrawableSpan.ALIGN_BOTTOM) {
private var sizePx: Int = resolveSize(sourceFontMetrics)
private fun resolveSize(metrics: Paint.FontMetricsInt?): Int {
val metricsSize = metrics?.let { kotlin.math.abs(it.descent) + kotlin.math.abs(it.ascent) } ?: 0
if (metricsSize > 0) return metricsSize
val intrinsic = drawable.intrinsicHeight
return if (intrinsic > 0) intrinsic else 20
}
override fun getSize(
paint: Paint,
text: CharSequence,
start: Int,
end: Int,
fm: Paint.FontMetricsInt?
): Int {
val metrics = sourceFontMetrics ?: paint.fontMetricsInt
sourceFontMetrics = metrics
sizePx = resolveSize(metrics)
val scaledSize = sizePx.coerceAtLeast(1)
drawable.setBounds(0, 0, scaledSize, scaledSize)
fm?.let {
it.ascent = metrics.ascent
it.descent = metrics.descent
it.top = metrics.top
it.bottom = metrics.bottom
it.leading = metrics.leading
}
return scaledSize
}
}
/** /**
* Apple Emoji EditText - кастомный EditText с PNG эмодзи * Apple Emoji EditText - кастомный EditText с PNG эмодзи
* Заменяет системные эмодзи на Apple PNG изображения из assets * Заменяет системные эмодзи на Apple PNG изображения из assets
@@ -98,9 +138,8 @@ class AppleEmojiEditTextView @JvmOverloads constructor(
// 🔥 Паттерн для :emoji_XXXX: формата (как в десктопе) // 🔥 Паттерн для :emoji_XXXX: формата (как в десктопе)
val EMOJI_CODE_PATTERN: Pattern = Pattern.compile(":emoji_([a-fA-F0-9_-]+):") val EMOJI_CODE_PATTERN: Pattern = Pattern.compile(":emoji_([a-fA-F0-9_-]+):")
// Кэш для bitmap и drawable // Кэш bitmap
private val bitmapCache = LruCache<String, Bitmap>(500) private val bitmapCache = LruCache<String, Bitmap>(500)
private val drawableCache = LruCache<String, BitmapDrawable>(500)
} }
init { init {
@@ -195,9 +234,6 @@ class AppleEmojiEditTextView @JvmOverloads constructor(
if (existingSpans.isNotEmpty()) continue if (existingSpans.isNotEmpty()) continue
val unified = match.unified val unified = match.unified
var drawable = drawableCache.get(unified)
if (drawable == null) {
var bitmap = bitmapCache.get(unified) var bitmap = bitmapCache.get(unified)
if (bitmap == null) { if (bitmap == null) {
bitmap = loadFromAssets(unified) bitmap = loadFromAssets(unified)
@@ -206,16 +242,9 @@ class AppleEmojiEditTextView @JvmOverloads constructor(
} }
} }
if (bitmap != null) { if (bitmap != null && start < editable.length && end <= editable.length) {
drawable = BitmapDrawable(getContext().resources, bitmap) val drawable = BitmapDrawable(resources, bitmap)
val size = (textSize * 1.15).toInt() val imageSpan = TelegramLikeEmojiSpan(drawable, paint.fontMetricsInt)
drawable.setBounds(0, 0, size, size)
drawableCache.put(unified, drawable)
}
}
if (drawable != null && start < editable.length && end <= editable.length) {
val imageSpan = ImageSpan(drawable, ImageSpan.ALIGN_CENTER)
editable.setSpan(imageSpan, start, end, SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE) editable.setSpan(imageSpan, start, end, SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE)
} }
} }
@@ -577,12 +606,8 @@ class AppleEmojiTextView @JvmOverloads constructor(
for (match in emojiMatches) { for (match in emojiMatches) {
val bitmap = loadEmojiBitmap(match.unified) val bitmap = loadEmojiBitmap(match.unified)
if (bitmap != null) { if (bitmap != null) {
val size = (textSize * 1.3).toInt() val drawable = BitmapDrawable(resources, bitmap)
val scaledBitmap = Bitmap.createScaledBitmap(bitmap, size, size, true) val span = TelegramLikeEmojiSpan(drawable, paint.fontMetricsInt)
val drawable = BitmapDrawable(resources, scaledBitmap)
drawable.setBounds(0, 0, size, size)
val span = ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM)
// Для :emoji_XXXX: заменяем весь текст на пробел + span // Для :emoji_XXXX: заменяем весь текст на пробел + span
// Для Unicode эмодзи оставляем символ как есть // Для Unicode эмодзи оставляем символ как есть

View File

@@ -253,7 +253,8 @@ fun BackupScreen(
.fillMaxWidth() .fillMaxWidth()
.height(52.dp), .height(52.dp),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
containerColor = Color(0xFF248AE6) containerColor = Color(0xFF248AE6),
contentColor = Color.White
), ),
shape = RoundedCornerShape(10.dp) shape = RoundedCornerShape(10.dp)
) { ) {
@@ -266,7 +267,8 @@ fun BackupScreen(
Text( Text(
text = "Copy Seed Phrase", text = "Copy Seed Phrase",
fontSize = 15.sp, fontSize = 15.sp,
fontWeight = FontWeight.Medium fontWeight = FontWeight.Medium,
color = Color.White
) )
} }

View File

@@ -2138,9 +2138,9 @@ private fun CollapsingOtherProfileHeader(
Modifier.align(Alignment.TopCenter).offset(y = textY), Modifier.align(Alignment.TopCenter).offset(y = textY),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
val verifiedBadgeSize = (nameFontSize.value * 0.8f).toInt()
// Name + Verified Badge // Name + Verified Badge
Row( Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center horizontalArrangement = Arrangement.Center
) { ) {
Text( Text(
@@ -2150,20 +2150,25 @@ private fun CollapsingOtherProfileHeader(
color = textColor, color = textColor,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
modifier = Modifier.widthIn(max = 220.dp), modifier = Modifier.widthIn(max = 220.dp).alignByBaseline(),
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
if (verified > 0 || isRosettaOfficial || isFreddyOfficial) { if (verified > 0 || isRosettaOfficial || isFreddyOfficial) {
Spacer(modifier = Modifier.width(4.dp)) Box(
modifier =
Modifier.padding(start = 4.dp)
.alignBy { (it.measuredHeight * 0.78f).toInt() }
) {
VerifiedBadge( VerifiedBadge(
verified = if (verified > 0) verified else 1, verified = if (verified > 0) verified else 1,
size = (nameFontSize.value * 0.8f).toInt(), size = verifiedBadgeSize,
isDarkTheme = isDarkTheme, isDarkTheme = isDarkTheme,
badgeTint = if (isDarkTheme) Color.White else PrimaryBlue badgeTint = Color.White
) )
} }
} }
}
Spacer(modifier = Modifier.height(2.dp)) Spacer(modifier = Modifier.height(2.dp))

View File

@@ -1389,8 +1389,8 @@ private fun CollapsingProfileHeader(
Modifier.align(Alignment.TopCenter).offset(y = textY), Modifier.align(Alignment.TopCenter).offset(y = textY),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
val verifiedBadgeSize = (nameFontSize.value * 0.8f).toInt()
Row( Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center horizontalArrangement = Arrangement.Center
) { ) {
Text( Text(
@@ -1400,19 +1400,24 @@ private fun CollapsingProfileHeader(
color = textColor, color = textColor,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
modifier = Modifier.widthIn(max = 220.dp), modifier = Modifier.widthIn(max = 220.dp).alignByBaseline(),
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
if (verified > 0 || isRosettaOfficial || isFreddyOfficial) { if (verified > 0 || isRosettaOfficial || isFreddyOfficial) {
Spacer(modifier = Modifier.width(4.dp)) Box(
modifier =
Modifier.padding(start = 4.dp)
.alignBy { (it.measuredHeight * 0.78f).toInt() }
) {
VerifiedBadge( VerifiedBadge(
verified = if (verified > 0) verified else 2, verified = if (verified > 0) verified else 2,
size = (nameFontSize.value * 0.8f).toInt(), size = verifiedBadgeSize,
isDarkTheme = isDarkTheme, isDarkTheme = isDarkTheme,
badgeTint = if (isDarkTheme) Color.White else PrimaryBlue badgeTint = Color.White
) )
} }
} }
}
Spacer(modifier = Modifier.height(2.dp)) Spacer(modifier = Modifier.height(2.dp))