Digital gold ux enhancements (#6886)

* TP-32626: Fix softInputKeyboard issues in DG KYC page

* TP-32833: Fix decimal places precision support to PaymentWidget

* TP-00000 | Add KYC verify success bottom sheet in DG journery

* TP-0000 | fixes (#6887)

* TP-0000 | continue button disable fix on invalid input (#6888)

* TP-0000 | reward reversal partial changes (#6889)

* TP-00000 | contract changes

* TP-00000 | Add dimissible flag for bottom sheet in kyc journey

Co-authored-by: Ashutosh Y <ashutosh.y@navi.com>
Co-authored-by: Apoorv Nigam <apoorv.nigam@navi.com>
This commit is contained in:
Siddiboina Susai
2023-06-15 00:27:41 +05:30
committed by GitHub Enterprise
parent 96541da3f4
commit f0ca669575
12 changed files with 148 additions and 34 deletions

View File

@@ -432,10 +432,11 @@
android:name=".digitalgold.ui.DigitalGoldSellActivity"
android:screenOrientation="portrait"
android:theme="@style/BaseThemeStyleWithShadowOpacity"
android:windowSoftInputMode="adjustNothing" />
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".digitalgold.ui.DigitalGoldBuyActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"
android:theme="@style/BaseThemeStyleWithShadowOpacity" />
<activity android:name=".digitalgold.ui.DigitalGoldInfoActivity"
android:screenOrientation="portrait"

View File

@@ -29,11 +29,16 @@ import com.navi.base.utils.isNotNullAndNotEmpty
import com.navi.common.listeners.BackPressedListener
import com.navi.common.listeners.FragmentInterchangeListener
import com.navi.common.listeners.NewBottomSheetListener
import com.navi.common.model.ActionCheckResponse
import com.navi.common.ui.bottomsheet.WidgetsSupportedBottomSheet
import com.navi.common.ui.fragment.BaseFragment
import com.navi.common.ui.fragment.NewCommonBottomSheet
import com.navi.common.ui.fragment.PaymentCheckFragment
import com.navi.common.utils.Constants.REFRESH
import com.navi.common.utils.observeNonNull
import com.navi.common.utils.toCtaData
import com.navi.common.viewmodel.WidgetSupportedBottomSheetSharedVM
import com.navi.naviwidgets.actions.NaviWidgetClick
import com.navi.naviwidgets.adapters.NaviAdapter
import com.navi.naviwidgets.callbacks.WidgetCallback
import com.navi.naviwidgets.extensions.showWhenDataIsAvailable
@@ -54,21 +59,17 @@ import com.naviapp.databinding.FragmentDigitalGoldKycBinding
import com.naviapp.digitalgold.model.GoldKycCheckResponse
import com.naviapp.digitalgold.model.GoldKycPageRequest
import com.naviapp.digitalgold.model.GoldKycVerifyRequest
import com.naviapp.digitalgold.viewmodels.DigitalGoldKycVM
import com.naviapp.home.model.WidgetResponse
import com.navi.common.model.ActionCheckResponse
import com.navi.naviwidgets.actions.NaviWidgetClick
import com.naviapp.digitalgold.viewmodels.DigitalGoldCommonVM
import com.navi.common.ui.bottomsheet.WidgetsSupportedBottomSheet
import com.navi.common.ui.fragment.PaymentCheckFragment
import com.navi.common.viewmodel.WidgetSupportedBottomSheetSharedVM
import com.naviapp.digitalgold.viewmodels.DigitalGoldKycVM
import com.naviapp.home.analytics.LandingScreenAnalytics
import com.naviapp.home.model.WidgetResponse
import com.naviapp.utils.AMOUNT_DATA
import com.naviapp.utils.Constants
import com.naviapp.utils.Constants.COMMON_BOTTOM_SHEET_ID
import com.naviapp.utils.Constants.TYPE
import com.naviapp.utils.toOpenBottomSheet
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
@AndroidEntryPoint
class DigitalGoldKycFragment : BaseFragment(), WidgetCallback, NewBottomSheetListener,
@@ -217,17 +218,39 @@ class DigitalGoldKycFragment : BaseFragment(), WidgetCallback, NewBottomSheetLis
goldKycResponse.paymentCheckResponse?.let {
navigateToNextScreen(it)
} ?: kotlin.run {
goldKycResponse.actionData?.let {
NaviDeepLinkNavigator.navigate(
activity,
it.toCtaData(),
finish = true
)
viewModel.digitalGoldKycWidgets.value?.extraData?.successBottomSheet?.let { successBottomSheet ->
val displayTime = successBottomSheet.displayTime ?: 1000L
successBottomSheet.bottomSheetData?.data?.let { widgetList ->
val bottomSheet = showWidgetBottomSheet(
widgetList = widgetList,
isCancellable = successBottomSheet.isDismissible ?: true
)
lifecycleScope.launchWhenResumed {
delay(displayTime)
bottomSheet.safelyDismissDialog()
navigateWith(goldKycResponse)
}
} ?: kotlin.run {
navigateWith(goldKycResponse)
}
} ?: kotlin.run {
navigateWith(goldKycResponse)
}
}
}
}
private fun navigateWith(goldKycResponse: GoldKycCheckResponse) {
goldKycResponse.actionData?.let {
NaviDeepLinkNavigator.navigate(
activity,
it.toCtaData(),
finish = true
)
}
}
private fun navigateToNextScreen(paymentCheckResponse: ActionCheckResponse) {
val bundle = Bundle()
bundle.putParcelable(PaymentCheckFragment.DATA, paymentCheckResponse)
@@ -424,6 +447,30 @@ class DigitalGoldKycFragment : BaseFragment(), WidgetCallback, NewBottomSheetLis
widget = naviBaseAdapterModel
}
}
naviAdapter.list.forEachIndexed { index, naviAdapterModel ->
if (naviAdapterModel is LabeledTextInputWidgetModelV2) {
if (viewModel.getName()
.isNotNullAndNotEmpty() && naviAdapterModel?.widgetData?.fieldName == FULL_NAME
&& !(viewModel.getName()
.isNullOrEmpty() || viewModel.getName() == NULL_STRING)
) {
naviAdapterModel.widgetData?.inputTextData?.savedText = viewModel.getName()
}
if (viewModel.getPinCode()
.isNotNullAndNotEmpty() && naviAdapterModel?.widgetData?.fieldName == PIN_CODE
&& !(viewModel.getPinCode().isNullOrEmpty() || viewModel.getPinCode() == NULL_STRING)
) {
naviAdapterModel.widgetData?.inputTextData?.savedText = viewModel.getPinCode()
}
if ( viewModel.getPanNumber()
.isNotNullAndNotEmpty() && naviAdapterModel?.widgetData?.fieldName == PAN_NUMBER
&& !(viewModel.getPanNumber().isNotNullAndNotEmpty() || viewModel.getPanNumber() == NULL_STRING)
) {
naviAdapterModel.widgetData?.inputTextData?.savedText = viewModel.getPanNumber()
}
}
}
if (updateIndex >= 0) {
naviFooterAdapter.notifyItemChanged(
updateIndex,
@@ -464,14 +511,17 @@ class DigitalGoldKycFragment : BaseFragment(), WidgetCallback, NewBottomSheetLis
private fun showWidgetBottomSheet(
widgetList: List<NaviWidget>?,
allowTopPadding: Boolean = true,
bgColor: Int = Color.WHITE
) {
bgColor: Int = Color.WHITE,
isCancellable: Boolean = true
): WidgetsSupportedBottomSheet {
bottomSheetSharedVM.setBottomSheetData(NaviWidgetClick(listOfWidget = widgetList))
val widgetBottomSheet = WidgetsSupportedBottomSheet.getInstance(
allowTopPadding = allowTopPadding,
bgColor = bgColor
bgColor = bgColor,
isCancellable = isCancellable
)
safelyShowBottomSheet(widgetBottomSheet, WidgetsSupportedBottomSheet.TAG)
return widgetBottomSheet
}
companion object {

View File

@@ -91,7 +91,18 @@ data class ExtraDataDetails(
@SerializedName("dialogData")
val uitronData: UiTronData? = null,
@SerializedName("showPageGradient")
val showPageGradient: Boolean? = null
val showPageGradient: Boolean? = null,
@SerializedName("successBottomSheetWithParams")
val successBottomSheet: WidgetBottomSheetWithParams? = null
)
data class WidgetBottomSheetWithParams(
@SerializedName("isDismissible")
val isDismissible: Boolean? = null,
@SerializedName("displayTime")
val displayTime : Long? = null,
@SerializedName("bottomSheetData")
val bottomSheetData: WidgetBottomSheetData? = null
)
data class UiTronData(

View File

@@ -853,4 +853,16 @@
<item name="android:textColor">@color/color_6B6B6B</item>
<item name="android:letterSpacing">0.01</item>
</style>
<style name="WhiteRegularFontStyle">
<item name="android:textColor">@color/buttonTitleColor</item>
<item name="android:fontFamily">@font/tt_regular</item>
<item name="android:textSize">@dimen/sp_10</item>
</style>
<style name="WhiteSemiBoldFontStyle">
<item name="android:textColor">@color/buttonTitleColor</item>
<item name="android:fontFamily">@font/tt_semi_bold</item>
<item name="android:textSize">@dimen/sp_14</item>
</style>
</resources>

View File

@@ -51,7 +51,9 @@ abstract class InputWidgetData(
@SerializedName("endButtonData")
var endButtonData: EndButtonData? = null,
@SerializedName("disableTextCopy")
var disableTextCopy: Boolean? = null
var disableTextCopy: Boolean? = null,
@SerializedName("validationDelay")
var validationDelay: String? = null
)
@Parcelize

View File

@@ -8,6 +8,7 @@
package com.navi.naviwidgets.interfaces
import com.navi.base.model.ActionData
import com.navi.design.common.Padding
import com.navi.naviwidgets.models.NaviWidget
import com.navi.naviwidgets.models.Radius
import com.navi.naviwidgets.models.WidgetLayoutParams
@@ -25,4 +26,5 @@ interface ContainerWidgetInfo {
fun removeElevation(): Boolean?
fun setMargin(): Margin?
fun actionData(): ActionData?
fun setPadding(): Padding?
}

View File

@@ -9,6 +9,7 @@ package com.navi.naviwidgets.models
import com.google.gson.annotations.SerializedName
import com.navi.base.model.ActionData
import com.navi.design.common.Padding
import com.navi.naviwidgets.interfaces.ContainerWidgetInfo
import com.navi.naviwidgets.models.response.WidgetError
import com.navi.naviwidgets.widgets.textdisplay.Margin
@@ -55,6 +56,8 @@ data class ContainerWidget(
override fun setMargin(): Margin? = widgetData?.margin
override fun actionData(): ActionData? = widgetData?.actionData
override fun setPadding(): Padding? = widgetData?.padding
}
data class ContainerWidgetData(
@@ -77,5 +80,7 @@ data class ContainerWidgetData(
@SerializedName("items")
val items: List<NaviWidget>? = null,
@SerializedName("actionData")
val actionData: ActionData? = null
val actionData: ActionData? = null,
@SerializedName("padding")
val padding: Padding? = null
) : Serializable

View File

@@ -30,7 +30,9 @@ data class PaymentWidgetData(
val actionData: ActionData? = null,
@SerializedName("subTitle")
val subTitle: NaviTextComponent? = null,
var totalAmount: Double? = null
var totalAmount: Double? = null,
@SerializedName("precision")
val precision: Int? = null
)
data class PaymentData(

View File

@@ -140,6 +140,14 @@ class ContainerWidgetLayout @JvmOverloads constructor(
dpToPxInInt(16),
dpToPxInInt(info.borderWidth() ?: 0)
)
info.setPadding()?.let {
llParent.setPadding(
dpToPxInInt((it.start ?: 16).toInt()),
dpToPxInInt((it.top ?: 0).toInt()),
dpToPxInInt((it.end ?: 16).toInt()),
dpToPxInInt((it.bottom ?: 0).toInt()),
)
}
info.isDisabled()?.let {
if (it) {
root.alpha = 0.4F

View File

@@ -5,8 +5,8 @@ import android.util.AttributeSet
import androidx.constraintlayout.widget.ConstraintLayout
import com.navi.base.model.ActionData
import com.navi.base.utils.isNotNull
import com.navi.design.utils.decimalFormatForAmount
import com.navi.design.utils.Constants.AMOUNT
import com.navi.design.utils.decimalFormatForAmount
import com.navi.design.utils.spannedText
import com.navi.naviwidgets.R
import com.navi.naviwidgets.actions.PaymentWidgetClickAction
@@ -15,6 +15,7 @@ import com.navi.naviwidgets.databinding.PaymentWidgetLayoutBinding
import com.navi.naviwidgets.extensions.showWhenDataIsAvailable
import com.navi.naviwidgets.models.PaymentWidget
import java.math.RoundingMode
import java.text.DecimalFormat
class PaymentWidgetLayout @JvmOverloads constructor(
context: Context,
@@ -43,12 +44,32 @@ class PaymentWidgetLayout @JvmOverloads constructor(
private fun setProperties() {
binding.apply {
title.text = if ((paymentWidget?.widgetData?.totalAmount ?: 0.0) > 0.0) {
decimalFormatForAmount.roundingMode = RoundingMode.UP
val customPrecision = paymentWidget?.widgetData?.precision?.let { precision ->
if (precision > 0) {
precision
} else {
0
}
} ?: 0
val formatter = if (customPrecision > 0) {
val precisionBuilder = StringBuilder("##,##,##,##,###.")
for (index in 0 until customPrecision) {
precisionBuilder.append('0')
}
DecimalFormat(precisionBuilder.toString())
} else {
decimalFormatForAmount
}
formatter.roundingMode = RoundingMode.UP
String.format(
context.getString(R.string.rupee_symbol_with_amount),
decimalFormatForAmount.format(paymentWidget?.widgetData?.totalAmount)
formatter.format(paymentWidget?.widgetData?.totalAmount)
)
} else {
paymentWidget?.widgetData?.title?.text.spannedText(
context = context,

View File

@@ -206,7 +206,7 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
widgetCallback?.getLifeCycle()?.coroutineScope?.let { coroutineScope ->
widgetBinding.plainTextInput
.textChanges()
.debounce(QUERY_DELAY)
.debounce(widgetModel.widgetData?.validationDelay?.toLong() ?: QUERY_DELAY)
.onEach { charSequence ->
if (charSequence.toString().isNotNullAndNotEmpty()) {
val resultText: String? = getUserInputPostValidation()

View File

@@ -15,14 +15,14 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/tooltip_rectangle_0px"
app:layout_constraintBottom_toBottomOf="@+id/txtViewData"
app:layout_constraintBottom_toBottomOf="@+id/dateTextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/dateTextView" />
app:layout_constraintTop_toTopOf="@+id/txtViewData" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/dateTextView"
style="@style/TextExtraSmallFontWhiteColorStyle"
android:id="@+id/txtViewData"
style="@style/WhiteSemiBoldFontStyle"
android:layout_width="wrap_content"
android:minWidth="@dimen/dp_90"
android:layout_height="wrap_content"
@@ -35,8 +35,8 @@
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/txtViewData"
style="@style/TextExtraSmallFontWhiteColorStyle"
android:id="@+id/dateTextView"
style="@style/WhiteRegularFontStyle"
android:layout_width="wrap_content"
android:minWidth="@dimen/dp_90"
android:layout_height="wrap_content"
@@ -44,9 +44,9 @@
android:gravity="center"
android:paddingHorizontal="@dimen/dp_8"
android:paddingBottom="@dimen/dp_4"
app:layout_constraintStart_toStartOf="@id/dateTextView"
app:layout_constraintTop_toBottomOf="@id/dateTextView"
app:layout_constraintEnd_toEndOf="@id/dateTextView"
app:layout_constraintStart_toStartOf="@id/txtViewData"
app:layout_constraintTop_toBottomOf="@id/txtViewData"
app:layout_constraintEnd_toEndOf="@id/txtViewData"
/>
<androidx.appcompat.widget.AppCompatImageView