NTP-71853 || Shrihari | SIP Sanity v3-4 (#16631)

This commit is contained in:
A Shrihari Raju
2025-06-18 16:29:32 +05:30
committed by GitHub
parent ed7d5dacca
commit f974ad25f9
12 changed files with 271 additions and 111 deletions

View File

@@ -32,6 +32,7 @@ import com.navi.design.utils.getNaviDrawable
import com.navi.design.utils.parseColorSafe
import com.navi.design.utils.setSpannableString
import com.navi.naviwidgets.extensions.showWhenDataIsAvailable
import com.navi.naviwidgets.models.response.ImageFieldData
class AmcCommonBottomSheet : BaseBottomSheet() {
private var listener: NewBottomSheetListener? = null
@@ -47,6 +48,7 @@ class AmcCommonBottomSheet : BaseBottomSheet() {
initObservers()
bottomSheetSharedVM.setVisibility(true)
binding.apply {
response.modifyIconProperties?.let { iconProperties -> modifyIcon(iconProperties) }
icon.showWhenDataIsAvailable(response.iconCode)
rightIcon.showWhenDataIsAvailable(response.rightIconCode)
rightIcon.setOnClickListener { safelyDismissDialog() }
@@ -70,6 +72,15 @@ class AmcCommonBottomSheet : BaseBottomSheet() {
}
}
private fun modifyIcon(iconProperties: ImageFieldData? = null) {
val params = binding.icon.layoutParams
params.apply {
width = dpToPxInInt(iconProperties?.iconWidth ?: 24)
height = dpToPxInInt(iconProperties?.iconHeight ?: 24)
}
binding.icon.layoutParams = params
}
private fun onSpanClick(actionData: ActionData?) {
listener?.buttonClick(actionData)
safelyDismissDialog()

View File

@@ -52,7 +52,7 @@ class NudgeBottomSheet : BaseBottomSheet(), FooterInteractionListener {
title.setSpannableString(data.container?.title)
subtitle.setSpannableString(data.container?.subtitle)
icon.showWhenDataIsAvailable(data.container?.lottieFileName)
imageView.showWhenDataIsAvailable(data.container?.imageUrl)
image.showWhenDataIsAvailable(data.container?.imageUrl)
root.background =
getNaviDrawable(
cornerRadius = resources.getDimension(DesignR.dimen.dp_4).toInt(),
@@ -66,6 +66,7 @@ class NudgeBottomSheet : BaseBottomSheet(), FooterInteractionListener {
)
}
footer.disableShadow()
footer.removeElevation()
footer.setProperties(data.footer, this@NudgeBottomSheet)
}
}

View File

@@ -13,6 +13,7 @@ import com.navi.base.model.ActionData
import com.navi.base.model.GenericAnalytics
import com.navi.design.textview.model.TextWithStyle
import com.navi.naviwidgets.models.CalendarWidget
import com.navi.naviwidgets.models.response.ImageFieldData
import kotlinx.parcelize.Parcelize
@Parcelize
@@ -28,6 +29,7 @@ data class AmcCommonBottomSheetData(
@SerializedName("note") val note: AmcCommonBsheetNoteData? = null,
@SerializedName("imageUrl") val imageUrl: String? = null,
@SerializedName("calendarData") val calendarData: CalendarWidget? = null,
@SerializedName("modifyIconProperties") val modifyIconProperties: ImageFieldData? = null,
) : Parcelable
@Parcelize

View File

@@ -21,6 +21,7 @@ data class Footer(
@SerializedName("title") var title: TextWithStyle? = null,
@SerializedName("nextCta") var nextCta: ActionData? = null,
@SerializedName("backCta") var backCta: ActionData? = null,
@SerializedName("horizontalActions") val horizontalActions: Boolean = true,
@SerializedName("progress") var progress: Int? = null,
@SerializedName("note") var note: DataSafeWidget? = null,
@SerializedName("footerCallout") var footerCallout: FooterCallout? = null,

View File

@@ -22,6 +22,7 @@ import com.navi.amc.databinding.FooterLayoutBinding
import com.navi.amc.utils.Constant.WHITE
import com.navi.base.model.ActionData
import com.navi.common.R as CommonR
import com.navi.design.textview.NaviTextView
import com.navi.design.utils.getNaviDrawable
import com.navi.design.utils.parseColorSafe
import com.navi.design.utils.setSpannableString
@@ -35,6 +36,8 @@ class FooterView(context: Context, attrs: AttributeSet?) : ConstraintLayout(cont
private var footerInteractionListener: FooterInteractionListener? = null
private var nextCtaText: String? = null
private var nextCtaColor: Int? = null
private var activeBackCta: NaviTextView? = null
private var inactiveBackCta: NaviTextView? = null
init {
val inflater = LayoutInflater.from(context)
@@ -47,11 +50,14 @@ class FooterView(context: Context, attrs: AttributeSet?) : ConstraintLayout(cont
this.footerInteractionListener = footerInteractionListener
binding.nextCta.visibility = View.VISIBLE
binding.progressBar.visibility = View.VISIBLE
handleHorizontalAction(footer.horizontalActions)
if (footer?.backCta == null) {
binding.backCta.visibility = View.GONE
activeBackCta?.visibility = View.GONE
inactiveBackCta?.visibility = View.GONE
} else {
binding.backCta.visibility = View.VISIBLE
binding.backCta.setOnClickListener {
activeBackCta?.visibility = View.VISIBLE
inactiveBackCta?.visibility = View.GONE
activeBackCta?.setOnClickListener {
footerInteractionListener?.onFooterBackPress(footer.backCta)
}
}
@@ -63,8 +69,8 @@ class FooterView(context: Context, attrs: AttributeSet?) : ConstraintLayout(cont
binding.nextCta.setTextColor(it.parseColorSafe())
nextCtaColor = it.parseColorSafe()
}
footer?.backCta?.title?.let { binding.backCta.text = it }
footer?.backCta?.titleColor?.let { binding.backCta.setTextColor(it.parseColorSafe()) }
footer?.backCta?.title?.let { activeBackCta?.text = it }
footer?.backCta?.titleColor?.let { activeBackCta?.setTextColor(it.parseColorSafe()) }
binding.nextCta.addOnMultipleClicksHandler {
footerInteractionListener?.onFooterNextPress(footer?.nextCta)
}
@@ -133,18 +139,18 @@ class FooterView(context: Context, attrs: AttributeSet?) : ConstraintLayout(cont
}
fun enableBackButtons(enabled: Boolean) {
binding.backCta.isEnabled = enabled
activeBackCta?.isEnabled = enabled
if (enabled) {
binding.backCta.alpha = 1.0F
binding.backCta.tag = NextButtonTag.ENABLED
activeBackCta?.alpha = 1.0F
activeBackCta?.tag = NextButtonTag.ENABLED
} else {
binding.backCta.alpha = 0.5F
binding.backCta.tag = NextButtonTag.DISABLED
activeBackCta?.alpha = 0.5F
activeBackCta?.tag = NextButtonTag.DISABLED
}
}
fun setBackButtonVisibility(visibility: Int) {
binding.backCta.visibility = visibility
activeBackCta?.visibility = visibility
}
fun disableShadow() {
@@ -209,4 +215,14 @@ class FooterView(context: Context, attrs: AttributeSet?) : ConstraintLayout(cont
private fun action(actionData: ActionData?) {
footerInteractionListener?.onFooterNoteClicked(actionData)
}
private fun handleHorizontalAction(horizontalActions: Boolean) {
if (!horizontalActions) {
activeBackCta = binding.secondaryBackCta
inactiveBackCta = binding.backCta
} else {
activeBackCta = binding.backCta
inactiveBackCta = binding.secondaryBackCta
}
}
}

View File

@@ -17,10 +17,12 @@ import androidx.core.view.updateLayoutParams
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.navi.amc.R
import com.navi.amc.common.activity.CheckerActivity
import com.navi.amc.common.fragment.AmcBaseFragment
import com.navi.amc.common.fragment.AmcCommonBottomSheet
import com.navi.amc.common.listener.FooterInteractionListener
import com.navi.amc.common.model.InformationCardData
import com.navi.amc.common.model.SipOrderSummaryData
@@ -51,6 +53,7 @@ import com.navi.amc.utils.Constant.ACTION_PERFORMED
import com.navi.amc.utils.Constant.AMOUNT
import com.navi.amc.utils.Constant.BANK_DETAILS_REF_ID
import com.navi.amc.utils.Constant.BYPASS_OTP
import com.navi.amc.utils.Constant.DATA
import com.navi.amc.utils.Constant.DELETED
import com.navi.amc.utils.Constant.DELETE_SIP_WITH_REASON
import com.navi.amc.utils.Constant.DISMISS
@@ -60,11 +63,14 @@ import com.navi.amc.utils.Constant.FORMATTED_AMOUNT
import com.navi.amc.utils.Constant.GET_SIP_SUMMARY_BOTTOMSHEET
import com.navi.amc.utils.Constant.MODIFY_BOTTOM_SHEET
import com.navi.amc.utils.Constant.NEW_FLOW_TYPE
import com.navi.amc.utils.Constant.NUDGE_BOTTOMSHEET
import com.navi.amc.utils.Constant.ORDER_HEADER_SUBTITLE
import com.navi.amc.utils.Constant.SETUP_AUTOPAY_EXISTING_SIP
import com.navi.amc.utils.Constant.SHOW_TOAST_MESSAGE
import com.navi.amc.utils.Constant.SIP_REFERENCE_ID
import com.navi.amc.utils.SubPageStatusType
import com.navi.amc.utils.createCartRequest
import com.navi.amc.utils.getBottomSheet
import com.navi.amc.utils.getJsonObject
import com.navi.amc.utils.getPaymentSyncFlowStatusCta
import com.navi.amc.utils.shouldCallUpdateSip
@@ -76,6 +82,7 @@ import com.navi.common.csat.CsatBottomSheet
import com.navi.common.csat.models.NetPromoterScoreRequest
import com.navi.common.listeners.FragmentInterchangeListener
import com.navi.common.listeners.HeaderInteractionListener
import com.navi.common.listeners.NewBottomSheetListener
import com.navi.common.model.AmcBottomSheetData
import com.navi.common.model.ModuleNameV2
import com.navi.common.network.models.GenericErrorResponse
@@ -192,15 +199,6 @@ class SipModifyFragment : AmcBaseFragment(), FooterInteractionListener {
}
binding.itemContainer.addView(getDividerView(context, 50))
}
response?.content?.toastMessage?.let { toastMessage ->
showToastMessage(context, toastMessage)
sendEvent(
AmcAnalytics.AMC_INIT_SIP_DETAILS_SIP_SUCCESS_TOAST,
hashMapOf(AmcAnalytics.FUND_ID to arguments?.getString(ISIN).orEmpty()),
)
response?.content?.toastMessage = null // so that we wont show the same toast again
}
}
viewModel.sipUpdateData.observeNonNull(viewLifecycleOwner) {
it?.let {
@@ -306,95 +304,90 @@ class SipModifyFragment : AmcBaseFragment(), FooterInteractionListener {
private fun handleOnClick(actionData: ActionData?, isFooterAction: Boolean? = false) {
sendEvent(actionData?.metaData?.clickedData)
if (
viewModel.sipDetailsData.value?.content?.genericBottomSheets?.get(actionData?.url) !=
null
) {
bottomSheetData =
viewModel.sipDetailsData.value?.content?.genericBottomSheets?.get(actionData?.url)
bottomSheetData?.let {
val fragment =
HorizontalActionErrorFragment.getInstance(
error = it,
action = primaryClickListener,
cancelable = true,
sourceScreenName = screenName,
secondaryAction = secondaryClickListener,
moduleName = ModuleNameV2.AMC.name,
)
safelyShowBottomSheet(fragment, HorizontalActionErrorFragment.TAG)
}
} else if (actionData?.url == MODIFY_BOTTOM_SHEET) {
openBottomSheet(viewModel.sipDetailsData.value?.content?.modifyBottomSheetData)
} else if (actionData?.url == DELETE_SIP_WITH_REASON) {
openCsatBottomSheet(viewModel.sipDetailsData.value?.content?.csatWidgetData)
} else if (shouldCallUpdateSip(actionData?.url)) {
showLoader()
viewModel.updateSip(
arguments?.getString(SIP_REFERENCE_ID).orEmpty(),
actionData?.url.orEmpty(),
viewModel.getNetPromoterScoreRequest(),
)
} else if (actionData?.url == BYPASS_OTP) {
buyFlowVM.apply {
fundName = viewModel.sipDetailsData.value?.content?.subHeader?.title?.text.orEmpty()
fundId = getParameterValue(ISIN)
}
buyFlowVM.setInitialData(
FundBuyFlowViewModel.TransactionFunnelEventModel(
isin = getParameterValue(ISIN),
value = getParameterValue(AMOUNT),
transactionType = Constant.SIP,
sipReferenceId = getParameterValue(SIP_REFERENCE_ID),
)
)
AmcAnalytics.sendTxnFunnelEvent(
transactionFunnelEventModel = buyFlowVM.getTxnFunnelEventObject(),
extraAttributes =
hashMapOf(STEP to SIP_DETAILS_PAYMENT_INITITATE, SOURCE to screenName),
screenName = screenName,
)
val sipDetailsData =
SipDetailsData(
sipReferenceId = getParameterValue(SIP_REFERENCE_ID),
amount = getParameterValue(AMOUNT),
scheme = getParameterValue(ISIN),
)
arguments?.apply {
putString(AMOUNT, getParameterValue(FORMATTED_AMOUNT))
putString(ORDER_HEADER_SUBTITLE, getParameterValue(ORDER_HEADER_SUBTITLE))
putString(ORDER_TYPE, getParameterValue(ORDER_TYPE))
putString(FLOW_TYPE, getParameterValue(FLOW_TYPE))
putString(ISIN, getParameterValue(ISIN))
putString(NEW_FLOW_TYPE, getParameterValue(NEW_FLOW_TYPE))
}
updateLoadingState(isLoading = true, autoPayCard = false)
viewModel.initiateSipPayment(sipDetailsData, cartRequest = createCartRequest(arguments))
} else if (actionData?.url == GET_SIP_SUMMARY_BOTTOMSHEET) {
val sipOrderSummary =
SipOrderSummaryData(
screenName = screenName,
sipReferenceId = arguments?.getString(SIP_REFERENCE_ID).orEmpty(),
)
updateLoadingState(true, !isFooterAction!!)
buyFlowVM.getSipOrderSummaryData(
sipOrderSummaryData = sipOrderSummary,
screenName = screenName,
)
} else {
val orderType = actionData?.parameters?.firstOrNull() { it.key == ORDER_TYPE }?.value
val flowType = actionData?.parameters?.firstOrNull() { it.key == FLOW_TYPE }?.value
arguments?.putString(ORDER_TYPE, orderType)
arguments?.putString(FLOW_TYPE, flowType)
arguments?.putString(AMOUNT, getParameterValue(AMOUNT))
fragmentInterchangeListener?.navigateToNextScreen(actionData, arguments ?: Bundle())
val ctaUrl = actionData?.url
when {
isCommonBottomSheetAction(actionData) -> openCommonBottomSheet(actionData)
isNudgeBottomSheetAction(actionData) -> openConfirmBottomSheets(actionData)
ctaUrl == SHOW_TOAST_MESSAGE -> handleToastMessage()
isGenericBottomSheetAction(actionData) -> handleGenericBottomSheet(actionData)
ctaUrl == MODIFY_BOTTOM_SHEET -> handleModifyBottomSheet()
ctaUrl == DELETE_SIP_WITH_REASON -> handleDeleteSipAction()
shouldCallUpdateSip(ctaUrl) -> handleUpdateSipAction(actionData)
ctaUrl == BYPASS_OTP -> handleBypassOtpAction()
ctaUrl == GET_SIP_SUMMARY_BOTTOMSHEET -> handleSipSummaryAction(isFooterAction)
else -> handleNavigationAction(actionData)
}
}
private fun isCommonBottomSheetAction(actionData: ActionData?): Boolean {
return viewModel.sipDetailsData.value?.content?.commonBottomSheets?.get(actionData?.url) !=
null
}
private fun isNudgeBottomSheetAction(actionData: ActionData?): Boolean {
return viewModel.sipDetailsData.value?.content?.nudgeBottomSheets?.get(actionData?.url) !=
null
}
private fun isGenericBottomSheetAction(actionData: ActionData?): Boolean {
return viewModel.sipDetailsData.value?.content?.genericBottomSheets?.get(actionData?.url) !=
null
}
private fun handleToastMessage() {
viewModel.sipDetailsData.value?.content?.toastMessage?.let { toast ->
showToastMessage(context, toast)
}
}
private fun handleGenericBottomSheet(actionData: ActionData?) {
bottomSheetData =
viewModel.sipDetailsData.value?.content?.genericBottomSheets?.get(actionData?.url)
bottomSheetData?.let {
val fragment =
HorizontalActionErrorFragment.getInstance(
error = it,
action = primaryClickListener,
cancelable = true,
sourceScreenName = screenName,
secondaryAction = secondaryClickListener,
moduleName = ModuleNameV2.AMC.name,
)
safelyShowBottomSheet(fragment, HorizontalActionErrorFragment.TAG)
}
}
private fun handleUpdateSipAction(actionData: ActionData?) {
showLoader()
viewModel.updateSip(
arguments?.getString(SIP_REFERENCE_ID).orEmpty(),
actionData?.url.orEmpty(),
viewModel.getNetPromoterScoreRequest(),
)
}
private fun handleSipSummaryAction(isFooterAction: Boolean?) {
val sipOrderSummary =
SipOrderSummaryData(
screenName = screenName,
sipReferenceId = arguments?.getString(SIP_REFERENCE_ID).orEmpty(),
)
updateLoadingState(true, !isFooterAction!!)
buyFlowVM.getSipOrderSummaryData(
sipOrderSummaryData = sipOrderSummary,
screenName = screenName,
)
}
private fun handleNavigationAction(actionData: ActionData?) {
val orderType = actionData?.parameters?.firstOrNull { it.key == ORDER_TYPE }?.value
val flowType = actionData?.parameters?.firstOrNull { it.key == FLOW_TYPE }?.value
arguments?.putString(ORDER_TYPE, orderType)
arguments?.putString(FLOW_TYPE, flowType)
arguments?.putString(AMOUNT, getParameterValue(AMOUNT))
fragmentInterchangeListener?.navigateToNextScreen(actionData, arguments ?: Bundle())
}
private fun getParameterValue(key: String): String {
return viewModel.sipDetailsData.value
?.footer
@@ -488,6 +481,104 @@ class SipModifyFragment : AmcBaseFragment(), FooterInteractionListener {
)
}
private fun openConfirmBottomSheets(actionData: ActionData? = null) {
val bottomSheetData =
viewModel.sipDetailsData.value?.content?.nudgeBottomSheets?.get(actionData?.url)
bottomSheetData?.let { nudgeBottomSheetData ->
val key = NUDGE_BOTTOMSHEET
val bundle = createBottomSheetBundle(nudgeBottomSheetData)
getBottomSheet(key, bundle, secondaryListener = createBottomSheetListener())?.let {
bottomSheet ->
safelyShowBottomSheet(bottomSheet, NUDGE_BOTTOMSHEET)
}
}
}
private fun createBottomSheetListener(): NewBottomSheetListener {
return object : NewBottomSheetListener {
override fun buttonClick(actionData: ActionData?) {
handleOnClick(actionData)
}
}
}
private fun openCommonBottomSheet(actionData: ActionData? = null) {
val bottomSheetData =
viewModel.sipDetailsData.value?.content?.commonBottomSheets?.get(actionData?.url)
bottomSheetData?.let { data ->
val bundle = createBottomSheetBundle(data)
val key = SubPageStatusType.AMC_COMMON_BOTTOMSHEET
getBottomSheet(key, bundle, genericListener = ::handleOnClick)?.let { bottomSheet ->
safelyShowBottomSheet(bottomSheet, AmcCommonBottomSheet.TAG)
}
}
}
private fun createBottomSheetBundle(data: Any): Bundle {
return Bundle().apply { putString(DATA, Gson().toJson(data)) }
}
private fun handleModifyBottomSheet() {
openBottomSheet(viewModel.sipDetailsData.value?.content?.modifyBottomSheetData)
}
private fun handleDeleteSipAction() {
openCsatBottomSheet(viewModel.sipDetailsData.value?.content?.csatWidgetData)
}
private fun handleBypassOtpAction() {
setupBuyFlowViewModel()
sendAnalyticsEvent()
val sipDetailsData = createSipDetailsData()
updateArgumentsForPayment()
updateLoadingState(isLoading = true, autoPayCard = false)
viewModel.initiateSipPayment(sipDetailsData, cartRequest = createCartRequest(arguments))
}
private fun setupBuyFlowViewModel() {
buyFlowVM.apply {
fundName = viewModel.sipDetailsData.value?.content?.subHeader?.title?.text.orEmpty()
fundId = getParameterValue(ISIN)
}
buyFlowVM.setInitialData(
FundBuyFlowViewModel.TransactionFunnelEventModel(
isin = getParameterValue(ISIN),
value = getParameterValue(AMOUNT),
transactionType = Constant.SIP,
sipReferenceId = getParameterValue(SIP_REFERENCE_ID),
)
)
}
private fun sendAnalyticsEvent() {
AmcAnalytics.sendTxnFunnelEvent(
transactionFunnelEventModel = buyFlowVM.getTxnFunnelEventObject(),
extraAttributes =
hashMapOf(STEP to SIP_DETAILS_PAYMENT_INITITATE, SOURCE to screenName),
screenName = screenName,
)
}
private fun createSipDetailsData(): SipDetailsData {
return SipDetailsData(
sipReferenceId = getParameterValue(SIP_REFERENCE_ID),
amount = getParameterValue(AMOUNT),
scheme = getParameterValue(ISIN),
)
}
private fun updateArgumentsForPayment() {
arguments?.apply {
putString(AMOUNT, getParameterValue(FORMATTED_AMOUNT))
putString(ORDER_HEADER_SUBTITLE, getParameterValue(ORDER_HEADER_SUBTITLE))
putString(ORDER_TYPE, getParameterValue(ORDER_TYPE))
putString(FLOW_TYPE, getParameterValue(FLOW_TYPE))
putString(ISIN, getParameterValue(ISIN))
putString(NEW_FLOW_TYPE, getParameterValue(NEW_FLOW_TYPE))
}
}
companion object {
fun newInstance(bundle: Bundle? = null): SipModifyFragment {
return SipModifyFragment().apply { arguments = bundle }

View File

@@ -8,7 +8,9 @@
package com.navi.amc.portfolio.models
import com.google.gson.annotations.SerializedName
import com.navi.amc.common.model.AmcCommonBottomSheetData
import com.navi.amc.common.model.Footer
import com.navi.amc.common.model.NudgeBottomSheetData
import com.navi.amc.fundbuy.models.AmcHeaderData
import com.navi.amc.fundbuy.models.ToastMessage
import com.navi.common.model.Header
@@ -29,6 +31,10 @@ data class SipModificationContent(
val modifyBottomSheetData: SingleSelectionBottomSheetData? = null,
@SerializedName("genericBottomSheets")
val genericBottomSheets: Map<String, GenericErrorResponse>? = null,
@SerializedName("nudgeBottomSheets")
val nudgeBottomSheets: Map<String, NudgeBottomSheetData>? = null,
@SerializedName("commonBottomSheets")
val commonBottomSheets: Map<String, AmcCommonBottomSheetData>? = null,
@SerializedName("items") val items: List<CardType>? = null,
@SerializedName("toastMessage") var toastMessage: ToastMessage? = null,
@SerializedName("csatWidgetData") val csatWidgetData: CsatWidgetData? = null,

View File

@@ -268,4 +268,5 @@ object Constant {
const val KEY = "key"
const val VALUE = "value"
const val SIP_TYPE_CAMEL_CASE = "sipType"
const val SHOW_TOAST_MESSAGE = "showToastMessage"
}

View File

@@ -86,12 +86,12 @@ fun showToastMessage(context: Context?, toastData: ToastMessage) {
toastLayoutBinding.messageTv.setSpannableString(toastData.text)
toastLayoutBinding.root.background =
getNaviDrawable(
cornerRadius = dpToPxInInt(16),
cornerRadius = dpToPxInInt(4),
backgroundColor = toastData.bgColor.parseColorSafe(),
)
val toast = Toast(context.applicationContext)
toast.setGravity(Gravity.BOTTOM, 0, 220)
toast.setGravity(Gravity.BOTTOM, 0, dpToPxInInt(125))
toast.duration = Toast.LENGTH_SHORT
toast.view = toastLayoutBinding.root
toast.show()

View File

@@ -112,6 +112,23 @@
app:layout_goneMarginStart="@dimen/dp_16"
tools:text="HELP" />
<com.navi.design.textview.NaviTextView
android:id="@+id/secondary_back_cta"
style="@style/ActionButtonText10Style"
android:layout_width="@dimen/_0dp"
android:layout_height="@dimen/dp_48"
android:layout_marginStart="@dimen/dp_16"
android:layout_marginTop="@dimen/dp_16"
android:layout_marginEnd="@dimen/_16dp"
android:background="@drawable/bg_cta_secondary_amc_rounded_4"
android:gravity="center"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/next_cta"
app:layout_goneMarginEnd="@dimen/dp_16"
tools:text="LOAN APPROVAL" />
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/button_loader"
android:layout_width="wrap_content"

View File

@@ -40,4 +40,16 @@
android:layout_marginEnd="@dimen/dp_16"
android:layout_marginBottom="@dimen/dp_12"
app:layout_constraintBottom_toBottomOf="parent"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="@dimen/dp_12"
android:layout_marginEnd="@dimen/dp_16"
android:layout_marginBottom="@dimen/dp_12"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -6,7 +6,8 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/_18dp">
android:paddingVertical="@dimen/_12dp"
android:paddingHorizontal="@dimen/_16dp">
<ImageView
android:id="@+id/icon_iv"
@@ -20,7 +21,8 @@
android:id="@+id/message_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/_18dp"
android:layout_marginStart="@dimen/_8dp"
android:fontFamily="@font/navi_headline_regular"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"