Ensure link are clickable on simple body (#2038)
This commit is contained in:
parent
d653ec20de
commit
fc5a41ec98
2 changed files with 44 additions and 2 deletions
|
|
@ -21,6 +21,7 @@ import android.text.style.URLSpan
|
||||||
import android.text.util.Linkify
|
import android.text.util.Linkify
|
||||||
import androidx.core.text.buildSpannedString
|
import androidx.core.text.buildSpannedString
|
||||||
import androidx.core.text.getSpans
|
import androidx.core.text.getSpans
|
||||||
|
import androidx.core.text.toSpannable
|
||||||
import androidx.core.text.util.LinkifyCompat
|
import androidx.core.text.util.LinkifyCompat
|
||||||
import io.element.android.features.location.api.Location
|
import io.element.android.features.location.api.Location
|
||||||
import io.element.android.features.messages.api.timeline.HtmlConverterProvider
|
import io.element.android.features.messages.api.timeline.HtmlConverterProvider
|
||||||
|
|
@ -178,7 +179,7 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||||
TimelineItemTextContent(
|
TimelineItemTextContent(
|
||||||
body = messageType.body,
|
body = messageType.body,
|
||||||
htmlDocument = messageType.formatted?.toHtmlDocument(),
|
htmlDocument = messageType.formatted?.toHtmlDocument(),
|
||||||
formattedBody = parseHtml(messageType.formatted),
|
formattedBody = parseHtml(messageType.formatted) ?: messageType.body.withLinks(),
|
||||||
isEdited = content.isEdited,
|
isEdited = content.isEdited,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -237,3 +238,12 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun String.withLinks(): CharSequence? {
|
||||||
|
val spannable = toSpannable()
|
||||||
|
LinkifyCompat.addLinks(spannable, Linkify.WEB_URLS or Linkify.PHONE_NUMBERS)
|
||||||
|
if (spannable.getSpans<URLSpan>().isEmpty()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return spannable
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,9 @@
|
||||||
package io.element.android.features.messages.impl.timeline.factories.event
|
package io.element.android.features.messages.impl.timeline.factories.event
|
||||||
|
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
import android.text.SpannableStringBuilder
|
import android.text.Spanned
|
||||||
import android.text.style.URLSpan
|
import android.text.style.URLSpan
|
||||||
|
import androidx.core.text.buildSpannedString
|
||||||
import androidx.core.text.inSpans
|
import androidx.core.text.inSpans
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.features.location.api.Location
|
import io.element.android.features.location.api.Location
|
||||||
|
|
@ -144,6 +145,37 @@ class TimelineItemContentMessageFactoryTest {
|
||||||
assertThat(result).isEqualTo(expected)
|
assertThat(result).isEqualTo(expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test create TextMessageType with simple link`() = runTest {
|
||||||
|
val sut = createTimelineItemContentMessageFactory()
|
||||||
|
val result = sut.create(
|
||||||
|
content = createMessageContent(type = TextMessageType("https://www.example.org", null)),
|
||||||
|
senderDisplayName = "Bob",
|
||||||
|
eventId = AN_EVENT_ID,
|
||||||
|
) as TimelineItemTextContent
|
||||||
|
val expected = TimelineItemTextContent(
|
||||||
|
body = "https://www.example.org",
|
||||||
|
htmlDocument = null,
|
||||||
|
plainText = "https://www.example.org",
|
||||||
|
isEdited = false,
|
||||||
|
formattedBody = buildSpannedString {
|
||||||
|
inSpans(URLSpan("https://www.example.org")) {
|
||||||
|
append("https://www.example.org")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assertThat(result.body).isEqualTo(expected.body)
|
||||||
|
assertThat(result.htmlDocument).isEqualTo(expected.htmlDocument)
|
||||||
|
assertThat(result.plainText).isEqualTo(expected.plainText)
|
||||||
|
assertThat(result.isEdited).isEqualTo(expected.isEdited)
|
||||||
|
assertThat(result.formattedBody).isInstanceOf(Spanned::class.java)
|
||||||
|
val spanned = result.formattedBody as Spanned
|
||||||
|
assertThat(spanned.toString()).isEqualTo("https://www.example.org")
|
||||||
|
val urlSpans = spanned.getSpans(0, spanned.length, URLSpan::class.java)
|
||||||
|
assertThat(urlSpans).hasLength(1)
|
||||||
|
assertThat(urlSpans[0].url).isEqualTo("https://www.example.org")
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test create TextMessageType with HTML formatted body`() = runTest {
|
fun `test create TextMessageType with HTML formatted body`() = runTest {
|
||||||
val expected = SpannableStringBuilder().apply {
|
val expected = SpannableStringBuilder().apply {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue