feat: Implement emoji preloading in background for improved performance
This commit is contained in:
@@ -260,8 +260,7 @@ fun ChatDetailScreen(
|
||||
|
||||
// Состояние показа логов
|
||||
var showLogs by remember { mutableStateOf(false) }
|
||||
// val debugLogs by ProtocolManager.debugLogs.collectAsState()
|
||||
val debugLogs = remember { emptyList<String>() }
|
||||
val debugLogs by com.rosetta.messenger.network.ProtocolManager.debugLogs.collectAsState()
|
||||
|
||||
// Состояние выпадающего меню
|
||||
var showMenu by remember { mutableStateOf(false) }
|
||||
@@ -345,6 +344,8 @@ fun ChatDetailScreen(
|
||||
if (!isSavedMessages) {
|
||||
viewModel.subscribeToOnlineStatus()
|
||||
}
|
||||
// 🔥 Предзагружаем эмодзи в фоне
|
||||
com.rosetta.messenger.ui.components.EmojiCache.preload(context)
|
||||
}
|
||||
|
||||
// Отмечаем сообщения как прочитанные когда они видны
|
||||
@@ -658,6 +659,30 @@ fun ChatDetailScreen(
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// Debug Logs
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
Icons.Default.BugReport,
|
||||
contentDescription = null,
|
||||
tint = secondaryTextColor,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
Text(
|
||||
"Debug Logs",
|
||||
color = textColor,
|
||||
fontSize = 16.sp
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
showMenu = false
|
||||
showLogs = true
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -940,7 +965,7 @@ fun ChatDetailScreen(
|
||||
}
|
||||
|
||||
// 🔥 SELECTION ACTION BAR - Reply/Forward (появляется при выборе сообщений)
|
||||
// Стеклянный стиль как у инпута с блюром
|
||||
// Плоский стиль как у инпута с border сверху
|
||||
AnimatedVisibility(
|
||||
visible = isSelectionMode,
|
||||
enter = fadeIn(tween(200)) + slideInVertically(initialOffsetY = { it }),
|
||||
@@ -949,46 +974,36 @@ fun ChatDetailScreen(
|
||||
.align(Alignment.BottomCenter)
|
||||
.fillMaxWidth()
|
||||
.imePadding()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||
) {
|
||||
// Glass container с эффектом блюра
|
||||
Box(
|
||||
// Плоский контейнер как у инпута
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(24.dp))
|
||||
.background(
|
||||
if (isDarkTheme) Color(0xFF1C1C1E).copy(alpha = 0.7f)
|
||||
else Color(0xFFF8F9FA).copy(alpha = 0.8f)
|
||||
)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = if (isDarkTheme) Color.White.copy(alpha = 0.12f)
|
||||
else Color.Black.copy(alpha = 0.08f),
|
||||
shape = RoundedCornerShape(24.dp)
|
||||
)
|
||||
.background(backgroundColor)
|
||||
) {
|
||||
// Border сверху
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(0.5.dp)
|
||||
.background(if (isDarkTheme) Color.White.copy(alpha = 0.15f) else Color.Black.copy(alpha = 0.1f))
|
||||
)
|
||||
|
||||
// Кнопки Reply и Forward
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 10.dp, horizontal = 12.dp),
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||
.padding(bottom = if (WindowInsets.ime.getBottom(LocalDensity.current) == 0) 16.dp else 0.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
// Reply button - стеклянная кнопка с блюром
|
||||
// Reply button
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(
|
||||
if (isDarkTheme) Color.White.copy(alpha = 0.1f)
|
||||
else Color.Black.copy(alpha = 0.06f)
|
||||
)
|
||||
.border(
|
||||
width = 0.5.dp,
|
||||
color = if (isDarkTheme) Color.White.copy(alpha = 0.15f)
|
||||
else Color.Black.copy(alpha = 0.1f),
|
||||
shape = RoundedCornerShape(16.dp)
|
||||
)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.background(PrimaryBlue.copy(alpha = 0.1f))
|
||||
.clickable {
|
||||
val selectedMsgs = messages
|
||||
.filter { selectedMessages.contains(it.id) }
|
||||
@@ -996,7 +1011,7 @@ fun ChatDetailScreen(
|
||||
viewModel.setReplyMessages(selectedMsgs)
|
||||
selectedMessages = emptySet()
|
||||
}
|
||||
.padding(vertical = 14.dp, horizontal = 16.dp),
|
||||
.padding(vertical = 14.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Row(
|
||||
@@ -1019,21 +1034,12 @@ fun ChatDetailScreen(
|
||||
}
|
||||
}
|
||||
|
||||
// Forward button - стеклянная кнопка с блюром
|
||||
// Forward button
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(
|
||||
if (isDarkTheme) Color.White.copy(alpha = 0.1f)
|
||||
else Color.Black.copy(alpha = 0.06f)
|
||||
)
|
||||
.border(
|
||||
width = 0.5.dp,
|
||||
color = if (isDarkTheme) Color.White.copy(alpha = 0.15f)
|
||||
else Color.Black.copy(alpha = 0.1f),
|
||||
shape = RoundedCornerShape(16.dp)
|
||||
)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.background(PrimaryBlue.copy(alpha = 0.1f))
|
||||
.clickable {
|
||||
val selectedMsgs = messages
|
||||
.filter { selectedMessages.contains(it.id) }
|
||||
@@ -1041,7 +1047,7 @@ fun ChatDetailScreen(
|
||||
viewModel.setForwardMessages(selectedMsgs)
|
||||
selectedMessages = emptySet()
|
||||
}
|
||||
.padding(vertical = 14.dp, horizontal = 16.dp),
|
||||
.padding(vertical = 14.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Row(
|
||||
@@ -1074,27 +1080,37 @@ fun ChatDetailScreen(
|
||||
if (showLogs) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { showLogs = false },
|
||||
containerColor = if (isDarkTheme) Color(0xFF1C1C1E) else Color.White,
|
||||
title = {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text("Debug Logs", fontWeight = FontWeight.Bold)
|
||||
Text("Debug Logs (${debugLogs.size})", fontWeight = FontWeight.Bold, color = textColor)
|
||||
IconButton(
|
||||
onClick = {
|
||||
// ProtocolManager.clearLogs()
|
||||
com.rosetta.messenger.network.ProtocolManager.clearLogs()
|
||||
}
|
||||
) { Icon(Icons.Default.Delete, contentDescription = "Clear") }
|
||||
) { Icon(Icons.Default.Delete, contentDescription = "Clear", tint = Color(0xFFFF3B30)) }
|
||||
}
|
||||
},
|
||||
text = {
|
||||
LazyColumn(modifier = Modifier.fillMaxWidth().heightIn(max = 400.dp)) {
|
||||
LazyColumn(modifier = Modifier.fillMaxWidth().heightIn(max = 500.dp)) {
|
||||
items(debugLogs.reversed()) { log ->
|
||||
val logColor = when {
|
||||
log.contains("❌") || log.contains("Error") -> Color(0xFFFF3B30)
|
||||
log.contains("✅") -> Color(0xFF38B24D)
|
||||
log.contains("📤") -> PrimaryBlue
|
||||
log.contains("📥") -> Color(0xFFFF9500)
|
||||
log.contains("⚠️") -> Color(0xFFFFCC00)
|
||||
else -> if (isDarkTheme) Color.White.copy(alpha = 0.8f) else Color.Black.copy(alpha = 0.8f)
|
||||
}
|
||||
Text(
|
||||
text = log,
|
||||
fontSize = 12.sp,
|
||||
fontSize = 11.sp,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
color = logColor,
|
||||
modifier = Modifier.padding(vertical = 2.dp)
|
||||
)
|
||||
}
|
||||
@@ -1102,14 +1118,14 @@ fun ChatDetailScreen(
|
||||
item {
|
||||
Text(
|
||||
text = "No logs yet. Try sending a message.",
|
||||
color = Color.Gray,
|
||||
color = secondaryTextColor,
|
||||
fontSize = 12.sp
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = { TextButton(onClick = { showLogs = false }) { Text("Close") } }
|
||||
confirmButton = { TextButton(onClick = { showLogs = false }) { Text("Close", color = PrimaryBlue) } }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1620,39 +1636,44 @@ private fun MessageInputBar(
|
||||
.fillMaxWidth()
|
||||
.imePadding()
|
||||
) {
|
||||
// Если пользователь заблокирован - показываем BlockedChatFooter
|
||||
// Если пользователь заблокирован - показываем BlockedChatFooter (плоский как инпут)
|
||||
if (isBlocked) {
|
||||
// BLOCKED CHAT FOOTER
|
||||
Row(
|
||||
// BLOCKED CHAT FOOTER - плоский стиль
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 16.dp)
|
||||
.background(
|
||||
color = if (isDarkTheme) Color(0xFF2C2C2E) else Color(0xFFF2F3F5),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = if (isDarkTheme) Color(0xFF3A3A3C) else Color(0xFFE5E5EA),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
)
|
||||
.padding(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.Center
|
||||
.background(backgroundColor)
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Block,
|
||||
contentDescription = null,
|
||||
tint = Color(0xFFFF6B6B),
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = "You need to unblock user to send messages.",
|
||||
fontSize = 14.sp,
|
||||
color = secondaryTextColor,
|
||||
textAlign = androidx.compose.ui.text.style.TextAlign.Center
|
||||
// Border сверху
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(0.5.dp)
|
||||
.background(if (isDarkTheme) Color.White.copy(alpha = 0.1f) else Color.Black.copy(alpha = 0.08f))
|
||||
)
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 16.dp)
|
||||
.padding(bottom = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.Center
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Block,
|
||||
contentDescription = null,
|
||||
tint = Color(0xFFFF6B6B),
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = "You need to unblock user to send messages.",
|
||||
fontSize = 14.sp,
|
||||
color = secondaryTextColor,
|
||||
textAlign = androidx.compose.ui.text.style.TextAlign.Center
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 🔥 TELEGRAM STYLE: фон как у чата, верхний border
|
||||
|
||||
Reference in New Issue
Block a user