Fall back to the message body when the formatted body has nothing to render

The HTML sanitiser in toHtmlDocument() drops every tag outside its safelist,
which does not include img. A formatted body whose only content is an image —
a custom emoji, or a bot posting an image inline — therefore cleans down to an
empty document, and because that document is not null the ?: body fallbacks in
the timeline item factory, the room list preview, the notification resolver and
plainText are all dead. The message renders as an empty bubble.

Return null from toHtmlDocument() when no text survives the sanitisation, so the
existing fallbacks take the plain text body, which for these messages carries the
alt text the sender provided.
This commit is contained in:
hayaksi1
2026-08-25 11:03:42 +03:00
parent 6ab3d7393b
commit 6b2e83cb63
4 changed files with 58 additions and 2 deletions
@@ -229,6 +229,25 @@ class TimelineItemContentMessageFactoryTest : RobolectricTest() {
assertThat((result as TimelineItemTextContent).formattedBody).isEqualTo(SpannedString("body"))
}
@Test
fun `test create TextMessageType with a formatted body containing only an image falls back to the body`() = runTest {
val sut = createTimelineItemContentMessageFactory()
val result = sut.create(
content = createMessageContent(
type = TextMessageType(
body = "\uD83D\uDE1C",
formatted = FormattedBody(MessageFormat.HTML, "<img src=\"mxc://matrix.org/anImage\" alt=\"\uD83D\uDE1C\" />")
)
),
senderId = A_USER_ID,
senderProfile = aProfileDetails(),
eventId = AN_EVENT_ID,
)
assertThat((result as TimelineItemTextContent).formattedBody).isEqualTo(SpannedString("\uD83D\uDE1C"))
assertThat(result.htmlDocument).isNull()
assertThat(result.plainText).isEqualTo("\uD83D\uDE1C")
}
@Test
fun `test create VideoMessageType`() = runTest {
val sut = createTimelineItemContentMessageFactory()