TP-84808 | Insurance Tab Compose Migration (#12774)
This commit is contained in:
committed by
GitHub
parent
9bf6bfb5fa
commit
8d4244f26c
@@ -1,354 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.naviapp.common.tab
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.LocalOverscrollConfiguration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.neverEqualPolicy
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.facebook.react.ReactApplication
|
||||
import com.facebook.shimmer.ShimmerFrameLayout
|
||||
import com.navi.analytics.utils.NaviTrackEvent
|
||||
import com.navi.base.model.ActionData
|
||||
import com.navi.base.model.CtaData
|
||||
import com.navi.base.model.CtaType
|
||||
import com.navi.base.model.NaviClickAction
|
||||
import com.navi.base.utils.isNotNull
|
||||
import com.navi.base.utils.orFalse
|
||||
import com.navi.base.utils.orZero
|
||||
import com.navi.common.analytics.NaviAnalytics
|
||||
import com.navi.common.callback.RequestToCallbackHandler
|
||||
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper
|
||||
import com.navi.common.listeners.NewBottomSheetListener
|
||||
import com.navi.common.react.ReactPreLoadHeadLessActivity
|
||||
import com.navi.common.ui.errorview.FullScreenErrorComposeView
|
||||
import com.navi.common.ui.fragment.BaseFragment
|
||||
import com.navi.insurance.R
|
||||
import com.navi.insurance.common.models.InsuranceTabState
|
||||
import com.navi.insurance.navigator.NaviInsuranceDeeplinkNavigator
|
||||
import com.navi.insurance.util.Constants
|
||||
import com.navi.insurance.util.log
|
||||
import com.navi.naviwidgets.callbacks.WidgetCallback
|
||||
import com.navi.naviwidgets.composewidget.GenericComposableWidgetFactory
|
||||
import com.navi.naviwidgets.extensions.FloatingButtonOverlay
|
||||
import com.navi.naviwidgets.extensions.isScrollingDown
|
||||
import com.navi.uitron.render.UiTronRenderer
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class InsuranceTabFragment(private val lazyListState: () -> LazyListState? = { null }) :
|
||||
BaseFragment(), WidgetCallback, NewBottomSheetListener {
|
||||
private val viewModel by viewModels<InsuranceTabViewModel>()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
val layout =
|
||||
ComposeView(requireContext()).apply {
|
||||
setContent { RenderUiTronDataSecondary(lazyListState) }
|
||||
}
|
||||
observeCtaData()
|
||||
viewModel.clearCacheOnVersionUpgrade()
|
||||
if (
|
||||
FirebaseRemoteConfigHelper.getBoolean(
|
||||
key = FirebaseRemoteConfigHelper.ENABLE_REACT_PREFETCH_IN_TAB,
|
||||
defaultValue = false
|
||||
)
|
||||
) {
|
||||
try {
|
||||
preLoadReactResources()
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
}
|
||||
}
|
||||
return layout
|
||||
}
|
||||
|
||||
private fun preLoadReactResources() {
|
||||
try {
|
||||
val reactApplication = requireActivity().application as ReactApplication
|
||||
reactApplication.reactNativeHost.reactInstanceManager.createReactContextInBackground()
|
||||
val intent = Intent(requireActivity(), ReactPreLoadHeadLessActivity::class.java)
|
||||
startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
viewModel.fetchInsuranceTabDetails()
|
||||
}
|
||||
|
||||
private fun observeCtaData() {
|
||||
viewModel.redirectionCta.observe(viewLifecycleOwner) { ctaData ->
|
||||
NaviTrackEvent.sendEvent(ctaData, screenName)
|
||||
ctaData.let {
|
||||
NaviInsuranceDeeplinkNavigator.navigate(
|
||||
requireActivity(),
|
||||
it,
|
||||
finish = it.finish.orFalse(),
|
||||
clearTask = it.clearTask.orFalse(),
|
||||
callbackHandler =
|
||||
object : RequestToCallbackHandler {
|
||||
override fun onCallbackRaised() {
|
||||
viewModel.fetchInsuranceTabDetails()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(naviClickAction: NaviClickAction, widgetId: String?) {
|
||||
if (naviClickAction is CtaData) {
|
||||
NaviTrackEvent.sendEvent(naviClickAction, screenName)
|
||||
val bundle = Bundle()
|
||||
bundle.putParcelable(Constants.PARAMS_EXTRA, naviClickAction)
|
||||
when (naviClickAction.type) {
|
||||
CtaType.DISMISS_TOAST.value -> {
|
||||
var toastIdentifier: String? = null
|
||||
naviClickAction.parameters?.forEach { lineItem ->
|
||||
if (lineItem.key == "toastIdentifier") {
|
||||
toastIdentifier = lineItem.value.orEmpty()
|
||||
}
|
||||
}
|
||||
viewModel.dismissCta(toastIdentifier.orEmpty())
|
||||
}
|
||||
CtaType.CANCEL_QUOTE.value -> {
|
||||
var quoteId: String? = null
|
||||
naviClickAction.parameters?.forEach { lineItem ->
|
||||
if (lineItem.key == "quoteId") {
|
||||
quoteId = lineItem.value.orEmpty()
|
||||
}
|
||||
}
|
||||
viewModel.closePolicyCard(quoteId.orEmpty())
|
||||
}
|
||||
else -> {
|
||||
NaviInsuranceDeeplinkNavigator.navigate(
|
||||
requireActivity(),
|
||||
naviClickAction,
|
||||
finish = naviClickAction.finish.orFalse(),
|
||||
clearTask = naviClickAction.clearTask.orFalse(),
|
||||
callbackHandler =
|
||||
object : RequestToCallbackHandler {
|
||||
override fun onCallbackRaised() {
|
||||
viewModel.fetchInsuranceTabDetails()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
NaviTrackEvent.trackEventOnClickStream(NaviAnalytics.INSURANCE_TAB_INIT)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun RenderUiTronDataSecondary(lazyListState: () -> LazyListState? = { null }) {
|
||||
val state by viewModel.insuranceTabDataFlow.collectAsState()
|
||||
val listState = lazyListState() ?: rememberLazyListState()
|
||||
val isScrollingDown = listState.isScrollingDown()
|
||||
val widgetCallback: WidgetCallback = this
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
when {
|
||||
state.data.isNotNull() -> {
|
||||
LaunchedEffect(Unit) {
|
||||
state.data?.pageMetaData?.analyticsEvents?.forEach {
|
||||
NaviTrackEvent.trackEvent(
|
||||
it.name.orEmpty(),
|
||||
it.properties,
|
||||
it.isNeededForAppsflyer.orFalse(),
|
||||
it.isNeededForFirebase.orFalse()
|
||||
)
|
||||
}
|
||||
}
|
||||
Box {
|
||||
Scaffold(
|
||||
modifier =
|
||||
Modifier.fillMaxSize()
|
||||
.animateContentSize(
|
||||
animationSpec = tween(durationMillis = 600, delayMillis = 0)
|
||||
),
|
||||
topBar = {
|
||||
if (state.data?.headerWidget.isNotNull()) {
|
||||
UiTronRenderer(state.data?.headerWidget?.data, viewModel)
|
||||
.Render(
|
||||
composeViews =
|
||||
state.data
|
||||
?.headerWidget
|
||||
?.parentComposeView
|
||||
.orEmpty()
|
||||
)
|
||||
} else {
|
||||
state.data?.headerNativeWidget?.let { data ->
|
||||
Box(modifier = Modifier.background(Color.White)) {
|
||||
GenericComposableWidgetFactory(
|
||||
data = data,
|
||||
widgetCallback = widgetCallback
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
bottomBar = {
|
||||
if (state.data?.footerWidget.isNotNull()) {
|
||||
UiTronRenderer(state.data?.footerWidget?.data, viewModel)
|
||||
.Render(
|
||||
composeViews =
|
||||
state.data
|
||||
?.footerWidget
|
||||
?.parentComposeView
|
||||
.orEmpty()
|
||||
)
|
||||
} else {
|
||||
state.data?.footerNativeWidget?.let { data ->
|
||||
Box(modifier = Modifier.background(Color.White)) {
|
||||
GenericComposableWidgetFactory(
|
||||
data = data,
|
||||
widgetCallback = widgetCallback
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
CompositionLocalProvider(LocalOverscrollConfiguration provides null) {
|
||||
ContentComposable(
|
||||
listState = listState,
|
||||
widgetCallback = widgetCallback,
|
||||
state = state
|
||||
)
|
||||
}
|
||||
}
|
||||
if (state.data?.floatingButtonData.isNotNull()) {
|
||||
FloatingButtonOverlay(
|
||||
state.data?.floatingButtonData,
|
||||
!isScrollingDown,
|
||||
widgetCallback,
|
||||
screenName
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
state.isLoading -> {
|
||||
ShowShimmer()
|
||||
}
|
||||
state.hasErrorOccurred -> {
|
||||
FullScreenErrorComposeView(
|
||||
error = state.genericErrorResponse,
|
||||
onRetryClick = { viewModel.fetchInsuranceTabDetails() }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ContentComposable(
|
||||
listState: LazyListState,
|
||||
state: InsuranceTabState? = null,
|
||||
widgetCallback: WidgetCallback?,
|
||||
) {
|
||||
val currentList = state?.data?.listOfNativeWidgets
|
||||
var dataList by
|
||||
remember(
|
||||
key1 = state?.data,
|
||||
calculation = { mutableStateOf(currentList, neverEqualPolicy()) }
|
||||
)
|
||||
LazyColumn(state = listState, modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
|
||||
if (state?.data?.listOfUiTronWidgets.isNotNull()) {
|
||||
items(state?.data?.listOfUiTronWidgets?.size.orZero()) { index ->
|
||||
val uiTronResponse = state?.data?.listOfUiTronWidgets?.getOrNull(index)
|
||||
|
||||
Column(modifier = Modifier.wrapContentSize()) {
|
||||
UiTronRenderer(uiTronResponse?.data, viewModel)
|
||||
.Render(composeViews = uiTronResponse?.parentComposeView.orEmpty())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
items(dataList?.size.orZero(), key = { index -> index }) { index ->
|
||||
val widgetData = dataList?.getOrNull(index)
|
||||
Column(modifier = Modifier.wrapContentSize()) {
|
||||
GenericComposableWidgetFactory(
|
||||
data = widgetData,
|
||||
widgetCallback = widgetCallback,
|
||||
onWidgetUpdate = { data ->
|
||||
val updatedList = dataList?.toMutableList() ?: mutableListOf()
|
||||
updatedList[index] = data
|
||||
dataList = updatedList
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ShowShimmer() {
|
||||
val layout = ShimmerFrameLayout(requireContext())
|
||||
layout.addView(
|
||||
LayoutInflater.from(requireContext())
|
||||
.inflate(R.layout.shimmer_tab_layout, layout, false)
|
||||
)
|
||||
AndroidView(modifier = Modifier.fillMaxSize().background(Color.White), factory = { layout })
|
||||
}
|
||||
|
||||
override fun buttonClick(actionData: ActionData?) = Unit
|
||||
|
||||
companion object {
|
||||
fun newInstance(
|
||||
bundle: Bundle?,
|
||||
lazyListState: () -> LazyListState? = { null }
|
||||
): InsuranceTabFragment {
|
||||
return InsuranceTabFragment(lazyListState).apply { arguments = bundle }
|
||||
}
|
||||
}
|
||||
|
||||
override val screenName: String
|
||||
get() = NaviAnalytics.INSURANCE_TAB_INIT
|
||||
}
|
||||
@@ -7,27 +7,41 @@
|
||||
|
||||
package com.naviapp.common.tab
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.facebook.react.ReactApplication
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.navi.analytics.utils.NaviTrackEvent
|
||||
import com.navi.base.cache.repository.NaviCacheRepository
|
||||
import com.navi.base.model.CtaData
|
||||
import com.navi.base.model.CtaType
|
||||
import com.navi.base.model.NaviClickAction
|
||||
import com.navi.base.utils.isNotNull
|
||||
import com.navi.base.utils.isNull
|
||||
import com.navi.base.utils.orFalse
|
||||
import com.navi.base.utils.orZero
|
||||
import com.navi.common.analytics.NaviAnalytics
|
||||
import com.navi.common.analytics.NaviAnalytics.Companion.CACHE_API_LOAD_ERROR
|
||||
import com.navi.common.analytics.NaviAnalytics.Companion.INSURANCE_TAB_INIT
|
||||
import com.navi.common.callback.RequestToCallbackHandler
|
||||
import com.navi.common.model.ModuleNameV2
|
||||
import com.navi.common.network.models.ErrorMetaData
|
||||
import com.navi.common.react.ReactPreLoadHeadLessActivity
|
||||
import com.navi.common.uitron.model.action.CtaAction
|
||||
import com.navi.common.utils.SingleLiveEvent
|
||||
import com.navi.common.utils.isValidResponse
|
||||
import com.navi.common.viewmodel.BaseVM
|
||||
import com.navi.insurance.common.models.GiErrorMetaData
|
||||
import com.navi.insurance.common.models.InsuranceTabState
|
||||
import com.navi.insurance.navigator.NaviInsuranceDeeplinkNavigator
|
||||
import com.navi.insurance.network.ApiErrorTagType
|
||||
import com.navi.insurance.util.Constants
|
||||
import com.navi.insurance.util.log
|
||||
import com.navi.uitron.model.action.AnalyticsAction
|
||||
import com.navi.uitron.model.data.UiTronAction
|
||||
import com.naviapp.home.compose.activity.HomePageActivity
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -54,7 +68,7 @@ constructor(
|
||||
val insuranceTabDataFlow: StateFlow<InsuranceTabState>
|
||||
get() = _insuranceTabDataFlow.asStateFlow()
|
||||
|
||||
val redirectionCta = SingleLiveEvent<CtaData>()
|
||||
private val redirectionCta = SingleLiveEvent<CtaData>()
|
||||
|
||||
fun fetchInsuranceTabDetails() {
|
||||
if (_insuranceTabDataFlow.value.data.isNull()) {
|
||||
@@ -84,7 +98,7 @@ constructor(
|
||||
)
|
||||
)
|
||||
sendFailureEvent(
|
||||
NaviAnalytics.INSURANCE_TAB_INIT,
|
||||
INSURANCE_TAB_INIT,
|
||||
errorUnifiedResponse,
|
||||
ModuleNameV2.Insurance.name
|
||||
)
|
||||
@@ -100,7 +114,7 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun dismissCta(toastIdentifier: String) {
|
||||
private fun dismissCta(toastIdentifier: String) {
|
||||
viewModelScope.safeLaunch(coroutineContext = Dispatchers.IO) {
|
||||
val response = repository.dismissCta(toastIdentifier)
|
||||
if (response.statusCode.orZero().equals(200)) {} else {
|
||||
@@ -131,7 +145,7 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun closePolicyCard(quoteId: String) {
|
||||
private fun closePolicyCard(quoteId: String) {
|
||||
_insuranceTabDataFlow.update { it.copy(isLoading = true, data = null) }
|
||||
viewModelScope.safeLaunch(coroutineContext = Dispatchers.IO) {
|
||||
val response = repository.closePolicyCard(quoteId)
|
||||
@@ -192,7 +206,7 @@ constructor(
|
||||
}
|
||||
|
||||
private fun handleCtaAction(ctaAction: CtaAction) {
|
||||
ctaAction.ctaData?.let { ctaData -> redirectionCta.postValue(ctaAction.ctaData) }
|
||||
ctaAction.ctaData?.let { ctaData -> redirectionCta.postValue(ctaData) }
|
||||
}
|
||||
|
||||
fun clearCacheOnVersionUpgrade() {
|
||||
@@ -214,16 +228,97 @@ constructor(
|
||||
error = response.error,
|
||||
errorMetaData =
|
||||
ErrorMetaData(
|
||||
methodName = ApiErrorTagType.INSURANCE_TAB_SCREEN_PAGE_ERROR.value,
|
||||
methodName = CACHE_API_LOAD_ERROR,
|
||||
flowName = GiErrorMetaData.INSURANCE_TAB_FLOW
|
||||
)
|
||||
)
|
||||
sendFailureEvent(
|
||||
NaviAnalytics.INSURANCE_TAB_INIT,
|
||||
CACHE_API_LOAD_ERROR,
|
||||
errorUnifiedResponse,
|
||||
ModuleNameV2.Insurance.name
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun preLoadReactResources(activity: HomePageActivity) {
|
||||
try {
|
||||
val reactApplication = activity.application as ReactApplication
|
||||
reactApplication.reactNativeHost.reactInstanceManager.createReactContextInBackground()
|
||||
val intent = Intent(activity, ReactPreLoadHeadLessActivity::class.java)
|
||||
activity.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
}
|
||||
}
|
||||
|
||||
fun observeCtaData(
|
||||
viewmodel: InsuranceTabViewModel,
|
||||
activity: HomePageActivity,
|
||||
lifeCycleOwner: LifecycleOwner
|
||||
) {
|
||||
viewmodel.redirectionCta.observe(lifeCycleOwner) { ctaData ->
|
||||
NaviTrackEvent.sendEvent(ctaData, INSURANCE_TAB_INIT)
|
||||
ctaData.let {
|
||||
NaviInsuranceDeeplinkNavigator.navigate(
|
||||
activity,
|
||||
it,
|
||||
finish = it.finish.orFalse(),
|
||||
clearTask = it.clearTask.orFalse(),
|
||||
callbackHandler =
|
||||
object : RequestToCallbackHandler {
|
||||
override fun onCallbackRaised() {
|
||||
viewmodel.fetchInsuranceTabDetails()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onCtaClick(
|
||||
naviClickAction: NaviClickAction,
|
||||
viewModel: InsuranceTabViewModel,
|
||||
activity: HomePageActivity
|
||||
) {
|
||||
if (naviClickAction is CtaData) {
|
||||
NaviTrackEvent.sendEvent(naviClickAction, INSURANCE_TAB_INIT)
|
||||
val bundle = Bundle()
|
||||
bundle.putParcelable(Constants.PARAMS_EXTRA, naviClickAction)
|
||||
when (naviClickAction.type) {
|
||||
CtaType.DISMISS_TOAST.value -> {
|
||||
var toastIdentifier: String? = null
|
||||
naviClickAction.parameters?.forEach { lineItem ->
|
||||
if (lineItem.key == "toastIdentifier") {
|
||||
toastIdentifier = lineItem.value.orEmpty()
|
||||
}
|
||||
}
|
||||
viewModel.dismissCta(toastIdentifier.orEmpty())
|
||||
}
|
||||
CtaType.CANCEL_QUOTE.value -> {
|
||||
var quoteId: String? = null
|
||||
naviClickAction.parameters?.forEach { lineItem ->
|
||||
if (lineItem.key == "quoteId") {
|
||||
quoteId = lineItem.value.orEmpty()
|
||||
}
|
||||
}
|
||||
viewModel.closePolicyCard(quoteId.orEmpty())
|
||||
}
|
||||
else -> {
|
||||
NaviInsuranceDeeplinkNavigator.navigate(
|
||||
activity,
|
||||
naviClickAction,
|
||||
finish = naviClickAction.finish.orFalse(),
|
||||
clearTask = naviClickAction.clearTask.orFalse(),
|
||||
callbackHandler =
|
||||
object : RequestToCallbackHandler {
|
||||
override fun onCallbackRaised() {
|
||||
viewModel.fetchInsuranceTabDetails()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
package com.naviapp.common.viewmodel
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.navi.common.lottie.LottieRemoteHelper
|
||||
import com.navi.common.viewmodel.BaseVM
|
||||
@@ -38,8 +37,6 @@ class BottomNavBarVM @Inject constructor() : BaseVM() {
|
||||
|
||||
private val naviAnalyticsEventTracker = NaviAnalytics.naviAnalytics.Dashboard()
|
||||
|
||||
var isInsuranceTabOnNewInstanceCalled = false
|
||||
|
||||
private val _shouldUpdateSelectedBottomTab =
|
||||
MutableSharedFlow<UpdateTabFragmentData>(replay = 1)
|
||||
val shouldUpdateSelectedBottomTab = _shouldUpdateSelectedBottomTab.asSharedFlow()
|
||||
@@ -70,15 +67,6 @@ class BottomNavBarVM @Inject constructor() : BaseVM() {
|
||||
_bottomStickyNudgeData.update { BottomStickyNudgeData(visible, bottomStickyNudgeState) }
|
||||
}
|
||||
|
||||
fun updateInsuranceTabFragmentInCompose(screen: String, bundle: Bundle?, subType: String) {
|
||||
viewModelScope.launch {
|
||||
isInsuranceTabOnNewInstanceCalled = true
|
||||
_shouldUpdateSelectedBottomTab.emit(
|
||||
UpdateTabFragmentData(screen = screen, bundle = bundle, subType = subType)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun triggerTabClickedEvent(tabId: String, screenName: String) {
|
||||
when (tabId) {
|
||||
BottomBarTabType.HOME.name -> {
|
||||
|
||||
@@ -72,7 +72,6 @@ import com.navi.common.resourcemanager.manager.ResourceManager
|
||||
import com.navi.common.utils.ApiPollScheduler
|
||||
import com.navi.common.utils.BiometricPromptUtils.Companion.getScreenLockEventName
|
||||
import com.navi.common.utils.CommonNaviAnalytics
|
||||
import com.navi.common.utils.Constants.EMPTY
|
||||
import com.navi.common.utils.Constants.INSURANCE
|
||||
import com.navi.common.utils.Constants.IN_APP_UPDATE_REQUEST_CODE
|
||||
import com.navi.common.utils.Constants.SUB_REDIRECT
|
||||
@@ -977,15 +976,6 @@ class HomePageActivity :
|
||||
|
||||
private fun redirectToTab() {
|
||||
intent?.getStringExtra(Constants.REDIRECT_STATUS)?.let {
|
||||
val bundle = intent.extras
|
||||
val subType = bundle?.getString(SUB_REDIRECT) ?: EMPTY
|
||||
if (subType.lowercase().contains(INSURANCE)) {
|
||||
bottomNavBarVM.updateInsuranceTabFragmentInCompose(
|
||||
screen = it,
|
||||
bundle = bundle,
|
||||
subType = subType
|
||||
)
|
||||
}
|
||||
updateTab(screen = it, bundle = intent.extras)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.naviapp.home.compose.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.navi.base.utils.isNotNull
|
||||
import com.navi.common.ui.fragment.BaseFragment
|
||||
import com.navi.insurance.common.fragment.LandingPageInfoFragment
|
||||
import com.navi.insurance.common.util.NavigationHandler.Companion.URL_INSURANCE_TAB_FRAGMENT
|
||||
import com.naviapp.R
|
||||
import com.naviapp.common.tab.InsuranceTabFragment
|
||||
import com.naviapp.common.tab.insurance.ui.TrialInsuranceDashboardFragment
|
||||
import com.naviapp.common.viewmodel.BottomNavBarVM
|
||||
import com.naviapp.databinding.FragmentInsuranceContainerBinding
|
||||
import com.naviapp.home.dashboard.models.response.DashboardTab
|
||||
import com.naviapp.home.dashboard.ui.DashboardFragment
|
||||
import com.naviapp.home.dashboard.ui.ProductFragment
|
||||
import com.naviapp.utils.Constants
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class InsuranceContainerFragment(private val lazyListState: LazyListState? = null) :
|
||||
BaseFragment() {
|
||||
override val screenName: String
|
||||
get() = "InsuranceContainerFragment"
|
||||
|
||||
private lateinit var binding: FragmentInsuranceContainerBinding
|
||||
private val bottomNavBarVM by lazy {
|
||||
ViewModelProvider(requireActivity())[BottomNavBarVM::class.java]
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = FragmentInsuranceContainerBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
if (!bottomNavBarVM.isInsuranceTabOnNewInstanceCalled) {
|
||||
navigateToNextScreen(
|
||||
currentScreenTag = DashboardFragment.TAG,
|
||||
bundle = null,
|
||||
subType = URL_INSURANCE_TAB_FRAGMENT
|
||||
)
|
||||
}
|
||||
initFragmentChangeListener()
|
||||
}
|
||||
|
||||
private fun initFragmentChangeListener() {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
bottomNavBarVM.shouldUpdateSelectedBottomTab.collect { fragmentData ->
|
||||
bottomNavBarVM.clearShouldUpdateSelectedBottomTab()
|
||||
navigateToNextScreen(fragmentData.screen, fragmentData.bundle, fragmentData.subType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideFragments(fragmentTransaction: FragmentTransaction) {
|
||||
val fragments = childFragmentManager.fragments
|
||||
fragments.forEach { currentFragment ->
|
||||
currentFragment?.let { fragmentTransaction.hide(it) }
|
||||
}
|
||||
}
|
||||
|
||||
fun navigateToNextScreen(currentScreenTag: String, bundle: Bundle?, subType: String? = null) {
|
||||
val fragmentTag =
|
||||
if (subType == null) {
|
||||
currentScreenTag
|
||||
} else {
|
||||
currentScreenTag + subType
|
||||
}
|
||||
|
||||
val fragment: Fragment
|
||||
if (
|
||||
bundle?.get(Constants.OPEN_NEW_FRAGMENT).isNotNull() &&
|
||||
bundle?.get(Constants.OPEN_NEW_FRAGMENT) == "true"
|
||||
) {
|
||||
fragment = getFragment(screen = currentScreenTag, bundle = bundle, subType = subType)
|
||||
} else {
|
||||
fragment =
|
||||
childFragmentManager.findFragmentByTag(fragmentTag)
|
||||
?: getFragment(screen = currentScreenTag, bundle = bundle, subType = subType)
|
||||
}
|
||||
val fragmentTransaction = childFragmentManager.beginTransaction()
|
||||
if (!childFragmentManager.isStateSaved && !childFragmentManager.isDestroyed) {
|
||||
hideFragments(fragmentTransaction)
|
||||
if (fragment.isAdded) {
|
||||
fragmentTransaction.show(fragment)
|
||||
} else {
|
||||
fragmentTransaction.add(R.id.container, fragment, fragmentTag)
|
||||
}
|
||||
fragmentTransaction.commitNow()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFragment(screen: String, bundle: Bundle?, subType: String? = null): Fragment {
|
||||
return getInsuranceFragment(
|
||||
screen,
|
||||
subType ?: bundle?.getString(com.navi.common.utils.Constants.SUB_REDIRECT),
|
||||
bundle
|
||||
)
|
||||
}
|
||||
|
||||
private fun getInsuranceFragment(screen: String, subType: String?, bundle: Bundle?): Fragment {
|
||||
return when (subType) {
|
||||
ProductFragment.DashboardTypes.Insurance.name ->
|
||||
handleInsuranceDashboardTab(screen = screen, subType = subType, bundle = bundle)
|
||||
ProductFragment.DashboardTypes.Insurance_tab_page.name ->
|
||||
InsuranceTabFragment.newInstance(bundle) { lazyListState }
|
||||
ProductFragment.DashboardTypes.Trial_Insurance_Dashboard.name ->
|
||||
TrialInsuranceDashboardFragment.newInstance(bundle) { lazyListState }
|
||||
ProductFragment.DashboardTypes.Insurance_landing_page.name ->
|
||||
LandingPageInfoFragment().apply { arguments = bundle }
|
||||
else -> DashboardFragment.getInstance(bundle)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleInsuranceDashboardTab(
|
||||
screen: String,
|
||||
subType: String,
|
||||
bundle: Bundle?
|
||||
): Fragment {
|
||||
if (
|
||||
bundle?.get(Constants.OPEN_NEW_FRAGMENT).isNotNull() &&
|
||||
bundle?.get(Constants.OPEN_NEW_FRAGMENT) == "true"
|
||||
) {
|
||||
for (fragment in childFragmentManager.fragments) {
|
||||
childFragmentManager.beginTransaction().remove(fragment).commit()
|
||||
}
|
||||
} else {
|
||||
val fragment =
|
||||
childFragmentManager.findFragmentByTag(
|
||||
screen + ProductFragment.DashboardTypes.Insurance_landing_page.name
|
||||
)
|
||||
if (fragment != null) {
|
||||
val fragmentTransaction = childFragmentManager.beginTransaction()
|
||||
fragmentTransaction.remove(fragment)
|
||||
fragmentTransaction.commit()
|
||||
}
|
||||
}
|
||||
return ProductFragment.getInstance(DashboardTab(subType), bundle)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getInstance(lazyListState: LazyListState? = null): InsuranceContainerFragment {
|
||||
return InsuranceContainerFragment(lazyListState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.naviapp.home.compose.home.navigation
|
||||
|
||||
import InsuranceTabScreen
|
||||
import InvestmentsScreen
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@@ -18,17 +19,13 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.navi.common.ui.fragment.BaseFragment
|
||||
import com.naviapp.analytics.utils.NaviAnalytics
|
||||
import com.naviapp.common.viewmodel.InAppUpdateVM
|
||||
import com.naviapp.dashboard.viewmodels.DashboardSharedVM
|
||||
import com.naviapp.home.common.hopperProcessor.processHandlerImpl.Hopper
|
||||
import com.naviapp.home.compose.activity.HomePageActivity
|
||||
import com.naviapp.home.compose.fragment.InsuranceContainerFragment
|
||||
import com.naviapp.home.compose.home.ui.footer.utils.FragmentContainer
|
||||
import com.naviapp.home.compose.home.ui.screen.HomeScreen
|
||||
import com.naviapp.home.dashboard.ui.compose.loansTab.LoansTabScreen
|
||||
import com.naviapp.home.reducer.HpEvents
|
||||
import com.naviapp.home.reducer.HpStates
|
||||
import com.naviapp.home.viewmodel.HomeViewModel
|
||||
import com.naviapp.home.viewmodel.NotificationVM
|
||||
@@ -87,22 +84,14 @@ fun NavGraphNavigationItem(
|
||||
.background(Color.White)
|
||||
)
|
||||
NavigationItem.Insurance.tabId -> {
|
||||
FragmentContainer(
|
||||
modifier = Modifier.fillMaxSize().padding(bottom = 56.dp).statusBarsPadding(),
|
||||
fragmentManager = activity.supportFragmentManager
|
||||
) { containerId ->
|
||||
val fragment = InsuranceContainerFragment.getInstance(insuranceScrollState)
|
||||
val screenName =
|
||||
(fragment as? BaseFragment)?.screenName ?: NaviAnalytics.NEW_HOME_ACTIVITY
|
||||
homeVM().sendEvent(HpEvents.UpdateCurrentLoadedFragmentName(screenName))
|
||||
if (!fragment.isStateSaved && !fragment.isAdded) {
|
||||
if (fragment.isAdded) {
|
||||
show(fragment)
|
||||
} else {
|
||||
add(containerId, fragment, "insurance")
|
||||
}
|
||||
}
|
||||
}
|
||||
InsuranceTabScreen(
|
||||
activity = activity,
|
||||
modifier =
|
||||
Modifier.fillMaxSize()
|
||||
.padding(bottom = 56.dp)
|
||||
.statusBarsPadding()
|
||||
.background(Color.White)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.naviapp.home.compose.home.ui.footer.utils
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentContainerView
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import androidx.fragment.app.commit
|
||||
import com.navi.base.utils.isNotNull
|
||||
import com.naviapp.common.tab.InsuranceTabFragment
|
||||
import com.naviapp.common.tab.insurance.ui.TrialInsuranceDashboardFragment
|
||||
import com.naviapp.home.compose.activity.HomePageActivity
|
||||
import com.naviapp.home.dashboard.models.response.DashboardTab
|
||||
import com.naviapp.home.dashboard.ui.DashboardFragment
|
||||
import com.naviapp.home.dashboard.ui.ProductFragment
|
||||
import com.naviapp.utils.Constants
|
||||
|
||||
@Composable
|
||||
fun FragmentContainer(
|
||||
modifier: Modifier = Modifier,
|
||||
fragmentManager: FragmentManager,
|
||||
commit: FragmentTransaction.(containerId: Int) -> Unit
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
val containerId by rememberSaveable { mutableIntStateOf(View.generateViewId()) }
|
||||
AndroidView(
|
||||
modifier = Modifier.background(color = Color.White).fillMaxSize(),
|
||||
factory = { context ->
|
||||
fragmentManager.findFragmentById(containerId)?.view?.also {
|
||||
(it.parent as? ViewGroup)?.removeView(it)
|
||||
}
|
||||
?: FragmentContainerView(context)
|
||||
.apply { id = containerId }
|
||||
.also { fragmentManager.commit(allowStateLoss = true) { commit(it.id) } }
|
||||
},
|
||||
update = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFragment(
|
||||
activity: HomePageActivity,
|
||||
screen: String,
|
||||
bundle: Bundle?,
|
||||
subType: String? = null,
|
||||
listState: () -> LazyListState? = { null }
|
||||
): Fragment =
|
||||
getDashboardFragment(
|
||||
activity = activity,
|
||||
screen = screen,
|
||||
subType = subType ?: bundle?.getString(com.navi.common.utils.Constants.SUB_REDIRECT),
|
||||
bundle = bundle,
|
||||
listState = listState
|
||||
)
|
||||
|
||||
fun getDashboardFragment(
|
||||
activity: HomePageActivity,
|
||||
screen: String,
|
||||
subType: String?,
|
||||
bundle: Bundle?,
|
||||
listState: () -> LazyListState? = { null }
|
||||
): Fragment {
|
||||
return when (subType) {
|
||||
ProductFragment.DashboardTypes.Insurance.name ->
|
||||
handleInsuranceDashboardTab(
|
||||
activity = activity,
|
||||
screen = screen,
|
||||
subType = subType,
|
||||
bundle = bundle
|
||||
)
|
||||
ProductFragment.DashboardTypes.Insurance_tab_page.name ->
|
||||
InsuranceTabFragment.newInstance(bundle)
|
||||
ProductFragment.DashboardTypes.Trial_Insurance_Dashboard.name -> {
|
||||
TrialInsuranceDashboardFragment.newInstance(bundle)
|
||||
}
|
||||
else -> DashboardFragment.getInstance(bundle)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CommitTransaction")
|
||||
private fun handleInsuranceDashboardTab(
|
||||
activity: HomePageActivity,
|
||||
screen: String,
|
||||
subType: String,
|
||||
bundle: Bundle?
|
||||
): Fragment {
|
||||
if (
|
||||
bundle?.get(Constants.OPEN_NEW_FRAGMENT).isNotNull() &&
|
||||
bundle?.get(Constants.OPEN_NEW_FRAGMENT) == "true"
|
||||
) {
|
||||
for (fragment in activity.supportFragmentManager.fragments) {
|
||||
activity.supportFragmentManager.beginTransaction().remove(fragment).commit()
|
||||
}
|
||||
} else {
|
||||
val fragment =
|
||||
activity.supportFragmentManager.findFragmentByTag(
|
||||
screen + ProductFragment.DashboardTypes.Insurance_landing_page.name
|
||||
)
|
||||
if (fragment != null) {
|
||||
val fragmentTransaction = activity.supportFragmentManager.beginTransaction()
|
||||
fragmentTransaction.remove(fragment)
|
||||
fragmentTransaction.commit()
|
||||
}
|
||||
}
|
||||
return ProductFragment.getInstance(DashboardTab(subType), bundle)
|
||||
}
|
||||
|
||||
fun loadFragmentInContainer(
|
||||
activity: HomePageActivity,
|
||||
currentScreenTag: String,
|
||||
bundle: Bundle?,
|
||||
subType: String?,
|
||||
fragmentTag: String,
|
||||
listState: () -> LazyListState? = { null }
|
||||
): Fragment {
|
||||
|
||||
val fragment: Fragment
|
||||
if (
|
||||
bundle?.get(Constants.OPEN_NEW_FRAGMENT).isNotNull() &&
|
||||
bundle?.get(Constants.OPEN_NEW_FRAGMENT) == "true"
|
||||
) {
|
||||
fragment =
|
||||
getFragment(
|
||||
activity = activity,
|
||||
screen = currentScreenTag,
|
||||
bundle = bundle,
|
||||
subType = subType,
|
||||
listState = listState
|
||||
)
|
||||
} else {
|
||||
fragment =
|
||||
activity.supportFragmentManager.findFragmentByTag(fragmentTag)
|
||||
?: getFragment(
|
||||
activity = activity,
|
||||
screen = currentScreenTag,
|
||||
bundle = bundle,
|
||||
subType = subType,
|
||||
listState = listState
|
||||
)
|
||||
}
|
||||
return fragment
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.naviapp.home.dashboard.ui.compose.insuranceTab
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper
|
||||
import com.navi.insurance.util.log
|
||||
import com.naviapp.common.tab.InsuranceTabViewModel
|
||||
import com.naviapp.home.compose.activity.HomePageActivity
|
||||
|
||||
@Composable
|
||||
fun InitScreenLifeCycleListener(activity: HomePageActivity, viewmodel: InsuranceTabViewModel) {
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
DisposableEffect(key1 = lifecycleOwner) {
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
when (event) {
|
||||
Lifecycle.Event.ON_RESUME -> {
|
||||
viewmodel.fetchInsuranceTabDetails()
|
||||
viewmodel.clearCacheOnVersionUpgrade()
|
||||
viewmodel.observeCtaData(
|
||||
viewmodel = viewmodel,
|
||||
activity = activity,
|
||||
lifeCycleOwner = lifecycleOwner
|
||||
)
|
||||
if (
|
||||
FirebaseRemoteConfigHelper.getBoolean(
|
||||
key = FirebaseRemoteConfigHelper.ENABLE_REACT_PREFETCH_IN_TAB,
|
||||
defaultValue = false
|
||||
)
|
||||
) {
|
||||
try {
|
||||
viewmodel.preLoadReactResources(activity)
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
lifecycleOwner.lifecycle.addObserver(observer)
|
||||
onDispose { lifecycleOwner.lifecycle.removeObserver(observer) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.navi.base.model.NaviClickAction
|
||||
import com.navi.naviwidgets.callbacks.WidgetCallback
|
||||
import com.naviapp.common.tab.InsuranceTabViewModel
|
||||
import com.naviapp.home.compose.activity.HomePageActivity
|
||||
import com.naviapp.home.dashboard.ui.compose.insuranceTab.InsuranceTabInit
|
||||
import com.naviapp.home.dashboard.ui.compose.insuranceTab.RenderUiTronDataSecondary
|
||||
|
||||
@Composable
|
||||
fun InsuranceTabScreen(activity: HomePageActivity, modifier: Modifier = Modifier) {
|
||||
val viewModel: InsuranceTabViewModel = hiltViewModel()
|
||||
val widgetCallback =
|
||||
object : WidgetCallback {
|
||||
override fun onClick(naviClickAction: NaviClickAction, widgetId: String?) {
|
||||
viewModel.onCtaClick(naviClickAction, viewModel, activity)
|
||||
}
|
||||
}
|
||||
InsuranceTabInit(viewModel = viewModel, activity = activity)
|
||||
RenderUiTronDataSecondary(
|
||||
modifier = modifier,
|
||||
viewModel = viewModel,
|
||||
widgetCallback = widgetCallback
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.naviapp.home.dashboard.ui.compose.insuranceTab
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.LocalOverscrollConfiguration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.neverEqualPolicy
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.facebook.shimmer.ShimmerFrameLayout
|
||||
import com.navi.analytics.utils.NaviTrackEvent
|
||||
import com.navi.base.utils.isNotNull
|
||||
import com.navi.base.utils.orFalse
|
||||
import com.navi.base.utils.orZero
|
||||
import com.navi.common.analytics.NaviAnalytics.Companion.INSURANCE_TAB_INIT
|
||||
import com.navi.common.ui.errorview.FullScreenErrorComposeView
|
||||
import com.navi.insurance.R
|
||||
import com.navi.insurance.common.models.InsuranceTabResponse
|
||||
import com.navi.naviwidgets.callbacks.WidgetCallback
|
||||
import com.navi.naviwidgets.composewidget.GenericComposableWidgetFactory
|
||||
import com.navi.naviwidgets.extensions.FloatingButtonOverlay
|
||||
import com.navi.naviwidgets.extensions.isScrollingDown
|
||||
import com.navi.uitron.render.UiTronRenderer
|
||||
import com.naviapp.common.tab.InsuranceTabViewModel
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun RenderUiTronDataSecondary(
|
||||
modifier: Modifier,
|
||||
viewModel: InsuranceTabViewModel,
|
||||
widgetCallback: WidgetCallback? = null
|
||||
) {
|
||||
val state by viewModel.insuranceTabDataFlow.collectAsStateWithLifecycle()
|
||||
val listState = rememberLazyListState()
|
||||
val isScrollingDown = listState.isScrollingDown()
|
||||
Box(modifier = modifier.fillMaxSize()) {
|
||||
when {
|
||||
state.data.isNotNull() -> {
|
||||
LaunchedEffect(Unit) {
|
||||
state.data?.pageMetaData?.analyticsEvents?.forEach {
|
||||
NaviTrackEvent.trackEvent(
|
||||
it.name.orEmpty(),
|
||||
it.properties,
|
||||
it.isNeededForAppsflyer.orFalse(),
|
||||
it.isNeededForFirebase.orFalse()
|
||||
)
|
||||
}
|
||||
}
|
||||
Box {
|
||||
Scaffold(
|
||||
modifier =
|
||||
Modifier.fillMaxSize()
|
||||
.animateContentSize(
|
||||
animationSpec = tween(durationMillis = 600, delayMillis = 0)
|
||||
),
|
||||
topBar = {
|
||||
if (state.data?.headerWidget.isNotNull()) {
|
||||
UiTronRenderer(state.data?.headerWidget?.data, viewModel)
|
||||
.Render(
|
||||
composeViews =
|
||||
state.data?.headerWidget?.parentComposeView.orEmpty()
|
||||
)
|
||||
} else {
|
||||
state.data?.headerNativeWidget?.let { data ->
|
||||
Box(modifier = Modifier.background(Color.White)) {
|
||||
GenericComposableWidgetFactory(
|
||||
data = data,
|
||||
widgetCallback = widgetCallback
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
bottomBar = {
|
||||
if (state.data?.footerWidget.isNotNull()) {
|
||||
UiTronRenderer(state.data?.footerWidget?.data, viewModel)
|
||||
.Render(
|
||||
composeViews =
|
||||
state.data?.footerWidget?.parentComposeView.orEmpty()
|
||||
)
|
||||
} else {
|
||||
state.data?.footerNativeWidget?.let { data ->
|
||||
Box(modifier = Modifier.background(Color.White)) {
|
||||
GenericComposableWidgetFactory(
|
||||
data = data,
|
||||
widgetCallback = widgetCallback
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
CompositionLocalProvider(LocalOverscrollConfiguration provides null) {
|
||||
ContentComposable(
|
||||
listState = listState,
|
||||
widgetCallback = widgetCallback,
|
||||
data = state?.data,
|
||||
viewModel = viewModel
|
||||
)
|
||||
}
|
||||
}
|
||||
if (state.data?.floatingButtonData.isNotNull()) {
|
||||
FloatingButtonOverlay(
|
||||
state.data?.floatingButtonData,
|
||||
!isScrollingDown,
|
||||
widgetCallback,
|
||||
INSURANCE_TAB_INIT
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
state.isLoading -> {
|
||||
ShowShimmer()
|
||||
}
|
||||
state.hasErrorOccurred -> {
|
||||
FullScreenErrorComposeView(
|
||||
error = state.genericErrorResponse,
|
||||
onRetryClick = { viewModel.fetchInsuranceTabDetails() }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ContentComposable(
|
||||
listState: LazyListState,
|
||||
data: InsuranceTabResponse? = null,
|
||||
widgetCallback: WidgetCallback?,
|
||||
viewModel: InsuranceTabViewModel
|
||||
) {
|
||||
var dataList by
|
||||
remember(
|
||||
key1 = data,
|
||||
calculation = { mutableStateOf(data?.listOfNativeWidgets, neverEqualPolicy()) }
|
||||
)
|
||||
LazyColumn(state = listState, modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
|
||||
if (data?.listOfUiTronWidgets.isNotNull()) {
|
||||
items(data?.listOfUiTronWidgets?.size.orZero()) { index ->
|
||||
val uiTronResponse = data?.listOfUiTronWidgets?.getOrNull(index)
|
||||
|
||||
Column(modifier = Modifier.wrapContentSize()) {
|
||||
UiTronRenderer(uiTronResponse?.data, viewModel)
|
||||
.Render(composeViews = uiTronResponse?.parentComposeView.orEmpty())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
items(dataList?.size.orZero(), key = { index -> index }) { index ->
|
||||
val widgetData = dataList?.getOrNull(index)
|
||||
Column(modifier = Modifier.wrapContentSize()) {
|
||||
GenericComposableWidgetFactory(
|
||||
data = widgetData,
|
||||
widgetCallback = widgetCallback,
|
||||
onWidgetUpdate = { data ->
|
||||
val updatedList = dataList?.toMutableList() ?: mutableListOf()
|
||||
updatedList[index] = data
|
||||
dataList = updatedList
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ShowShimmer() {
|
||||
val context = LocalContext.current
|
||||
val layout = ShimmerFrameLayout(context)
|
||||
layout.addView(LayoutInflater.from(context).inflate(R.layout.shimmer_tab_layout, layout, false))
|
||||
AndroidView(modifier = Modifier.fillMaxSize().background(Color.White), factory = { layout })
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.naviapp.home.dashboard.ui.compose.insuranceTab
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import com.navi.analytics.utils.NaviTrackEvent
|
||||
import com.navi.common.analytics.NaviAnalytics.Companion.INSURANCE_TAB_INIT
|
||||
import com.naviapp.common.tab.InsuranceTabViewModel
|
||||
import com.naviapp.home.compose.activity.HomePageActivity
|
||||
|
||||
@Composable
|
||||
fun InsuranceTabInit(viewModel: InsuranceTabViewModel, activity: HomePageActivity) {
|
||||
InitScreenLifeCycleListener(viewmodel = viewModel, activity = activity)
|
||||
LaunchedEffect(Unit) { NaviTrackEvent.trackEventOnClickStream(INSURANCE_TAB_INIT) }
|
||||
}
|
||||
@@ -90,6 +90,7 @@ class NaviAnalytics private constructor() {
|
||||
const val PL_FINARKEIN_EVENT = "finarkein_event_"
|
||||
const val HL_FINARKEIN_EVENT = "hl_finarkein_event_"
|
||||
const val INSURANCE_TAB_INIT = "hi_insurance_tab_screen_init"
|
||||
const val CACHE_API_LOAD_ERROR = "hi_cache_api_load_error"
|
||||
const val DISMISS_TOAST = "hi_dismiss_toast"
|
||||
const val CLOSE_POLICY_CARD = "hi_close_policy_card"
|
||||
const val TRIAL_INSURANCE_DASHBOARD_INIT = "hi_trial_insurance_dashboard_init"
|
||||
|
||||
Reference in New Issue
Block a user