Markdown improvements

This commit is contained in:
Phillip Thelen 2022-05-27 15:38:02 +02:00
parent f7cc63a774
commit 8a5877ab13
2 changed files with 31 additions and 12 deletions

View file

@ -30,7 +30,7 @@ import io.reactivex.rxjava3.functions.Consumer
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
object MarkdownParser { object MarkdownParser {
private val cache = sortedMapOf<Int, Spanned>()
internal var markwon: Markwon? = null internal var markwon: Markwon? = null
fun setup(context: Context) { fun setup(context: Context) {
@ -90,9 +90,19 @@ object MarkdownParser {
if (input == null) { if (input == null) {
return SpannableString("") return SpannableString("")
} }
val hashCode = input.hashCode()
if (cache.containsKey(hashCode)) {
return cache[hashCode] ?: SpannableString(input)
}
val text = EmojiParser.parseEmojis(input) ?: input val text = EmojiParser.parseEmojis(input) ?: input
// Adding this space here bc for some reason some markdown is not rendered correctly when the whole string is supposed to be formatted // Adding this space here bc for some reason some markdown is not rendered correctly when the whole string is supposed to be formatted
return markwon?.toMarkdown("$text ") ?: SpannableString(text) val result = markwon?.toMarkdown("$text ") ?: SpannableString(text)
cache[hashCode] = result
if (cache.size > 100) {
cache.remove(0)
}
return result
} }
fun parseMarkdownAsync(input: String?, onSuccess: Consumer<Spanned>) { fun parseMarkdownAsync(input: String?, onSuccess: Consumer<Spanned>) {
@ -103,6 +113,10 @@ object MarkdownParser {
.subscribe(onSuccess, RxErrorHandler.handleEmptyError()) .subscribe(onSuccess, RxErrorHandler.handleEmptyError())
} }
fun hasCached(input: String?): Boolean {
return cache.containsKey(input?.hashCode())
}
/** /**
* Converts stylized CharSequence into markdown * Converts stylized CharSequence into markdown
* *

View file

@ -1,7 +1,6 @@
package com.habitrpg.android.habitica.ui.viewHolders.tasks package com.habitrpg.android.habitica.ui.viewHolders.tasks
import android.content.Context import android.content.Context
import android.text.TextUtils
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
@ -151,12 +150,13 @@ abstract class BaseTaskViewHolder constructor(
if (canContainMarkdown()) { if (canContainMarkdown()) {
if (data.parsedText != null) { if (data.parsedText != null) {
titleTextView.setParsedMarkdown(data.parsedText) titleTextView.setParsedMarkdown(data.parsedText)
} else if (MarkdownParser.hasCached(data.text)) {
titleTextView.setParsedMarkdown(MarkdownParser.parseMarkdown(data.text))
} else { } else {
titleTextView.text = data.text titleTextView.text = data.text
titleTextView.setSpannableFactory(NoCopySpannableFactory.getInstance()) titleTextView.setSpannableFactory(NoCopySpannableFactory.getInstance())
if (data.text.isNotEmpty()) { if (data.text.isNotEmpty()) {
Single.just(data.text) Single.just(data.text)
.map { TextUtils.concat(it, "\u200B").toString() }
.map { MarkdownParser.parseMarkdown(it) } .map { MarkdownParser.parseMarkdown(it) }
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
@ -168,10 +168,16 @@ abstract class BaseTaskViewHolder constructor(
RxErrorHandler.handleEmptyError() RxErrorHandler.handleEmptyError()
) )
} }
if (displayMode != "minimal") { }
if (data.parsedNotes != null) { if (displayMode != "minimal") {
notesTextView?.setParsedMarkdown(data.parsedText) when {
} else { data.parsedNotes != null -> {
notesTextView?.setParsedMarkdown(data.parsedNotes)
}
MarkdownParser.hasCached(data.notes) -> {
notesTextView?.setParsedMarkdown(MarkdownParser.parseMarkdown(data.notes))
}
else -> {
notesTextView?.text = data.notes notesTextView?.text = data.notes
notesTextView?.setSpannableFactory(NoCopySpannableFactory.getInstance()) notesTextView?.setSpannableFactory(NoCopySpannableFactory.getInstance())
data.notes?.let { notes -> data.notes?.let { notes ->
@ -179,22 +185,21 @@ abstract class BaseTaskViewHolder constructor(
return@let return@let
} }
Single.just(notes) Single.just(notes)
.map { TextUtils.concat(it, "\u200B").toString() }
.map { MarkdownParser.parseMarkdown(it) } .map { MarkdownParser.parseMarkdown(it) }
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe( .subscribe(
{ parsedNotes -> { parsedNotes ->
notesTextView?.text = parsedNotes data.parsedNotes = parsedNotes
notesTextView?.setParsedMarkdown(parsedNotes) notesTextView?.setParsedMarkdown(parsedNotes)
}, },
RxErrorHandler.handleEmptyError() RxErrorHandler.handleEmptyError()
) )
} }
} }
} else {
notesTextView?.visibility = View.GONE
} }
} else {
notesTextView?.visibility = View.GONE
} }
} else { } else {
titleTextView.text = data.text titleTextView.text = data.text