feat: Replace avatar placeholder with real image loading in ChatItem and RecentUserItem components
This commit is contained in:
@@ -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)) {
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user