Browse Source

Fix rendering of inline elements in list items in messages (#1091)

Co-authored-by: ElementBot <benoitm+elementbot@element.io>
pull/1095/head
Jorge Martin Espinosa 1 year ago committed by GitHub
parent
commit
6a4a4ebf26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      changelog.d/1090.bugfix
  2. 2
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/html/DocumentProvider.kt
  3. 42
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/html/HtmlDocument.kt
  4. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocumentDark_0_null_16,NEXUS_5,1.0,en].png
  5. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocumentDark_0_null_20,NEXUS_5,1.0,en].png
  6. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocumentDark_0_null_21,NEXUS_5,1.0,en].png
  7. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocumentLight_0_null_16,NEXUS_5,1.0,en].png
  8. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocumentLight_0_null_20,NEXUS_5,1.0,en].png
  9. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocumentLight_0_null_21,NEXUS_5,1.0,en].png

1
changelog.d/1090.bugfix

@ -0,0 +1 @@
Fix rendering of inline elements in list items.

2
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/html/DocumentProvider.kt

@ -50,5 +50,7 @@ open class DocumentProvider : PreviewParameterProvider<Document> {
// "<pre>pre</pre>", // "<pre>pre</pre>",
"<mx-reply><blockquote><a href=\\\"https://matrix.to/#/!roomId/\$eventId?via=matrix.org\\\">In reply to</a> " + "<mx-reply><blockquote><a href=\\\"https://matrix.to/#/!roomId/\$eventId?via=matrix.org\\\">In reply to</a> " +
"<a href=\\\"https://matrix.to/#/@alice:matrix.org\\\">@alice:matrix.org</a><br>original message</blockquote></mx-reply>reply", "<a href=\\\"https://matrix.to/#/@alice:matrix.org\\\">@alice:matrix.org</a><br>original message</blockquote></mx-reply>reply",
"<ol><li>Testing <a href='#'>link</a> item.</li><li>And <a href='#'>another</a> item.</li></ol>",
"<ul><li>Testing <a href='#'>link</a> item.</li><li>And <a href='#'>another</a> item.</li></ul>",
).map { Jsoup.parse(it) } ).map { Jsoup.parse(it) }
} }

42
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/html/HtmlDocument.kt

@ -400,22 +400,14 @@ private fun HtmlOrderedList(
onTextClicked: () -> Unit = {}, onTextClicked: () -> Unit = {},
onTextLongClicked: () -> Unit = {}, onTextLongClicked: () -> Unit = {},
) { ) {
var number = 1
val delimiter = "." val delimiter = "."
HtmlListItems( HtmlListItems(
list = orderedList, list = orderedList,
marker = { index -> "$index$delimiter"},
modifier = modifier, modifier = modifier,
onTextClicked = onTextClicked, onTextLongClicked = onTextLongClicked, onTextClicked = onTextClicked, onTextLongClicked = onTextLongClicked,
interactionSource = interactionSource interactionSource = interactionSource
) {
val text = buildAnnotatedString {
append("${number++}$delimiter ${it.text()}")
}
HtmlText(
text = text, onClick = onTextClicked,
onLongClick = onTextLongClicked, interactionSource = interactionSource
) )
}
} }
@Composable @Composable
@ -429,35 +421,44 @@ private fun HtmlUnorderedList(
val marker = "" val marker = ""
HtmlListItems( HtmlListItems(
list = unorderedList, list = unorderedList,
marker = { marker },
modifier = modifier, modifier = modifier,
onTextClicked = onTextClicked, onTextLongClicked = onTextLongClicked, onTextClicked = onTextClicked, onTextLongClicked = onTextLongClicked,
interactionSource = interactionSource interactionSource = interactionSource
) {
val text = buildAnnotatedString {
append("$marker ${it.text()}")
}
HtmlText(
text = text, onClick = onTextClicked,
onLongClick = onTextLongClicked, interactionSource = interactionSource
) )
}
} }
@Composable @Composable
private fun HtmlListItems( private fun HtmlListItems(
list: Element, list: Element,
marker: (Int) -> String,
interactionSource: MutableInteractionSource, interactionSource: MutableInteractionSource,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onTextClicked: () -> Unit = {}, onTextClicked: () -> Unit = {},
onTextLongClicked: () -> Unit = {}, onTextLongClicked: () -> Unit = {},
content: @Composable (node: TextNode) -> Unit = {}
) { ) {
Column(modifier = modifier) { Column(modifier = modifier) {
for (node in list.children()) { for ((index, node) in list.children().withIndex()) {
val areAllChildrenInline = node.childNodes().all { it is TextNode || it is Element && it.isInline() }
if (areAllChildrenInline) {
val text = buildAnnotatedString {
append("${marker(index + 1)} ")
appendInlineChildrenElements(node.childNodes(), MaterialTheme.colorScheme)
}
HtmlText(text = text, interactionSource = remember { MutableInteractionSource() })
} else {
for (innerNode in node.childNodes()) { for (innerNode in node.childNodes()) {
when (innerNode) { when (innerNode) {
is TextNode -> { is TextNode -> {
if (!innerNode.isBlank) content(innerNode) if (!innerNode.isBlank) {
val text = buildAnnotatedString {
append("${marker(index + 1)} ")
}
HtmlText(
text = text, onClick = onTextClicked,
onLongClick = onTextLongClicked, interactionSource = interactionSource
)
}
} }
is Element -> HtmlBlock( is Element -> HtmlBlock(
element = innerNode, element = innerNode,
@ -469,6 +470,7 @@ private fun HtmlListItems(
} }
} }
} }
}
} }
private fun ColorScheme.codeBackground(): Color { private fun ColorScheme.codeBackground(): Color {

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocumentDark_0_null_16,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocumentDark_0_null_20,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocumentDark_0_null_21,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocumentLight_0_null_16,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocumentLight_0_null_20,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocumentLight_0_null_21,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.
Loading…
Cancel
Save