diff --git a/app/build.gradle b/app/build.gradle index d6e4fe13a..4bbb72dd4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,10 +66,12 @@ android { dependencies { implementation 'com.github.alorma:compose-settings-ui-m3:0.27.0' - implementation 'com.github.jeziellago:compose-markdown:0.3.1' - implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.11' + // Markdown support + implementation 'io.noties.markwon:core:4.6.2' + implementation 'io.noties.markwon:image-coil:4.6.2' + // Accompanist implementation 'com.google.accompanist:accompanist-pager:0.30.1' implementation 'com.google.accompanist:accompanist-pager-indicators:0.30.1' diff --git a/app/src/main/java/com/jerboa/MainActivity.kt b/app/src/main/java/com/jerboa/MainActivity.kt index 1ef77708a..2015cd042 100644 --- a/app/src/main/java/com/jerboa/MainActivity.kt +++ b/app/src/main/java/com/jerboa/MainActivity.kt @@ -33,6 +33,7 @@ import com.jerboa.ui.components.comment.edit.CommentEditActivity import com.jerboa.ui.components.comment.edit.CommentEditViewModel import com.jerboa.ui.components.comment.reply.CommentReplyActivity import com.jerboa.ui.components.comment.reply.CommentReplyViewModel +import com.jerboa.ui.components.common.MarkdownHelper import com.jerboa.ui.components.common.ShowChangelog import com.jerboa.ui.components.common.getCurrentAccount import com.jerboa.ui.components.common.getCurrentAccountSync @@ -100,6 +101,7 @@ class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + MarkdownHelper.init(this) window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) val accountSync = getCurrentAccountSync(accountViewModel) diff --git a/app/src/main/java/com/jerboa/ui/components/common/InputFields.kt b/app/src/main/java/com/jerboa/ui/components/common/InputFields.kt index d5df7a99c..741dee503 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/InputFields.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/InputFields.kt @@ -11,7 +11,6 @@ import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState @@ -71,11 +70,9 @@ import com.jerboa.api.uploadPictrsImage import com.jerboa.appendMarkdownImage import com.jerboa.db.Account import com.jerboa.imageInputStreamFromUri -import com.jerboa.ui.theme.MARKDOWN_FONT_MULTIPLIER import com.jerboa.ui.theme.MEDIUM_PADDING import com.jerboa.ui.theme.SMALL_PADDING import com.jerboa.ui.theme.muted -import dev.jeziellago.compose.markdowntext.MarkdownText import kotlinx.coroutines.launch @Composable @@ -680,15 +677,13 @@ fun MyMarkdownText( markdown: String, color: Color = MaterialTheme.colorScheme.onSurface, onClick: () -> Unit, + onLongClick: (() -> Unit)? = null, ) { - MarkdownText( + MarkdownHelper.CreateMarkdownView( markdown = markdown, - modifier = Modifier.fillMaxSize(), - onClick = onClick, color = color, - fontSize = MaterialTheme.typography.bodyLarge.fontSize.times(MARKDOWN_FONT_MULTIPLIER), -// style = MaterialTheme.typography.titleLarge, -// imageLoader = LocalImageLoader.current + onClick = onClick, + onLongClick = onLongClick, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/common/MarkdownHelper.kt b/app/src/main/java/com/jerboa/ui/components/common/MarkdownHelper.kt new file mode 100644 index 000000000..8da15e4d4 --- /dev/null +++ b/app/src/main/java/com/jerboa/ui/components/common/MarkdownHelper.kt @@ -0,0 +1,116 @@ +package com.jerboa.ui.components.common + +import android.content.Context +import android.util.TypedValue +import android.view.View +import android.widget.TextView +import androidx.annotation.FontRes +import androidx.annotation.IdRes +import androidx.compose.material.LocalContentAlpha +import androidx.compose.material.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.takeOrElse +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.viewinterop.AndroidView +import androidx.core.content.res.ResourcesCompat +import coil.ImageLoader +import com.jerboa.R +import io.noties.markwon.Markwon +import io.noties.markwon.image.coil.CoilImagesPlugin + +object MarkdownHelper { + private var markwon: Markwon? = null + + fun init(context: Context) { + val loader = ImageLoader.Builder(context) + .crossfade(true) + .placeholder(R.drawable.ic_launcher_foreground) + .build() + + markwon = Markwon.builder(context) + .usePlugin(CoilImagesPlugin.create(context, loader)) + .build() + } + + @Composable + fun CreateMarkdownView( + markdown: String, + color: Color = Color.Unspecified, + onClick: (() -> Unit)? = null, + onLongClick: (() -> Unit)? = null, + ) { + val style = MaterialTheme.typography.bodyLarge + val defaultColor: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current) + + AndroidView( + factory = { ctx -> + createTextView( + context = ctx, + color = color, + defaultColor = defaultColor, + fontSize = TextUnit.Unspecified, + style = style, + viewId = null, + onClick = onClick, + onLongClick = onLongClick, + ) + }, + update = { textView -> + markwon!!.setMarkdown(textView, markdown) +// if (disableLinkMovementMethod) { +// textView.movementMethod = null +// } + }, + ) + } + + private fun createTextView( + context: Context, + color: Color = Color.Unspecified, + defaultColor: Color, + fontSize: TextUnit = TextUnit.Unspecified, + textAlign: TextAlign? = null, + maxLines: Int = Int.MAX_VALUE, + @FontRes fontResource: Int? = null, + style: TextStyle, + @IdRes viewId: Int? = null, + onClick: (() -> Unit)? = null, + onLongClick: (() -> Unit)? = null, + ): TextView { + val textColor = color.takeOrElse { style.color.takeOrElse { defaultColor } } + val mergedStyle = style.merge( + TextStyle( + color = textColor, + fontSize = if (fontSize != TextUnit.Unspecified) fontSize else style.fontSize, + textAlign = textAlign, + ), + ) + return TextView(context).apply { + onClick?.let { setOnClickListener { onClick() } } + onLongClick?.let { setOnLongClickListener { onLongClick(); true } } + setTextColor(textColor.toArgb()) + setMaxLines(maxLines) + setTextSize(TypedValue.COMPLEX_UNIT_DIP, mergedStyle.fontSize.value) + width = maxWidth + + viewId?.let { id = viewId } + textAlign?.let { align -> + textAlignment = when (align) { + TextAlign.Left, TextAlign.Start -> View.TEXT_ALIGNMENT_TEXT_START + TextAlign.Right, TextAlign.End -> View.TEXT_ALIGNMENT_TEXT_END + TextAlign.Center -> View.TEXT_ALIGNMENT_CENTER + else -> View.TEXT_ALIGNMENT_TEXT_START + } + } + + fontResource?.let { font -> + typeface = ResourcesCompat.getFont(context, font) + } + } + } +} diff --git a/app/src/main/java/com/jerboa/ui/theme/Type.kt b/app/src/main/java/com/jerboa/ui/theme/Type.kt index 043901e6d..6d6e7c4cb 100644 --- a/app/src/main/java/com/jerboa/ui/theme/Type.kt +++ b/app/src/main/java/com/jerboa/ui/theme/Type.kt @@ -6,7 +6,6 @@ import androidx.compose.ui.unit.TextUnit const val FONT_LARGE_MULTIPLIER = 1.3 const val FONT_MEDIUM_MULTIPLIER = 0.8 const val FONT_SMALL_MULTIPLIER = 0.7 -const val MARKDOWN_FONT_MULTIPLIER = 1.2 // Set of Material typography styles to start with fun generateTypography(baseFontSize: TextUnit): Typography {