package chats.presentation.components import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.runtime.remember import chats.domain.model.Chat import chats.domain.model.Message import chats.domain.model.MediaType import core.presentation.components.AppAvatar import ru.knot.messager.R import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Done import androidx.compose.material.icons.filled.DoneAll @Composable fun ChatItem( chat: Chat, onClick: (String) -> Unit ) { val currentUserId = "current_user_id" // TODO: Get from AuthManager/TokenManager Row( modifier = Modifier .fillMaxWidth() .clickable { onClick(chat.id) } .padding(12.dp), verticalAlignment = Alignment.CenterVertically ) { AppAvatar( url = chat.avatar, name = chat.name, size = 50.dp ) Spacer(modifier = Modifier.width(12.dp)) Column(modifier = Modifier.weight(1f)) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { Text( text = chat.name, style = MaterialTheme.typography.bodyLarge.copy(fontWeight = FontWeight.Bold), maxLines = 1, overflow = TextOverflow.Ellipsis ) chat.lastMessage?.let { val formattedTime = remember(it.createdAt) { try { it.createdAt.substringAfter('T').take(5) } catch (e: Exception) { "" } } Text( text = formattedTime, style = MaterialTheme.typography.labelSmall, color = Color.Gray ) } } Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { val context = LocalContext.current val previewText = remember(chat.lastMessage) { val msg = chat.lastMessage if (msg == null) return@remember context.getString(R.string.no_messages_yet) if (!msg.content.isNullOrBlank()) { msg.content } else if (msg.mediaType == MediaType.AUDIO) { context.getString(R.string.voice_message) } else if (msg.media.isNotEmpty()) { when (msg.mediaType) { MediaType.IMAGE -> "Фото" MediaType.VIDEO -> "Видео" MediaType.FILE -> "Файл" else -> "Медиа" } } else { context.getString(R.string.message) } } Text( text = previewText, style = MaterialTheme.typography.bodyMedium, color = Color.Gray, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.weight(1f) ) Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(start = 8.dp) ) { // Галочки прочтения только для своих сообщений chat.lastMessage?.let { lastMessage -> if (lastMessage.senderId == currentUserId && !lastMessage.isRead) { Icon( imageVector = Icons.Default.Done, contentDescription = null, tint = Color.Gray, modifier = Modifier.size(14.dp) ) } else if (lastMessage.senderId == currentUserId && lastMessage.isRead) { Icon( imageVector = Icons.Default.DoneAll, contentDescription = null, tint = Color.Blue, modifier = Modifier.size(14.dp) ) } } if (chat.unreadCount > 0) { Spacer(modifier = Modifier.width(4.dp)) Box( modifier = Modifier .background(MaterialTheme.colorScheme.primary, CircleShape) .padding(horizontal = 6.dp, vertical = 2.dp), contentAlignment = Alignment.Center ) { Text( text = chat.unreadCount.toString(), color = Color.White, fontSize = 10.sp, fontWeight = FontWeight.Bold ) } } } } } } }