diff --git a/changelog.d/8187.bugfix b/changelog.d/8187.bugfix new file mode 100644 index 0000000000..e0a9dd3a29 --- /dev/null +++ b/changelog.d/8187.bugfix @@ -0,0 +1 @@ +Extend workaround for extra new lines in timeline \ No newline at end of file diff --git a/vector/src/androidTest/java/im/vector/app/core/utils/TestSpan.kt b/vector/src/androidTest/java/im/vector/app/core/utils/TestSpan.kt index 1d0d6548e1..ebbe565642 100644 --- a/vector/src/androidTest/java/im/vector/app/core/utils/TestSpan.kt +++ b/vector/src/androidTest/java/im/vector/app/core/utils/TestSpan.kt @@ -20,6 +20,7 @@ import android.graphics.Canvas import android.graphics.Paint import android.text.Layout import android.text.Spanned +import android.text.style.StrikethroughSpan import androidx.core.text.getSpans import im.vector.app.features.html.HtmlCodeSpan import io.element.android.wysiwyg.spans.InlineCodeSpan @@ -28,6 +29,7 @@ import io.mockk.mockk import io.mockk.slot import io.mockk.verify import io.noties.markwon.core.spans.EmphasisSpan +import io.noties.markwon.core.spans.LinkSpan import io.noties.markwon.core.spans.OrderedListItemSpan import io.noties.markwon.core.spans.StrongEmphasisSpan import me.gujun.android.span.style.CustomTypefaceSpan @@ -59,6 +61,8 @@ private fun Any.readTags(): SpanTags { StrongEmphasisSpan::class -> "bold" EmphasisSpan::class, CustomTypefaceSpan::class -> "italic" InlineCodeSpan::class -> "inline code" + StrikethroughSpan::class -> "strikethrough" + LinkSpan::class -> "link" else -> if (this::class.qualifiedName!!.startsWith("android.widget")) { null } else { diff --git a/vector/src/androidTest/java/im/vector/app/features/html/EventHtmlRendererTest.kt b/vector/src/androidTest/java/im/vector/app/features/html/EventHtmlRendererTest.kt index c095b33b44..94d60538d9 100644 --- a/vector/src/androidTest/java/im/vector/app/features/html/EventHtmlRendererTest.kt +++ b/vector/src/androidTest/java/im/vector/app/features/html/EventHtmlRendererTest.kt @@ -73,6 +73,30 @@ class EventHtmlRendererTest { result shouldBeEqualTo "__italic__ **bold**" } + // https://github.com/noties/Markwon/issues/423 + @Test + fun doesNotIntroduceExtraNewLines() { + // Given initial render (required to trigger bug) + """Some italic""".renderAsTestSpan() + val results = arrayOf( + """Some italic""".renderAsTestSpan(), + """Some bold""".renderAsTestSpan(), + """Some code""".renderAsTestSpan(), + """Some link""".renderAsTestSpan(), + """Some strikethrough""".renderAsTestSpan(), + """Some span""".renderAsTestSpan(), + ) + + results shouldBeEqualTo arrayOf( + "Some [italic]italic[/italic]", + "Some [bold]bold[/bold]", + "Some [inline code]code[/inline code]", + "Some [link]link[/link]", + "Some \n[strikethrough]strikethrough[/strikethrough]", // FIXME + "Some \nspan", // FIXME + ) + } + @Test fun processesHtmlWithinCodeBlocks() { val result = """italic bold""".renderAsTestSpan() diff --git a/vector/src/main/java/im/vector/app/features/html/EventHtmlRenderer.kt b/vector/src/main/java/im/vector/app/features/html/EventHtmlRenderer.kt index e75d12f1d8..cb3f12d867 100644 --- a/vector/src/main/java/im/vector/app/features/html/EventHtmlRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/html/EventHtmlRenderer.kt @@ -31,6 +31,9 @@ import android.graphics.Typeface import android.graphics.drawable.Drawable import android.text.Spannable import android.text.SpannableStringBuilder +import android.text.style.StrikethroughSpan +import android.text.style.URLSpan +import android.text.style.UnderlineSpan import android.widget.TextView import androidx.core.text.toSpannable import com.bumptech.glide.Glide @@ -46,6 +49,8 @@ import io.noties.markwon.Markwon import io.noties.markwon.MarkwonPlugin import io.noties.markwon.MarkwonSpansFactory import io.noties.markwon.PrecomputedFutureTextSetterCompat +import io.noties.markwon.core.spans.EmphasisSpan +import io.noties.markwon.core.spans.StrongEmphasisSpan import io.noties.markwon.ext.latex.JLatexMathPlugin import io.noties.markwon.ext.latex.JLatexMathTheme import io.noties.markwon.html.HtmlPlugin @@ -154,14 +159,24 @@ class EventHtmlRenderer @Inject constructor( /** * Workaround for https://github.com/noties/Markwon/issues/423 */ - private val removeLeadingNewlineForInlineCode = object : AbstractMarkwonPlugin() { + private val removeLeadingNewlineForInlineElement = object : AbstractMarkwonPlugin() { override fun afterSetText(textView: TextView) { super.afterSetText(textView) val text = SpannableStringBuilder(textView.text.toSpannable()) - val inlineCodeSpans = text.getSpans(0, textView.length(), InlineCodeSpan::class.java).toList() - val legacyInlineCodeSpans = text.getSpans(0, textView.length(), HtmlCodeSpan::class.java).filter { !it.isBlock } - val spans = inlineCodeSpans + legacyInlineCodeSpans + val length = textView.length() + val spans = arrayOf( + InlineCodeSpan::class.java, + EmphasisSpan::class.java, + CustomTypefaceSpan::class.java, + StrongEmphasisSpan::class.java, + UnderlineSpan::class.java, + URLSpan::class.java, + StrikethroughSpan::class.java + ).map { text.getSpans(0, length, it) } + .toTypedArray() + .plus(text.getSpans(0, length, HtmlCodeSpan::class.java).filter { !it.isBlock }.toTypedArray()) + .flatten() if (spans.isEmpty()) return @@ -179,11 +194,11 @@ class EventHtmlRenderer @Inject constructor( private val markwon = Markwon.builder(context) .usePlugin(HtmlRootTagPlugin()) .usePlugin(HtmlPlugin.create(htmlConfigure)) - .usePlugin(removeLeadingNewlineForInlineCode) + .usePlugin(removeLeadingNewlineForInlineElement) .usePlugin(glidePlugin) .apply { if (vectorPreferences.latexMathsIsEnabled()) { - // If latex maths is enabled in app preferences, refomat it so Markwon recognises it + // If latex maths is enabled in app preferences, reformat it so Markwon recognises it // It needs to be in this specific format: https://noties.io/Markwon/docs/v4/ext-latex latexPlugins.forEach(::usePlugin) }