Make it even smoother

Signed-off-by: denis0001-dev <denis0001.dev@ya.ru>
This commit is contained in:
2026-02-19 23:46:28 +03:00
Unverified
parent 900fc3429d
commit 6303657e10
3 changed files with 14 additions and 8 deletions
@@ -8,6 +8,7 @@ import androidx.compose.animation.fadeOut
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -59,7 +60,7 @@ import ru.fromchat.api.DmEnvelope
import ru.fromchat.api.DmFile
private val IMAGE_SIZE = 160.dp
private val IMAGE_RADIUS = 8.dp
private val IMAGE_RADIUS = 12.dp
internal fun isImageFilename(name: String): Boolean =
name.endsWith(".png", true) || name.endsWith(".jpg", true) ||
@@ -125,7 +126,7 @@ fun AttachmentPreview(
Box(
modifier = modifier
.then(
if (onImageClick != null && isFullyLoaded && !isExpanded) Modifier.clickable(onClick = onImageClick)
if (onImageClick != null && isFullyLoaded && !isExpanded) Modifier.clickable(indication = null, interactionSource = remember { MutableInteractionSource() }, onClick = onImageClick)
else Modifier
)
.conditional(
@@ -180,7 +180,7 @@ fun ImageFullscreenPreview(
val thumbWidth = thumbnailBounds.width
val s = thumbWidth / containerWidth
val o = thumbCenter - fullCenter
InitialTransform(s, o.x, o.y, 8f, 0f)
InitialTransform(s, o.x, o.y, 12f, 0f)
} else {
InitialTransform(1f, 0f, 0f, 0f, 1f)
}
@@ -216,7 +216,7 @@ fun ImageFullscreenPreview(
scaleAnim.snapTo(startScale)
offsetXAnim.snapTo(startOffset.x)
offsetYAnim.snapTo(startOffset.y)
cornerRadiusAnim.snapTo(8f)
cornerRadiusAnim.snapTo(12f)
backgroundAlpha.snapTo(0f)
menusVisible = false
@@ -262,7 +262,7 @@ fun ImageFullscreenPreview(
launch { scaleAnim.animateTo(targetScale, tween(250)) }
launch { offsetXAnim.animateTo(targetOffset.x, tween(250)) }
launch { offsetYAnim.animateTo(targetOffset.y, tween(250)) }
launch { cornerRadiusAnim.animateTo(8f, tween(250)) }
launch { cornerRadiusAnim.animateTo(12f, tween(250)) }
launch { backgroundAlpha.animateTo(0f, tween(250)) }
}
} else {
@@ -351,8 +351,9 @@ fun ImageFullscreenPreview(
.graphicsLayer {
scaleX = scaleAnim.value
scaleY = scaleAnim.value
shape = androidx.compose.foundation.shape.RoundedCornerShape(cornerRadiusAnim.value.dp)
clip = cornerRadiusAnim.value > 0f
val scale = maxOf(scaleAnim.value, 0.01f)
shape = androidx.compose.foundation.shape.RoundedCornerShape((cornerRadiusAnim.value / scale).dp)
clip = true
},
contentScale = ContentScale.FillWidth
)
@@ -119,6 +119,10 @@ fun MessageItem(
) {
// Message bubble
val isDark = isSystemInDarkTheme()
val firstContentIsImage = (!showUsername || isAuthor) &&
message.reply_to == null &&
(message.pendingFileUri?.let { isImageFilename(it.substringAfterLast('/').substringBefore('?')) } == true ||
message.files?.firstOrNull()?.let { isImageFilename(it.name) } == true)
Box(
modifier = Modifier
// Max width: 70% of row, min width: content-driven
@@ -151,7 +155,7 @@ fun MessageItem(
background(MaterialTheme.colorScheme.surfaceContainerHighest)
}
)
.padding(top = 6.dp)
.padding(top = if (firstContentIsImage) 0.dp else 6.dp)
) {
Column {
// Username inside bubble (for received messages)