TP-62951 | Saksham Mahajan | Amc stop sip (#10315)
Co-authored-by: saksham <saksham>
This commit is contained in:
@@ -22,4 +22,12 @@ data class Footer(
|
||||
@SerializedName("backCta") var backCta: ActionData? = null,
|
||||
@SerializedName("progress") var progress: Int? = null,
|
||||
@SerializedName("note") var note: DataSafeWidget? = null,
|
||||
@SerializedName("footerCallout") var footerCallout: FooterCallout? = null
|
||||
) : Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class FooterCallout(
|
||||
@SerializedName("title") var title: TextWithStyle? = null,
|
||||
@SerializedName("subTitle", alternate = ["subtitle"]) var subTitle: TextWithStyle? = null,
|
||||
@SerializedName("iconCode") var iconCode: String? = null,
|
||||
) : Parcelable
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.navi.base.model.ActionData
|
||||
import com.navi.design.utils.parseColorSafe
|
||||
import com.navi.design.utils.setSpannableString
|
||||
import com.navi.naviwidgets.extensions.setGradient
|
||||
import com.navi.naviwidgets.extensions.showWhenDataIsAvailable
|
||||
|
||||
class FooterView(context: Context, attrs: AttributeSet?) : ConstraintLayout(context, attrs) {
|
||||
private var binding: FooterLayoutBinding
|
||||
@@ -95,6 +96,18 @@ class FooterView(context: Context, attrs: AttributeSet?) : ConstraintLayout(cont
|
||||
} ?: kotlin.run {
|
||||
binding.footerNote.isVisible = false
|
||||
}
|
||||
|
||||
footer?.footerCallout?.let {
|
||||
binding.footerTextWithImage.root.isVisible = true
|
||||
binding.footerTextWithImage.title.showWhenDataIsAvailable(it.title)
|
||||
binding.footerTextWithImage.subTitle.showWhenDataIsAvailable(it.subTitle)
|
||||
binding.footerTextWithImage.image.showWhenDataIsAvailable(it.iconCode)
|
||||
binding.divider.isVisible = true
|
||||
} ?: kotlin.run {
|
||||
binding.footerTextWithImage.root.isVisible = false
|
||||
binding.divider.isVisible = false
|
||||
}
|
||||
|
||||
} ?: run {
|
||||
isVisible = false
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.navi.amc.redemption.model.RedemptionOrderDetails
|
||||
import com.navi.amc.utils.Constant.FUND_LANDING_DATA_V2
|
||||
import com.navi.amc.utils.Constant.FUND_LIST_DATA_V2
|
||||
import com.navi.base.model.ActionData
|
||||
import com.navi.common.csat.models.NetPromoterScoreRequest
|
||||
import com.navi.common.model.UploadDataAsyncResponse
|
||||
import com.navi.common.network.models.GenericResponse
|
||||
import com.navi.common.network.models.SuccessResponse
|
||||
@@ -319,7 +320,8 @@ interface RetrofitService {
|
||||
@POST("/sip/modify")
|
||||
suspend fun updateSip(
|
||||
@Query("sipReferenceId") sipReferenceId: String,
|
||||
@Query("modifyAction") modifyAction: String
|
||||
@Query("modifyAction") modifyAction: String,
|
||||
@Body netPromoterScoreRequest: NetPromoterScoreRequest
|
||||
): Response<GenericResponse<SipUpdateResponse>>
|
||||
|
||||
@POST("/orders/create-redemption-order/vendor")
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.navi.amc.utils.AmcAnalytics
|
||||
import com.navi.amc.utils.Constant
|
||||
import com.navi.amc.utils.Constant.ACTION_PERFORMED
|
||||
import com.navi.amc.utils.Constant.DELETED
|
||||
import com.navi.amc.utils.Constant.DELETE_SIP_WITH_REASON
|
||||
import com.navi.amc.utils.Constant.MANDATE_OPTED_IN
|
||||
import com.navi.amc.utils.Constant.MANDATE_OPTED_OUT
|
||||
import com.navi.amc.utils.Constant.MODIFY_BOTTOM_SHEET
|
||||
@@ -44,7 +45,10 @@ import com.navi.amc.utils.Constant.SKIPPED
|
||||
import com.navi.amc.utils.SubPageStatusType
|
||||
import com.navi.amc.utils.showToastMessage
|
||||
import com.navi.base.model.ActionData
|
||||
import com.navi.base.model.CtaData
|
||||
import com.navi.base.utils.orFalse
|
||||
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.model.ModuleNameV2
|
||||
@@ -55,6 +59,7 @@ import com.navi.common.utils.observeNonNull
|
||||
import com.navi.common.utils.toActionData
|
||||
import com.navi.design.utils.dpToPxInInt
|
||||
import com.navi.naviwidgets.models.SingleSelectionBottomSheetData
|
||||
import com.navi.naviwidgets.models.response.CsatWidgetData
|
||||
import com.navi.naviwidgets.models.response.DataSafeWidget
|
||||
import com.navi.naviwidgets.models.response.NoteWidget
|
||||
import com.navi.naviwidgets.utils.getDividerView
|
||||
@@ -210,19 +215,42 @@ class SipModifyFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
}
|
||||
} else if (actionData?.url == MODIFY_BOTTOM_SHEET) {
|
||||
openBottomSheet(viewModel.sipDetailsData.value?.content?.modifyBottomSheetData)
|
||||
} else if (isApiNeedsToCall(actionData?.url)) {
|
||||
} else if (actionData?.url == DELETE_SIP_WITH_REASON) {
|
||||
openCsatBottomSheet(viewModel.sipDetailsData.value?.content?.csatWidgetData)
|
||||
}
|
||||
else if (isApiNeedsToCall(actionData?.url)) {
|
||||
showLoader()
|
||||
viewModel.updateSip(
|
||||
arguments?.getString(SIP_REFERENCE_ID).orEmpty(),
|
||||
actionData?.url.orEmpty()
|
||||
actionData?.url.orEmpty(),
|
||||
viewModel.getNetPromoterScoreRequest()
|
||||
)
|
||||
} else if (actionData?.url.isNullOrEmpty().not()) {
|
||||
fragmentInterchangeListener?.navigateToNextScreen(actionData, arguments ?: Bundle())
|
||||
}
|
||||
}
|
||||
|
||||
private fun openCsatBottomSheet(data: CsatWidgetData?) {
|
||||
data?.selected = DELETE_SIP_WITH_REASON
|
||||
data?.bottomSheetData?.get(DELETE_SIP_WITH_REASON)?.reasons?.forEach {
|
||||
it.isChecked = false
|
||||
}
|
||||
val bottomSheet =
|
||||
CsatBottomSheet.getInstance(data, enableBlackCtaStyle = true, action = ::onClickCtaData)
|
||||
safelyShowBottomSheet(bottomSheet, CsatBottomSheet.TAG)
|
||||
}
|
||||
|
||||
private fun onClickCtaData(
|
||||
ctaData: CtaData,
|
||||
netPromoterScoreRequest: NetPromoterScoreRequest
|
||||
) {
|
||||
viewModel.setNetPromoterScoreRequest(netPromoterScoreRequest)
|
||||
handleOnClick(ctaData.toActionData())
|
||||
}
|
||||
|
||||
private fun openBottomSheet(data: SingleSelectionBottomSheetData?) {
|
||||
val bottomSheet = SingleSelectionBottomSheet.getInstance(data)
|
||||
viewModel.clearNetPromoterScoreRequest()
|
||||
safelyShowBottomSheet(bottomSheet, SingleSelectionBottomSheet.SINGLE_SELECTION_BOTTOM_SHEET)
|
||||
bottomSheet.selectedItem.observeNonNull(this) { item ->
|
||||
handleOnClick(ActionData(url = item.id))
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.navi.common.network.models.GenericErrorResponse
|
||||
import com.navi.naviwidgets.models.NaviWidget
|
||||
import com.navi.naviwidgets.models.SingleSelectionBottomSheetData
|
||||
import com.navi.naviwidgets.models.response.CardType
|
||||
import com.navi.naviwidgets.models.response.CsatWidgetData
|
||||
|
||||
data class SipModificationResponse(
|
||||
@SerializedName("header") val header: Header? = null,
|
||||
@@ -30,7 +31,8 @@ data class SipModificationContent(
|
||||
@SerializedName("genericBottomSheets")
|
||||
val genericBottomSheets: Map<String, GenericErrorResponse>? = null,
|
||||
@SerializedName("items") val items: List<CardType>? = null,
|
||||
@SerializedName("toastMessage") var toastMessage: ToastMessage? = null
|
||||
@SerializedName("toastMessage") var toastMessage: ToastMessage? = null,
|
||||
@SerializedName("csatWidgetData") val csatWidgetData: CsatWidgetData? = null
|
||||
)
|
||||
|
||||
data class SipItems(@SerializedName("widgets") val widgets: List<NaviWidget>? = null)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
package com.navi.amc.portfolio.repositories
|
||||
|
||||
import com.navi.amc.network.retrofit.RetrofitService
|
||||
import com.navi.common.csat.models.NetPromoterScoreRequest
|
||||
import com.navi.common.network.retrofit.ResponseCallback
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -17,6 +18,16 @@ class SipModificationRepository @Inject constructor(private val retrofitService:
|
||||
suspend fun fetchSipModificationDetails(sipReferenceId: String, source: String) =
|
||||
apiResponseCallback(retrofitService.fetchSipModificationDetails(sipReferenceId, source))
|
||||
|
||||
suspend fun updateSip(sipReferenceId: String, action: String) =
|
||||
apiResponseCallback(retrofitService.updateSip(sipReferenceId, action))
|
||||
suspend fun updateSip(
|
||||
sipReferenceId: String,
|
||||
action: String,
|
||||
netPromoterScoreRequest: NetPromoterScoreRequest
|
||||
) =
|
||||
apiResponseCallback(
|
||||
retrofitService.updateSip(
|
||||
sipReferenceId,
|
||||
action,
|
||||
netPromoterScoreRequest
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import androidx.lifecycle.viewModelScope
|
||||
import com.navi.amc.portfolio.models.SipModificationResponse
|
||||
import com.navi.amc.portfolio.models.SipUpdateResponse
|
||||
import com.navi.amc.portfolio.repositories.SipModificationRepository
|
||||
import com.navi.common.csat.models.NetPromoterScoreRequest
|
||||
import com.navi.common.utils.SingleLiveEvent
|
||||
import com.navi.common.viewmodel.BaseVM
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
@@ -30,6 +31,8 @@ class SipModificationVM @Inject constructor(private val repository: SipModificat
|
||||
val sipUpdateData: LiveData<SipUpdateResponse?>
|
||||
get() = _sipUpdateData
|
||||
|
||||
private var netPromoterScoreRequest : NetPromoterScoreRequest = NetPromoterScoreRequest()
|
||||
|
||||
fun fetchSipModificationDetails(sipReferenceId: String, source: String) {
|
||||
viewModelScope.launch {
|
||||
val response = repository.fetchSipModificationDetails(sipReferenceId, source)
|
||||
@@ -41,9 +44,13 @@ class SipModificationVM @Inject constructor(private val repository: SipModificat
|
||||
}
|
||||
}
|
||||
|
||||
fun updateSip(sipReferenceId: String, action: String) {
|
||||
fun updateSip(
|
||||
sipReferenceId: String,
|
||||
action: String,
|
||||
netPromoterScoreRequest: NetPromoterScoreRequest = NetPromoterScoreRequest()
|
||||
) {
|
||||
viewModelScope.launch {
|
||||
val response = repository.updateSip(sipReferenceId, action)
|
||||
val response = repository.updateSip(sipReferenceId, action, netPromoterScoreRequest)
|
||||
if (response.error == null && response.errors.isNullOrEmpty()) {
|
||||
_sipUpdateData.value = response.data
|
||||
} else {
|
||||
@@ -52,10 +59,23 @@ class SipModificationVM @Inject constructor(private val repository: SipModificat
|
||||
}
|
||||
}
|
||||
|
||||
fun getNetPromoterScoreRequest(): NetPromoterScoreRequest {
|
||||
return netPromoterScoreRequest
|
||||
}
|
||||
|
||||
fun clearNetPromoterScoreRequest() {
|
||||
netPromoterScoreRequest = NetPromoterScoreRequest()
|
||||
}
|
||||
|
||||
fun setNetPromoterScoreRequest(netPromoterScoreRequest: NetPromoterScoreRequest) {
|
||||
this.netPromoterScoreRequest = netPromoterScoreRequest
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
_sipDetailsData.value = null
|
||||
_sipUpdateData.value = null
|
||||
errorResponse.value = null
|
||||
netPromoterScoreRequest = NetPromoterScoreRequest()
|
||||
super.onCleared()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,4 +175,5 @@ object Constant {
|
||||
const val CAPS_DATA ="DATA"
|
||||
const val AUTOPAY_TYPE = "autopay_type"
|
||||
const val AUTOPAY = "AUTOPAY"
|
||||
const val DELETE_SIP_WITH_REASON = "DELETE_SIP_WITH_REASON"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_16">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="@dimen/_24dp"
|
||||
android:layout_height="@dimen/_24dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_12"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/image"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Autopay failed, SIP at risk!"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/subTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_12"
|
||||
android:layout_marginTop="@dimen/dp_4"
|
||||
android:gravity="start"
|
||||
android:lineHeight="@dimen/_18sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/image"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
tools:text="Pay installment to avoid SIP deletion. SIPs will be auto-deleted after 2 more failures."
|
||||
tools:visibility="visible" />
|
||||
/>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
@@ -41,26 +41,40 @@
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
android:layout_marginTop="@dimen/dp_12"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="@dimen/dp_8"
|
||||
android:paddingVertical="@dimen/dp_4"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/progress_bar"
|
||||
tools:text="Set up an account win up to ₹100" />
|
||||
tools:text="Set up an account win up to ₹100"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<include
|
||||
android:id="@+id/footer_text_with_image"
|
||||
layout="@layout/footer_image_with_text_and_subtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
android:layout_marginTop="@dimen/dp_12"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="@dimen/dp_0"
|
||||
android:visibility="gone"
|
||||
android:layout_height="@dimen/dp_2"
|
||||
android:layout_marginTop="@dimen/dp_12"
|
||||
android:layout_marginHorizontal="@dimen/dp_16"
|
||||
android:layout_marginTop="@dimen/dp_12"
|
||||
android:background="@drawable/dash_line_horizontal_grey"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
android:background="@drawable/dash_line_horizontal_grey" />
|
||||
app:layout_constraintTop_toBottomOf="@id/footer_text_with_image"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/back_cta"
|
||||
|
||||
@@ -120,6 +120,7 @@ class CsatAdapter(
|
||||
view.setOnClickListener {
|
||||
data.isChecked = data.isChecked.not()
|
||||
freeTextBoxListener?.onOptionSelect(data)
|
||||
freeTextBoxListener?.onOptionClicked(data)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
return view
|
||||
|
||||
@@ -19,6 +19,7 @@ import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.ContextCompat.getColor
|
||||
import androidx.core.content.ContextCompat.getSystemService
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.databinding.DataBindingUtil
|
||||
@@ -26,6 +27,7 @@ import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.airbnb.lottie.LottieAnimationView
|
||||
import com.navi.base.model.AnalyticsEvent
|
||||
import com.navi.base.model.CtaData
|
||||
import com.navi.base.model.ImageDetail
|
||||
import com.navi.base.utils.isNotNull
|
||||
import com.navi.base.utils.isNotNullAndNotEmpty
|
||||
@@ -71,11 +73,13 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
|
||||
private var selectedRating: Int? = null
|
||||
|
||||
private val csatVM: CsatVM by viewModels<CsatVM>()
|
||||
private var action: ((CtaData, NetPromoterScoreRequest) -> Unit)? = null
|
||||
|
||||
override fun setContainerView(viewStub: ViewStub) {
|
||||
viewStub.layoutResource = R.layout.csat_common_bottom_sheet
|
||||
binding = DataBindingUtil.getBinding(viewStub.inflate())!!
|
||||
initUI()
|
||||
initObserver()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@@ -83,15 +87,51 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
|
||||
setBottomSheetHeightRatio(0.15f)
|
||||
}
|
||||
|
||||
private fun initUI() {
|
||||
arguments?.getParcelable<CsatWidgetData>(DATA)?.let { npsV2WidgetData ->
|
||||
updateLayoutData(npsV2WidgetData)
|
||||
private fun initObserver() {
|
||||
csatVM.numberOfItemSelected.observeNonNull(viewLifecycleOwner) { numberOfItems ->
|
||||
if (bottomSheetData?.shouldDisableFooter.orFalse()) {
|
||||
if (numberOfItems > 0) {
|
||||
binding.primaryAbv.isEnabled = true
|
||||
binding.primaryAbv.background =
|
||||
getNaviDrawable(
|
||||
backgroundColor =
|
||||
getColor(requireContext(), DesignR.color.purple_button_color),
|
||||
radii =
|
||||
CornerRadius(
|
||||
leftTop = dpToPx(4),
|
||||
rightTop = dpToPx(4),
|
||||
leftBottom = dpToPx(4),
|
||||
rightBottom = dpToPx(4)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
binding.primaryAbv.isEnabled = false
|
||||
binding.primaryAbv.background =
|
||||
getNaviDrawable(
|
||||
backgroundColor = getColor(requireContext(), DesignR.color.dark_grey),
|
||||
radii =
|
||||
CornerRadius(
|
||||
leftTop = dpToPx(4),
|
||||
rightTop = dpToPx(4),
|
||||
leftBottom = dpToPx(4),
|
||||
rightBottom = dpToPx(4)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initUI() {
|
||||
arguments?.getBoolean(ENABLE_BLACK_CTA_STYLE)?.let { enableBlackCtaStyle ->
|
||||
if (enableBlackCtaStyle) {
|
||||
enableBlackCta = true
|
||||
}
|
||||
}
|
||||
arguments?.getParcelable<CsatWidgetData>(DATA)?.let { npsV2WidgetData ->
|
||||
addCountOfPreSelectedItems(npsV2WidgetData)
|
||||
updateLayoutData(npsV2WidgetData)
|
||||
}
|
||||
|
||||
csatVM.errorResponse.observeNonNull(viewLifecycleOwner) {
|
||||
it.first.let {
|
||||
@@ -114,7 +154,8 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
|
||||
if (enableBlackCta.orFalse()) {
|
||||
binding.tryAgainBtn.background =
|
||||
getNaviDrawable(
|
||||
backgroundColor = blackCtaColor.parseColorSafe(),
|
||||
backgroundColor =
|
||||
getColor(requireContext(), DesignR.color.purple_button_color),
|
||||
radii =
|
||||
CornerRadius(
|
||||
leftTop = dpToPx(4),
|
||||
@@ -208,6 +249,14 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
|
||||
}
|
||||
}
|
||||
|
||||
private fun addCountOfPreSelectedItems(csatWidgetData: CsatWidgetData) {
|
||||
csatWidgetData.bottomSheetData?.get(csatWidgetData.selected)?.reasons?.forEach {
|
||||
if (it.isChecked) {
|
||||
csatVM.incrementNumberOfItemSelected()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateLayoutData(csatWidgetData: CsatWidgetData) {
|
||||
val bottomSheetData = csatWidgetData.bottomSheetData?.get(csatWidgetData.selected)
|
||||
bottomSheetData?.let { data ->
|
||||
@@ -255,6 +304,29 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
|
||||
binding.csatOptionsLayout.addView(itemView)
|
||||
}
|
||||
binding.primaryAbv.setLayoutFieldData(data.footer)
|
||||
data.secondaryFooter?.let {
|
||||
binding.secondaryAbv.apply {
|
||||
setLayoutFieldData(it)
|
||||
background =
|
||||
getNaviDrawable(
|
||||
backgroundColor = data?.secondaryFooter?.bgColor?.parseColorSafe(),
|
||||
radii =
|
||||
CornerRadius(
|
||||
leftTop = dpToPx(4),
|
||||
rightTop = dpToPx(4),
|
||||
leftBottom = dpToPx(4),
|
||||
rightBottom = dpToPx(4)
|
||||
)
|
||||
)
|
||||
visibility = View.VISIBLE
|
||||
setOnClickListener {
|
||||
bottomSheetData?.secondaryFooter?.action?.cta?.let {
|
||||
action?.invoke(it, getNetPromoterScoreRequest(data, csatWidgetData))
|
||||
safelyDismissDialog()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (screen?.equals(REWARDS) == true) {
|
||||
if (csatVM.isRatingGood(data.ratingIndex?.toIntOrNull().orZero())) {
|
||||
val layoutParams =
|
||||
@@ -271,7 +343,8 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
|
||||
if (enableBlackCta.orFalse()) {
|
||||
binding.primaryAbv.background =
|
||||
getNaviDrawable(
|
||||
backgroundColor = blackCtaColor.parseColorSafe(),
|
||||
backgroundColor =
|
||||
getColor(requireContext(), DesignR.color.purple_button_color),
|
||||
radii =
|
||||
CornerRadius(
|
||||
leftTop = dpToPx(4),
|
||||
@@ -284,8 +357,43 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
|
||||
|
||||
binding.primaryAbv.setOnClickListener(
|
||||
MultipleClicksHandler {
|
||||
selectedRating = data.ratingIndex?.toIntOrNull()
|
||||
submitNpsDetails(data, csatWidgetData)
|
||||
bottomSheetData?.footer?.action?.cta?.let {
|
||||
var isFreeTextEmpty = false
|
||||
bottomSheetData?.reasons?.let {
|
||||
it.forEach { response ->
|
||||
if (response.isChecked) {
|
||||
if (
|
||||
response.takeUserInput == true &&
|
||||
binding.freeText.isVisible &&
|
||||
binding.freeText.text?.isEmpty() == true
|
||||
) {
|
||||
isFreeTextEmpty = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isFreeTextEmpty) {
|
||||
binding.freeText.background =
|
||||
getNaviDrawable(
|
||||
strokeColor = getColor(requireContext(), DesignR.color.red),
|
||||
strokeWidth = dpToPx(1).toInt(),
|
||||
radii =
|
||||
CornerRadius(
|
||||
leftTop = dpToPx(8),
|
||||
rightTop = dpToPx(8),
|
||||
leftBottom = dpToPx(8),
|
||||
rightBottom = dpToPx(8)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
action?.invoke(it, getNetPromoterScoreRequest(data, csatWidgetData))
|
||||
safelyDismissDialog()
|
||||
}
|
||||
}
|
||||
?: run {
|
||||
selectedRating = data.ratingIndex?.toIntOrNull()
|
||||
submitNpsDetails(data, csatWidgetData)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -437,13 +545,13 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
|
||||
const val DEFAULT_DELAY_BETWEEN_SCREENS_IN_MILLISECS = 3000L
|
||||
const val METADATA_SUBMIT_ANALYTICS_EVENT = "submitAnalyticsEvent"
|
||||
const val METADATA_PARTIAL_FILL_ANALYTICS_EVENT = "partialFillAnalyticsEvent"
|
||||
const val blackCtaColor = "#1F002A"
|
||||
const val FIVE_RATING = 5
|
||||
const val FOUR_RATING = 4
|
||||
|
||||
fun getInstance(
|
||||
npsV2WidgetData: CsatWidgetData? = null,
|
||||
enableBlackCtaStyle: Boolean = false
|
||||
enableBlackCtaStyle: Boolean = false,
|
||||
action: ((CtaData, NetPromoterScoreRequest) -> Unit)? = null
|
||||
): CsatBottomSheet {
|
||||
return CsatBottomSheet().apply {
|
||||
arguments =
|
||||
@@ -451,6 +559,7 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
|
||||
putParcelable(Constants.DATA, npsV2WidgetData)
|
||||
putBoolean(Constants.ENABLE_BLACK_CTA_STYLE, enableBlackCtaStyle)
|
||||
}
|
||||
this.action = action
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -459,6 +568,22 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
|
||||
if (data?.takeUserInput == true) {
|
||||
binding.freeText.isVisible = data.isChecked == true
|
||||
binding.freeText.setRawInputType(EditorInfo.TYPE_CLASS_TEXT)
|
||||
binding.freeText.setOnTouchListener { _, _ ->
|
||||
binding.freeText.background =
|
||||
getNaviDrawable(
|
||||
strokeColor =
|
||||
getColor(requireContext(), DesignR.color.border_dark_grey_color),
|
||||
strokeWidth = dpToPx(1).toInt(),
|
||||
radii =
|
||||
CornerRadius(
|
||||
leftTop = dpToPx(8),
|
||||
rightTop = dpToPx(8),
|
||||
leftBottom = dpToPx(8),
|
||||
rightBottom = dpToPx(8)
|
||||
)
|
||||
)
|
||||
false
|
||||
}
|
||||
binding.freeText.setOnEditorActionListener { v, actionId, event ->
|
||||
if (
|
||||
actionId == EditorInfo.IME_ACTION_DONE ||
|
||||
@@ -483,6 +608,16 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionClicked(data: ReasonItem?) {
|
||||
if (bottomSheetData?.shouldDisableFooter.orFalse()) {
|
||||
if (data?.isChecked == true) {
|
||||
csatVM.incrementNumberOfItemSelected()
|
||||
} else {
|
||||
csatVM.decrementNumberOfItemSelected()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setListener(listener: CsatCompletionListener) {
|
||||
npsCompletionListener = listener
|
||||
}
|
||||
@@ -518,6 +653,8 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
|
||||
|
||||
interface OthersInputBoxListener {
|
||||
fun onOptionSelect(data: ReasonItem?)
|
||||
|
||||
fun onOptionClicked(data: ReasonItem?)
|
||||
}
|
||||
|
||||
interface CsatCompletionListener {
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
package com.navi.common.csat
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.navi.common.csat.models.NetPromoterScoreRequest
|
||||
import com.navi.common.csat.state.CsatSubmitResponseState
|
||||
import com.navi.common.viewmodel.BaseVM
|
||||
@@ -25,6 +27,10 @@ class CsatVM @Inject constructor(private val repository: CsatRepository) : BaseV
|
||||
|
||||
inline fun isRatingGood(rating: Int): Boolean = rating >= NPS_RATING_GOOD
|
||||
|
||||
private val _numberOfItemSelected = MutableLiveData<Int>(0)
|
||||
val numberOfItemSelected: LiveData<Int>
|
||||
get() = _numberOfItemSelected
|
||||
|
||||
fun submitNpsDetails(netPromoterScoreRequest: NetPromoterScoreRequest) {
|
||||
coroutineScope.launch {
|
||||
_npsSubmitResponse.emit(CsatSubmitResponseState.Loading)
|
||||
@@ -38,6 +44,14 @@ class CsatVM @Inject constructor(private val repository: CsatRepository) : BaseV
|
||||
}
|
||||
}
|
||||
|
||||
fun incrementNumberOfItemSelected() {
|
||||
_numberOfItemSelected.value = (_numberOfItemSelected.value ?: 0) + 1
|
||||
}
|
||||
|
||||
fun decrementNumberOfItemSelected() {
|
||||
_numberOfItemSelected.value = (_numberOfItemSelected.value ?: 0) - 1
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val NPS_RATING_GOOD = 4
|
||||
}
|
||||
|
||||
@@ -245,9 +245,28 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/free_text_heading" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/secondary_abv"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_32"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:layout_marginBottom="@dimen/layout_dp_16"
|
||||
android:background="@drawable/rounded_negative_button_bg"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingVertical="@dimen/dp_13"
|
||||
android:textColor="@color/white"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/primary_abv"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/free_text"
|
||||
tools:text="Submit"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/primary_abv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_32"
|
||||
android:layout_marginBottom="@dimen/layout_dp_16"
|
||||
@@ -258,7 +277,7 @@
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/secondary_abv"
|
||||
app:layout_constraintTop_toBottomOf="@id/free_text"
|
||||
tools:text="Submit"
|
||||
tools:visibility="visible" />
|
||||
|
||||
@@ -56,6 +56,8 @@ data class CsatBottomSheetData(
|
||||
@SerializedName("state") val state: CsatReasonSelectionState? = null,
|
||||
@SerializedName("reasons") val reasons: List<ReasonItem>? = null,
|
||||
@SerializedName("footer") val footer: LayoutFieldData? = null,
|
||||
@SerializedName("shouldDisableFooter") val shouldDisableFooter: Boolean? = false,
|
||||
@SerializedName("secondaryFooter") val secondaryFooter: LayoutFieldData? = null,
|
||||
@SerializedName("ratingIndex") val ratingIndex: String? = null,
|
||||
@SerializedName("metadata") var metadata: MutableMap<String?, ParameterValue?>? = null
|
||||
) : Parcelable
|
||||
|
||||
Reference in New Issue
Block a user