refactor: Clean up imports and improve code formatting in OtherProfileScreen

This commit is contained in:
k1ngsterr1
2026-01-31 04:09:28 +05:00
parent 3ed4986393
commit c6f1998dc9

View File

@@ -1,32 +1,21 @@
package com.rosetta.messenger.ui.settings
import androidx.activity.compose.BackHandler
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.outlined.Block
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.lifecycle.viewmodel.compose.viewModel
import com.rosetta.messenger.data.MessageRepository
import com.rosetta.messenger.database.RosettaDatabase
import com.rosetta.messenger.ui.chats.ChatViewModel
import com.rosetta.messenger.ui.chats.ChatsListViewModel
import com.rosetta.messenger.ui.onboarding.PrimaryBlue
import com.rosetta.messenger.ui.components.VerifiedBadge
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
@@ -41,17 +30,22 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.rosetta.messenger.data.MessageRepository
import com.rosetta.messenger.database.RosettaDatabase
import com.rosetta.messenger.network.SearchUser
import com.rosetta.messenger.repository.AvatarRepository
import com.rosetta.messenger.ui.chats.ChatViewModel
import com.rosetta.messenger.ui.chats.ChatsListViewModel
import com.rosetta.messenger.ui.components.AvatarImage
import com.rosetta.messenger.ui.components.BlurredAvatarBackground
import com.rosetta.messenger.ui.components.VerifiedBadge
import com.rosetta.messenger.ui.onboarding.PrimaryBlue
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.math.roundToInt
// Collapsing header constants
private val EXPANDED_HEADER_HEIGHT_OTHER = 280.dp
@@ -62,10 +56,10 @@ private val AVATAR_SIZE_COLLAPSED_OTHER = 36.dp
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
@Composable
fun OtherProfileScreen(
user: SearchUser,
isDarkTheme: Boolean,
onBack: () -> Unit,
avatarRepository: AvatarRepository? = null
user: SearchUser,
isDarkTheme: Boolean,
onBack: () -> Unit,
avatarRepository: AvatarRepository? = null
) {
var isBlocked by remember { mutableStateOf(false) }
var showAvatarMenu by remember { mutableStateOf(false) }
@@ -75,91 +69,98 @@ fun OtherProfileScreen(
val secondaryTextColor = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666)
val avatarColors = getAvatarColor(user.publicKey, isDarkTheme)
val context = LocalContext.current
// 🔥 Получаем тот же ChatViewModel что и в ChatDetailScreen для очистки истории
val viewModel: ChatViewModel = viewModel(key = "chat_${user.publicKey}")
// 🔥 ChatsListViewModel для блокировки/разблокировки
val chatsListViewModel: ChatsListViewModel = viewModel()
val coroutineScope = rememberCoroutineScope()
// 🔥 Загружаем статус блокировки при открытии экрана
LaunchedEffect(user.publicKey) {
isBlocked = chatsListViewModel.isUserBlocked(user.publicKey)
}
LaunchedEffect(user.publicKey) { isBlocked = chatsListViewModel.isUserBlocked(user.publicKey) }
// 🎹 Для закрытия клавиатуры
val keyboardController = LocalSoftwareKeyboardController.current
val focusManager = LocalFocusManager.current
// 🗑️ Для удаления диалога
val database = remember { RosettaDatabase.getDatabase(context) }
// 🔥 Закрываем клавиатуру при открытии экрана
LaunchedEffect(Unit) {
keyboardController?.hide()
focusManager.clearFocus()
}
// <20>🟢 Наблюдаем за онлайн статусом пользователя в реальном времени
val messageRepository = remember { MessageRepository.getInstance(context) }
val onlineStatus by messageRepository.observeUserOnlineStatus(user.publicKey)
.collectAsState(initial = false to 0L)
val onlineStatus by
messageRepository
.observeUserOnlineStatus(user.publicKey)
.collectAsState(initial = false to 0L)
val isOnline = onlineStatus.first
val lastSeen = onlineStatus.second
// Scroll state for collapsing header animation
val density = LocalDensity.current
val statusBarHeight = WindowInsets.statusBars.asPaddingValues().calculateTopPadding()
val expandedHeightPx = with(density) { (EXPANDED_HEADER_HEIGHT_OTHER + statusBarHeight).toPx() }
val collapsedHeightPx = with(density) { (COLLAPSED_HEADER_HEIGHT_OTHER + statusBarHeight).toPx() }
val collapsedHeightPx =
with(density) { (COLLAPSED_HEADER_HEIGHT_OTHER + statusBarHeight).toPx() }
var scrollOffset by remember { mutableFloatStateOf(0f) }
val maxScrollOffset = expandedHeightPx - collapsedHeightPx
val collapseProgress by remember {
derivedStateOf {
(scrollOffset / maxScrollOffset).coerceIn(0f, 1f)
}
derivedStateOf { (scrollOffset / maxScrollOffset).coerceIn(0f, 1f) }
}
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
val delta = available.y
val newOffset = scrollOffset - delta
val consumed = when {
delta < 0 && scrollOffset < maxScrollOffset -> {
val consumed = (newOffset.coerceIn(0f, maxScrollOffset) - scrollOffset)
scrollOffset = newOffset.coerceIn(0f, maxScrollOffset)
-consumed
}
delta > 0 && scrollOffset > 0 -> {
val consumed = scrollOffset - newOffset.coerceIn(0f, maxScrollOffset)
scrollOffset = newOffset.coerceIn(0f, maxScrollOffset)
consumed
}
else -> 0f
}
val consumed =
when {
delta < 0 && scrollOffset < maxScrollOffset -> {
val consumed =
(newOffset.coerceIn(0f, maxScrollOffset) - scrollOffset)
scrollOffset = newOffset.coerceIn(0f, maxScrollOffset)
-consumed
}
delta > 0 && scrollOffset > 0 -> {
val consumed =
scrollOffset - newOffset.coerceIn(0f, maxScrollOffset)
scrollOffset = newOffset.coerceIn(0f, maxScrollOffset)
consumed
}
else -> 0f
}
return Offset(0f, consumed)
}
}
}
// Handle back gesture
BackHandler { onBack() }
Box(
modifier = Modifier
.fillMaxSize()
.background(backgroundColor)
.nestedScroll(nestedScrollConnection)
modifier =
Modifier.fillMaxSize()
.background(backgroundColor)
.nestedScroll(nestedScrollConnection)
) {
// Scrollable content
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(top = with(density) { (expandedHeightPx - scrollOffset).toDp() })
modifier =
Modifier.fillMaxSize()
.padding(
top =
with(density) {
(expandedHeightPx - scrollOffset).toDp()
}
)
) {
item {
Spacer(modifier = Modifier.height(16.dp))
@@ -169,25 +170,25 @@ fun OtherProfileScreen(
// ═══════════════════════════════════════════════════════════
if (user.username.isNotBlank()) {
TelegramSectionTitle(title = "Info", isDarkTheme = isDarkTheme)
TelegramCopyField(
value = "@${user.username}",
fullValue = user.username,
label = "Username",
isDarkTheme = isDarkTheme
value = "@${user.username}",
fullValue = user.username,
label = "Username",
isDarkTheme = isDarkTheme
)
Spacer(modifier = Modifier.height(24.dp))
}
// Public Key Section
TelegramSectionTitle(title = "Public Key", isDarkTheme = isDarkTheme)
TelegramCopyField(
value = user.publicKey.take(16) + "..." + user.publicKey.takeLast(6),
fullValue = user.publicKey,
label = "Public Key",
isDarkTheme = isDarkTheme
value = user.publicKey.take(16) + "..." + user.publicKey.takeLast(6),
fullValue = user.publicKey,
label = "Public Key",
isDarkTheme = isDarkTheme
)
Spacer(modifier = Modifier.height(32.dp))
@@ -198,43 +199,43 @@ fun OtherProfileScreen(
// 🎨 COLLAPSING HEADER
// ═══════════════════════════════════════════════════════════
CollapsingOtherProfileHeader(
name = user.title.ifEmpty { "Unknown User" },
username = user.username,
publicKey = user.publicKey,
verified = user.verified,
isOnline = isOnline,
lastSeen = lastSeen,
avatarColors = avatarColors,
collapseProgress = collapseProgress,
onBack = onBack,
isDarkTheme = isDarkTheme,
showAvatarMenu = showAvatarMenu,
onAvatarMenuChange = { showAvatarMenu = it },
isBlocked = isBlocked,
onBlockToggle = {
coroutineScope.launch {
if (isBlocked) {
chatsListViewModel.unblockUser(user.publicKey)
} else {
chatsListViewModel.blockUser(user.publicKey)
name = user.title.ifEmpty { "Unknown User" },
username = user.username,
publicKey = user.publicKey,
verified = user.verified,
isOnline = isOnline,
lastSeen = lastSeen,
avatarColors = avatarColors,
collapseProgress = collapseProgress,
onBack = onBack,
isDarkTheme = isDarkTheme,
showAvatarMenu = showAvatarMenu,
onAvatarMenuChange = { showAvatarMenu = it },
isBlocked = isBlocked,
onBlockToggle = {
coroutineScope.launch {
if (isBlocked) {
chatsListViewModel.unblockUser(user.publicKey)
} else {
chatsListViewModel.blockUser(user.publicKey)
}
// Обновляем локальное состояние
isBlocked = !isBlocked
}
// Обновляем локальное состояние
isBlocked = !isBlocked
}
},
avatarRepository = avatarRepository,
onClearChat = {
viewModel.clearChatHistory()
// 🗑️ Удаляем диалог из списка после очистки истории
CoroutineScope(Dispatchers.IO).launch {
try {
val account = viewModel.myPublicKey ?: return@launch
database.dialogDao().deleteDialog(account, user.publicKey)
} catch (e: Exception) {
android.util.Log.e("OtherProfileScreen", "Failed to delete dialog", e)
},
avatarRepository = avatarRepository,
onClearChat = {
viewModel.clearChatHistory()
// 🗑️ Удаляем диалог из списка после очистки истории
CoroutineScope(Dispatchers.IO).launch {
try {
val account = viewModel.myPublicKey ?: return@launch
database.dialogDao().deleteDialog(account, user.publicKey)
} catch (e: Exception) {
android.util.Log.e("OtherProfileScreen", "Failed to delete dialog", e)
}
}
}
}
)
}
}
@@ -243,205 +244,207 @@ fun OtherProfileScreen(
// ═══════════════════════════════════════════════════════════
@Composable
private fun CollapsingOtherProfileHeader(
name: String,
username: String,
publicKey: String,
verified: Int,
isOnline: Boolean,
lastSeen: Long,
avatarColors: AvatarColors,
collapseProgress: Float,
onBack: () -> Unit,
isDarkTheme: Boolean,
showAvatarMenu: Boolean,
onAvatarMenuChange: (Boolean) -> Unit,
isBlocked: Boolean,
onBlockToggle: () -> Unit,
avatarRepository: AvatarRepository? = null,
onClearChat: () -> Unit
name: String,
username: String,
publicKey: String,
verified: Int,
isOnline: Boolean,
lastSeen: Long,
avatarColors: AvatarColors,
collapseProgress: Float,
onBack: () -> Unit,
isDarkTheme: Boolean,
showAvatarMenu: Boolean,
onAvatarMenuChange: (Boolean) -> Unit,
isBlocked: Boolean,
onBlockToggle: () -> Unit,
avatarRepository: AvatarRepository? = null,
onClearChat: () -> Unit
) {
val density = LocalDensity.current
val configuration = LocalConfiguration.current
val screenWidthDp = configuration.screenWidthDp.dp
val statusBarHeight = WindowInsets.statusBars.asPaddingValues().calculateTopPadding()
val expandedHeight = EXPANDED_HEADER_HEIGHT_OTHER + statusBarHeight
val collapsedHeight = COLLAPSED_HEADER_HEIGHT_OTHER + statusBarHeight
val headerHeight = androidx.compose.ui.unit.lerp(expandedHeight, collapsedHeight, collapseProgress)
val headerHeight =
androidx.compose.ui.unit.lerp(expandedHeight, collapsedHeight, collapseProgress)
// Avatar animation
val avatarCenterX = (screenWidthDp - AVATAR_SIZE_EXPANDED_OTHER) / 2
val avatarStartY = statusBarHeight + 32.dp
val avatarEndY = statusBarHeight - 60.dp
val avatarY = androidx.compose.ui.unit.lerp(avatarStartY, avatarEndY, collapseProgress)
val avatarSize = androidx.compose.ui.unit.lerp(AVATAR_SIZE_EXPANDED_OTHER, 0.dp, collapseProgress)
val avatarSize =
androidx.compose.ui.unit.lerp(AVATAR_SIZE_EXPANDED_OTHER, 0.dp, collapseProgress)
val avatarFontSize = androidx.compose.ui.unit.lerp(40.sp, 0.sp, collapseProgress)
// Text animation - always centered
val textExpandedY = statusBarHeight + 32.dp + AVATAR_SIZE_EXPANDED_OTHER + 48.dp
val textCollapsedY = statusBarHeight + COLLAPSED_HEADER_HEIGHT_OTHER / 2
val textY = androidx.compose.ui.unit.lerp(textExpandedY, textCollapsedY, collapseProgress)
val nameFontSize = androidx.compose.ui.unit.lerp(24.sp, 18.sp, collapseProgress)
val onlineFontSize = androidx.compose.ui.unit.lerp(14.sp, 13.sp, collapseProgress)
Box(
modifier = Modifier
.fillMaxWidth()
.height(headerHeight)
) {
Box(modifier = Modifier.fillMaxWidth().height(headerHeight)) {
// ═══════════════════════════════════════════════════════════
// 🎨 BLURRED AVATAR BACKGROUND
// ═══════════════════════════════════════════════════════════
BlurredAvatarBackground(
publicKey = publicKey,
avatarRepository = avatarRepository,
fallbackColor = avatarColors.backgroundColor,
blurRadius = 25f,
alpha = 0.3f
publicKey = publicKey,
avatarRepository = avatarRepository,
fallbackColor = avatarColors.backgroundColor,
blurRadius = 25f,
alpha = 0.3f
)
// ═══════════════════════════════════════════════════════════
// 🔙 BACK BUTTON
// ═══════════════════════════════════════════════════════════
Box(
modifier = Modifier
.padding(top = statusBarHeight)
.padding(start = 4.dp, top = 4.dp)
.size(48.dp),
contentAlignment = Alignment.Center
modifier =
Modifier.padding(top = statusBarHeight)
.padding(start = 4.dp, top = 4.dp)
.size(48.dp),
contentAlignment = Alignment.Center
) {
IconButton(
onClick = onBack,
modifier = Modifier.size(48.dp)
) {
IconButton(onClick = onBack, modifier = Modifier.size(48.dp)) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = "Back",
tint = if (isColorLight(avatarColors.backgroundColor)) Color.Black else Color.White,
modifier = Modifier.size(24.dp)
imageVector = Icons.Filled.ArrowBack,
contentDescription = "Back",
tint = if (isDarkTheme) Color.White else Color(0xFF007AFF),
modifier = Modifier.size(24.dp)
)
}
}
// ═══════════════════════════════════════════════════════════
// ⋮ 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
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)
) {
IconButton(onClick = { onAvatarMenuChange(true) }, modifier = Modifier.size(48.dp)) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = "Profile menu",
tint = if (isColorLight(avatarColors.backgroundColor)) Color.Black else Color.White,
modifier = Modifier.size(24.dp)
imageVector = Icons.Default.MoreVert,
contentDescription = "Profile menu",
tint =
if (isColorLight(avatarColors.backgroundColor)) Color.Black
else Color.White,
modifier = Modifier.size(24.dp)
)
}
// Меню с блокировкой пользователя
com.rosetta.messenger.ui.chats.components.OtherProfileMenu(
expanded = showAvatarMenu,
onDismiss = { onAvatarMenuChange(false) },
isDarkTheme = isDarkTheme,
isBlocked = isBlocked,
onBlockClick = {
onAvatarMenuChange(false)
onBlockToggle()
},
onClearChatClick = {
onAvatarMenuChange(false)
onClearChat()
}
expanded = showAvatarMenu,
onDismiss = { onAvatarMenuChange(false) },
isDarkTheme = isDarkTheme,
isBlocked = isBlocked,
onBlockClick = {
onAvatarMenuChange(false)
onBlockToggle()
},
onClearChatClick = {
onAvatarMenuChange(false)
onClearChat()
}
)
}
// ═══════════════════════════════════════════════════════════
// 👤 AVATAR - shrinks and moves up
// ═══════════════════════════════════════════════════════════
if (avatarSize > 1.dp) {
Box(
modifier = Modifier
.offset(
x = avatarCenterX + (AVATAR_SIZE_EXPANDED_OTHER - avatarSize) / 2,
y = avatarY
)
.size(avatarSize)
.clip(CircleShape)
.background(Color.White.copy(alpha = 0.15f))
.padding(2.dp)
.clip(CircleShape),
contentAlignment = Alignment.Center
modifier =
Modifier.offset(
x =
avatarCenterX +
(AVATAR_SIZE_EXPANDED_OTHER -
avatarSize) / 2,
y = avatarY
)
.size(avatarSize)
.clip(CircleShape)
.background(Color.White.copy(alpha = 0.15f))
.padding(2.dp)
.clip(CircleShape),
contentAlignment = Alignment.Center
) {
AvatarImage(
publicKey = publicKey,
avatarRepository = avatarRepository,
size = avatarSize - 4.dp,
isDarkTheme = isDarkTheme
publicKey = publicKey,
avatarRepository = avatarRepository,
size = avatarSize - 4.dp,
isDarkTheme = isDarkTheme
)
}
}
// ═══════════════════════════════════════════════════════════
// 📝 TEXT BLOCK - Name + Verified + Online, always centered
// ═══════════════════════════════════════════════════════════
Column(
modifier = Modifier
.align(Alignment.TopCenter)
.offset(y = textY)
.graphicsLayer {
val centerOffsetY = with(density) {
androidx.compose.ui.unit.lerp(24.dp, 18.dp, collapseProgress).toPx()
}
translationY = -centerOffsetY
},
horizontalAlignment = Alignment.CenterHorizontally
modifier =
Modifier.align(Alignment.TopCenter).offset(y = textY).graphicsLayer {
val centerOffsetY =
with(density) {
androidx.compose
.ui
.unit
.lerp(24.dp, 18.dp, collapseProgress)
.toPx()
}
translationY = -centerOffsetY
},
horizontalAlignment = Alignment.CenterHorizontally
) {
// Name + Verified Badge
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Text(
text = name,
fontSize = nameFontSize,
fontWeight = FontWeight.SemiBold,
color = if (isColorLight(avatarColors.backgroundColor)) Color.Black else Color.White,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
textAlign = TextAlign.Center
text = name,
fontSize = nameFontSize,
fontWeight = FontWeight.SemiBold,
color =
if (isColorLight(avatarColors.backgroundColor)) Color.Black
else Color.White,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
textAlign = TextAlign.Center
)
if (verified > 0) {
Spacer(modifier = Modifier.width(4.dp))
VerifiedBadge(
verified = verified,
size = (nameFontSize.value * 0.8f).toInt()
)
VerifiedBadge(verified = verified, size = (nameFontSize.value * 0.8f).toInt())
}
}
Spacer(modifier = Modifier.height(2.dp))
// Online/Offline status
Text(
text = if (isOnline) "online" else "offline",
fontSize = onlineFontSize,
color = if (isOnline) {
Color(0xFF4CAF50)
} else {
if (isColorLight(avatarColors.backgroundColor)) Color.Black.copy(alpha = 0.6f) else Color.White.copy(alpha = 0.6f)
}
text = if (isOnline) "online" else "offline",
fontSize = onlineFontSize,
color =
if (isOnline) {
Color(0xFF4CAF50)
} else {
if (isColorLight(avatarColors.backgroundColor))
Color.Black.copy(alpha = 0.6f)
else Color.White.copy(alpha = 0.6f)
}
)
}
}
@@ -451,44 +454,42 @@ private fun CollapsingOtherProfileHeader(
// 🚫 BLOCK/UNBLOCK ITEM
// ═══════════════════════════════════════════════════════════
@Composable
private fun TelegramBlockItem(
isBlocked: Boolean,
onToggle: () -> Unit,
isDarkTheme: Boolean
) {
private fun TelegramBlockItem(isBlocked: Boolean, onToggle: () -> Unit, isDarkTheme: Boolean) {
val textColor = if (isDarkTheme) Color.White else Color.Black
val iconColor = PrimaryBlue
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onToggle)
.padding(horizontal = 16.dp, vertical = 14.dp),
verticalAlignment = Alignment.CenterVertically
modifier =
Modifier.fillMaxWidth()
.clickable(onClick = onToggle)
.padding(horizontal = 16.dp, vertical = 14.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Outlined.Block,
contentDescription = null,
tint = iconColor,
modifier = Modifier.size(24.dp)
imageVector = Icons.Outlined.Block,
contentDescription = null,
tint = iconColor,
modifier = Modifier.size(24.dp)
)
Spacer(modifier = Modifier.width(20.dp))
Column(modifier = Modifier.weight(1f)) {
Text(
text = if (isBlocked) "Unblock User" else "Block User",
fontSize = 16.sp,
color = iconColor,
fontWeight = FontWeight.Medium
text = if (isBlocked) "Unblock User" else "Block User",
fontSize = 16.sp,
color = iconColor,
fontWeight = FontWeight.Medium
)
Spacer(modifier = Modifier.height(2.dp))
Text(
text = if (isBlocked) "Allow this user to message you" else "Prevent this user from messaging you",
fontSize = 13.sp,
color = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666),
lineHeight = 16.sp
text =
if (isBlocked) "Allow this user to message you"
else "Prevent this user from messaging you",
fontSize = 13.sp,
color = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666),
lineHeight = 16.sp
)
}
}
}
}