NTP-949 | optimising pages for repeat users (#11971)

This commit is contained in:
Ashutosh Y
2024-08-02 01:23:18 +05:30
committed by GitHub
parent ff690e4e97
commit 2a7ba20501
15 changed files with 169 additions and 56 deletions

View File

@@ -210,7 +210,8 @@ class OrderStatusFragment :
}
} else {
showLoader()
viewModel.fetchScreenData(orderId, dataSource, extraParams)
val sourceType = arguments?.getString(Constant.SOURCE_TYPE).orEmpty()
viewModel.fetchScreenData(orderId, dataSource, extraParams, sourceType)
}
if (forceRefresh.not() && viewModel.isOrderStatusPolling.orFalse().not())
viewModel.fetchCSATResponse(dataSource, orderId)
@@ -691,9 +692,10 @@ class OrderStatusFragment :
orderId = it.value.orEmpty()
}
}
val sourceType = arguments?.getString(Constant.SOURCE_TYPE).orEmpty()
triggerPreloadIfRequired()
viewModel.onPaymentPollingSuccess()
viewModel.fetchScreenData(orderId, dataSource, extraParams)
viewModel.fetchScreenData(orderId, dataSource, extraParams, sourceType)
viewModel.fetchCSATResponse(dataSource, orderId)
}
}

View File

@@ -52,6 +52,7 @@ import com.navi.amc.utils.Constant.OTP_FLOW_TYPE_RETRY_PAYMENT
import com.navi.amc.utils.Constant.OTP_FLOW_TYPE_SIP_AUTOPAY
import com.navi.amc.utils.Constant.OTP_FLOW_TYPE_SIP_MANUAL
import com.navi.amc.utils.Constant.OTP_FLOW_TYPE_SIP_PURCHASE
import com.navi.amc.utils.Constant.PAYMENT
import com.navi.amc.utils.Constant.REDEMPTION_ORDER_ID
import com.navi.amc.utils.Constant.REQUEST_CONFIG
import com.navi.amc.utils.Constant.SECONDS_PER_MINUTE
@@ -59,6 +60,7 @@ import com.navi.amc.utils.Constant.SIP_AUTOPAY_PRESENT
import com.navi.amc.utils.Constant.SIP_DATE
import com.navi.amc.utils.Constant.SIP_REFERENCE_ID
import com.navi.amc.utils.Constant.SOURCE_REF_ID
import com.navi.amc.utils.Constant.SOURCE_TYPE
import com.navi.amc.utils.Constant.TRANSACTION_ID
import com.navi.amc.utils.TempStorageHelper
import com.navi.amc.utils.bundleToMap
@@ -259,6 +261,7 @@ class OtpFragment : AmcBaseFragment(), View.OnClickListener {
val bundle =
Bundle().apply {
putAll(arguments)
putString(SOURCE_TYPE, PAYMENT)
putString(
TRANSACTION_ID,
viewModel.paymentInitiateData.value?.tokenDetails?.transactionId
@@ -340,6 +343,7 @@ class OtpFragment : AmcBaseFragment(), View.OnClickListener {
val bundle =
Bundle().apply {
putAll(arguments)
putString(SOURCE_TYPE, PAYMENT)
putString(
TRANSACTION_ID,
viewModel.paymentInitiateData.value?.tokenDetails?.transactionId

View File

@@ -23,10 +23,11 @@ constructor(
suspend fun fetchOrderStatusData(
orderId: String,
dataSource: String,
extraParams: Map<String, String>
extraParams: Map<String, String>,
sourceType: String
) =
apiResponseCallback(
retrofitService.fetchOrderStatusDetails(orderId, dataSource, extraParams)
retrofitService.fetchOrderStatusDetails(orderId, dataSource, extraParams, sourceType)
)
suspend fun checkApiPollStatus(requestId: String) =

View File

@@ -116,10 +116,20 @@ constructor(
_orderStatusScreenData.value = getOrderPollingTimeOutScreenData()
}
fun fetchScreenData(orderId: String, dataSource: String, extraParams: Map<String, String>?) {
fun fetchScreenData(
orderId: String,
dataSource: String,
extraParams: Map<String, String>?,
sourceType: String
) {
viewModelScope.launch {
val response =
repository.fetchOrderStatusData(orderId, dataSource, extraParams.orEmpty())
repository.fetchOrderStatusData(
orderId,
dataSource,
extraParams.orEmpty(),
sourceType
)
if (response.error == null && response.errors.isNullOrEmpty()) {
_orderStatusScreenData.value = response.data
triggerInitEvent()

View File

@@ -41,6 +41,7 @@ import com.navi.amc.utils.Constant.AUTOPAY_CHECKED
import com.navi.amc.utils.Constant.DISMISS
import com.navi.amc.utils.Constant.FREQUENCY
import com.navi.amc.utils.Constant.INVESTMENT_TYPE
import com.navi.amc.utils.Constant.ORDER_AMOUNT
import com.navi.amc.utils.Constant.SIP_DATE
import com.navi.amc.utils.SubPageStatusType
import com.navi.amc.utils.TempStorageHelper
@@ -131,7 +132,8 @@ class FundBuyingFragmentV2 : AmcBaseFragment(), WidgetCallback {
private fun fetchScreenData() {
showLoader()
isin?.let { viewModel.getFundBuyScreenData(it, confinedInvestmentType) }
val orderAmount = arguments?.getString(ORDER_AMOUNT)
isin?.let { viewModel.getFundBuyScreenData(it, confinedInvestmentType, orderAmount) }
}
private fun initUI(isLeftOptionSip: Boolean, userSelectedSipChoice: Boolean?) {

View File

@@ -21,14 +21,15 @@ class FundBuyRepository @Inject constructor(private val retrofitService: Retrofi
suspend fun getFundBuyDetail(
isin: String,
investmentType: String? = null
investmentType: String? = null,
orderAmount: String? = null
): RepoResult<FundBuyScreenData> {
val response =
when (investmentType) {
AmcAnalytics.SIP -> retrofitService.fetchFundSipBuyDetails(isin)
AmcAnalytics.LUMPSUMP -> retrofitService.fetchFundLumpsumBuyDetails(isin)
else -> retrofitService.fetchFundBuyDetails(isin)
else -> retrofitService.fetchFundBuyDetails(isin, orderAmount)
}
return apiResponseCallback(response)

View File

@@ -78,9 +78,13 @@ class FundBuyV2ViewModel @Inject constructor(private val repository: FundBuyRepo
private val gson by lazy { Gson() }
fun getFundBuyScreenData(isin: String, confinedInvestmentType: String? = null) {
fun getFundBuyScreenData(
isin: String,
confinedInvestmentType: String? = null,
orderAmount: String? = null
) {
viewModelScope.launch {
val response = repository.getFundBuyDetail(isin, confinedInvestmentType)
val response = repository.getFundBuyDetail(isin, confinedInvestmentType, orderAmount)
if (response.error == null && response.errors.isNullOrEmpty()) {
_fundBuyScreenData.value = response.data
} else {

View File

@@ -1,6 +1,6 @@
/*
*
* * Copyright © 2023 by Navi Technologies Limited
* * Copyright © 2023-2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
@@ -36,7 +36,7 @@ data class BankDetailsContent(
@Parcelize
data class Note(
@SerializedName("bgColor") val bgColor: String? = null,
@SerializedName("iconCode") val iconCode: String? = null,
@SerializedName("iconCode", alternate = ["icon"]) val iconCode: String? = null,
@SerializedName("title") val title: TextWithStyle? = null,
@SerializedName("toShowShimmer") val toShowShimmer: Boolean? = null
) : Parcelable

View File

@@ -280,7 +280,8 @@ interface RetrofitService {
suspend fun fetchOrderStatusDetails(
@Path("orderId") orderId: String,
@Query("dataSource") dataSource: String,
@QueryMap extraParams: Map<String, String>
@QueryMap extraParams: Map<String, String>,
@Query("sourceType") sourceType: String
): Response<GenericResponse<OrderStatusScreenData>>
@GET("/fund/redeem-start-page")
@@ -360,7 +361,8 @@ interface RetrofitService {
@GET("/fund/purchase-start-page")
suspend fun fetchFundBuyDetails(
@Query("isin") isin: String
@Query("isin") isin: String,
@Query("orderAmount") orderAmount: String? = null
): Response<GenericResponse<FundBuyScreenData>>
@GET("/fund/lumpsum-purchase-start-page")

View File

@@ -196,16 +196,23 @@ class PortfolioFragment() : AmcBaseFragment() {
topRight.subItem = it
View.VISIBLE
} ?: run { View.INVISIBLE }
bottomLeft.root.visibility =
data.bottomLeft?.let {
bottomLeft.subItem = it
View.VISIBLE
} ?: run { View.INVISIBLE }
bottomRight.root.visibility =
data.bottomRight?.let {
bottomRight.subItem = it
View.VISIBLE
} ?: run { View.INVISIBLE }
data.actionData?.primaryAction?.let { action ->
primaryBtn.visibility = View.VISIBLE
primaryBtn.isEnabled = action.disabled.orFalse().not()
primaryBtn.text = action.title
primaryBtn.setOnClickListener { navigate(action) }
} ?: run { primaryBtn.visibility = View.GONE }
data.actionData?.secondaryAction?.let { action ->
secondaryBtn.visibility = View.VISIBLE
secondaryBtn.isEnabled = !action.disabled.orFalse().not()
secondaryBtn.text = action.title
secondaryBtn.setOnClickListener { navigate(action) }
} ?: run { secondaryBtn.visibility = View.GONE }
data.noteBanner?.let {
note.root.visibility = View.VISIBLE
note.title.setSpannableString(it.title)
note.icon.showWhenDataIsAvailable(it.iconCode)
} ?: run { note.root.visibility = View.GONE }
root.setOnClickListener {
val bundle =
Bundle().apply {

View File

@@ -9,6 +9,7 @@ package com.navi.amc.portfolio.models
import com.google.gson.annotations.SerializedName
import com.navi.amc.fundbuy.models.SubItemData
import com.navi.amc.kyc.model.Note
import com.navi.base.model.ActionData
import com.navi.common.model.LabelData
import com.navi.common.model.common.CacheConfig
@@ -65,9 +66,11 @@ data class OverviewCardData(
@SerializedName("bottomLeft") val bottomLeft: SubItemData? = null,
@SerializedName("bottomRight") val bottomRight: SubItemData? = null,
@SerializedName("action") val action: ActionData? = null,
@SerializedName("actionData") val actionData: ActionData? = null,
@SerializedName("cardAction") val cardAction: ActionData? = null,
@SerializedName("label") val label: LabelData? = null,
@SerializedName("metadata") val metaData: OverViewCardMetaData? = null
@SerializedName("metadata") val metaData: OverViewCardMetaData? = null,
@SerializedName("noteBanner") val noteBanner: Note? = null
) : CardType()
data class OverViewCardMetaData(

View File

@@ -190,6 +190,8 @@ object Constant {
const val PAYMENT_TIMESTAMP = "paymentTimeStamp"
const val FUND_ID = "fundId"
const val RUPEE_SYMBOL = ""
const val SOURCE_TYPE = "sourceType"
const val ORDER_AMOUNT = "orderAmount"
const val UPI_INTENT = "upi://pay"
const val NAVI = "navi"
}

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/gray_rounded_background"
xmlns:tools="http://schemas.android.com/tools"
android:paddingStart="@dimen/dp_16"
android:paddingTop="@dimen/dp_4"
android:paddingEnd="@dimen/dp_16"
android:paddingBottom="@dimen/dp_4">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="@dimen/dp_12"
android:layout_height="@dimen/dp_12"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.navi.design.textview.NaviTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
tools:text="Investments"
android:layout_marginStart="@dimen/dp_8"
app:layout_constraintStart_toEndOf="@id/icon" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -15,8 +15,7 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_border_grey_rounded_4"
android:paddingBottom="@dimen/dp_16">
android:background="@drawable/bg_border_grey_rounded_4">
<com.navi.design.textview.NaviTextView
android:id="@+id/title"
@@ -50,42 +49,28 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_16"
android:layout_marginTop="@dimen/dp_16"
android:layout_marginBottom="@dimen/dp_16"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.576" />
<include
android:id="@+id/bottom_left"
layout="@layout/title_subtitle_layout"
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_16"
android:layout_marginTop="@dimen/dp_16"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_left" />
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<include
android:id="@+id/top_right"
layout="@layout/title_subtitle_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dp_16"
app:layout_constraintBottom_toTopOf="@id/primary_btn"
app:layout_constraintStart_toEndOf="@id/guideline"
app:layout_constraintTop_toTopOf="@id/top_left" />
<include
android:id="@+id/bottom_right"
layout="@layout/title_subtitle_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@id/guideline"
app:layout_constraintTop_toTopOf="@id/bottom_left" />
<com.navi.design.textview.NaviTextView
android:id="@+id/label"
android:layout_width="wrap_content"
@@ -100,20 +85,53 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.navi.design.textview.NaviTextView
android:id="@+id/action_btn"
style="@style/ActionButtonTextStyle"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_40"
<Button
android:id="@+id/secondary_btn"
style="@style/TextV8Style"
android:layout_width="@dimen/dp_0"
android:layout_height="@dimen/dp_32"
android:layout_marginStart="@dimen/dp_16"
android:layout_marginTop="@dimen/dp_16"
android:layout_marginEnd="@dimen/dp_16"
android:background="@drawable/purple_border_bg_rounded_4"
android:fontFamily="@font/tt_semi_bold"
android:gravity="center"
android:textAllCaps="false"
android:visibility="gone"
app:layout_constraintEnd_toStartOf="@id/guideline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_right"
app:layout_goneMarginBottom="@dimen/dp_16" />
<Button
android:id="@+id/primary_btn"
style="@style/ActionButtonTextStyle"
android:layout_width="@dimen/dp_0"
android:layout_height="@dimen/dp_32"
android:layout_marginEnd="@dimen/dp_16"
android:layout_marginBottom="@dimen/dp_16"
android:background="@drawable/primary_button_background"
android:fontFamily="@font/tt_semi_bold"
android:gravity="center"
android:textAllCaps="false"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/note"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/guideline"
app:layout_constraintTop_toBottomOf="@id/top_right"
app:layout_goneMarginBottom="@dimen/dp_16" />
<include
android:id="@+id/note"
layout="@layout/icon_title_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/bottom_left" />
app:layout_constraintTop_toBottomOf="@id/primary_btn"
app:layout_goneMarginBottom="@dimen/dp_16" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</layout>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<corners
android:bottomLeftRadius="4dp"
android:bottomRightRadius="4dp" />
<solid android:color="#F5F5F5" />
</shape>
</item>
<item android:top="-1dp">
<shape>
<stroke
android:width="1dp"
android:color="@color/border_dark_grey_color" />
<solid android:color="#F5F5F5" />
<corners
android:bottomLeftRadius="4dp"
android:bottomRightRadius="4dp" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="0dp" />
</shape>
</item>
</layer-list>