NTP-66592 add ttl for home page content widgets (#16522)

This commit is contained in:
Hitesh Kumar
2025-06-17 19:11:30 +05:30
committed by GitHub
parent adde68c7a4
commit bbb86346eb
6 changed files with 97 additions and 4 deletions

View File

@@ -64,6 +64,7 @@ import com.navi.uitron.model.UiTronResponse
import com.naviapp.home.reducer.HpEffects
import com.naviapp.home.reducer.HpEvents
import com.naviapp.home.utils.getHomeWidgetAnimationSpec
import com.naviapp.home.utils.shouldRenderWidget
import com.naviapp.home.viewmodel.HomeViewModel
import com.naviapp.utils.Constants.HOME_SCREEN_IN_CAPS
import kotlinx.coroutines.Dispatchers
@@ -147,6 +148,13 @@ private fun MastheadWidget(
mastheadWidget: MastheadWidgetData?,
appBarHeight: Dp,
) {
val shouldRender =
mastheadWidget?.let { shouldRenderWidget(it.renderActions?.preRenderAction) } ?: false
if (!shouldRender) {
Box(modifier = Modifier.padding(top = appBarHeight, bottom = 16.dp).fillMaxWidth())
return
}
mastheadWidget?.let {
Box(
modifier =

View File

@@ -17,9 +17,11 @@ import com.navi.base.cache.util.NaviSharedDbKeys
import com.navi.common.alchemist.model.AlchemistScreenDefinition
import com.navi.common.utils.safeAsync
import com.navi.common.utils.safeLaunch
import com.naviapp.home.model.HomePrioritySectionData
import com.naviapp.home.model.HomeScreenContentResult
import com.naviapp.home.model.SelectiveRefreshState
import com.naviapp.home.reducer.HpEvents
import com.naviapp.home.utils.getFilteredWidgets
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
@@ -221,8 +223,15 @@ constructor(
deserializer.setCacheEntity(cachedHomeContent.value)
val priorityContentSection = deserializer.getPrioritySection()
eventHandler(HpEvents.UpdatePrioritySectionData(priorityContentSection))
val prioritySection = deserializer.getPrioritySection()
val updatedPriorityContentSection =
HomePrioritySectionData(
content = getFilteredWidgets(prioritySection.content),
topNav = prioritySection.topNav,
)
eventHandler(HpEvents.UpdatePrioritySectionData(updatedPriorityContentSection))
trackEvent(
TYPE_CACHE_PROCESS,
mapOf(PARAM_CONTENT_STATUS to VALUE_PRIORITY_SECTION_UPDATED),
@@ -247,7 +256,7 @@ constructor(
screenLayoutDeferred.await()
eventHandler(
HpEvents.UpdateFrontLayerContent(
content = content,
content = getFilteredWidgets(content) ?: emptyList(),
isRenderingFirstTime = true,
)
)
@@ -406,7 +415,7 @@ constructor(
eventHandler(HpEvents.UpdateScreenWithoutContent(screenContent))
screenContent.screenStructure?.content?.widgets?.let { homeWidgets ->
getFilteredWidgets(screenContent.screenStructure?.content?.widgets)?.let { homeWidgets ->
eventHandler(HpEvents.UpdateFrontLayerContent(homeWidgets, isFirstRender))
}
}

View File

@@ -30,7 +30,11 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewModelScope
import com.navi.base.utils.TrustedTimeAccessor
import com.navi.common.alchemist.model.AlchemistWidgetModelDefinition
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper
import com.navi.common.utils.CommonNaviAnalytics
import com.navi.common.utils.evaluateMvelExpression
import com.navi.common.viewmodel.BaseVM
import com.navi.design.font.FontWeightEnum
import com.navi.design.font.getFontWeight
@@ -40,8 +44,11 @@ import com.navi.design.theme.FF959595
import com.navi.naviwidgets.extensions.NaviText
import com.navi.pay.common.theme.color.NaviPayColor
import com.navi.uitron.model.UiTronResponse
import com.navi.uitron.model.action.MvelAction
import com.navi.uitron.model.action.PublishEventAction
import com.navi.uitron.model.action.PublishableEventData
import com.navi.uitron.model.data.UiTronActionData
import com.navi.uitron.model.data.UiTronActionType
import com.navi.uitron.render.UiTronRenderer
import com.navi.uitron.viewmodel.UiTronViewModel
import com.naviapp.common.listeners.InAppUpdateBridge
@@ -62,6 +69,8 @@ import com.naviapp.screenOverlay.nudge.domain.model.data.StaticNudgeUiState
import com.naviapp.screenOverlay.nudge.domain.model.effect.NudgeEffect
import com.naviapp.screenOverlay.nudge.domain.model.event.NudgeEvent
import com.naviapp.screenOverlay.viewModel.ScreenOverlayVM
import com.naviapp.utils.Constants.CURRENT_TIME_IN_MILLIS
import com.naviapp.utils.Constants.FIREBASE_REMOTE_CONFIG_HELPER
import com.naviapp.utils.Constants.HOME_SCREEN_IN_CAPS
import com.naviapp.utils.Constants.HomePageConstants.HOME_PAGE_CTA_ACTION
import com.naviapp.utils.Constants.HomePageConstants.HOME_PAGE_CTA_ACTION_STATE
@@ -251,3 +260,35 @@ fun publishHomePageScrollActionState(viewModel: UiTronViewModel) {
)
)
}
// Filter widgets based on pre render action
fun getFilteredWidgets(
widgets: List<AlchemistWidgetModelDefinition<UiTronResponse>>?
): List<AlchemistWidgetModelDefinition<UiTronResponse>>? {
return widgets?.filter { widget ->
shouldRenderWidget(widget.widgetRenderActions?.preRenderAction)
}
}
// Check if a widget should render based on preRenderAction
fun shouldRenderWidget(actionData: UiTronActionData?): Boolean {
val mvelActions =
actionData?.actions?.filterIsInstance<MvelAction>()?.filter {
it.type == UiTronActionType.MvelAction.name
}
return mvelActions?.all { isConditionSatisfied(it) } ?: true
}
// Check if widget visibility condition is satisfied
fun isConditionSatisfied(action: MvelAction?): Boolean {
val expression = action?.inputExpression ?: return true
val dataMap =
mapOf(
CURRENT_TIME_IN_MILLIS to TrustedTimeAccessor.getCurrentTimeMillis(),
FIREBASE_REMOTE_CONFIG_HELPER to FirebaseRemoteConfigHelper,
)
return evaluateMvelExpression(expression = expression, dataMap = dataMap, defaultValue = true)
}

View File

@@ -232,6 +232,8 @@ object Constants {
const val TOPIC = "topic"
const val UNKNOWN_ERROR = "Unknown error"
const val HOME_SCREEN_SCREEN_HASH = "HOME_SCREEN_SCREEN_HASH"
const val CURRENT_TIME_IN_MILLIS = "currentTimeMillis"
const val FIREBASE_REMOTE_CONFIG_HELPER = "FirebaseRemoteConfigHelper"
object Notification {
const val HIDE_NOTIFICATION_COUNT = "hideNotificationCount"

View File

@@ -7,10 +7,13 @@
package com.navi.common.model.common
import com.navi.common.alchemist.model.AlchemistRenderActions
data class MastheadWidgetData(
val widgetData: UiTronActionAndResponse? = null,
val backgroundIllustration: UiTronActionAndResponse? = null,
val useLightStatusBar: Boolean = false,
val updateIconsOnScroll: Boolean = false,
val widgetBottomPadding: Int = 16,
val renderActions: AlchemistRenderActions? = null,
)

View File

@@ -0,0 +1,30 @@
/*
*
* * Copyright © 2025 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.common.utils
import com.google.gson.Gson
import org.mvel2.MVEL
inline fun <reified T> evaluateMvelExpression(
expression: String?,
dataMap: Map<String, Any?>,
defaultValue: T,
onFailure: ((Throwable) -> Unit) = {},
): T =
if (expression.isNullOrEmpty()) {
onFailure(IllegalArgumentException("Expression is null or empty"))
defaultValue
} else
try {
val result = MVEL.eval(expression, dataMap)
Gson().fromJson(result.toString(), T::class.java)
} catch (e: Exception) {
e.log()
onFailure(e)
defaultValue
}