From effaae66ef20ea057fd402ffd36f85f5c395e6e9 Mon Sep 17 00:00:00 2001 From: Tushar Kumar Saha Date: Tue, 11 Apr 2023 13:42:43 +0530 Subject: [PATCH] TP-24304 | provide support for spannable text (#5) --- app/src/main/res/raw/mock.json | 82 +++++++++++++++---- .../ComposePropertyDeserializer.kt | 3 + .../deserializer/UiTronDataDeserializer.kt | 7 +- .../uitron/model/data/SpannableTextData.kt | 17 ++++ .../navi/uitron/model/ui/SpannableProperty.kt | 10 +++ .../com/navi/uitron/model/ui/UiTronView.kt | 3 +- .../uitron/render/SpannableTextRenderer.kt | 70 ++++++++++++++++ .../com/navi/uitron/render/UiTronRenderer.kt | 9 ++ 8 files changed, 184 insertions(+), 17 deletions(-) create mode 100644 navi-uitron/src/main/java/com/navi/uitron/model/data/SpannableTextData.kt create mode 100644 navi-uitron/src/main/java/com/navi/uitron/model/ui/SpannableProperty.kt create mode 100644 navi-uitron/src/main/java/com/navi/uitron/render/SpannableTextRenderer.kt diff --git a/app/src/main/res/raw/mock.json b/app/src/main/res/raw/mock.json index d91d0be..a997eae 100644 --- a/app/src/main/res/raw/mock.json +++ b/app/src/main/res/raw/mock.json @@ -9,20 +9,66 @@ "childrenViews": [ { "property": { - "viewType": "Spacer", - "layoutId": "item_1", - "backgroundColor": "#ABABAB", - "height": "200", - "width": "200" - } - }, - { - "property": { - "viewType": "Spacer", - "layoutId": "item_2", - "backgroundColor": "#010101", - "height": "200", - "width": "200" + "spanProperty": [ + { + "stringId": "text_id_1", + "property": { + "fontFamily": "naviSansFamily", + "fontWeight": "BOLD", + "fontSize": 16, + "textColor": "#FFE388" + }, + "tag": "CTA", + "cta": "item/navi/amc" + }, + { + "stringId": "text_id_2", + "property": { + "fontFamily": "naviSansFamily", + "fontWeight": "BOLD", + "fontSize": 18, + "textColor": "#2F003F" + }, + "tag": "CTA1", + "cta": "CTA1" + }, + { + "stringId": "text_id_3", + "property": { + "fontFamily": "naviSansFamily", + "fontWeight": "BOLD", + "fontSize": 12, + "textColor": "#3C0050" + }, + "tag": "CTA", + "cta": "item/navi/loan" + } + ], + "viewType": "SpannableText", + "layoutId": "spannable_id", + "padding": { + "start": 8, + "end": 8, + "top": 5, + "bottom": 5 + }, + "constraintLinks": { + "start": { + "viewId": "parent", + "constraint": "START", + "margin": 16 + }, + "end": { + "viewId": "parent", + "constraint": "END", + "margin": 16 + }, + "top": { + "viewId": "tagCard", + "constraint": "BOTTOM", + "margin": 28 + } + } } } ] @@ -32,6 +78,14 @@ "title": { "viewType": "Text", "text": "Testing deserializer's" + }, + "spannable_id": { + "viewType": "SpannableText", + "textMap": { + "text_id_1": "This is a sample", + "text_id_2": "Spannable text.", + "text_id_3": "Please enjoy while it renders" + } } } } diff --git a/navi-uitron/src/main/java/com/navi/uitron/deserializer/ComposePropertyDeserializer.kt b/navi-uitron/src/main/java/com/navi/uitron/deserializer/ComposePropertyDeserializer.kt index 2d594a1..39815d0 100644 --- a/navi-uitron/src/main/java/com/navi/uitron/deserializer/ComposePropertyDeserializer.kt +++ b/navi-uitron/src/main/java/com/navi/uitron/deserializer/ComposePropertyDeserializer.kt @@ -109,6 +109,9 @@ class ComposePropertyDeserializer : JsonDeserializer { ComposeViewType.Grid.name -> { context?.deserialize(jsonObject, GridProperty::class.java) } + ComposeViewType.SpannableText.name -> { + context?.deserialize(jsonObject, SpannableProperty::class.java) + } else -> null } } diff --git a/navi-uitron/src/main/java/com/navi/uitron/deserializer/UiTronDataDeserializer.kt b/navi-uitron/src/main/java/com/navi/uitron/deserializer/UiTronDataDeserializer.kt index c598f3f..026a92e 100644 --- a/navi-uitron/src/main/java/com/navi/uitron/deserializer/UiTronDataDeserializer.kt +++ b/navi-uitron/src/main/java/com/navi/uitron/deserializer/UiTronDataDeserializer.kt @@ -119,10 +119,13 @@ class UiTronDataDeserializer : JsonDeserializer { context?.deserialize(jsonObject, LazyRowData::class.java) } ComposeViewType.Pager.name -> { - context?.deserialize(jsonObject , PagerData::class.java) + context?.deserialize(jsonObject, PagerData::class.java) } ComposeViewType.Grid.name -> { - context?.deserialize(jsonObject , GridData::class.java) + context?.deserialize(jsonObject, GridData::class.java) + } + ComposeViewType.SpannableText.name -> { + context?.deserialize(jsonObject, SpannableTextData::class.java) } else -> null } diff --git a/navi-uitron/src/main/java/com/navi/uitron/model/data/SpannableTextData.kt b/navi-uitron/src/main/java/com/navi/uitron/model/data/SpannableTextData.kt new file mode 100644 index 0000000..e9ef3a1 --- /dev/null +++ b/navi-uitron/src/main/java/com/navi/uitron/model/data/SpannableTextData.kt @@ -0,0 +1,17 @@ +package com.navi.uitron.model.data + +/** + * this text map contains mapping of id and string content of individual spans + * + * for eg: + * + * "textMap": { + * "text_id_1": "This is a sample", + * "text_id_2": "Spannable text.", + * "text_id_3": "Please enjoy while it renders" + * } + * + */ +data class SpannableTextData( + val textMap: HashMap? = null, +) : UiTronData() \ No newline at end of file diff --git a/navi-uitron/src/main/java/com/navi/uitron/model/ui/SpannableProperty.kt b/navi-uitron/src/main/java/com/navi/uitron/model/ui/SpannableProperty.kt new file mode 100644 index 0000000..8f0f3f5 --- /dev/null +++ b/navi-uitron/src/main/java/com/navi/uitron/model/ui/SpannableProperty.kt @@ -0,0 +1,10 @@ +package com.navi.uitron.model.ui + +data class SpannableProperty( + val spanProperty: List +) : BaseProperty() + +data class SpanProperty( + val stringId: String? = null, + val property: TextProperty, +) \ No newline at end of file diff --git a/navi-uitron/src/main/java/com/navi/uitron/model/ui/UiTronView.kt b/navi-uitron/src/main/java/com/navi/uitron/model/ui/UiTronView.kt index af934dd..4b12ca0 100644 --- a/navi-uitron/src/main/java/com/navi/uitron/model/ui/UiTronView.kt +++ b/navi-uitron/src/main/java/com/navi/uitron/model/ui/UiTronView.kt @@ -133,7 +133,8 @@ enum class ComposeViewType { PagerIndicator, LazyColumn, LazyRow, - Grid + Grid, + SpannableText } enum class HorizontalArrangementType { diff --git a/navi-uitron/src/main/java/com/navi/uitron/render/SpannableTextRenderer.kt b/navi-uitron/src/main/java/com/navi/uitron/render/SpannableTextRenderer.kt new file mode 100644 index 0000000..f2472d4 --- /dev/null +++ b/navi-uitron/src/main/java/com/navi/uitron/render/SpannableTextRenderer.kt @@ -0,0 +1,70 @@ +package com.navi.uitron.render + +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.ClickableText +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.layoutId +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.navi.uitron.UiTronSdkManager +import com.navi.uitron.model.data.SpannableTextData +import com.navi.uitron.model.data.UiTronData +import com.navi.uitron.model.ui.SpannableProperty +import getTextDecoration +import hexToComposeColor +import setBackground + +/** + * this is simple Spannable text renderer. It doesn't handle clicks + * Sample can be found here: + * https://navihq.atlassian.net/wiki/spaces/NAVI/pages/643825690/UITron+Atomic+components+Spannable+text + */ +class SpannableTextRenderer : Renderer { + @Composable + override fun Render(property: SpannableProperty, uiTronData: UiTronData?) { + val spanProperties = property.spanProperty + val spanData = uiTronData as? SpannableTextData + val text = java.lang.StringBuilder() + val annotatedString = buildAnnotatedString { + spanProperties.forEach { spanProperty -> + val string = spanData?.textMap?.get(spanProperty.stringId) ?: "" + val startIndex = text.length + val endIndex = text.length + (string.length) + addStyle( + style = SpanStyle( + fontFamily = UiTronSdkManager.getDependencyProvider().getFontFamily(spanProperty.property.fontFamily), + fontWeight = UiTronSdkManager.getDependencyProvider().getFontWeight(spanProperty.property.fontWeight), + fontSize = spanProperty.property.fontSize?.sp ?: 14.sp, + color = spanProperty.property.textColor?.hexToComposeColor ?: Color.Black, + textDecoration = getTextDecoration(spanProperty.property.textDecoration), + letterSpacing = spanProperty.property.letterSpacing?.sp ?: 0.sp, + ), startIndex, endIndex + ) + + text.append("$string ") + } + append(text.toString()) + } + ClickableText(text = annotatedString, + modifier = Modifier + .layoutId(property.layoutId.orEmpty()) + .padding( + top = property.padding?.top?.dp ?: 0.dp, + bottom = property.padding?.bottom?.dp ?: 0.dp, + start = property.padding?.start?.dp ?: 0.dp, + end = property.padding?.end?.dp ?: 0.dp + ) + .setBackground( + property.backgroundColor, + property.shape, + property.backGroundBrushData + ), + onClick = { + + }) + } +} \ No newline at end of file diff --git a/navi-uitron/src/main/java/com/navi/uitron/render/UiTronRenderer.kt b/navi-uitron/src/main/java/com/navi/uitron/render/UiTronRenderer.kt index 501e06f..c94e9ab 100644 --- a/navi-uitron/src/main/java/com/navi/uitron/render/UiTronRenderer.kt +++ b/navi-uitron/src/main/java/com/navi/uitron/render/UiTronRenderer.kt @@ -337,6 +337,15 @@ class UiTronRenderer( ) } } + ComposeViewType.SpannableText.name -> { + (composeView.property as? SpannableProperty)?.let { + SpannableTextRenderer().Render(property = it, + uiTronData = dataMap?.getOrElse( + it.layoutId.orEmpty() + ) { null } + ) + } + } } } }