feat: Replace avatar placeholder with real image loading in ChatItem and RecentUserItem components

This commit is contained in:
k1ngsterr1
2026-01-28 02:10:00 +05:00
parent 3b4e4ee594
commit 6b59ed9bd8
2 changed files with 45 additions and 49 deletions

View File

@@ -10,6 +10,9 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.platform.LocalContext
import com.rosetta.messenger.repository.AvatarRepository
import com.rosetta.messenger.ui.components.AvatarImage
import androidx.compose.material3.* import androidx.compose.material3.*
import compose.icons.TablerIcons import compose.icons.TablerIcons
import compose.icons.tablericons.* import compose.icons.tablericons.*
@@ -1217,7 +1220,12 @@ private fun EmptyChatsState(isDarkTheme: Boolean, modifier: Modifier = Modifier)
// Chat item for list // Chat item for list
@Composable @Composable
fun ChatItem(chat: Chat, isDarkTheme: Boolean, onClick: () -> Unit) { fun ChatItem(
chat: Chat,
isDarkTheme: Boolean,
avatarRepository: com.rosetta.messenger.repository.AvatarRepository? = null,
onClick: () -> Unit
) {
val textColor = if (isDarkTheme) Color.White else Color.Black val textColor = if (isDarkTheme) Color.White else Color.Black
val secondaryTextColor = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666) val secondaryTextColor = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666)
val dividerColor = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE8E8E8) val dividerColor = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE8E8E8)
@@ -1233,41 +1241,16 @@ fun ChatItem(chat: Chat, isDarkTheme: Boolean, onClick: () -> Unit) {
.padding(horizontal = 16.dp, vertical = 12.dp), .padding(horizontal = 16.dp, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
// Avatar // Avatar with real image
Box( AvatarImage(
modifier = publicKey = chat.publicKey,
Modifier.size(56.dp) avatarRepository = avatarRepository,
.clip(CircleShape) size = 56.dp,
.background(avatarColors.backgroundColor), isDarkTheme = isDarkTheme,
contentAlignment = Alignment.Center showOnlineIndicator = true,
) { isOnline = chat.isOnline
Text(
text = avatarText,
fontSize = 20.sp,
fontWeight = FontWeight.SemiBold,
color = avatarColors.textColor
) )
// Online indicator
if (chat.isOnline) {
Box(
modifier =
Modifier.align(Alignment.BottomEnd)
.offset(x = 2.dp, y = 2.dp)
.size(16.dp)
.clip(CircleShape)
.background(
if (isDarkTheme)
Color(0xFF1A1A1A)
else Color.White
)
.padding(2.dp)
.clip(CircleShape)
.background(Color(0xFF4CAF50))
)
}
}
Spacer(modifier = Modifier.width(12.dp)) Spacer(modifier = Modifier.width(12.dp))
Column(modifier = Modifier.weight(1f)) { Column(modifier = Modifier.weight(1f)) {

View File

@@ -28,6 +28,9 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import com.rosetta.messenger.repository.AvatarRepository
import com.rosetta.messenger.ui.components.AvatarImage
import com.rosetta.messenger.database.RosettaDatabase
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -84,6 +87,20 @@ fun SearchScreen(
// Recent users - отложенная подписка // Recent users - отложенная подписка
val recentUsers by RecentSearchesManager.recentUsers.collectAsState() val recentUsers by RecentSearchesManager.recentUsers.collectAsState()
// AvatarRepository для загрузки аватаров
val avatarRepository = remember(currentUserPublicKey) {
if (currentUserPublicKey.isNotBlank()) {
val database = RosettaDatabase.getDatabase(context)
AvatarRepository(
context = context,
avatarDao = database.avatarDao(),
currentPublicKey = currentUserPublicKey
)
} else {
null
}
}
// 🔥 ОПТИМИЗАЦИЯ: Lottie загружается асинхронно и не блокирует первый кадр // 🔥 ОПТИМИЗАЦИЯ: Lottie загружается асинхронно и не блокирует первый кадр
val searchLottieComposition by val searchLottieComposition by
rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.search)) rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.search))
@@ -258,6 +275,7 @@ fun SearchScreen(
isDarkTheme = isDarkTheme, isDarkTheme = isDarkTheme,
textColor = textColor, textColor = textColor,
secondaryTextColor = secondaryTextColor, secondaryTextColor = secondaryTextColor,
avatarRepository = avatarRepository,
onClick = { onClick = {
hideKeyboardInstantly() hideKeyboardInstantly()
RecentSearchesManager.addUser(user) RecentSearchesManager.addUser(user)
@@ -325,6 +343,7 @@ private fun RecentUserItem(
isDarkTheme: Boolean, isDarkTheme: Boolean,
textColor: Color, textColor: Color,
secondaryTextColor: Color, secondaryTextColor: Color,
avatarRepository: AvatarRepository?,
onClick: () -> Unit, onClick: () -> Unit,
onRemove: () -> Unit onRemove: () -> Unit
) { ) {
@@ -344,20 +363,14 @@ private fun RecentUserItem(
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
// Avatar // Avatar
Box( AvatarImage(
modifier = publicKey = user.publicKey,
Modifier.size(48.dp) avatarRepository = avatarRepository,
.clip(CircleShape) size = 48.dp,
.background(avatarColors.backgroundColor), isDarkTheme = isDarkTheme,
contentAlignment = Alignment.Center showOnlineIndicator = false,
) { isOnline = false
Text(
text = initials,
fontSize = 16.sp,
fontWeight = FontWeight.SemiBold,
color = avatarColors.textColor
) )
}
Spacer(modifier = Modifier.width(12.dp)) Spacer(modifier = Modifier.width(12.dp))