fix(CON-271) : Fix rich text issue
This commit is contained in:
parent
c94f8a4f05
commit
ad08a4325f
@ -102,10 +102,11 @@ dependencies {
|
||||
implementation(libs.coil)
|
||||
implementation(libs.coil.network)
|
||||
|
||||
// Rich text formatting
|
||||
implementation(libs.rich.text)
|
||||
|
||||
// Tests
|
||||
testImplementation(libs.test.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.test.espresso)
|
||||
|
||||
|
||||
}
|
@ -29,7 +29,7 @@ import fr.openium.consentium_ui.ui.components.core.button.ConsentiumUIButtonStyl
|
||||
import fr.openium.consentium_ui.ui.components.style.ConsentiumUITheme
|
||||
import fr.openium.consentium_ui.ui.model.DetailConsentUI
|
||||
import fr.openium.consentium_ui.ui.model.LoadingElement
|
||||
import fr.openium.consentium_ui.ui.utils.htmlToAnnotatedString
|
||||
import fr.openium.consentium_ui.ui.utils.toRichHtmlString
|
||||
|
||||
|
||||
@Composable
|
||||
@ -73,7 +73,7 @@ internal fun ConsentiumUIDetailConsentComponent(
|
||||
Spacer(modifier = Modifier.height(25.dp))
|
||||
|
||||
Text(
|
||||
text = htmlToAnnotatedString(detailConsentUI.conservationDurationText),
|
||||
text = detailConsentUI.conservationDurationText.toRichHtmlString(),
|
||||
style = ConsentiumUITheme.typography.p3,
|
||||
color = ConsentiumUITheme.colors.onSurface,
|
||||
)
|
||||
|
@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil3.compose.AsyncImage
|
||||
@ -25,7 +26,7 @@ import fr.openium.consentium_ui.ui.components.core.button.ConsentiumUIButtonStyl
|
||||
import fr.openium.consentium_ui.ui.components.style.ConsentiumUITheme
|
||||
import fr.openium.consentium_ui.ui.model.GeneralConsentUI
|
||||
import fr.openium.consentium_ui.ui.model.LoadingElement
|
||||
import fr.openium.consentium_ui.ui.utils.htmlToAnnotatedString
|
||||
import fr.openium.consentium_ui.ui.utils.toRichHtmlString
|
||||
|
||||
@Composable
|
||||
internal fun ConsentiumUIGeneralConsentComponent(
|
||||
@ -42,36 +43,40 @@ internal fun ConsentiumUIGeneralConsentComponent(
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = 24.dp),
|
||||
) {
|
||||
if (generalConsentUI.iconUrl != null) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
AsyncImage(
|
||||
modifier = Modifier.heightIn(min = 48.dp),
|
||||
model = generalConsentUI.iconUrl,
|
||||
contentDescription = "Image",
|
||||
contentScale = ContentScale.FillBounds,
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
AsyncImage(
|
||||
modifier = Modifier.heightIn(min = 48.dp),
|
||||
model = generalConsentUI.iconUrl,
|
||||
contentDescription = "Image",
|
||||
contentScale = ContentScale.FillBounds,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
Text(
|
||||
text = htmlToAnnotatedString(generalConsentUI.mainConsentText),
|
||||
text = generalConsentUI.mainConsentText.toRichHtmlString(),
|
||||
style = ConsentiumUITheme.typography.p3,
|
||||
textAlign = TextAlign.Start,
|
||||
color = ConsentiumUITheme.colors.onSurface,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
TextLink(
|
||||
text = stringResource(R.string.cookies),
|
||||
onclick = onClickCookiesPolicies,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Spacer(modifier = Modifier
|
||||
.heightIn(16.dp)
|
||||
.weight(1f))
|
||||
|
||||
TextLink(
|
||||
text = stringResource(R.string.refuse),
|
||||
|
@ -21,7 +21,7 @@ import fr.openium.consentium_ui.ui.components.core.toggle.ConsentiumUISwitch
|
||||
import fr.openium.consentium_ui.ui.components.style.ConsentiumUITheme
|
||||
import fr.openium.consentium_ui.ui.model.PurposeStatusUI
|
||||
import fr.openium.consentium_ui.ui.model.PurposeUI
|
||||
import fr.openium.consentium_ui.ui.utils.htmlToAnnotatedString
|
||||
import fr.openium.consentium_ui.ui.utils.toRichHtmlString
|
||||
|
||||
@Composable
|
||||
internal fun PurposeComponent(
|
||||
@ -81,7 +81,7 @@ internal fun PurposeComponent(
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
|
||||
Text(
|
||||
text = htmlToAnnotatedString(purposeUI.description),
|
||||
text = purposeUI.description.toRichHtmlString(),
|
||||
style = ConsentiumUITheme.typography.p3,
|
||||
color = ConsentiumUITheme.colors.onSurface,
|
||||
)
|
||||
|
@ -1,54 +1,17 @@
|
||||
package fr.openium.consentium_ui.ui.utils
|
||||
|
||||
import android.text.ParcelableSpan
|
||||
import android.text.Spanned
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.core.text.HtmlCompat
|
||||
import com.mohamedrejeb.richeditor.model.rememberRichTextState
|
||||
|
||||
fun htmlToAnnotatedString(html: String): AnnotatedString {
|
||||
val spanned: Spanned = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||
return buildAnnotatedString {
|
||||
val text = spanned.toString()
|
||||
var start = 0
|
||||
spanned.getSpans(0, spanned.length, Any::class.java).map { it as ParcelableSpan }.forEach { span ->
|
||||
val startSpan = spanned.getSpanStart(span)
|
||||
val endSpan = spanned.getSpanEnd(span)
|
||||
@Composable
|
||||
fun String.toRichHtmlString(): AnnotatedString {
|
||||
val state = rememberRichTextState()
|
||||
|
||||
// Ajoutez le texte précédent sans style
|
||||
if (start < startSpan) {
|
||||
append(text.substring(start, startSpan))
|
||||
}
|
||||
|
||||
// Ajoutez le texte stylé
|
||||
withStyle(style = span.toSpanStyle()) {
|
||||
append(text.substring(startSpan, endSpan))
|
||||
}
|
||||
start = endSpan
|
||||
}
|
||||
|
||||
// Ajoutez le texte restant sans style
|
||||
if (start < text.length) {
|
||||
append(text.substring(start, text.length).trimEnd())
|
||||
}
|
||||
LaunchedEffect(this) {
|
||||
state.setHtml(this@toRichHtmlString)
|
||||
}
|
||||
}
|
||||
|
||||
fun ParcelableSpan.toSpanStyle(): SpanStyle {
|
||||
return when (this) {
|
||||
is android.text.style.StyleSpan -> {
|
||||
when (style) {
|
||||
android.graphics.Typeface.BOLD -> SpanStyle(fontWeight = androidx.compose.ui.text.font.FontWeight.Bold)
|
||||
android.graphics.Typeface.ITALIC -> SpanStyle(fontStyle = androidx.compose.ui.text.font.FontStyle.Italic)
|
||||
else -> SpanStyle()
|
||||
}
|
||||
}
|
||||
|
||||
is android.text.style.UnderlineSpan -> SpanStyle(textDecoration = TextDecoration.Underline)
|
||||
is android.text.style.StrikethroughSpan -> SpanStyle(textDecoration = TextDecoration.LineThrough)
|
||||
else -> SpanStyle()
|
||||
}
|
||||
return state.annotatedString
|
||||
}
|
@ -144,6 +144,9 @@ ga4 = { module = "com.google.firebase:firebase-analytics", version.ref = "ga4" }
|
||||
coil = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" }
|
||||
coil-network = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" }
|
||||
|
||||
# Rich text formating
|
||||
rich-text = { module = "com.mohamedrejeb.richeditor:richeditor-compose", version = "1.0.0-rc05-k2" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user