TP-58098 | Prod Bug Fix - Landing page opening when back pressed from quote page (#10047)

This commit is contained in:
Balrambhai Sharma
2024-03-12 19:59:22 +05:30
committed by GitHub
parent 6f0dfa895a
commit 0e9110ffbf
9 changed files with 119 additions and 173 deletions

View File

@@ -79,7 +79,7 @@ class InsuranceTabFragment : BaseFragment(), WidgetCallback, NewBottomSheetListe
private fun observeCtaData() {
viewModel.redirectionCta.observe(viewLifecycleOwner) { ctaData ->
NaviTrackEvent.sendEvent(ctaData)
NaviTrackEvent.sendEvent(ctaData, screenName)
ctaData.let {
NaviInsuranceDeeplinkNavigator.navigate(
requireActivity(),
@@ -93,7 +93,7 @@ class InsuranceTabFragment : BaseFragment(), WidgetCallback, NewBottomSheetListe
override fun onClick(naviClickAction: NaviClickAction, widgetId: String?) {
if (naviClickAction is CtaData) {
NaviTrackEvent.sendEvent(naviClickAction)
NaviTrackEvent.sendEvent(naviClickAction, screenName)
val bundle = Bundle()
bundle.putParcelable(Constants.PARAMS_EXTRA, naviClickAction)
when (naviClickAction.type) {
@@ -199,7 +199,8 @@ class InsuranceTabFragment : BaseFragment(), WidgetCallback, NewBottomSheetListe
if (state.data?.floatingButtonData.isNotNull()) {
FloatingButtonOverlay(
state.data?.floatingButtonData,
!isScrollingDown, widgetCallback
!isScrollingDown, widgetCallback,
screenName
)
}
}

View File

@@ -269,6 +269,6 @@ object NaviTrackEvent {
}
fun sendEvent(ctaData: CtaData, screen: String? = null) {
sendEvent(AnalyticsEvent(name = ctaData.analyticsEventName), screen)
sendEvent(ctaData.analyticsEventProperties, screen)
}
}

View File

@@ -307,21 +307,14 @@ object NaviInsuranceDeeplinkNavigator {
bundle.putParcelable(KEY_CTA_DATA, ctaData)
}
CHAT -> {
intent =
if (shouldOpenIntroActivity(ctaData)) {
Intent(activity, IntroActivityV3::class.java)
} else {
//Should not get this URL, redirect to home if received
DeepLinkManager.getDeepLinkListener()
?.navigateTo(
activity,
CtaData(url = DeeplinkConstants.HOME),
true,
null
)
return@navigate
}
bundle.putParcelable(KEY_CTA_DATA, ctaData)
DeepLinkManager.getDeepLinkListener()
?.navigateTo(
activity,
CtaData(url = DeeplinkConstants.HOME),
true,
null
)
return@navigate
}
NavigationHandler.URL_GI_HEALTH_RISK_ACTIVITY -> {
intent = Intent(activity, HealthRiskScoreActivity::class.java)
@@ -526,12 +519,7 @@ object NaviInsuranceDeeplinkNavigator {
}
NavigationHandler.URL_FRESH_POLICY_FORM_ACTIVY,
NavigationHandler.URL_GI_PORTING_FORM_ACTIVITY -> {
intent =
if (shouldOpenIntroActivity(ctaData)) {
Intent(activity, IntroActivityV3::class.java)
} else {
Intent(activity, FormActivity::class.java)
}
intent = Intent(activity, FormActivity::class.java)
bundle.putParcelable(KEY_CTA_DATA, ctaData)
}
NavigationHandler.URL_GI_SUPER_TOPUP_FORM_ACTIVITY -> {
@@ -581,9 +569,6 @@ object NaviInsuranceDeeplinkNavigator {
}
NavigationHandler.URL_INSURANCE_CONTAINER -> {
intent = Intent(activity, InsuranceContainerActivity::class.java)
intent?.addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP
)
}
NavigationHandler.URL_KYC_ACTIVITY -> {
intent = Intent(activity, KycActivity::class.java)

View File

@@ -10,6 +10,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.navi.base.utils.orZero
import com.navi.insurance.pre.purchase.journey.PreQuotePatchData
import com.navi.insurance.pre.purchase.journey.pre.purchase.journey.theme.LocalDimensions
import com.navi.naviwidgets.callbacks.WidgetCallback
import com.navi.naviwidgets.extensions.NaviImage
@@ -20,7 +21,8 @@ import kotlinx.coroutines.delay
@Composable
fun DetailsStatusWidgetComposable(
data: DetailsStatusWidget,
widgetCallback: WidgetCallback?
widgetCallback: WidgetCallback?,
updatePatchCallData: (PreQuotePatchData) -> Unit
) {
LaunchedEffect(Unit) {
delay(data.data?.redirectionDelay.orZero().toLong())
@@ -39,5 +41,6 @@ fun DetailsStatusWidgetComposable(
top = LocalDimensions.current.dp24)
)
}
updatePatchCallData(PreQuotePatchData())
}

View File

@@ -62,7 +62,7 @@ fun ComposableWidgetFactory(
widgetCallback = widgetCallback
)
is DetailsStatusWidget -> DetailsStatusWidgetComposable(data, widgetCallback)
is DetailsStatusWidget -> DetailsStatusWidgetComposable(data, widgetCallback, updatePatchCallData)
is TextWithAgeSelectorWidget -> TextWithAgeSelectorWidgetComposable(
data,
isValidWidget,

View File

@@ -94,6 +94,7 @@ class PreQuoteJourneyFragment() : GiBaseFragment(), WidgetCallback, NewBottomShe
private val viewModel by viewModels<PreQuoteJourneyViewModel>()
private var naviLocationManager: NaviLocationManager? = null
var view: NaviErrorPageView? = null
var isBackPressInProgress: Boolean = false
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -128,11 +129,15 @@ class PreQuoteJourneyFragment() : GiBaseFragment(), WidgetCallback, NewBottomShe
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
isBackPressInProgress = false
val callback = object : OnBackPressedCallback(
true
) {
override fun handleOnBackPressed() {
viewModel.moveToNextPage(MOVE_BACK)
if (!isBackPressInProgress) {
viewModel.moveToNextPage(MOVE_BACK)
isBackPressInProgress = true
}
}
}
requireActivity().onBackPressedDispatcher.addCallback(
@@ -312,6 +317,7 @@ class PreQuoteJourneyFragment() : GiBaseFragment(), WidgetCallback, NewBottomShe
state.data.isNotNull() -> {
sendPageViewEvent(state.data?.metaData?.pageType.orEmpty())
isBackPressInProgress = false
viewModel.updateCurrentPageData(state.data)
}
}
@@ -399,6 +405,7 @@ class PreQuoteJourneyFragment() : GiBaseFragment(), WidgetCallback, NewBottomShe
}
CtaType.GO_BACK.value -> {
isBackPressInProgress = true
viewModel.moveToNextPage(MOVE_BACK)
}

View File

@@ -3,11 +3,11 @@ package com.navi.insurance.pre.purchase.journey.ui
import android.os.Bundle
import androidx.lifecycle.viewModelScope
import com.navi.base.model.CtaData
import com.navi.base.model.CtaType
import com.navi.base.utils.isNotNull
import com.navi.base.utils.isNotNullAndNotEmpty
import com.navi.base.utils.isNull
import com.navi.base.utils.orFalse
import com.navi.common.network.models.ErrorMessage
import com.navi.common.network.models.RepoResult
import com.navi.insurance.common.GiBaseVM
import com.navi.insurance.common.models.GiErrorMetaData
@@ -17,8 +17,6 @@ import com.navi.insurance.pre.purchase.journey.ERROR
import com.navi.insurance.pre.purchase.journey.ERRORMESSAGE
import com.navi.insurance.pre.purchase.journey.ERRORTAG
import com.navi.insurance.pre.purchase.journey.ERROR_CODE_400
import com.navi.insurance.pre.purchase.journey.ERROR_CODE_500
import com.navi.insurance.pre.purchase.journey.ERROR_MESSAGE_SWW
import com.navi.insurance.pre.purchase.journey.FooterButtonState
import com.navi.insurance.pre.purchase.journey.FormWidgetRequest
import com.navi.insurance.pre.purchase.journey.PreQuoteJourneyPageResponse
@@ -107,16 +105,6 @@ class PreQuoteJourneyViewModel @Inject constructor(
fun fetchPreQuoteJourneyResponse() {
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(isLoading = true)
if (applicationType.isNullOrEmpty() && preQuoteId.isNullOrEmpty()) {
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
isLoading = false,
data = null,
hasErrorOccurred = true,
errorMessage = ApiErrorTagType.FORM_PAGE_LOAD_ERROR.value,
)
showSWWError()
return
}
viewModelScope.launch(Dispatchers.IO + exceptionHandler(ApiErrorTagType.FORM_PAGE_LOAD_ERROR.value)) {
var response: RepoResult<PreQuoteJourneyPageResponse>? = null
if (quoteId.isNotNullAndNotEmpty()) {
@@ -186,54 +174,52 @@ class PreQuoteJourneyViewModel @Inject constructor(
}
fun makeNextPageAPICall() {
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
isLoading = true,
hasErrorOccurred = false,
ctaData = null
)
if (preQuoteId.isNullOrEmpty() || transitionName.isNullOrEmpty()) {
patchRequestData?.let {
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
isLoading = false,
data = null,
hasErrorOccurred = true,
errorMessage = ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value,
isLoading = true,
hasErrorOccurred = false,
ctaData = null
)
showSWWError()
return
}
viewModelScope.launch(Dispatchers.IO + exceptionHandler(ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value)) {
val response =
patchRequestData?.let {
repository.makeNextPageFormRequest(
formRequest = it,
preQuoteId = preQuoteId.orEmpty(),
transitionName = transitionName.orEmpty()
)
}
response?.let { response ->
if (response.error.isNull() && response.errors.isNullOrEmpty() && response.data.isNotNull()) {
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
ctaData = response.data?.cta,
hasErrorOccurred = false
)
} else {
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
isLoading = false,
data = null,
hasErrorOccurred = true,
errorMessage = ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value,
)
logError(
response,
GiErrorMetaData(
ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value,
flowName = GiErrorMetaData.FLOW_PRE_PURCHASE
viewModelScope.launch(Dispatchers.IO + exceptionHandler(ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value)) {
val response = repository.makeNextPageFormRequest(
formRequest = it,
preQuoteId = preQuoteId.orEmpty(),
transitionName = transitionName.orEmpty()
)
response?.let { response ->
if (response.error.isNull() && response.errors.isNullOrEmpty() && response.data.isNotNull()) {
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
ctaData = response.data?.cta,
hasErrorOccurred = false
)
)
_showOverLay.value = true
_footerState.value = FooterButtonState.DISABLED.name
} else {
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
isLoading = false,
data = null,
hasErrorOccurred = true,
errorMessage = ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value,
)
logError(
response,
GiErrorMetaData(
ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value,
flowName = GiErrorMetaData.FLOW_PRE_PURCHASE
)
)
_showOverLay.value = true
_footerState.value = FooterButtonState.DISABLED.name
}
}
}
} ?: run {
val cta = CtaData(
type = CtaType.CLOSE_SCREEN.value
)
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
ctaData = cta,
isLoading = false,
hasErrorOccurred = false
)
}
}
@@ -285,62 +271,59 @@ class PreQuoteJourneyViewModel @Inject constructor(
}
fun moveToNextPage(transitionName: String? = null) {
_footerState.value = FooterButtonState.LOADING.name
_showOverLay.value = true
this.transitionName = transitionName
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
ctaData = null, isLoading = false, hasErrorOccurred = false
)
if (preQuoteId.isNullOrEmpty() || transitionName.isNullOrEmpty()) {
patchRequestData?.let {
_footerState.value = FooterButtonState.LOADING.name
_showOverLay.value = true
this.transitionName = transitionName
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
isLoading = false,
data = null,
hasErrorOccurred = true,
errorMessage = ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value,
ctaData = null, isLoading = false, hasErrorOccurred = false
)
_showOverLay.value = false
_footerState.value = FooterButtonState.DISABLED.name
showSWWError()
return
}
viewModelScope.launch(Dispatchers.IO + exceptionHandler(ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value)) {
val response =
patchRequestData?.let {
viewModelScope.launch(Dispatchers.IO + exceptionHandler(ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value)) {
val response =
repository.makeNextPageFormRequest(
formRequest = it,
preQuoteId = preQuoteId.orEmpty(),
transitionName = transitionName.orEmpty()
)
}
response?.let { pageResponse ->
if (pageResponse.error.isNull() && pageResponse.errors.isNullOrEmpty() && pageResponse.data.isNotNull()) {
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
ctaData = pageResponse.data?.cta,
isLoading = false,
hasErrorOccurred = false
)
} else {
if (pageResponse.statusCode == ERROR_CODE_400) {
showFooterError(pageResponse.errors?.getOrNull(0)?.message)
} else {
response?.let { pageResponse ->
if (pageResponse.error.isNull() && pageResponse.errors.isNullOrEmpty() && pageResponse.data.isNotNull()) {
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
ctaData = pageResponse.data?.cta,
isLoading = false,
data = null,
hasErrorOccurred = true,
errorMessage = ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value,
hasErrorOccurred = false
)
logError(
pageResponse,
GiErrorMetaData(
ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value,
flowName = GiErrorMetaData.FLOW_PRE_PURCHASE
} else {
if (pageResponse.statusCode == ERROR_CODE_400) {
showFooterError(pageResponse.errors?.getOrNull(0)?.message)
} else {
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
isLoading = false,
data = null,
hasErrorOccurred = true,
errorMessage = ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value,
)
)
_showOverLay.value = true
_footerState.value = FooterButtonState.DISABLED.name
logError(
pageResponse,
GiErrorMetaData(
ApiErrorTagType.FORM_NEXT_PAGE_API_ERROR.value,
flowName = GiErrorMetaData.FLOW_PRE_PURCHASE
)
)
_showOverLay.value = true
_footerState.value = FooterButtonState.DISABLED.name
}
}
}
}
} ?: run {
val cta = CtaData(
type = CtaType.CLOSE_SCREEN.value
)
_preQuoteJourneyFlow.value = _preQuoteJourneyFlow.value.copy(
ctaData = cta,
isLoading = false,
hasErrorOccurred = false
)
}
}
@@ -442,22 +425,6 @@ class PreQuoteJourneyViewModel @Inject constructor(
footerButtonData = data
}
fun showSWWError() {
val errorResponse = RepoResult<PreQuoteJourneyPageResponse>(
error = ErrorMessage(
ERROR_CODE_500,
ERROR_MESSAGE_SWW
)
)
logError(
errorResponse,
GiErrorMetaData(
ApiErrorTagType.FORM_PAGE_LOAD_ERROR.value,
flowName = GiErrorMetaData.FLOW_PRE_PURCHASE
)
)
}
fun setNstpFlow(isNstpFlow: Boolean) {
this.isNstPFlow = isNstpFlow
}
@@ -490,7 +457,7 @@ class PreQuoteJourneyViewModel @Inject constructor(
}
}
fun handleCheckBoxScrollState(checkBoxWithDropDownSelectorWidget: CheckBoxWithDropDownSelectorWidget): Boolean {
private fun handleCheckBoxScrollState(checkBoxWithDropDownSelectorWidget: CheckBoxWithDropDownSelectorWidget): Boolean {
var isValid = true
var scrollIndex: Int = Int.MAX_VALUE
checkBoxWithDropDownSelectorWidget.data?.itemList?.forEachIndexed { index, data ->
@@ -511,7 +478,7 @@ class PreQuoteJourneyViewModel @Inject constructor(
return isValid
}
fun handleMultiTypeSelectionScrollState(multiTypeSelectionWidget: MultiTypeSelectionWidget): Boolean {
private fun handleMultiTypeSelectionScrollState(multiTypeSelectionWidget: MultiTypeSelectionWidget): Boolean {
var isValid = true
var scrollIndex: Int = Int.MAX_VALUE
multiTypeSelectionWidget.data?.questionList?.forEachIndexed { index, data ->

View File

@@ -445,29 +445,7 @@ class QuoteActivity :
(supportFragmentManager.backStackEntryCount == 1 &&
intent?.getBooleanExtra(Constants.FROM_DEEP_LINK, false) == true)
) {
val preQuoteId =
intent?.getStringExtra(PRE_QUOTE_ID_EXTRA) ?: quoteViewModel.preQuoteId.value
if (!preQuoteId.isNullOrEmpty()) {
// Whenever pre-quoteid is present it is assumed to open Form on backpress
// Communicated to backend to send back cta it will be future scope
val navigationUrl =
if (
quoteViewModel?.quoteResponse?.value?.headerWidget?.get(0)?.deductibleInfo !=
null
)
NavigationHandler.URL_DEDUCTIBLE_FORM
else NavigationHandler.URL_PORTING_FORM
val ctaData =
CtaData(
type = "DEEP_LINK",
url = navigationUrl,
parameters = listOf(LineItem(key = PRE_QUOTE_ID_EXTRA, value = preQuoteId))
)
NaviInsuranceDeeplinkNavigator.navigate(this, ctaData, finish = true)
return
} else {
finish()
}
finish()
} else {
super.onBackPressed()
}

View File

@@ -23,19 +23,24 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.navi.analytics.utils.NaviTrackEvent
import com.navi.base.utils.orFalse
import com.navi.naviwidgets.callbacks.WidgetCallback
import com.navi.naviwidgets.models.response.FloatingButtonData
import com.navi.uitron.utils.orFalse
import com.navi.uitron.utils.EMPTY
@Composable
fun FloatingButtonOverlay(
floatingButtonData: FloatingButtonData?,
isExpanded: Boolean?,
widgetCallback: WidgetCallback
widgetCallback: WidgetCallback,
screenName: String? = EMPTY
) {
floatingButtonData?.let { floatingButtonData ->
LaunchedEffect(key1 = floatingButtonData.buttonData?.toString()) {
NaviTrackEvent.sendEvent(floatingButtonData.metaData?.analyticsEventProperties)
NaviTrackEvent.sendEvent(
floatingButtonData.metaData?.analyticsEventProperties,
screenName
)
}
Box(
modifier = Modifier.fillMaxSize(),