Fix sticker capture and rendering

This commit is contained in:
sevenhill
2026-07-06 13:37:07 +03:00
parent 30361370da
commit e50b99bcd2
3 changed files with 223 additions and 24 deletions
@@ -2506,6 +2506,7 @@ private fun replyPreviewBody(message: MessageDto): String {
val attachment = message.attachments.firstOrNull() ?: return "Message"
return when {
attachment.isEmojiAttachment() -> "Emoji"
attachment.isStickerAttachment() -> "Sticker"
attachment.isImageAttachment() -> "Photo"
attachment.isVideoAttachment() -> "Video"
attachment.isVoiceAttachment() -> "Voice message"
@@ -2689,6 +2690,13 @@ private fun AttachmentView(
cachedImagePath,
vm
)
attachment.isStickerAttachment() -> StickerAttachment(
attachment,
url,
session.accessToken,
cachedImagePath,
vm
)
attachment.isImageAttachment() -> ImageAttachment(
attachment,
url,
@@ -2704,6 +2712,47 @@ private fun AttachmentView(
}
}
@Composable
private fun StickerAttachment(
attachment: AttachmentDto,
url: String,
token: String,
cachedImagePath: String?,
vm: QMaxViewModel
) {
LaunchedEffect(attachment.id, url) {
vm.cacheImage(attachment)
}
val model = cachedImagePath?.let(::File) ?: imageRequest(url, token)
var imageLoaded by remember(attachment.id, cachedImagePath, url) { mutableStateOf(false) }
var imageFailed by remember(attachment.id, cachedImagePath, url) { mutableStateOf(false) }
Box(
modifier = Modifier
.size(156.dp)
.clip(RoundedCornerShape(6.dp))
.clickable { vm.openImage(cachedImagePath ?: url, listOf(cachedImagePath ?: url)) },
contentAlignment = Alignment.Center
) {
AsyncImage(
model = model,
contentDescription = attachment.fileName,
contentScale = ContentScale.Fit,
modifier = Modifier.fillMaxSize(),
onSuccess = {
imageLoaded = true
imageFailed = false
},
onError = {
imageLoaded = false
imageFailed = true
}
)
if (!imageLoaded) {
MediaImagePlaceholder(failed = imageFailed)
}
}
}
@Composable
private fun EmojiAttachment(
attachment: AttachmentDto,
@@ -3685,7 +3734,7 @@ private fun imageRequest(url: String, token: String): ImageRequest {
}
private fun AttachmentDto.isImageAttachment(): Boolean {
if (isEmojiAttachment()) {
if (isEmojiAttachment() || isStickerAttachment()) {
return false
}
return kind.equals("Image", true) ||
@@ -3700,6 +3749,12 @@ private fun AttachmentDto.isEmojiAttachment(): Boolean {
kind.equals("Emoji", true)
}
private fun AttachmentDto.isStickerAttachment(): Boolean {
val normalizedFileName = fileName.lowercase(Locale.ROOT)
return kind.equals("Sticker", true) ||
normalizedFileName.startsWith("max-sticker-")
}
private fun AttachmentDto.isContactAttachment(): Boolean {
return kind.equals("Contact", true) ||
contentType.contains("vcard", ignoreCase = true) ||
@@ -81,6 +81,7 @@ class AttachmentDiskCache(context: Context) {
attachment.downloadPath,
attachment.fileName,
attachment.contentType,
attachment.kind,
attachment.fileSizeBytes.toString()
).joinToString("|")
).take(40)