From a43f68b33e5f5d738f1e3984e9b5a3608b1dec97 Mon Sep 17 00:00:00 2001 From: Infi Date: Sun, 12 Mar 2023 04:35:34 +0100 Subject: [PATCH] feat: use an actual markdown rendering library it even highlights code blocks --- .idea/gradle.xml | 1 - .idea/misc.xml | 2 +- app/build.gradle | 3 +- .../chat/revolt/components/chat/Message.kt | 25 +++- .../revolt/components/generic/Markdown.kt | 118 +++++++++++++++ .../internals/markdown/BlockBackgroundNode.kt | 129 ++++++++++++++++ .../internals/markdown/MarkdownContext.kt | 19 ++- .../internals/markdown/MarkdownNodes.kt | 32 ++++ .../internals/markdown/MarkdownRules.kt | 138 ++++++++++++++++++ .../dialogs/safety/ReportMessageDialog.kt | 3 +- .../screens/chat/views/ChannelScreen.kt | 47 +++++- app/src/main/res/font/inter.xml | 39 +++++ .../main/res/font/jetbrainsmono_regular.ttf | Bin 0 -> 114320 bytes app/src/main/res/values/strings.xml | 2 +- app/src/main/res/values/styles.xml | 38 +++++ app/src/main/res/values/themes.xml | 2 +- markdown/.gitignore | 1 - markdown/build.gradle | 50 ------- markdown/consumer-rules.pro | 0 markdown/proguard-rules.pro | 21 --- markdown/src/main/AndroidManifest.xml | 4 - .../java/chat/revolt/markdown/Markdown.kt | 28 ---- .../java/chat/revolt/markdown/ast/MdAst.kt | 91 ------------ .../java/chat/revolt/markdown/ast/UniSt.kt | 60 -------- .../chat/revolt/markdown/parser/Parser.kt | 4 - .../chat/revolt/markdown/ExampleUnitTest.kt | 17 --- settings.gradle | 2 +- 27 files changed, 580 insertions(+), 296 deletions(-) create mode 100644 app/src/main/java/chat/revolt/components/generic/Markdown.kt create mode 100644 app/src/main/java/chat/revolt/internals/markdown/BlockBackgroundNode.kt create mode 100644 app/src/main/java/chat/revolt/internals/markdown/MarkdownNodes.kt create mode 100644 app/src/main/java/chat/revolt/internals/markdown/MarkdownRules.kt create mode 100644 app/src/main/res/font/inter.xml create mode 100644 app/src/main/res/font/jetbrainsmono_regular.ttf create mode 100644 app/src/main/res/values/styles.xml delete mode 100644 markdown/.gitignore delete mode 100644 markdown/build.gradle delete mode 100644 markdown/consumer-rules.pro delete mode 100644 markdown/proguard-rules.pro delete mode 100644 markdown/src/main/AndroidManifest.xml delete mode 100644 markdown/src/main/java/chat/revolt/markdown/Markdown.kt delete mode 100644 markdown/src/main/java/chat/revolt/markdown/ast/MdAst.kt delete mode 100644 markdown/src/main/java/chat/revolt/markdown/ast/UniSt.kt delete mode 100644 markdown/src/main/java/chat/revolt/markdown/parser/Parser.kt delete mode 100644 markdown/src/test/java/chat/revolt/markdown/ExampleUnitTest.kt diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 5e3c93e2..49a14191 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -13,7 +13,6 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index b36f4a6d..2161c1f5 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -13,7 +13,7 @@ - + diff --git a/app/build.gradle b/app/build.gradle index 03a6bfd0..2dff1ff7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -163,7 +163,8 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2' // Markdown - implementation project(':markdown') + implementation "com.github.discord:SimpleAST:2.7.0" + implementation "androidx.appcompat:appcompat:1.7.0-alpha02" } kapt { diff --git a/app/src/main/java/chat/revolt/components/chat/Message.kt b/app/src/main/java/chat/revolt/components/chat/Message.kt index ac09b65c..ece442a6 100644 --- a/app/src/main/java/chat/revolt/components/chat/Message.kt +++ b/app/src/main/java/chat/revolt/components/chat/Message.kt @@ -1,6 +1,8 @@ package chat.revolt.components.chat import android.net.Uri +import android.text.SpannableStringBuilder +import android.text.TextUtils import android.widget.Toast import androidx.browser.customtabs.CustomTabsIntent import androidx.compose.foundation.* @@ -9,11 +11,15 @@ import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.compose.ui.viewinterop.AndroidView +import androidx.core.content.res.ResourcesCompat +import chat.revolt.R import chat.revolt.api.REVOLT_FILES import chat.revolt.api.RevoltAPI import chat.revolt.api.asJanuaryProxyUrl @@ -22,7 +28,6 @@ import chat.revolt.api.internals.WebCompat import chat.revolt.api.schemas.AutumnResource import chat.revolt.components.generic.UserAvatar import chat.revolt.components.generic.UserAvatarWidthPlaceholder -import chat.revolt.markdown.Markdown import chat.revolt.api.schemas.Message as MessageSchema fun viewAttachmentInBrowser(ctx: android.content.Context, attachment: AutumnResource) { @@ -49,10 +54,12 @@ fun formatLongAsTime(time: Long): String { fun Message( message: MessageSchema, truncate: Boolean = false, + parse: (MessageSchema) -> SpannableStringBuilder = { SpannableStringBuilder(it.content) }, onMessageContextMenu: () -> Unit = {}, ) { val author = RevoltAPI.userCache[message.author] ?: return CircularProgressIndicator() val context = LocalContext.current + val contentColor = LocalContentColor.current Column { if (message.tail == false) { @@ -134,11 +141,17 @@ fun Message( message.content?.let { if (message.content.isBlank()) return@let // if only an attachment is sent - Text( - text = Markdown.annotate(it), - maxLines = if (truncate) 1 else Int.MAX_VALUE, - overflow = TextOverflow.Ellipsis - ) + AndroidView(factory = { ctx -> + androidx.appcompat.widget.AppCompatTextView(ctx).apply { + text = parse(message) + maxLines = if (truncate) 1 else Int.MAX_VALUE + ellipsize = TextUtils.TruncateAt.END + textSize = 16f + typeface = ResourcesCompat.getFont(ctx, R.font.inter) + + setTextColor(contentColor.toArgb()) + } + }) } message.attachments?.let { diff --git a/app/src/main/java/chat/revolt/components/generic/Markdown.kt b/app/src/main/java/chat/revolt/components/generic/Markdown.kt new file mode 100644 index 00000000..b348c236 --- /dev/null +++ b/app/src/main/java/chat/revolt/components/generic/Markdown.kt @@ -0,0 +1,118 @@ +package chat.revolt.components.generic + +import android.text.SpannableStringBuilder +import android.text.TextUtils +import android.util.Log +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.surfaceColorAtElevation +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.viewinterop.AndroidView +import androidx.core.content.res.ResourcesCompat +import chat.revolt.R +import chat.revolt.api.RevoltAPI +import chat.revolt.internals.markdown.ChannelMentionRule +import chat.revolt.internals.markdown.CustomEmoteRule +import chat.revolt.internals.markdown.MarkdownContext +import chat.revolt.internals.markdown.MarkdownParser +import chat.revolt.internals.markdown.MarkdownState +import chat.revolt.internals.markdown.UserMentionRule +import chat.revolt.internals.markdown.createCodeRule +import chat.revolt.internals.markdown.createInlineCodeRule +import com.discord.simpleast.core.simple.SimpleMarkdownRules +import com.discord.simpleast.core.simple.SimpleRenderer + +/** + * A Markdown rendering component for Markdown embedded in UI (e.g. in a button). + * @param text The text to render. + * @param fontSize The font size to use. + * @param modifier The modifier to apply to the rendered text. Will be applied to AndroidView and thus subject to AndroidView's limitations. + * @param maxLines The maximum number of lines to display. Text will always be ellipsized on overflow. Defaults to [Int.MAX_VALUE]. + */ +@Composable +fun UIMarkdown( + text: String, + fontSize: TextUnit, + modifier: Modifier = Modifier, + maxLines: Int = Int.MAX_VALUE, +) { + val context = LocalContext.current + val foregroundColor = LocalContentColor.current + val codeBlockColor = MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp) + val spannableStringBuilder = remember { mutableStateOf(SpannableStringBuilder()) } + + LaunchedEffect(text) { + val parser = MarkdownParser() + .addRules( + SimpleMarkdownRules.createEscapeRule(), + UserMentionRule(), + ChannelMentionRule(), + CustomEmoteRule(), + ) + .addRules( + createCodeRule(context, codeBlockColor.toArgb()), + createInlineCodeRule(context, codeBlockColor.toArgb()), + ) + .addRules( + SimpleMarkdownRules.createSimpleMarkdownRules( + includeEscapeRule = false + ) + ) + + spannableStringBuilder.value = SimpleRenderer.render( + source = text, + parser = parser, + initialState = MarkdownState(0), + renderContext = MarkdownContext( + memberMap = mapOf(), + userMap = RevoltAPI.userCache.toMap(), + channelMap = RevoltAPI.channelCache.mapValues { ch -> + ch.value.name ?: ch.value.id!! + }, + emojiMap = RevoltAPI.emojiCache, + serverId = null + ) + ) + + Log.d("Markdown", "Rendered: ${spannableStringBuilder.value}") + } + + AndroidView( + factory = { + androidx.appcompat.widget.AppCompatTextView(it).apply { + ellipsize = TextUtils.TruncateAt.END + typeface = ResourcesCompat.getFont(it, R.font.inter) + + setTextColor(foregroundColor.toArgb()) + setMaxLines(maxLines) + setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, fontSize.value) + + setText(spannableStringBuilder.value) + } + }, + modifier = modifier, + update = { + it.text = spannableStringBuilder.value + }, + ) +} + +@Preview +@Composable +fun UIMarkdownPreview() { + // Will not render in side preview but will render on device + UIMarkdown( + text = "Hello, **world**!", + fontSize = 16.sp, + ) +} \ No newline at end of file diff --git a/app/src/main/java/chat/revolt/internals/markdown/BlockBackgroundNode.kt b/app/src/main/java/chat/revolt/internals/markdown/BlockBackgroundNode.kt new file mode 100644 index 00000000..4942e6d1 --- /dev/null +++ b/app/src/main/java/chat/revolt/internals/markdown/BlockBackgroundNode.kt @@ -0,0 +1,129 @@ +package chat.revolt.internals.markdown + +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.graphics.RectF +import android.text.SpannableStringBuilder +import android.text.Spanned +import android.text.style.LeadingMarginSpan +import android.text.style.LineBackgroundSpan +import androidx.annotation.ColorInt +import com.discord.simpleast.core.node.Node + +// Attribution: +// https://github.com/discord/SimpleAST/blob/567b61c51056cbdec39e839100690c576c26a4c6/app/src/main/java/com/discord/simpleast/sample/spans/BlockBackgroundNode.kt +// LICENSED UNDER THE APACHE LICENSE, VERSION 2.0 +// Adapted for Revolt. + +/** + * Creates a block background for code sections. + */ +class BlockBackgroundNode( + private val quoteDepth: Int, + private val fillColor: Int = Color.DKGRAY, + private val strokeColor: Int = Color.BLACK, + vararg children: Node, +) : Node.Parent(*children) { + + override fun render(builder: SpannableStringBuilder, renderContext: R) { + // Ensure the block we want to append starts on a newline. + ensureEndsWithNewline(builder) + + val codeStartIndex = builder.length + super.render(builder, renderContext) + // BlockBackgroundSpan requires this to function + ensureEndsWithNewline(builder) + + val backgroundSpan = BlockBackgroundSpan( + fillColor, strokeColor, + strokeWidth = 2, + strokeRadius = 15, + leftMargin = 40 * quoteDepth + ) + builder.setSpan( + backgroundSpan, + codeStartIndex, + builder.length, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + + // Apply a leading margin to all lines in the block. + val leadingMarginSpan = LeadingMarginSpan.Standard(15) + builder.setSpan( + leadingMarginSpan, + codeStartIndex, + builder.length, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + + private fun ensureEndsWithNewline(builder: SpannableStringBuilder) { + if (builder.isNotEmpty()) { + val lastChar = CharArray(6) + builder.getChars(builder.length - 1, builder.length, lastChar, 0) + if (lastChar[0] != '\n') { + builder.append('\n') + } + } + } +} + +/** + * Computes the position of the paragraph on the screen and draws the desired background. + */ +class BlockBackgroundSpan( + @ColorInt fillColor: Int, + @ColorInt strokeColor: Int, + strokeWidth: Int, + strokeRadius: Int, + val leftMargin: Int +) : LineBackgroundSpan { + + private val fillPaint = Paint().apply { + this.style = Paint.Style.FILL + this.color = fillColor + } + + private val strokePaint = Paint().apply { + this.style = Paint.Style.STROKE + this.color = strokeColor + this.strokeWidth = strokeWidth.toFloat() + this.isAntiAlias = true + } + + private val rect = RectF() + private val radius = strokeRadius.toFloat() + + fun draw(canvas: Canvas) { + canvas.drawRoundRect(rect, radius, radius, fillPaint) + canvas.drawRoundRect(rect, radius, radius, strokePaint) + } + + override fun drawBackground( + canvas: Canvas, + paint: Paint, + left: Int, + right: Int, + top: Int, + baseline: Int, + bottom: Int, + text: CharSequence, + start: Int, + end: Int, + lnum: Int + ) { + if (text !is Spanned) return + + if (text.getSpanStart(this) == start) { + rect.left = left.toFloat() + leftMargin + rect.top = top.toFloat() + } + + if (text.getSpanEnd(this) == end) { + rect.right = right.toFloat() + rect.bottom = bottom.toFloat() + draw(canvas) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/chat/revolt/internals/markdown/MarkdownContext.kt b/app/src/main/java/chat/revolt/internals/markdown/MarkdownContext.kt index 16e2a0a1..362d9f98 100644 --- a/app/src/main/java/chat/revolt/internals/markdown/MarkdownContext.kt +++ b/app/src/main/java/chat/revolt/internals/markdown/MarkdownContext.kt @@ -1,11 +1,20 @@ package chat.revolt.internals.markdown -import androidx.compose.runtime.snapshots.SnapshotStateMap +import chat.revolt.api.schemas.Emoji import chat.revolt.api.schemas.User +import com.discord.simpleast.core.node.Node +import com.discord.simpleast.core.parser.Parser + +typealias MarkdownParser = Parser, MarkdownState> + +data class MarkdownState(val currentQuoteDepth: Int) { + fun newQuoteDepth(depth: Int): MarkdownState = MarkdownState(depth) +} data class MarkdownContext( - val memberMap: SnapshotStateMap, - val userMap: SnapshotStateMap, - val channelMap: SnapshotStateMap, - val serverId: String, + val memberMap: Map, + val userMap: Map, + val channelMap: Map, + val emojiMap: Map, + val serverId: String? ) \ No newline at end of file diff --git a/app/src/main/java/chat/revolt/internals/markdown/MarkdownNodes.kt b/app/src/main/java/chat/revolt/internals/markdown/MarkdownNodes.kt new file mode 100644 index 00000000..010ba495 --- /dev/null +++ b/app/src/main/java/chat/revolt/internals/markdown/MarkdownNodes.kt @@ -0,0 +1,32 @@ +package chat.revolt.internals.markdown + +import android.text.SpannableStringBuilder +import com.discord.simpleast.core.node.Node + +class UserMentionNode(private val userId: String) : Node() { + override fun render(builder: SpannableStringBuilder, renderContext: MarkdownContext) { + builder.append( + renderContext.memberMap[userId]?.let { "@$it" } + ?: renderContext.userMap[userId]?.let { "@${it.username}" } + ?: "<@${userId}>" + ) + } +} + +class ChannelMentionNode(private val channelId: String) : Node() { + override fun render(builder: SpannableStringBuilder, renderContext: MarkdownContext) { + builder.append( + renderContext.channelMap[channelId]?.let { "#$it" } + ?: "<#${channelId}>" + ) + } +} + +class CustomEmoteNode(private val emoteId: String) : Node() { + override fun render(builder: SpannableStringBuilder, renderContext: MarkdownContext) { + builder.append( + renderContext.emojiMap[emoteId]?.let { ":${it.name}:" } + ?: ":${emoteId}:" + ) + } +} diff --git a/app/src/main/java/chat/revolt/internals/markdown/MarkdownRules.kt b/app/src/main/java/chat/revolt/internals/markdown/MarkdownRules.kt new file mode 100644 index 00000000..8d6d4266 --- /dev/null +++ b/app/src/main/java/chat/revolt/internals/markdown/MarkdownRules.kt @@ -0,0 +1,138 @@ +package chat.revolt.internals.markdown + +import android.content.Context +import android.text.style.BackgroundColorSpan +import android.text.style.TextAppearanceSpan +import chat.revolt.R +import com.discord.simpleast.code.CodeRules +import com.discord.simpleast.code.CodeStyleProviders +import com.discord.simpleast.core.node.Node +import com.discord.simpleast.core.node.StyleNode +import com.discord.simpleast.core.parser.ParseSpec +import com.discord.simpleast.core.parser.Parser +import com.discord.simpleast.core.parser.Rule +import java.util.regex.Matcher +import java.util.regex.Pattern + +class UserMentionRule : + Rule(Pattern.compile("^<@([0-9A-Z]{26})>")) { + override fun parse( + matcher: Matcher, + parser: Parser, + state: S + ): ParseSpec { + return ParseSpec.createTerminal(UserMentionNode(matcher.group(1)!!), state) + } +} + +class ChannelMentionRule : + Rule(Pattern.compile("^<#([0-9A-Z]{26})>")) { + override fun parse( + matcher: Matcher, + parser: Parser, + state: S + ): ParseSpec { + return ParseSpec.createTerminal(ChannelMentionNode(matcher.group(1)!!), state) + } +} + +class CustomEmoteRule : + Rule(Pattern.compile("^:([0-9A-Z]{26}):")) { + override fun parse( + matcher: Matcher, + parser: Parser, + state: S + ): ParseSpec { + return ParseSpec.createTerminal(CustomEmoteNode(matcher.group(1)!!), state) + } +} + +fun createInlineCodeRule(context: Context, backgroundColor: Int): Rule, S> { + return CodeRules.createInlineCodeRule( + { listOf(TextAppearanceSpan(context, R.style.Code_TextAppearance)) }, + { listOf(BackgroundColorSpan(backgroundColor)) } + ) +} + +fun createCodeRule( + context: Context, + backgroundColor: Int +): Rule, S> { + val codeStyleProviders = CodeStyleProviders( + defaultStyleProvider = { listOf(TextAppearanceSpan(context, R.style.Code_TextAppearance)) }, + commentStyleProvider = { + listOf( + TextAppearanceSpan( + context, + R.style.Code_TextAppearance_Comment + ) + ) + }, + literalStyleProvider = { + listOf( + TextAppearanceSpan( + context, + R.style.Code_TextAppearance_Literal + ) + ) + }, + keywordStyleProvider = { + listOf( + TextAppearanceSpan( + context, + R.style.Code_TextAppearance_Keyword + ) + ) + }, + identifierStyleProvider = { + listOf( + TextAppearanceSpan( + context, + R.style.Code_TextAppearance_Identifier + ) + ) + }, + typesStyleProvider = { + listOf( + TextAppearanceSpan( + context, + R.style.Code_TextAppearance_Types + ) + ) + }, + genericsStyleProvider = { + listOf( + TextAppearanceSpan( + context, + R.style.Code_TextAppearance_Generics + ) + ) + }, + paramsStyleProvider = { + listOf( + TextAppearanceSpan( + context, + R.style.Code_TextAppearance_Params + ) + ) + }, + ) + val languageMap = CodeRules.createCodeLanguageMap(codeStyleProviders) + + return CodeRules.createCodeRule( + codeStyleProviders.defaultStyleProvider, + languageMap + ) { codeNode, block, state -> + if (!block) { + StyleNode(listOf(BackgroundColorSpan(backgroundColor))) + .apply { addChild(codeNode) } + } else { + BlockBackgroundNode( + state.currentQuoteDepth, + backgroundColor, + backgroundColor, + codeNode + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/chat/revolt/screens/chat/dialogs/safety/ReportMessageDialog.kt b/app/src/main/java/chat/revolt/screens/chat/dialogs/safety/ReportMessageDialog.kt index ba31df98..83bef37e 100644 --- a/app/src/main/java/chat/revolt/screens/chat/dialogs/safety/ReportMessageDialog.kt +++ b/app/src/main/java/chat/revolt/screens/chat/dialogs/safety/ReportMessageDialog.kt @@ -28,7 +28,6 @@ import chat.revolt.api.routes.user.blockUser import chat.revolt.api.schemas.ContentReportReason import chat.revolt.components.chat.Message import chat.revolt.components.generic.FormTextField -import chat.revolt.markdown.Markdown import kotlinx.coroutines.launch enum class ReportingState { @@ -112,7 +111,7 @@ fun ReportMessageDialog( if (messageIsBridged) { Spacer(modifier = Modifier.height(8.dp)) Text( - text = Markdown.annotate(stringResource(id = R.string.report_message_bridge_notice)), + text = stringResource(id = R.string.report_message_bridge_notice), fontSize = 12.sp ) } diff --git a/app/src/main/java/chat/revolt/screens/chat/views/ChannelScreen.kt b/app/src/main/java/chat/revolt/screens/chat/views/ChannelScreen.kt index f4906d59..a266b3ac 100644 --- a/app/src/main/java/chat/revolt/screens/chat/views/ChannelScreen.kt +++ b/app/src/main/java/chat/revolt/screens/chat/views/ChannelScreen.kt @@ -19,6 +19,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight @@ -55,6 +56,16 @@ import chat.revolt.components.screens.chat.AttachmentManager import chat.revolt.components.screens.chat.ChannelIcon import chat.revolt.components.screens.chat.ReplyManager import chat.revolt.components.screens.chat.TypingIndicator +import chat.revolt.internals.markdown.ChannelMentionRule +import chat.revolt.internals.markdown.CustomEmoteRule +import chat.revolt.internals.markdown.MarkdownContext +import chat.revolt.internals.markdown.MarkdownParser +import chat.revolt.internals.markdown.MarkdownState +import chat.revolt.internals.markdown.UserMentionRule +import chat.revolt.internals.markdown.createCodeRule +import chat.revolt.internals.markdown.createInlineCodeRule +import com.discord.simpleast.core.simple.SimpleMarkdownRules +import com.discord.simpleast.core.simple.SimpleRenderer import io.ktor.http.* import kotlinx.coroutines.Job import kotlinx.coroutines.delay @@ -401,6 +412,8 @@ fun ChannelScreen( val lazyListState = rememberLazyListState() val coroutineScope = rememberCoroutineScope() + val codeBlockColor = MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp) + val pickFileLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.OpenMultipleDocuments() ) { uriList -> @@ -520,7 +533,39 @@ fun ChannelScreen( items = viewModel.renderableMessages, key = { it.id!! } ) { message -> - Message(message) { + Message(message, parse = { + val parser = MarkdownParser() + .addRules( + SimpleMarkdownRules.createEscapeRule(), + UserMentionRule(), + ChannelMentionRule(), + CustomEmoteRule(), + ) + .addRules( + createCodeRule(context, codeBlockColor.toArgb()), + createInlineCodeRule(context, codeBlockColor.toArgb()), + ) + .addRules( + SimpleMarkdownRules.createSimpleMarkdownRules( + includeEscapeRule = false + ) + ) + + SimpleRenderer.render( + source = it.content ?: "", + parser = parser, + initialState = MarkdownState(0), + renderContext = MarkdownContext( + memberMap = mapOf(), + userMap = RevoltAPI.userCache.toMap(), + channelMap = RevoltAPI.channelCache.mapValues { ch -> + ch.value.name ?: ch.value.id!! + }, + emojiMap = RevoltAPI.emojiCache, + serverId = channel.server ?: "", + ) + ) + }) { navController.navigate("message/${message.id}/menu") } } diff --git a/app/src/main/res/font/inter.xml b/app/src/main/res/font/inter.xml new file mode 100644 index 00000000..888c31f4 --- /dev/null +++ b/app/src/main/res/font/inter.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/font/jetbrainsmono_regular.ttf b/app/src/main/res/font/jetbrainsmono_regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7d26f5a508b139899bf9209d761e481890f1cee8 GIT binary patch literal 114320 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 hu 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 Q$5=)wXhISH$b|L(06RjR@Bjb+ literal 0 HcmV?d00001 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 059450d3..a16f502f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -155,7 +155,7 @@ Thank you for taking the time to report this message. Please provide a reason for reporting this message. Selected message: - **Note:** This message may have been sent from another platform. It is recommended to also report the message on the platform it was sent from. + Note: This message may have been sent from another platform. It is recommended to also report the message on the platform it was sent from. Thank you for taking the time to report this server. Please provide a reason for reporting this server. Selected server: Thank you for taking the time to report this user. Please provide a reason for reporting this user. diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..dc10fba1 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 940f944c..135e8333 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,5 +1,5 @@ -