Updated on 2026-08-14

This commit is contained in:
Tangem 2024-05-14 18:58:14 +05:00
parent 3b313ada7c
commit 4ef5b06701
7 changed files with 109 additions and 5 deletions

View file

@ -509,7 +509,7 @@
<string name="send_sending">Отправка</string>
<string name="send_summary_tap_hint">Нажмите на любое поле, чтобы изменить его</string>
<string name="send_summary_title">Отправка %s</string>
<string name="send_summary_transaction_description">Вы отправляете %1$s, включая комиссию сети %2$s</string>
<string name="send_summary_transaction_description">Вы отправляете **%1$s**, включая комиссию сети %2$s</string>
<string name="send_title_currency_format">Отправка %s</string>
<string name="send_total_label">Всего</string>
<string name="send_total_subtitle_asset_format">%1$s и %2$s будет отправлено</string>

View file

@ -508,7 +508,7 @@
<string name="send_sending">Sending...</string>
<string name="send_summary_tap_hint">Tap any field to change it</string>
<string name="send_summary_title">Send %s</string>
<string name="send_summary_transaction_description">You are sending %1$s including a network fee of %2$s</string>
<string name="send_summary_transaction_description">You are sending **%1$s** including a network fee of %2$s</string>
<string name="send_title_currency_format">Sending %s</string>
<string name="send_total_label">Total</string>
<string name="send_total_subtitle_asset_format">%1$s and %2$s will be sent</string>

View file

@ -45,4 +45,5 @@ dependencies {
implementation(deps.zxing.qrCore)
implementation(deps.jodatime)
implementation(deps.timber)
implementation(deps.markdown)
}

View file

@ -0,0 +1,56 @@
package com.tangem.core.ui.extensions
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import org.intellij.markdown.MarkdownElementTypes
import org.intellij.markdown.ast.ASTNode
import org.intellij.markdown.ast.getTextInNode
import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor
import org.intellij.markdown.parser.MarkdownParser
/** Markdown parser */
@Composable
fun rememberMarkdownParser() = remember {
MarkdownParser(CommonMarkFlavourDescriptor())
}
/**
* Styling markdown tree recursively
*
* @param markdownText original text
* @param node current processed node
*/
@Composable
fun AnnotatedString.Builder.appendMarkdown(markdownText: String, node: ASTNode): AnnotatedString.Builder {
when (node.type) {
MarkdownElementTypes.MARKDOWN_FILE, MarkdownElementTypes.PARAGRAPH -> {
node.children.forEach { childNode ->
appendMarkdown(
markdownText = markdownText,
node = childNode,
)
}
}
MarkdownElementTypes.STRONG -> {
withStyle(SpanStyle(fontWeight = FontWeight.Medium)) {
node.children
.drop(2)
.dropLast(2)
.forEach { childNode ->
appendMarkdown(
markdownText = markdownText,
node = childNode,
)
}
}
}
else -> {
append(node.getTextInNode(markdownText).toString())
}
}
return this
}

View file

@ -8,6 +8,9 @@ import androidx.compose.runtime.Immutable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.buildAnnotatedString
import org.intellij.markdown.MarkdownElementTypes
/**
* Utility class for creating text as [String] or [StringRes].
@ -160,6 +163,29 @@ fun TextReference.resolveReference(resources: Resources): String {
}
}
/** Resolve [TextReference] as [AnnotatedString] */
@Composable
fun TextReference.resolveAnnotatedReference(): AnnotatedString {
return when (this) {
is TextReference.Res -> {
val args = formatArgs
.map { if (it is TextReference) it.resolveReference() else it }
.toTypedArray()
formatAnnotated(stringResource(id = id, *args))
}
is TextReference.PluralRes -> formatAnnotated(
pluralStringResource(id, count, *formatArgs.toTypedArray()),
)
is TextReference.Str -> formatAnnotated(value)
is TextReference.Combined -> buildAnnotatedString {
refs.forEach {
append(formatAnnotated(it.resolveReference()))
}
}
}
}
/** Concatenate [this] reference with [ref] */
operator fun TextReference.plus(ref: TextReference): TextReference {
return when (this) {
@ -169,4 +195,14 @@ operator fun TextReference.plus(ref: TextReference): TextReference {
is TextReference.Str,
-> TextReference.Combined(refs = wrappedList(this, ref))
}
}
@Composable
private fun formatAnnotated(rawString: String): AnnotatedString {
val markdownDescriptor = rememberMarkdownParser()
val parsedTree = markdownDescriptor.parse(MarkdownElementTypes.MARKDOWN_FILE, rawString, true)
return buildAnnotatedString {
appendMarkdown(markdownText = rawString, node = parsedTree)
}
}

View file

@ -29,7 +29,10 @@ import com.tangem.core.ui.components.buttons.common.TangemButton
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
import com.tangem.core.ui.components.keyboardAsState
import com.tangem.core.ui.extensions.resolveAnnotatedReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.shareText
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.send.impl.presentation.state.SendUiCurrentScreen
import com.tangem.features.send.impl.presentation.state.SendUiState
@ -185,11 +188,17 @@ private fun SendingText(
currencySymbol = feeState.appCurrency.symbol,
currencyCode = feeState.appCurrency.code,
)
val textResource = remember(sendingValue, feeValue) {
resourceReference(
id = R.string.send_summary_transaction_description,
formatArgs = wrappedList(sendingValue, feeValue),
)
}
Text(
text = stringResource(id = R.string.send_summary_transaction_description, sendingValue, feeValue),
text = textResource.resolveAnnotatedReference(),
textAlign = TextAlign.Center,
style = TangemTheme.typography.caption1,
color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.primary1,
modifier = Modifier
.fillMaxWidth()
.padding(TangemTheme.dimens.spacing12),

View file

@ -82,6 +82,7 @@ swipeRefreshLayout = "1.1.0"
spr-client = "3.6.2"
web3j = "4.10.1"
leakcanary = "2.13"
markdown = "0.7.2"
# endregion Other libraries
# region Tangem
@ -249,4 +250,5 @@ camera-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref =
camera-view = { module = "androidx.camera:camera-view", version.ref = "androidXCamera" }
web3j-core = { module = "org.web3j:core", version.ref = "web3j" }
leakcanary = { module = "com.squareup.leakcanary:leakcanary-android", version.ref = "leakcanary" }
markdown = { module = "org.jetbrains:markdown", version.ref = "markdown" }
# endregion Other