diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt index 6ca953b4e4..ef442e3c5f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.amethyst.commons.richtext.UrlParser object CachedRichTextParser { private val richTextCache = LruCache(50) - private val isMarkdownCache = LruCache(200) private fun hashCodeCache( content: String, @@ -70,25 +69,6 @@ object CachedRichTextParser { newUrls } } - - // Shared across every RichTextViewer instance so that the same content quoted in multiple - // notes only pays for the scan once. The decision is purely a function of `content`. - fun isMarkdown(content: String): Boolean { - val key = content.hashCode() - isMarkdownCache[key]?.let { return it } - val result = computeIsMarkdown(content) - isMarkdownCache.put(key, result) - return result - } - - private fun computeIsMarkdown(content: String): Boolean = - content.startsWith("> ") || - content.startsWith("# ") || - content.contains("##") || - content.contains("__") || - content.contains("**") || - content.contains("```") || - content.contains("](") } object CachedUrlParser { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt index f54f53494c..62471f9509 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt @@ -136,7 +136,11 @@ fun RichTextViewer( nav: INav, ) { Column(modifier = modifier) { - if (remember(content) { CachedRichTextParser.isMarkdown(content) }) { + val state = + remember(content, tags) { + CachedRichTextParser.parseText(content, tags, callbackUri, authorPubKey) + } + if (state.isMarkdown) { RenderContentAsMarkdown(content, tags, canPreview, quotesLeft, backgroundColor, callbackUri, accountViewModel, nav) } else { RenderRegular(content, tags, canPreview, quotesLeft, backgroundColor, callbackUri, authorPubKey, accountViewModel, nav) diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/RichTextParser.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/RichTextParser.kt index e3cb263137..f3ed691345 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/RichTextParser.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/RichTextParser.kt @@ -224,6 +224,7 @@ class RichTextParser { customEmoji = emojiMap.toImmutableMap(), paragraphs = segments, tags = tags, + isMarkdown = isMarkdown(content), ) } @@ -411,6 +412,18 @@ class RichTextParser { } companion object { + // Cheap heuristic: stored on the parsed state so callers (e.g. RichTextViewer's + // markdown vs regular dispatch) can read the decision off the cached result instead + // of running a separate scan + maintaining a separate cache. + fun isMarkdown(content: String): Boolean = + content.startsWith("> ") || + content.startsWith("# ") || + content.contains("##") || + content.contains("__") || + content.contains("**") || + content.contains("```") || + content.contains("](") + val longDatePattern: Regex = Regex("^\\d{4}-\\d{2}-\\d{2}$") val shortDatePattern: Regex = Regex("^\\d{2}-\\d{2}-\\d{2}$") diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/RichTextParserSegments.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/RichTextParserSegments.kt index c0aa426c06..39a79378d1 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/RichTextParserSegments.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/RichTextParserSegments.kt @@ -33,6 +33,7 @@ class RichTextViewerState( val customEmoji: ImmutableMap, val paragraphs: ImmutableList, val tags: ImmutableListOfLists, + val isMarkdown: Boolean = false, ) @Immutable