From e8eae1eb97ee060aed9b4bda3c8807855de05a3e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 15 Oct 2024 10:29:53 +0200 Subject: [PATCH 1/3] RTL: ensure the top start corner is cropped. --- .../timeline/components/MessageEventBubble.kt | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt index f080bc58dd..1e69dbaa72 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt @@ -18,7 +18,10 @@ import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ripple import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -29,7 +32,10 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.CompositingStrategy import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.features.messages.impl.timeline.model.TimelineItemGroupPosition @@ -101,6 +107,8 @@ fun MessageEventBubble( val bubbleShape = bubbleShape() val radiusPx = (avatarRadius + SENDER_AVATAR_BORDER_WIDTH).toPx() val yOffsetPx = -(NEGATIVE_MARGIN_FOR_BUBBLE + avatarRadius).toPx() + val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl + var contentWidthPx by remember { mutableFloatStateOf(0f) } BoxWithConstraints( modifier = modifier .graphicsLayer { @@ -112,7 +120,7 @@ fun MessageEventBubble( drawCircle( color = Color.Black, center = Offset( - x = 0f, + x = if (isRtl) contentWidthPx else 0f, y = yOffsetPx, ), radius = radiusPx, @@ -129,7 +137,9 @@ fun MessageEventBubble( .testTag(TestTags.messageBubble) .widthIn( min = MIN_BUBBLE_WIDTH, - max = (constraints.maxWidth * BUBBLE_WIDTH_RATIO).toInt().toDp() + max = (constraints.maxWidth * BUBBLE_WIDTH_RATIO) + .toInt() + .toDp() ) .clip(bubbleShape) .combinedClickable( @@ -137,7 +147,10 @@ fun MessageEventBubble( onLongClick = onLongClick, indication = ripple(), interactionSource = interactionSource - ), + ) + .onGloballyPositioned { coordinates -> + contentWidthPx = coordinates.size.width.toFloat() + }, color = backgroundBubbleColor, shape = bubbleShape, content = content From 98fbb04fae6f2879c0feba267068a9f5a3fc6b11 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 15 Oct 2024 10:39:59 +0200 Subject: [PATCH 2/3] RTL: ensure the sender information are displayed at the start of the screen. --- .../messages/impl/timeline/components/TimelineItemEventRow.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index 67342203bd..06567f2d32 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -301,6 +301,8 @@ private fun TimelineItemEventRowContent( Modifier .constrainAs(sender) { top.linkTo(parent.top) + // Required for correct RTL layout + start.linkTo(parent.start) } .padding(horizontal = 16.dp) .zIndex(1f) From 4ec7e6fa87dbf88d521c79f31ee901bd2fffe68e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 16 Oct 2024 11:26:26 +0200 Subject: [PATCH 3/3] Use size from the DrawScope. --- .../impl/timeline/components/MessageEventBubble.kt | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt index 1e69dbaa72..50a1dd2a94 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt @@ -18,10 +18,7 @@ import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ripple import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -32,7 +29,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.CompositingStrategy import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.LayoutDirection @@ -108,7 +104,6 @@ fun MessageEventBubble( val radiusPx = (avatarRadius + SENDER_AVATAR_BORDER_WIDTH).toPx() val yOffsetPx = -(NEGATIVE_MARGIN_FOR_BUBBLE + avatarRadius).toPx() val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl - var contentWidthPx by remember { mutableFloatStateOf(0f) } BoxWithConstraints( modifier = modifier .graphicsLayer { @@ -120,7 +115,7 @@ fun MessageEventBubble( drawCircle( color = Color.Black, center = Offset( - x = if (isRtl) contentWidthPx else 0f, + x = if (isRtl) size.width else 0f, y = yOffsetPx, ), radius = radiusPx, @@ -147,10 +142,7 @@ fun MessageEventBubble( onLongClick = onLongClick, indication = ripple(), interactionSource = interactionSource - ) - .onGloballyPositioned { coordinates -> - contentWidthPx = coordinates.size.width.toFloat() - }, + ), color = backgroundBubbleColor, shape = bubbleShape, content = content