Attempt to fix the blur

Signed-off-by: denis0001-dev <denis0001.dev@ya.ru>
This commit is contained in:
2026-03-09 15:50:17 +03:00
Unverified
parent 77aa3fce14
commit 46426ec51b
@@ -4,6 +4,7 @@ import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animate import androidx.compose.animation.core.animate
import androidx.compose.animation.core.spring import androidx.compose.animation.core.spring
import androidx.compose.foundation.LocalIndication import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@@ -34,6 +35,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.TransformOrigin import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
@@ -47,8 +49,8 @@ import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupProperties import androidx.compose.ui.window.PopupProperties
import dev.chrisbanes.haze.HazeState import dev.chrisbanes.haze.HazeState
import dev.chrisbanes.haze.hazeEffect import dev.chrisbanes.haze.hazeEffect
import dev.chrisbanes.haze.materials.CupertinoMaterials
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
import dev.chrisbanes.haze.materials.HazeMaterials
import ru.fromchat.api.Message import ru.fromchat.api.Message
import ru.fromchat.ui.scaleOnPress import ru.fromchat.ui.scaleOnPress
@@ -236,9 +238,6 @@ private fun ContextMenuContent(
) { ) {
val menuShape = RoundedCornerShape(16.dp) val menuShape = RoundedCornerShape(16.dp)
val menuScrollState = rememberScrollState() val menuScrollState = rememberScrollState()
val baseModifier = modifier.width(IntrinsicSize.Max)
val clipped = baseModifier.clip(menuShape)
val density = LocalDensity.current val density = LocalDensity.current
val shadowElevationPx = if (withShadow) { val shadowElevationPx = if (withShadow) {
with(density) { 12.dp.toPx() } with(density) { 12.dp.toPx() }
@@ -246,59 +245,82 @@ private fun ContextMenuContent(
0f 0f
} }
val finalModifier = val baseModifier = modifier.width(IntrinsicSize.Max)
if (hazeState != null) {
clipped // Container that scales around the finger pivot and owns the material
.graphicsLayer( // bounds (shape + clipping) so the blur region exactly matches the card.
scaleX = if (animated) scale else 1f, val animatedContainerModifier =
scaleY = if (animated) scale else 1f, if (animated) {
alpha = if (animated) alpha else 1f, baseModifier.graphicsLayer(
transformOrigin = TransformOrigin(transformOriginX, transformOriginY), scaleX = scale,
shadowElevation = shadowElevationPx, scaleY = scale,
shape = menuShape, alpha = alpha,
clip = true transformOrigin = TransformOrigin(transformOriginX, transformOriginY),
) shadowElevation = shadowElevationPx,
.hazeEffect(state = hazeState, style = CupertinoMaterials.regular()) { shape = menuShape,
blurRadius = 8.dp clip = true
} )
} else { } else {
clipped.graphicsLayer( baseModifier.graphicsLayer(
shadowElevation = shadowElevationPx, shadowElevation = shadowElevationPx,
shape = menuShape, shape = menuShape,
clip = true clip = true
) )
} }
// Blur matches the material bounds from the parent, without its own transforms.
// Use a prebuilt material style, but with a transparent container color so we
// only get the blur characteristics, not an extra color wash.
val blurModifier =
if (hazeState != null) {
Modifier.hazeEffect(
state = hazeState,
style = HazeMaterials.thin(containerColor = Color.Transparent)
) {
noiseFactor = 0f
}
} else {
Modifier
}
// Fully transparent tint so we only see the material blur underneath.
val contentBackgroundColor = MaterialTheme.colorScheme.surface.copy(alpha = 0f)
val edgePadding = 8.dp val edgePadding = 8.dp
val itemSpacing = 2.dp val itemSpacing = 2.dp
Box(modifier = finalModifier) { Box(modifier = animatedContainerModifier) {
Column( Box(
modifier = Modifier modifier = blurModifier
.padding(horizontal = edgePadding, vertical = edgePadding) .background(contentBackgroundColor)
.verticalScroll(menuScrollState),
verticalArrangement = Arrangement.spacedBy(itemSpacing)
) { ) {
ContextMenuItem( Column(
icon = Icons.AutoMirrored.Filled.Reply, modifier = Modifier
text = "Reply", .padding(horizontal = edgePadding, vertical = edgePadding)
onClick = { .verticalScroll(menuScrollState),
onReply(message) verticalArrangement = Arrangement.spacedBy(itemSpacing)
) {
ContextMenuItem(
icon = Icons.AutoMirrored.Filled.Reply,
text = "Reply",
onClick = {
onReply(message)
}
)
if (isAuthor) {
ContextMenuItem(
icon = Icons.Default.Edit,
text = "Edit",
onClick = { onEdit(message) }
)
}
if (isAuthor) {
ContextMenuItem(
icon = Icons.Default.Delete,
text = "Delete",
onClick = { onDelete(message) },
isError = true
)
} }
)
if (isAuthor) {
ContextMenuItem(
icon = Icons.Default.Edit,
text = "Edit",
onClick = { onEdit(message) }
)
}
if (isAuthor) {
ContextMenuItem(
icon = Icons.Default.Delete,
text = "Delete",
onClick = { onDelete(message) },
isError = true
)
} }
} }
} }