APP-1433 | Data Layer Changes to Support Widget inside Widget + Mock Screen (#14)

This commit is contained in:
rahul bhat
2023-04-14 11:26:59 +05:30
committed by GitHub Enterprise
parent 1efa5f0074
commit 80e720a14a
22 changed files with 255 additions and 77 deletions

View File

@@ -18,17 +18,12 @@
android:label="@string/title_activity_main"
android:theme="@style/Theme.UiTron"
android:exported="true">
</activity>
<activity android:name=".MockActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -30,6 +30,7 @@ import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.demo.uitron.theme.PurpleDCD1F4
import com.demo.uitron.theme.RedEF0000
import com.uitron.demo.theme.UiTronTheme
class MainActivity : ComponentActivity() {
@@ -77,8 +78,11 @@ fun HomeScreen(navHostController: NavHostController) {
modifier = Modifier.padding(20.dp)
)
LazyVerticalGrid(columns = GridCells.Fixed(2), modifier = Modifier.padding(20.dp)) {
items(count = 1) {
PlaygroundBubble(navHostController)
items(count = 2) {
when (it) {
0 -> PlaygroundBubble(navHostController)
1 -> MockBubble(navHostController)
}
}
}
}
@@ -95,6 +99,7 @@ fun PlaygroundBubble(navHostController: NavHostController) {
modifier = Modifier
.width(60.dp)
.height(400.dp)
.padding(8.dp)
.background(color.value, shape = RoundedCornerShape(16.dp))
.clickable {
navHostController.navigate("playground")
@@ -104,6 +109,27 @@ fun PlaygroundBubble(navHostController: NavHostController) {
}
}
@Composable
fun MockBubble(navHostController: NavHostController) {
val color = remember { Animatable(RedEF0000) }
LaunchedEffect(Unit) {
color.animateTo(Color.White, animationSpec = tween(1000))
color.animateTo(RedEF0000, animationSpec = tween(1000))
}
Box(
modifier = Modifier
.width(60.dp)
.height(200.dp)
.padding(8.dp)
.background(color.value, shape = RoundedCornerShape(16.dp))
.clickable {
navHostController.navigate("mock")
}, contentAlignment = Alignment.Center
) {
Text(text = "Mock Testing", fontSize = 22.sp, fontWeight = FontWeight(800))
}
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {

View File

@@ -1,23 +0,0 @@
package com.uitron.demo
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import com.google.gson.reflect.TypeToken
import com.navi.uitron.model.UiTronResponse
import com.navi.uitron.render.UiTronRenderer
import com.navi.uitron.viewmodel.UiTronViewModel
class MockActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val type = object : TypeToken<UiTronResponse>() {}.type
val response = mockApiResponse<UiTronResponse>(this, type, "shapeMock")
setContent {
UiTronRenderer(
response.data,
UiTronViewModel()
).Render(composeViews = response.parentComposeView!!)
}
}
}

View File

@@ -0,0 +1,67 @@
import androidx.compose.foundation.layout.*
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import com.google.gson.reflect.TypeToken
import com.navi.uitron.model.UiTronResponse
import com.navi.uitron.render.UiTronRenderer
import com.navi.uitron.viewmodel.UiTronViewModel
import com.uitron.demo.mockApiResponse
import java.lang.Exception
/**
* Copyright © 2023 by Navi Technologies Private Limited
* All rights reserved. Strictly confidential
*/
@Composable
fun MockScreen() {
val mockValue = remember {
mutableStateOf(
"spinnerMockData"
)
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(20.dp)
) {
OutlinedTextField(
value = mockValue.value, onValueChange = { newValue ->
mockValue.value = newValue
}, modifier = Modifier
.fillMaxWidth()
.height(60.dp)
)
Spacer(modifier = Modifier.height(20.dp))
Column(
modifier = Modifier
.fillMaxWidth()
.fillMaxSize()
) {
if (mockValue.value.isEmpty().not()) {
val context = LocalContext.current
val uiTronResponse: UiTronResponse? = try {
val type = object : TypeToken<UiTronResponse>() {}.type
mockApiResponse<UiTronResponse>(context, type, mockValue.value)
} catch (e: Exception) {
null
}
uiTronResponse?.let {
UiTronRenderer(uiTronResponse.data, uiTronViewModel = UiTronViewModel())
.Render(composeViews = uiTronResponse.parentComposeView.orEmpty())
} ?: kotlin.run {
Text(text = "Error In Mock Config", color = Color.Red)
}
}
}
}
}

View File

@@ -18,6 +18,10 @@ fun UiTronDemoNavGraph(navController: NavHostController) {
composable(route = "playground") {
PlayGroundScreen()
}
composable(route = "mock") {
MockScreen()
}
}
}

View File

@@ -1,5 +1,5 @@
{
"mock": {
"spinnerMockData": {
"parentComposeView": [
{
"property": {
@@ -69,6 +69,20 @@
"margin": 28
}
}
},
"data": {
"title": {
"viewType": "Text",
"text": "Testing deserializer's"
},
"spannable_id": {
"viewType": "SpannableText",
"textMap": {
"text_id_1": "This is a new sample",
"text_id_2": "Spannable text.",
"text_id_3": "Please enjoy while it renders"
}
}
}
}
]

View File

@@ -7,14 +7,5 @@
package com.navi.uitron.model.data
/**
* Copyright © 2021 by Navi Technologies Private Limited
* All rights reserved. Strictly confidential
*/
data class ButtonData(
val textData: ButtonTextData? = null
) : UiTronData()
class ButtonData : UiTronData()
data class ButtonTextData(
val text: String? = null
)

View File

@@ -8,13 +8,15 @@
package com.navi.uitron.model.ui
import android.os.Parcelable
import com.navi.uitron.model.data.UiTronData
import kotlinx.parcelize.Parcelize
@Parcelize
data class UiTronView(
val property: BaseProperty? = null,
val childrenViews: List<UiTronView>? = null
val childrenViews: List<UiTronView>? = null,
val data: MutableMap<String, UiTronData?>? = null
) : Parcelable
@Parcelize

View File

@@ -63,12 +63,23 @@ class BoxRenderer(
top = property.padding?.top?.dp ?: 0.dp,
bottom = property.padding?.bottom?.dp ?: 0.dp
)
.customClickable({
uiTronViewModel.handleActions(uiTronData?.onClick)
}, interaction = property.interaction,
actions = uiTronData?.onClick?.actions)
.customClickable(
{
uiTronViewModel.handleActions(uiTronData?.onClick)
}, interaction = property.interaction,
actions = uiTronData?.onClick?.actions
)
) {
uiTronRenderer.Render(composeViews = childrenComposeViews)
childrenComposeViews.forEach {
if (it.data.isNullOrEmpty()) {
uiTronRenderer.Render(composeViews = listOf(it))
} else {
UiTronRenderer(
it.data,
uiTronViewModel
).Render(composeViews = listOf(it))
}
}
}
}
}

View File

@@ -41,7 +41,6 @@ class ButtonRenderer(
) : Renderer<ButtonProperty> {
@Composable
override fun Render(property: ButtonProperty, uiTronData: UiTronData?) {
val uiTronButtonData = uiTronData as? ButtonData
if (property.isStateFul.orFalse()) {
uiTronViewModel.addKeyToSavedStateHandle(property.layoutId.orEmpty())
val viewState = uiTronViewModel.handle.getStateFlow<String?>(

View File

@@ -76,7 +76,10 @@ class CardRenderer(
property.borderStrokeData?.color?.hexToComposeColor ?: Color.Transparent
)
) {
uiTronRenderer.Render(composeViews = childrenComposeViews)
childrenComposeViews.forEach {
if (it.data.isNullOrEmpty()) uiTronRenderer.Render(composeViews = listOf(it))
else UiTronRenderer(it.data, uiTronViewModel).Render(composeViews = listOf(it))
}
}
}
}

View File

@@ -76,7 +76,17 @@ class ColumnRenderer(
)
) {
if (property.repeat == null || (property.repeat ?: 0) <= 1) {
uiTronRenderer.Render(composeViews = childrenComposeViews)
childrenComposeViews.forEach {
if (it.data.isNullOrEmpty()) {
uiTronRenderer.Render(composeViews = listOf(it))
} else {
UiTronRenderer(it.data, uiTronViewModel).Render(
composeViews = listOf(
it
)
)
}
}
} else {
val uiTronColumnData = uiTronData as? ColumnData
uiTronColumnData?.childrenDataList?.forEachIndexed { index, uiTronData ->
@@ -90,7 +100,14 @@ class ColumnRenderer(
uiTronComposeViewProperty,
childrenComposeViews.getOrNull(0)?.childrenViews
)
uiTronRenderer.Render(listOf(childComposeView))
if (childComposeView.data.isNullOrEmpty()) {
uiTronRenderer.Render(listOf(childComposeView))
} else {
UiTronRenderer(childComposeView.data, uiTronViewModel).Render(
composeViews = listOf(childComposeView)
)
}
}
}
}

View File

@@ -46,7 +46,17 @@ class DialogRenderer(
uiTronViewModel.handleActions(dialogData?.onDismiss) // When user click outside of dialog
},
) {
uiTronRenderer.Render(composeViews = childrenComposeViews)
childrenComposeViews.forEach {
if (it.data.isNullOrEmpty()) {
uiTronRenderer.Render(composeViews = listOf(it))
} else {
UiTronRenderer(it.data, uiTronViewModel).Render(
composeViews = listOf(
it
)
)
}
}
}
}
}

View File

@@ -91,7 +91,15 @@ class DropdownRenderer(
DropdownMenuItem(onClick = {
isExpanded.value = false
}) {
uiTronRenderer.Render(composeViews = listOf(it))
if (it.data.isNullOrEmpty()) {
uiTronRenderer.Render(composeViews = listOf(it))
} else {
UiTronRenderer(it.data, uiTronViewModel).Render(
composeViews = listOf(
it
)
)
}
}
}
}

View File

@@ -1,10 +1,6 @@
package com.navi.uitron.render
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
@@ -89,7 +85,15 @@ class GridRenderer(
)
) {
if (index < itemCount) {
uiTronRenderer.Render(composeViews = listOf(childrenComposeViews[index]))
val childrenView = childrenComposeViews[index]
if (childrenView.data.isNullOrEmpty()) {
uiTronRenderer.Render(listOf(childrenView))
} else {
UiTronRenderer(
childrenView.data,
uiTronViewModel
).Render(listOf(childrenView))
}
}
}
}

View File

@@ -78,8 +78,15 @@ class LazyColumnRenderer(
actions = uiTronData?.onClick?.actions
),
) {
items(childrenComposeViews){
uiTronRenderer.Render(listOf(it))
items(childrenComposeViews) { childrenView ->
if (childrenView.data.isNullOrEmpty()) {
uiTronRenderer.Render(listOf(childrenView))
} else {
UiTronRenderer(
childrenView.data,
uiTronViewModel
).Render(listOf(childrenView))
}
}
}
lazyColumnData?.scrollData?.let {

View File

@@ -118,15 +118,22 @@ class LazyGridRenderer(
}
private fun LazyGridScope.getContent(lazyGridData: LazyGridData?) {
childrenComposeViews.forEach { uiTronView ->
childrenComposeViews.forEach { childrenView ->
item(
span = {
GridItemSpan(
currentLineSpan = lazyGridData?.childSpanCountMap?.get(uiTronView.property?.layoutId).orVal(1)
currentLineSpan = lazyGridData?.childSpanCountMap?.get(childrenView.property?.layoutId).orVal(1)
)
}
) {
uiTronRenderer.Render(listOf(uiTronView))
if (childrenView.data.isNullOrEmpty()) {
uiTronRenderer.Render(listOf(childrenView))
} else {
UiTronRenderer(
childrenView.data,
uiTronViewModel
).Render(listOf(childrenView))
}
}
}
}

View File

@@ -80,8 +80,15 @@ class LazyRowRenderer(
actions = uiTronData?.onClick?.actions
)
) {
items(childrenComposeViews) {
uiTronRenderer.Render(listOf(it))
items(childrenComposeViews) { childrenView ->
if (childrenView.data.isNullOrEmpty()) {
uiTronRenderer.Render(listOf(childrenView))
} else {
UiTronRenderer(
childrenView.data,
uiTronViewModel
).Render(listOf(childrenView))
}
}
}
lazyRowData?.scrollData?.let {

View File

@@ -38,8 +38,6 @@ import setWidth
@OptIn(ExperimentalPagerApi::class)
class PagerIndicatorRenderer(
private val childrenComposeViews: List<UiTronView>,
private val uiTronRenderer: UiTronRenderer,
private val uiTronViewModel: UiTronViewModel,
) : Renderer<PagerIndicatorProperty> {

View File

@@ -58,8 +58,9 @@ class PagerRenderer(
property.copyNonNullFrom(property.statesMap?.get(state.value))
}
if (property.visible.orTrue()) {
val pagerState = uiTronViewModel.stateHolder.getOrUpdatePagerState(property.pagerStateKey)
?: rememberPagerState()
val pagerState =
uiTronViewModel.stateHolder.getOrUpdatePagerState(property.pagerStateKey)
?: rememberPagerState()
if (property.orientation == PagerProperty.ORIENTATION_VERTICAL) {
VerticalPager(
count = childrenComposeViews.size,
@@ -91,7 +92,15 @@ class PagerRenderer(
horizontalAlignment = getHorizontalAlignment(property.horizontalAlignment),
contentPadding = getContentPaddingValues(property.contentPadding)
) { page ->
uiTronRenderer.Render(listOf(childrenComposeViews[page]))
val childrenView = childrenComposeViews[page]
if (childrenView.data.isNullOrEmpty()) {
uiTronRenderer.Render(listOf(childrenView))
} else {
UiTronRenderer(
childrenView.data,
uiTronViewModel
).Render(listOf(childrenView))
}
}
} else {
HorizontalPager(
@@ -124,7 +133,15 @@ class PagerRenderer(
verticalAlignment = getVerticalAlignment(verticalAlignment = property.verticalAlignment),
contentPadding = getContentPaddingValues(property.contentPadding)
) { page ->
uiTronRenderer.Render(listOf(childrenComposeViews[page]))
val childrenView = childrenComposeViews[page]
if (childrenView.data.isNullOrEmpty()) {
uiTronRenderer.Render(listOf(childrenView))
} else {
UiTronRenderer(
childrenView.data,
uiTronViewModel
).Render(listOf(childrenView))
}
}
}
if (property.scrollDelay.orZero() > 0) {

View File

@@ -76,7 +76,16 @@ class RowRenderer(
)
) {
if (property.repeat == null || (property.repeat ?: 0) <= 1) {
uiTronRenderer.Render(composeViews = childrenComposeViews)
childrenComposeViews.forEach { childrenView ->
if (childrenView.data.isNullOrEmpty()) {
uiTronRenderer.Render(listOf(childrenView))
} else {
UiTronRenderer(
childrenView.data,
uiTronViewModel
).Render(listOf(childrenView))
}
}
} else {
val uiTronRowData = uiTronData as? RowData
uiTronRowData?.childrenDataList?.forEachIndexed { index, uiTronData ->
@@ -86,11 +95,18 @@ class RowRenderer(
val uiTronComposeViewProperty = childrenComposeViews.getOrNull(0)?.property
uiTronComposeViewProperty?.layoutId =
property.layoutId?.plus(index)
val childComposeView = UiTronView(
val childrenView = UiTronView(
uiTronComposeViewProperty,
childrenComposeViews.getOrNull(0)?.childrenViews
)
uiTronRenderer.Render(listOf(childComposeView))
if (childrenView.data.isNullOrEmpty()) {
uiTronRenderer.Render(listOf(childrenView))
} else {
UiTronRenderer(
childrenView.data,
uiTronViewModel
).Render(listOf(childrenView))
}
}
}
}

View File

@@ -289,8 +289,6 @@ class UiTronRenderer(
ComposeViewType.PagerIndicator.name -> {
(composeView.property as? PagerIndicatorProperty)?.let {
PagerIndicatorRenderer(
childrenComposeViews = composeView.childrenViews.orEmpty(),
uiTronRenderer = this,
uiTronViewModel = uiTronViewModel
).Render(
property = it,