fix(CON-271) : Fix rich text issue

This commit is contained in:
Louis Legrand 2025-02-17 11:19:48 +01:00
parent c94f8a4f05
commit ad08a4325f
6 changed files with 40 additions and 68 deletions

View File

@ -102,10 +102,11 @@ dependencies {
implementation(libs.coil) implementation(libs.coil)
implementation(libs.coil.network) implementation(libs.coil.network)
// Rich text formatting
implementation(libs.rich.text)
// Tests // Tests
testImplementation(libs.test.junit) testImplementation(libs.test.junit)
androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.test.espresso) androidTestImplementation(libs.test.espresso)
} }

View File

@ -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.components.style.ConsentiumUITheme
import fr.openium.consentium_ui.ui.model.DetailConsentUI import fr.openium.consentium_ui.ui.model.DetailConsentUI
import fr.openium.consentium_ui.ui.model.LoadingElement 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 @Composable
@ -73,7 +73,7 @@ internal fun ConsentiumUIDetailConsentComponent(
Spacer(modifier = Modifier.height(25.dp)) Spacer(modifier = Modifier.height(25.dp))
Text( Text(
text = htmlToAnnotatedString(detailConsentUI.conservationDurationText), text = detailConsentUI.conservationDurationText.toRichHtmlString(),
style = ConsentiumUITheme.typography.p3, style = ConsentiumUITheme.typography.p3,
color = ConsentiumUITheme.colors.onSurface, color = ConsentiumUITheme.colors.onSurface,
) )

View File

@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign 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.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage 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.components.style.ConsentiumUITheme
import fr.openium.consentium_ui.ui.model.GeneralConsentUI import fr.openium.consentium_ui.ui.model.GeneralConsentUI
import fr.openium.consentium_ui.ui.model.LoadingElement 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 @Composable
internal fun ConsentiumUIGeneralConsentComponent( internal fun ConsentiumUIGeneralConsentComponent(
@ -42,7 +43,7 @@ internal fun ConsentiumUIGeneralConsentComponent(
.fillMaxSize() .fillMaxSize()
.padding(horizontal = 24.dp), .padding(horizontal = 24.dp),
) { ) {
if (generalConsentUI.iconUrl != null) {
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center, horizontalArrangement = Arrangement.Center,
@ -56,22 +57,26 @@ internal fun ConsentiumUIGeneralConsentComponent(
} }
Spacer(modifier = Modifier.height(24.dp)) Spacer(modifier = Modifier.height(24.dp))
}
Text( Text(
text = htmlToAnnotatedString(generalConsentUI.mainConsentText), text = generalConsentUI.mainConsentText.toRichHtmlString(),
style = ConsentiumUITheme.typography.p3, style = ConsentiumUITheme.typography.p3,
textAlign = TextAlign.Start, textAlign = TextAlign.Start,
color = ConsentiumUITheme.colors.onSurface, color = ConsentiumUITheme.colors.onSurface,
overflow = TextOverflow.Ellipsis,
) )
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(16.dp))
TextLink( TextLink(
text = stringResource(R.string.cookies), text = stringResource(R.string.cookies),
onclick = onClickCookiesPolicies, onclick = onClickCookiesPolicies,
) )
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier
.heightIn(16.dp)
.weight(1f))
TextLink( TextLink(
text = stringResource(R.string.refuse), text = stringResource(R.string.refuse),

View File

@ -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.components.style.ConsentiumUITheme
import fr.openium.consentium_ui.ui.model.PurposeStatusUI import fr.openium.consentium_ui.ui.model.PurposeStatusUI
import fr.openium.consentium_ui.ui.model.PurposeUI 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 @Composable
internal fun PurposeComponent( internal fun PurposeComponent(
@ -81,7 +81,7 @@ internal fun PurposeComponent(
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
Text( Text(
text = htmlToAnnotatedString(purposeUI.description), text = purposeUI.description.toRichHtmlString(),
style = ConsentiumUITheme.typography.p3, style = ConsentiumUITheme.typography.p3,
color = ConsentiumUITheme.colors.onSurface, color = ConsentiumUITheme.colors.onSurface,
) )

View File

@ -1,54 +1,17 @@
package fr.openium.consentium_ui.ui.utils package fr.openium.consentium_ui.ui.utils
import android.text.ParcelableSpan import androidx.compose.runtime.Composable
import android.text.Spanned import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle import com.mohamedrejeb.richeditor.model.rememberRichTextState
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withStyle
import androidx.core.text.HtmlCompat
fun htmlToAnnotatedString(html: String): AnnotatedString { @Composable
val spanned: Spanned = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY) fun String.toRichHtmlString(): AnnotatedString {
return buildAnnotatedString { val state = rememberRichTextState()
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)
// Ajoutez le texte précédent sans style LaunchedEffect(this) {
if (start < startSpan) { state.setHtml(this@toRichHtmlString)
append(text.substring(start, startSpan))
} }
// Ajoutez le texte stylé return state.annotatedString
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())
}
}
}
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()
}
} }

View File

@ -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 = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" }
coil-network = { module = "io.coil-kt.coil3:coil-network-okhttp", 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] [plugins]
android-application = { id = "com.android.application", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }