improvement: Ofload Markdown parsing (Vault, Send screens) from UI thread
This commit is contained in:
parent
aefb752467
commit
e6649feafa
@ -78,12 +78,15 @@ fun VaultViewNoteItem(
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
SelectionContainer {
|
||||
if (item.markdown) {
|
||||
MarkdownText(
|
||||
markdown = item.text,
|
||||
)
|
||||
} else {
|
||||
Text(item.text)
|
||||
when (item.content) {
|
||||
is VaultViewItem.Note.Content.Markdown -> {
|
||||
MarkdownText(
|
||||
markdown = item.content.node,
|
||||
)
|
||||
}
|
||||
is VaultViewItem.Note.Content.Text -> {
|
||||
Text(item.content.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ import com.artemchep.keyguard.common.usecase.CopyText
|
||||
import com.artemchep.keyguard.feature.attachments.model.AttachmentItem
|
||||
import com.artemchep.keyguard.ui.ContextItem
|
||||
import com.artemchep.keyguard.ui.FlatItemAction
|
||||
import com.halilibo.richtext.commonmark.CommonmarkAstNodeParser
|
||||
import com.halilibo.richtext.markdown.node.AstNode
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
@ -144,13 +146,39 @@ sealed interface VaultViewItem {
|
||||
|
||||
data class Note(
|
||||
override val id: String,
|
||||
val text: String,
|
||||
val markdown: Boolean,
|
||||
val content: Content,
|
||||
val elevation: Dp = 0.dp,
|
||||
val conceal: Boolean = false,
|
||||
val verify: ((() -> Unit) -> Unit)? = null,
|
||||
) : VaultViewItem {
|
||||
companion object
|
||||
companion object;
|
||||
|
||||
sealed interface Content {
|
||||
companion object {
|
||||
fun of(
|
||||
parser: CommonmarkAstNodeParser,
|
||||
markdown: Boolean,
|
||||
text: String,
|
||||
): Content =
|
||||
if (markdown) {
|
||||
kotlin.runCatching {
|
||||
val data = text.trimIndent()
|
||||
val node = parser.parse(data)
|
||||
Markdown(node)
|
||||
}.getOrNull()
|
||||
} else {
|
||||
null
|
||||
} ?: Text(text)
|
||||
}
|
||||
|
||||
data class Markdown(
|
||||
val node: AstNode,
|
||||
) : Content
|
||||
|
||||
data class Text(
|
||||
val text: String,
|
||||
) : Content
|
||||
}
|
||||
}
|
||||
|
||||
data class Spacer(
|
||||
|
@ -192,6 +192,7 @@ import com.artemchep.keyguard.ui.text.annotate
|
||||
import com.artemchep.keyguard.ui.theme.Dimens
|
||||
import com.artemchep.keyguard.ui.theme.combineAlpha
|
||||
import com.artemchep.keyguard.ui.totp.formatCode2
|
||||
import com.halilibo.richtext.commonmark.CommonmarkAstNodeParser
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@ -387,6 +388,7 @@ fun vaultViewScreenState(
|
||||
|
||||
val selectionHandle = selectionHandle("selection")
|
||||
val markdown = getMarkdown().first()
|
||||
val markdownParser = CommonmarkAstNodeParser()
|
||||
|
||||
val accountFlow = getAccounts()
|
||||
.map { accounts ->
|
||||
@ -715,6 +717,7 @@ fun vaultViewScreenState(
|
||||
primaryAction = primaryAction,
|
||||
items = oh(
|
||||
mode = mode,
|
||||
markdownParser = markdownParser,
|
||||
sharingScope = screenScope, // FIXME: must not be a screen scope!!
|
||||
selectionHandle = selectionHandle,
|
||||
canEdit = canEdit,
|
||||
@ -767,6 +770,7 @@ fun vaultViewScreenState(
|
||||
|
||||
private fun RememberStateFlowScope.oh(
|
||||
mode: AppMode,
|
||||
markdownParser: CommonmarkAstNodeParser,
|
||||
sharingScope: CoroutineScope,
|
||||
selectionHandle: SelectionHandle,
|
||||
canEdit: Boolean,
|
||||
@ -1423,10 +1427,14 @@ private fun RememberStateFlowScope.oh(
|
||||
}
|
||||
|
||||
if (cipher.type == DSecret.Type.SecureNote && cipher.notes.isNotEmpty()) {
|
||||
val content = VaultViewItem.Note.Content.of(
|
||||
parser = markdownParser,
|
||||
markdown = markdown,
|
||||
text = cipher.notes,
|
||||
)
|
||||
val note = VaultViewItem.Note(
|
||||
id = "note.text",
|
||||
text = if (markdown) cipher.notes.trimIndent() else cipher.notes,
|
||||
markdown = markdown,
|
||||
content = content,
|
||||
verify = verify,
|
||||
conceal = verify != null,
|
||||
)
|
||||
@ -1633,10 +1641,14 @@ private fun RememberStateFlowScope.oh(
|
||||
text = translate(Res.strings.notes),
|
||||
)
|
||||
emit(section)
|
||||
val content = VaultViewItem.Note.Content.of(
|
||||
parser = markdownParser,
|
||||
markdown = markdown,
|
||||
text = cipher.notes,
|
||||
)
|
||||
val note = VaultViewItem.Note(
|
||||
id = "note.text",
|
||||
text = if (markdown) cipher.notes.trimIndent() else cipher.notes,
|
||||
markdown = markdown,
|
||||
content = content,
|
||||
verify = verify,
|
||||
conceal = verify != null,
|
||||
)
|
||||
|
@ -87,6 +87,7 @@ import com.artemchep.keyguard.ui.icons.KeyguardView
|
||||
import com.artemchep.keyguard.ui.selection.SelectionHandle
|
||||
import com.artemchep.keyguard.ui.selection.selectionHandle
|
||||
import com.artemchep.keyguard.ui.text.annotate
|
||||
import com.halilibo.richtext.commonmark.CommonmarkAstNodeParser
|
||||
import io.ktor.http.Url
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.combine
|
||||
@ -226,6 +227,7 @@ fun sendViewScreenState(
|
||||
)
|
||||
|
||||
val markdown = getMarkdown().first()
|
||||
val markdownParser = CommonmarkAstNodeParser()
|
||||
|
||||
val accountFlow = getAccounts()
|
||||
.map { accounts ->
|
||||
@ -297,6 +299,7 @@ fun sendViewScreenState(
|
||||
null
|
||||
},
|
||||
items = oh(
|
||||
markdownParser = markdownParser,
|
||||
canEdit = canAddSecret,
|
||||
contentColor = contentColor,
|
||||
disabledContentColor = disabledContentColor,
|
||||
@ -323,6 +326,7 @@ fun sendViewScreenState(
|
||||
}
|
||||
|
||||
private fun RememberStateFlowScope.oh(
|
||||
markdownParser: CommonmarkAstNodeParser,
|
||||
canEdit: Boolean,
|
||||
contentColor: Color,
|
||||
disabledContentColor: Color,
|
||||
@ -438,10 +442,14 @@ private fun RememberStateFlowScope.oh(
|
||||
text = translate(Res.strings.notes),
|
||||
)
|
||||
emit(section)
|
||||
val content = VaultViewItem.Note.Content.of(
|
||||
parser = markdownParser,
|
||||
markdown = markdown,
|
||||
text = send.notes,
|
||||
)
|
||||
val note = VaultViewItem.Note(
|
||||
id = "note.text",
|
||||
text = if (markdown) send.notes.trimIndent() else send.notes,
|
||||
markdown = markdown,
|
||||
content = content,
|
||||
)
|
||||
emit(note)
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.halilibo.richtext.commonmark.Markdown
|
||||
import com.halilibo.richtext.markdown.BasicMarkdown
|
||||
import com.halilibo.richtext.markdown.node.AstNode
|
||||
import com.halilibo.richtext.ui.RichTextStyle
|
||||
import com.halilibo.richtext.ui.material3.RichText
|
||||
import com.halilibo.richtext.ui.resolveDefaults
|
||||
@ -14,13 +16,7 @@ fun MarkdownText(
|
||||
modifier: Modifier = Modifier,
|
||||
markdown: String,
|
||||
) {
|
||||
val richTextStyle = RichTextStyle().resolveDefaults().copy(
|
||||
stringStyle = RichTextStringStyle().copy(
|
||||
linkStyle = MaterialTheme.typography.bodyLarge.toSpanStyle().copy(
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
)
|
||||
val richTextStyle = getRichTextStyle()
|
||||
RichText(
|
||||
modifier = modifier,
|
||||
style = richTextStyle,
|
||||
@ -28,3 +24,28 @@ fun MarkdownText(
|
||||
Markdown(markdown)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MarkdownText(
|
||||
modifier: Modifier = Modifier,
|
||||
markdown: AstNode,
|
||||
) {
|
||||
val richTextStyle = getRichTextStyle()
|
||||
RichText(
|
||||
modifier = modifier,
|
||||
style = richTextStyle,
|
||||
) {
|
||||
BasicMarkdown(markdown)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getRichTextStyle(): RichTextStyle {
|
||||
return RichTextStyle().resolveDefaults().copy(
|
||||
stringStyle = RichTextStringStyle().copy(
|
||||
linkStyle = MaterialTheme.typography.bodyLarge.toSpanStyle().copy(
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user