Skip to content

Commit

Permalink
RUM-7631: Display captured text when the text has Ellipsis overflow
Browse files Browse the repository at this point in the history
  • Loading branch information
ambushwork committed Dec 10, 2024
1 parent d737ab4 commit 4e74cd1
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,12 @@
-keep class androidx.compose.ui.graphics.GraphicsLayerElement{
<fields>;
}

-keep class androidx.compose.ui.text.ParagraphInfo{
<fields>;
}
-keep class androidx.compose.ui.text.AndroidParagraph{
<fields>;
}
-keep class androidx.compose.ui.text.android.TextLayout{
<fields>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,17 @@ internal open class TextSemanticsNodeMapper(
parentContext: UiContext,
asyncJobStatusCallback: AsyncJobStatusCallback
): SemanticsWireframe {
val wireframes = arrayListOf<MobileSegment.Wireframe>()
val textAndInputPrivacy = semanticsUtils.getTextAndInputPrivacyOverride(semanticsNode)
?: parentContext.textAndInputPrivacy
val textWireframe = resolveTextWireFrame(parentContext, semanticsNode, textAndInputPrivacy)
val backgroundWireframes = resolveModifierWireframes(semanticsNode)
wireframes.addAll(backgroundWireframes)
textWireframe?.let {
wireframes.add(it)
}
return SemanticsWireframe(
wireframes = listOfNotNull(textWireframe),
wireframes = wireframes.toList(),
parentContext.copy(textAndInputPrivacy = textAndInputPrivacy)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package com.datadog.android.sessionreplay.compose.internal.reflection

import androidx.compose.ui.text.MultiParagraph
import com.datadog.android.Datadog
import com.datadog.android.api.InternalLogger
import com.datadog.android.api.feature.FeatureSdkCore
Expand Down Expand Up @@ -75,6 +76,16 @@ internal object ComposeReflection {

val AsyncImagePainterClass = getClassSafe("coil.compose.AsyncImagePainter")
val PainterFieldOfAsyncImagePainter = AsyncImagePainterClass?.getDeclaredFieldSafe("_painter")

// Region of MultiParagraph text
val ParagraphInfoListField =
MultiParagraph::class.java.getDeclaredFieldSafe("paragraphInfoList")
val ParagraphInfoClass = getClassSafe("androidx.compose.ui.text.ParagraphInfo")
val ParagraphField = ParagraphInfoClass?.getDeclaredFieldSafe("paragraph")
val AndroidParagraphClass = getClassSafe("androidx.compose.ui.text.AndroidParagraph")
val LayoutField = AndroidParagraphClass?.getDeclaredFieldSafe("layout")
val TextLayoutClass = getClassSafe("androidx.compose.ui.text.android.TextLayout")
val StaticLayoutField = TextLayoutClass?.getDeclaredFieldSafe("layout")
}

internal fun Field.accessible(): Field {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package com.datadog.android.sessionreplay.compose.internal.utils

import android.graphics.Bitmap
import android.text.StaticLayout
import android.view.View
import androidx.compose.runtime.Composition
import androidx.compose.ui.Modifier
Expand All @@ -19,19 +20,22 @@ import androidx.compose.ui.graphics.vector.VectorPainter
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.semantics.SemanticsNode
import androidx.compose.ui.semantics.SemanticsOwner
import androidx.compose.ui.text.MultiParagraph
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.BitmapField
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.CompositionField
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.ContentPainterElementClass
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.ContentPainterModifierClass
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.GetInnerLayerCoordinatorMethod
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.ImageField
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.LayoutField
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.LayoutNodeField
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.PainterElementClass
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.PainterField
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.PainterFieldOfAsyncImagePainter
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.PainterFieldOfContentPainterElement
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.PainterFieldOfContentPainterModifier
import com.datadog.android.sessionreplay.compose.internal.reflection.ComposeReflection.StaticLayoutField
import com.datadog.android.sessionreplay.compose.internal.reflection.getSafe

@Suppress("TooManyFunctions")
Expand Down Expand Up @@ -153,4 +157,13 @@ internal class ReflectionUtils {
fun getNestedPainter(painter: Painter): Painter? {
return PainterFieldOfAsyncImagePainter?.getSafe(painter) as? Painter
}

fun getMultiParagraphCapturedText(multiParagraph: MultiParagraph): String? {
val infoList = ComposeReflection.ParagraphInfoListField?.getSafe(multiParagraph) as? List<*>
val paragraphInfo = infoList?.firstOrNull()
val paragraph = ComposeReflection.ParagraphField?.getSafe(paragraphInfo)
val layout = LayoutField?.getSafe(paragraph)
val staticLayout = StaticLayoutField?.getSafe(layout) as? StaticLayout
return staticLayout?.text?.toString()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,15 @@ internal class SemanticsUtils(private val reflectionUtils: ReflectionUtils = Ref
semanticsNode.config.getOrNull(SemanticsActions.GetTextLayoutResult)?.action?.invoke(
textLayoutResults
)
val layoutInput = textLayoutResults.firstOrNull()?.layoutInput
val modifierColor = resolveModifierColor(semanticsNode)
return layoutInput?.let {
convertTextLayoutInfo(it, modifierColor)
return textLayoutResults.firstOrNull()?.let { textLayoutResult ->
val layoutInput = textLayoutResult.layoutInput
val multiParagraphCapturedText = if (textLayoutResult.didOverflowHeight) {
reflectionUtils.getMultiParagraphCapturedText(textLayoutResult.multiParagraph)
} else {
null
}
val modifierColor = resolveModifierColor(semanticsNode)
convertTextLayoutInfo(layoutInput, multiParagraphCapturedText, modifierColor)
}
}

Expand Down Expand Up @@ -240,10 +245,11 @@ internal class SemanticsUtils(private val reflectionUtils: ReflectionUtils = Ref

private fun convertTextLayoutInfo(
layoutInput: TextLayoutInput,
multiParagraphCapturedText: String?,
modifierColor: Color?
): TextLayoutInfo {
return TextLayoutInfo(
text = resolveAnnotatedString(layoutInput.text),
text = multiParagraphCapturedText ?: resolveAnnotatedString(layoutInput.text),
color = modifierColor?.value ?: layoutInput.style.color.value,
textAlign = layoutInput.style.textAlign,
fontSize = layoutInput.style.fontSize.value.toLong(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@

package com.datadog.android.sample.compose

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

@Suppress("LongMethod")
@Composable
internal fun TypographySample() {
Column {
Expand Down Expand Up @@ -56,12 +62,58 @@ internal fun TypographySample() {
),
modifier = Modifier.padding(16.dp)
)
Text(
text = FAKE_LONG_TEXT,
style = MaterialTheme.typography.caption.copy(
color = Color.Black
),
overflow = TextOverflow.Ellipsis,
modifier = Modifier
.height(60.dp)
.fillMaxWidth()
.background(color = Color.Yellow)
.padding(16.dp)
)
Row {
Text(
text = FAKE_LONG_TEXT,
style = MaterialTheme.typography.caption.copy(
color = Color.Black
),
overflow = TextOverflow.Ellipsis,
modifier = Modifier
.weight(1f)
.background(Color.Red)
.padding(16.dp),
maxLines = 1
)
Text(
text = FAKE_LONG_TEXT,
style = MaterialTheme.typography.caption.copy(
color = Color.Black
),
overflow = TextOverflow.Clip,
modifier = Modifier
.weight(1f)
.background(Color.Green)
.padding(16.dp),
maxLines = 1
)
}
}
}

@Preview
@Preview(showBackground = true)
@Composable
@Suppress("UnusedPrivateMember")
private fun PreviewTypographySample() {
TypographySample()
}

private const val FAKE_LONG_TEXT =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque posuere arcu eget est " +
"interdum, ac eleifend ex laoreet. Integer fringilla eros sed velit dapibus, sit" +
" amet egestas urna faucibus. Suspendisse potenti. Nulla facilisi. Proin sagittis " +
"eros eu nulla fringilla, quis consequat sapien tempus. Sed vel feugiat leo. Etiam " +
"id ultricies odio. Donec luctus sem vel magna consequat auctor. Fusce bibendum mi" +
" sed sapien faucibus, id scelerisque ligula hendrerit."

0 comments on commit 4e74cd1

Please sign in to comment.