mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-04-05 00:15:59 +00:00
android, desktop: view conditions as markdown (#5247)
* android, desktop: view conditions as markdown * better animation * unused * open chat links inside the app and removed divider, smaller font * paddings
This commit is contained in:
committed by
GitHub
parent
d912fe07a1
commit
7a91ed2ab2
@@ -48,6 +48,10 @@ kotlin {
|
||||
// Resources
|
||||
api("dev.icerock.moko:resources:0.23.0")
|
||||
api("dev.icerock.moko:resources-compose:0.23.0")
|
||||
|
||||
// Markdown
|
||||
implementation("com.mikepenz:multiplatform-markdown-renderer:0.27.0")
|
||||
implementation("com.mikepenz:multiplatform-markdown-renderer-m2:0.27.0")
|
||||
}
|
||||
}
|
||||
val commonTest by getting {
|
||||
|
||||
@@ -16,10 +16,11 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.platform.UriHandler
|
||||
import androidx.compose.ui.text.*
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.DpOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.unit.*
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.model.ChatController.appPrefs
|
||||
import chat.simplex.common.model.ChatController.getUsageConditions
|
||||
@@ -29,14 +30,19 @@ import chat.simplex.common.views.chat.item.ItemAction
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.onboarding.*
|
||||
import chat.simplex.res.MR
|
||||
import com.mikepenz.markdown.compose.Markdown
|
||||
import com.mikepenz.markdown.compose.components.markdownComponents
|
||||
import com.mikepenz.markdown.compose.elements.MarkdownHeader
|
||||
import com.mikepenz.markdown.m2.markdownColor
|
||||
import com.mikepenz.markdown.m2.markdownTypography
|
||||
import com.mikepenz.markdown.model.markdownPadding
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.net.URI
|
||||
import kotlinx.coroutines.*
|
||||
import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor
|
||||
|
||||
@Composable
|
||||
fun ModalData.OperatorView(
|
||||
fun OperatorView(
|
||||
currUserServers: MutableState<List<UserOperatorServers>>,
|
||||
userServers: MutableState<List<UserOperatorServers>>,
|
||||
serverErrors: MutableState<List<UserServersError>>,
|
||||
@@ -610,13 +616,20 @@ fun ConditionsTextView(
|
||||
val defaultConditionsLink = "https://github.com/simplex-chat/simplex-chat/blob/stable/PRIVACY.md"
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
// can show conditions when animation between modals finishes to prevent glitches
|
||||
val canShowConditionsAt = remember { System.currentTimeMillis() + 300 }
|
||||
LaunchedEffect(Unit) {
|
||||
scope.launch {
|
||||
scope.launch(Dispatchers.Default) {
|
||||
try {
|
||||
val conditions = getUsageConditions(rh = rhId)
|
||||
|
||||
if (conditions != null) {
|
||||
conditionsData.value = conditions
|
||||
val parentLink = "https://github.com/simplex-chat/simplex-chat/blob/${conditions.first.conditionsCommit}"
|
||||
val conditionsText = conditions.second
|
||||
val preparedText = if (conditionsText != null) prepareMarkdown(conditionsText.trimIndent(), parentLink) else null
|
||||
val modifiedConditions = Triple(conditions.first, preparedText, conditions.third)
|
||||
delay((canShowConditionsAt - System.currentTimeMillis()).coerceAtLeast(0))
|
||||
conditionsData.value = modifiedConditions
|
||||
} else {
|
||||
failedToLoad.value = true
|
||||
}
|
||||
@@ -639,10 +652,10 @@ fun ConditionsTextView(
|
||||
.verticalScroll(scrollState)
|
||||
.padding(8.dp)
|
||||
) {
|
||||
Text(
|
||||
text = conditionsText.trimIndent(),
|
||||
modifier = Modifier.padding(8.dp)
|
||||
)
|
||||
val parentUriHandler = LocalUriHandler.current
|
||||
CompositionLocalProvider(LocalUriHandler provides remember { internalUriHandler(parentUriHandler) }) {
|
||||
ConditionsMarkdown(conditionsText)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val conditionsLink = "https://github.com/simplex-chat/simplex-chat/blob/${usageConditions.conditionsCommit}/PRIVACY.md"
|
||||
@@ -655,6 +668,44 @@ fun ConditionsTextView(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ConditionsMarkdown(text: String) {
|
||||
Markdown(text,
|
||||
markdownColor(linkText = MaterialTheme.colors.primary),
|
||||
markdownTypography(
|
||||
h1 = MaterialTheme.typography.body1,
|
||||
h2 = MaterialTheme.typography.h3.copy(fontSize = 22.sp, fontWeight = FontWeight.Bold),
|
||||
h3 = MaterialTheme.typography.h4.copy(fontWeight = FontWeight.Bold),
|
||||
h4 = MaterialTheme.typography.h5.copy(fontSize = 16.sp, fontWeight = FontWeight.Bold),
|
||||
h5 = MaterialTheme.typography.h6.copy(fontWeight = FontWeight.Bold),
|
||||
link = MaterialTheme.typography.body1.copy(
|
||||
textDecoration = TextDecoration.Underline
|
||||
)
|
||||
),
|
||||
Modifier.padding(8.dp),
|
||||
// using CommonMarkFlavourDescriptor instead of GFMFlavourDescriptor because it shows `https://simplex.chat/` (link inside backticks) incorrectly
|
||||
flavour = CommonMarkFlavourDescriptor(),
|
||||
components = markdownComponents(
|
||||
heading2 = {
|
||||
Spacer(Modifier.height(10.dp))
|
||||
MarkdownHeader(it.content, it.node, it.typography.h2)
|
||||
Spacer(Modifier.height(5.dp))
|
||||
},
|
||||
heading3 = {
|
||||
Spacer(Modifier.height(10.dp))
|
||||
MarkdownHeader(it.content, it.node, it.typography.h3)
|
||||
Spacer(Modifier.height(3.dp))
|
||||
},
|
||||
heading4 = {
|
||||
Spacer(Modifier.height(10.dp))
|
||||
MarkdownHeader(it.content, it.node, it.typography.h4)
|
||||
Spacer(Modifier.height(4.dp))
|
||||
},
|
||||
),
|
||||
padding = markdownPadding(block = 4.dp)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ConditionsLinkView(conditionsLink: String) {
|
||||
SectionItemView {
|
||||
@@ -706,6 +757,24 @@ fun ConditionsLinkButton() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun internalUriHandler(parentUriHandler: UriHandler): UriHandler = object: UriHandler {
|
||||
override fun openUri(uri: String) {
|
||||
if (uri.startsWith("https://simplex.chat/contact#")) {
|
||||
openVerifiedSimplexUri(uri)
|
||||
} else {
|
||||
parentUriHandler.openUriCatching(uri)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun prepareMarkdown(text: String, parentLink: String): String {
|
||||
val localLinkRegex = Regex("\\[([^\\)]*)\\]\\(#.*\\)", RegexOption.MULTILINE)
|
||||
return text
|
||||
.replace("](/", "]($parentLink/")
|
||||
.replace("](./", "]($parentLink/")
|
||||
.replace(localLinkRegex) { it.groupValues.getOrNull(1) ?: it.value }
|
||||
}
|
||||
|
||||
private fun changeOperatorEnabled(userServers: MutableState<List<UserOperatorServers>>, operatorIndex: Int, enabled: Boolean) {
|
||||
userServers.value = userServers.value.toMutableList().apply {
|
||||
this[operatorIndex] = this[operatorIndex].copy(
|
||||
|
||||
Reference in New Issue
Block a user