TP-74012 | Naman Khurmi | Top Nav Fixes (#11817)
This commit is contained in:
@@ -14,6 +14,7 @@ import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.LocalOverscrollConfiguration
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -39,9 +40,8 @@ import com.airbnb.lottie.compose.LottieAnimation
|
||||
import com.airbnb.lottie.compose.LottieCompositionSpec
|
||||
import com.airbnb.lottie.compose.LottieConstants
|
||||
import com.airbnb.lottie.compose.rememberLottieComposition
|
||||
import com.navi.common.uitron.render.CommonCustomUiTronRenderer
|
||||
import com.navi.naviwidgets.R
|
||||
import com.navi.uitron.render.UiTronRenderer
|
||||
import com.naviapp.home.compose.widgetfactory.HomeWidgetRenderer
|
||||
import com.naviapp.home.model.WidgetUiState
|
||||
import com.naviapp.home.utils.getHomeWidgetAnimationSpec
|
||||
import com.naviapp.home.viewmodel.HomeVM
|
||||
@@ -60,7 +60,12 @@ typealias WidgetId = String
|
||||
*/
|
||||
@Composable
|
||||
@OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
|
||||
fun FrontLayerContent(modifier: Modifier, isShimmerVisible: Boolean, homeVM: HomeVM) {
|
||||
fun FrontLayerContent(
|
||||
modifier: Modifier,
|
||||
isShimmerVisible: Boolean,
|
||||
homeVM: HomeVM,
|
||||
homeScrollState: () -> ScrollState
|
||||
) {
|
||||
CompositionLocalProvider(LocalOverscrollConfiguration provides null) {
|
||||
Column(
|
||||
modifier.semantics { testTagsAsResourceId = true }.testTag("homeScreenWidgetsList")
|
||||
@@ -69,26 +74,33 @@ fun FrontLayerContent(modifier: Modifier, isShimmerVisible: Boolean, homeVM: Hom
|
||||
val widgetOrderList = homeVM.getHomeContentList()
|
||||
Column {
|
||||
UpperContent(homeVM) {
|
||||
RenderUiTronContent(widgetOrderList.take(homeVM.upperContentSize), homeVM)
|
||||
RenderUiTronContent(
|
||||
widgetOrderList.take(homeVM.upperContentSize),
|
||||
homeVM,
|
||||
homeScrollState
|
||||
)
|
||||
}
|
||||
val middleAndLowerContent = widgetOrderList.drop(homeVM.upperContentSize)
|
||||
UpperMiddleContent(homeVM) {
|
||||
RenderUiTronContent(
|
||||
middleAndLowerContent.take(Constants.SECTION_CONTENT_SIZE),
|
||||
homeVM
|
||||
homeVM,
|
||||
homeScrollState
|
||||
)
|
||||
}
|
||||
val lowerContent = middleAndLowerContent.drop(Constants.SECTION_CONTENT_SIZE)
|
||||
LowerMiddleContent(homeVM) {
|
||||
RenderUiTronContent(
|
||||
lowerContent.take(Constants.SECTION_CONTENT_SIZE),
|
||||
homeVM
|
||||
homeVM,
|
||||
homeScrollState
|
||||
)
|
||||
}
|
||||
LowerContent(homeVM) {
|
||||
RenderUiTronContent(
|
||||
lowerContent.drop(Constants.SECTION_CONTENT_SIZE),
|
||||
homeVM
|
||||
homeVM,
|
||||
homeScrollState
|
||||
)
|
||||
}
|
||||
ContentLoaderLottie(homeVM = homeVM)
|
||||
@@ -201,7 +213,11 @@ fun ContentLoaderLottie(homeVM: HomeVM) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderUiTronContent(elementList: List<WidgetId>, homeVM: HomeVM) {
|
||||
private fun RenderUiTronContent(
|
||||
elementList: List<WidgetId>,
|
||||
homeVM: HomeVM,
|
||||
homeScrollState: () -> ScrollState
|
||||
) {
|
||||
elementList.forEach { element ->
|
||||
key(element) {
|
||||
val widgetUiMap = homeVM.getWidgetUiStateMap()
|
||||
@@ -217,12 +233,12 @@ private fun RenderUiTronContent(elementList: List<WidgetId>, homeVM: HomeVM) {
|
||||
}
|
||||
AnimatedContainerForWidgets(isVisible = visible) {
|
||||
val response = homeVM.getWidgetUiStateMap()[element]?.widgetData
|
||||
UiTronRenderer(
|
||||
dataMap = response?.data,
|
||||
uiTronViewModel = homeVM,
|
||||
customUiTronRenderer = CommonCustomUiTronRenderer()
|
||||
)
|
||||
.Render(composeViews = response?.parentComposeView.orEmpty())
|
||||
HomeWidgetRenderer(
|
||||
widgetData = response?.data,
|
||||
viewModel = homeVM,
|
||||
composeView = response?.parentComposeView.orEmpty(),
|
||||
homeScrollState = homeScrollState
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +162,8 @@ private fun HomeScreenScaffoldRoot(
|
||||
.background(Color.White, frontLayerShape)
|
||||
.verticalScroll(homeScrollState),
|
||||
isShimmerVisible = widgetResponse.contentWidget.isNullOrEmpty(),
|
||||
homeVM = homeVM
|
||||
homeVM = homeVM,
|
||||
homeScrollState = { homeScrollState }
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.naviapp.home.compose.uiTron.helper
|
||||
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableIntState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class RotatingViewHelper @Inject constructor() {
|
||||
|
||||
private val mapOfRotatingViewIndexes = mutableMapOf<String, Int>()
|
||||
|
||||
private fun getIndex(layoutId: String): Int = mapOfRotatingViewIndexes.getOrElse(layoutId) { 0 }
|
||||
|
||||
private fun updateIndex(layoutId: String, index: Int) {
|
||||
mapOfRotatingViewIndexes[layoutId] = index
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun currentIndexToDisplay(
|
||||
layoutId: String,
|
||||
numberOfChildren: Int,
|
||||
delayDuration: Long,
|
||||
homeScrollState: () -> ScrollState
|
||||
): MutableIntState {
|
||||
return if (layoutId.isEmpty().not()) {
|
||||
var shouldPlayOnLifecycle by remember { mutableStateOf(false) }
|
||||
val currentIndex = remember { mutableIntStateOf(getIndex(layoutId)) }
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
if (homeScrollState().isScrollInProgress.not() && shouldPlayOnLifecycle) {
|
||||
LaunchedEffect(Unit) {
|
||||
while (true) {
|
||||
withContext(Dispatchers.IO) {
|
||||
delay(delayDuration.div(2))
|
||||
currentIndex.intValue = (currentIndex.intValue + 1) % numberOfChildren
|
||||
updateIndex(layoutId, currentIndex.intValue)
|
||||
delay(delayDuration.div(2))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DisposableEffect(lifecycleOwner) {
|
||||
val lifecycle = lifecycleOwner.lifecycle
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
shouldPlayOnLifecycle =
|
||||
when (event) {
|
||||
Lifecycle.Event.ON_RESUME -> {
|
||||
true
|
||||
}
|
||||
Lifecycle.Event.ON_STOP -> {
|
||||
false
|
||||
}
|
||||
else -> {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
lifecycle.addObserver(observer)
|
||||
|
||||
onDispose { lifecycle.removeObserver(observer) }
|
||||
}
|
||||
currentIndex
|
||||
} else remember { mutableIntStateOf(0) }
|
||||
}
|
||||
}
|
||||
@@ -13,10 +13,6 @@ import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableIntState
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.layout.layoutId
|
||||
@@ -39,7 +35,8 @@ import com.navi.uitron.utils.setWidth
|
||||
import com.navi.uitron.utils.setWidthRange
|
||||
import com.navi.uitron.viewmodel.UiTronViewModel
|
||||
import com.naviapp.home.compose.uiTron.model.viewProperties.RotatingViewProperty
|
||||
import kotlinx.coroutines.delay
|
||||
import com.naviapp.home.viewmodel.HomeVM
|
||||
import com.naviapp.utils.Constants.HomeCustomUitronWidgetConstants.ROTATING_VIEW_ANIMATION
|
||||
|
||||
class RotatingViewRenderer(
|
||||
private val childrenComposeViews: List<UiTronView>,
|
||||
@@ -87,10 +84,16 @@ class RotatingViewRenderer(
|
||||
RotatingView(
|
||||
modifier = viewModifier,
|
||||
indexValue = {
|
||||
currentIndexToDisplay(
|
||||
duration = { property.delay ?: 2000L },
|
||||
homeScrollState = homeScrollState
|
||||
)
|
||||
(uiTronViewModel as HomeVM)
|
||||
.rotatingViewHelper
|
||||
.get()
|
||||
.currentIndexToDisplay(
|
||||
layoutId = property.layoutId.orEmpty(),
|
||||
numberOfChildren = childrenComposeViews.size,
|
||||
delayDuration = property.delay ?: 2000L,
|
||||
homeScrollState = homeScrollState
|
||||
)
|
||||
.intValue
|
||||
},
|
||||
viewToRender = { uiTronRenderer.Render(composeViews = listOf(it)) }
|
||||
)
|
||||
@@ -100,34 +103,16 @@ class RotatingViewRenderer(
|
||||
@Composable
|
||||
private fun RotatingView(
|
||||
modifier: Modifier = Modifier,
|
||||
indexValue: @Composable () -> MutableIntState,
|
||||
indexValue: @Composable () -> Int,
|
||||
viewToRender: @Composable (UiTronView) -> Unit
|
||||
) {
|
||||
AnimatedContent(
|
||||
modifier = modifier,
|
||||
targetState = childrenComposeViews[indexValue().intValue],
|
||||
targetState = indexValue(),
|
||||
transitionSpec = { slideInVertically { it } togetherWith slideOutVertically { -it } },
|
||||
label = ""
|
||||
) { view ->
|
||||
viewToRender(view)
|
||||
label = ROTATING_VIEW_ANIMATION
|
||||
) { index ->
|
||||
viewToRender(childrenComposeViews[index])
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun currentIndexToDisplay(
|
||||
duration: () -> Long,
|
||||
homeScrollState: () -> ScrollState
|
||||
): MutableIntState {
|
||||
val currentIndex = remember { mutableIntStateOf(0) }
|
||||
if (homeScrollState().isScrollInProgress.not()) {
|
||||
LaunchedEffect(Unit) {
|
||||
while (true) {
|
||||
delay(duration().div(2))
|
||||
currentIndex.intValue = (currentIndex.intValue + 1) % childrenComposeViews.size
|
||||
delay(duration().div(2))
|
||||
}
|
||||
}
|
||||
}
|
||||
return remember { currentIndex }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ import com.naviapp.home.compose.listener.HomeScreenCallbackListener
|
||||
import com.naviapp.home.compose.model.BottomStickyNudgeState
|
||||
import com.naviapp.home.compose.model.HomePageExtraData
|
||||
import com.naviapp.home.compose.model.InitiatePaymentFromComposeData
|
||||
import com.naviapp.home.compose.uiTron.helper.RotatingViewHelper
|
||||
import com.naviapp.home.model.BottomBarTabType
|
||||
import com.naviapp.home.model.HomeCtaTypes
|
||||
import com.naviapp.home.respository.HomeRepository
|
||||
@@ -109,6 +110,7 @@ import com.naviapp.utils.Constants.OFFER_VIEWED
|
||||
import com.naviapp.utils.LOAN_ACCOUNT_NUMBER
|
||||
import com.naviapp.utils.NOTIFICATION_PERMISSION_SHOWN
|
||||
import com.naviapp.utils.naviAppSerializerGsonBuilder
|
||||
import dagger.Lazy
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -140,6 +142,7 @@ constructor(
|
||||
private val naviPayManager: NaviPayManager,
|
||||
private val selectiveRefreshHandler: SelectiveRefreshHandler,
|
||||
private val homePageDataUpdateHandler: HomePageDataUpdateHandler,
|
||||
val rotatingViewHelper: Lazy<RotatingViewHelper>,
|
||||
val nuxHandler: NewUserExperienceHandler
|
||||
) : BaseVM() {
|
||||
|
||||
|
||||
@@ -513,6 +513,10 @@ object Constants {
|
||||
const val SCROLL_FADE = "scroll_fade"
|
||||
}
|
||||
|
||||
object HomeCustomUitronWidgetConstants {
|
||||
const val ROTATING_VIEW_ANIMATION = "rotating view animation"
|
||||
}
|
||||
|
||||
enum class JourneyType(val type: String) {
|
||||
POST_PURCHASE("post_purchase")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user