feat: Add timestamp and message status to MessageBubble and ImageAttachment components
This commit is contained in:
@@ -3,13 +3,14 @@ package com.rosetta.messenger.ui.chats.components
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Canvas
|
||||
import android.util.Base64
|
||||
import android.util.Log
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
@@ -23,18 +24,23 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
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.ui.geometry.CornerRadius
|
||||
import compose.icons.TablerIcons
|
||||
import compose.icons.tablericons.*
|
||||
import com.rosetta.messenger.crypto.CryptoManager
|
||||
import com.rosetta.messenger.crypto.MessageCrypto
|
||||
import com.rosetta.messenger.network.AttachmentType
|
||||
import com.rosetta.messenger.network.MessageAttachment
|
||||
import com.rosetta.messenger.network.TransportManager
|
||||
import com.rosetta.messenger.repository.AvatarRepository
|
||||
import com.rosetta.messenger.ui.chats.models.MessageStatus
|
||||
import com.rosetta.messenger.ui.onboarding.PrimaryBlue
|
||||
import com.rosetta.messenger.utils.AvatarFileManager
|
||||
import com.vanniktech.blurhash.BlurHash
|
||||
@@ -67,6 +73,8 @@ fun MessageAttachments(
|
||||
isOutgoing: Boolean,
|
||||
isDarkTheme: Boolean,
|
||||
senderPublicKey: String,
|
||||
timestamp: java.util.Date,
|
||||
messageStatus: MessageStatus = MessageStatus.READ,
|
||||
avatarRepository: AvatarRepository? = null,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
@@ -84,7 +92,9 @@ fun MessageAttachments(
|
||||
chachaKey = chachaKey,
|
||||
privateKey = privateKey,
|
||||
isOutgoing = isOutgoing,
|
||||
isDarkTheme = isDarkTheme
|
||||
isDarkTheme = isDarkTheme,
|
||||
timestamp = timestamp,
|
||||
messageStatus = messageStatus
|
||||
)
|
||||
}
|
||||
AttachmentType.FILE -> {
|
||||
@@ -124,7 +134,9 @@ fun ImageAttachment(
|
||||
chachaKey: String,
|
||||
privateKey: String,
|
||||
isOutgoing: Boolean,
|
||||
isDarkTheme: Boolean
|
||||
isDarkTheme: Boolean,
|
||||
timestamp: java.util.Date,
|
||||
messageStatus: MessageStatus = MessageStatus.READ
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -224,12 +236,20 @@ fun ImageAttachment(
|
||||
}
|
||||
}
|
||||
|
||||
// Telegram-style image с blurhash placeholder
|
||||
// Telegram-style image с blurhash placeholder и тонким бордером
|
||||
val timeFormat = remember { java.text.SimpleDateFormat("HH:mm", java.util.Locale.getDefault()) }
|
||||
val borderColor = if (isOutgoing) {
|
||||
Color.White.copy(alpha = 0.15f)
|
||||
} else {
|
||||
if (isDarkTheme) Color.White.copy(alpha = 0.1f) else Color.Black.copy(alpha = 0.08f)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.widthIn(min = 180.dp, max = 260.dp)
|
||||
.heightIn(min = 140.dp, max = 300.dp)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.background(Color.Transparent)
|
||||
.clickable {
|
||||
when (downloadStatus) {
|
||||
DownloadStatus.NOT_DOWNLOADED -> download()
|
||||
@@ -272,6 +292,81 @@ fun ImageAttachment(
|
||||
}
|
||||
}
|
||||
|
||||
// Тонкий бордер как в Telegram (просто через border modifier)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = borderColor,
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
)
|
||||
)
|
||||
|
||||
// Время в правом нижнем углу (только если изображение загружено)
|
||||
if (downloadStatus == DownloadStatus.DOWNLOADED) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomEnd)
|
||||
.padding(8.dp)
|
||||
.background(
|
||||
Color.Black.copy(alpha = 0.5f),
|
||||
shape = RoundedCornerShape(10.dp)
|
||||
)
|
||||
.padding(horizontal = 6.dp, vertical = 3.dp)
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(2.dp)
|
||||
) {
|
||||
Text(
|
||||
text = timeFormat.format(timestamp),
|
||||
color = Color.White,
|
||||
fontSize = 11.sp,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
if (isOutgoing) {
|
||||
// Статус доставки для исходящих
|
||||
when (messageStatus) {
|
||||
MessageStatus.SENDING -> {
|
||||
Icon(
|
||||
compose.icons.TablerIcons.Clock,
|
||||
contentDescription = null,
|
||||
tint = Color.White.copy(alpha = 0.7f),
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
MessageStatus.SENT -> {
|
||||
Icon(
|
||||
compose.icons.TablerIcons.Check,
|
||||
contentDescription = null,
|
||||
tint = Color.White.copy(alpha = 0.7f),
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
MessageStatus.DELIVERED -> {
|
||||
Icon(
|
||||
compose.icons.TablerIcons.Checks,
|
||||
contentDescription = null,
|
||||
tint = Color.White.copy(alpha = 0.7f),
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
MessageStatus.READ -> {
|
||||
Icon(
|
||||
compose.icons.TablerIcons.Checks,
|
||||
contentDescription = null,
|
||||
tint = Color(0xFF4FC3F7),
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Оверлей для статуса скачивания
|
||||
if (downloadStatus != DownloadStatus.DOWNLOADED) {
|
||||
Box(
|
||||
|
||||
@@ -345,7 +345,9 @@ fun MessageBubble(
|
||||
privateKey = privateKey,
|
||||
isOutgoing = message.isOutgoing,
|
||||
isDarkTheme = isDarkTheme,
|
||||
senderPublicKey = senderPublicKey
|
||||
senderPublicKey = senderPublicKey,
|
||||
timestamp = message.timestamp,
|
||||
messageStatus = message.status
|
||||
)
|
||||
if (message.text.isNotEmpty()) {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
Reference in New Issue
Block a user