[PS] Feature invest before kyc (#5447)
* [PS] kyc after payment * [PS] fix bottom sheet issue on order status page * [PS] fix design changes * [PS] added kyc after payments events * [PS] fix design issues * [PS] resolved comments * [PS] resolved comments
This commit is contained in:
committed by
GitHub Enterprise
parent
f6e5331370
commit
7ff3f5e60f
@@ -138,6 +138,22 @@ class CheckerActivity : BasePaymentActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
viewModel.kycRedirectCta.observe(this) {
|
||||
val bundle = intent?.extras ?: Bundle()
|
||||
if(it?.url.isNotNullAndNotEmpty()) {
|
||||
it?.toNavigateAmcModule(activity = this, finish = true, bundle = bundle)
|
||||
} else {
|
||||
val response = viewModel.asyncResponse.value
|
||||
response?.data?.data?.statusData?.let {
|
||||
bundle.putParcelable(DATA, it)
|
||||
bundle.putString(TYPE, type)
|
||||
}
|
||||
response?.data
|
||||
?.data
|
||||
?.nextCTA
|
||||
?.toNavigateAmcModule(activity = this, finish = true, bundle = bundle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSpanClick(actionData: ActionData?) {
|
||||
@@ -207,6 +223,8 @@ class CheckerActivity : BasePaymentActivity() {
|
||||
recurring = "1",
|
||||
)
|
||||
)
|
||||
} else if(needRedirection(response.data?.data?.nextCTA)) {
|
||||
viewModel.fetchKycRedirectCta()
|
||||
} else if (response.data?.data?.nextCTA?.url.isNullOrEmpty().not()) {
|
||||
val bundle = intent?.extras ?: Bundle()
|
||||
response.data?.data?.statusData?.let {
|
||||
@@ -364,6 +382,10 @@ class CheckerActivity : BasePaymentActivity() {
|
||||
)
|
||||
}
|
||||
|
||||
private fun needRedirection(actionData: ActionData?): Boolean {
|
||||
return type == PENNY_DROP && actionData?.url.equals(REDIRECT_CTA)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_RETRY_COUNT = 10
|
||||
const val INITIATE_KYC = "INITIATE_KYC"
|
||||
@@ -378,6 +400,7 @@ class CheckerActivity : BasePaymentActivity() {
|
||||
const val AUTO_PAY_PAYMENT_CALLBACK = "autopay_payment_callback"
|
||||
const val PENNY_DROP = "PENNY_DROP"
|
||||
const val ERROR_DATA = "ERROR_DATA"
|
||||
const val REDIRECT_CTA = "REDIRECT_CTA"
|
||||
const val DATA = "DATA"
|
||||
const val TYPE = "TYPE"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
package com.navi.amc.common.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewStub
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.databinding.DataBindingUtil
|
||||
@@ -16,6 +15,7 @@ import com.google.gson.Gson
|
||||
import com.navi.amc.R
|
||||
import com.navi.amc.common.model.AmcCommonBottomSheetData
|
||||
import com.navi.amc.databinding.AmcCommonBottomsheetBinding
|
||||
import com.navi.amc.utils.AmcAnalytics
|
||||
import com.navi.amc.utils.Constant.DATA
|
||||
import com.navi.amc.utils.SubPageStatusType
|
||||
import com.navi.base.model.ActionData
|
||||
@@ -59,6 +59,7 @@ class AmcCommonBottomSheet : BaseBottomSheet() {
|
||||
safelyDismissDialog()
|
||||
}
|
||||
}
|
||||
AmcAnalytics.sendEvent(eventsData = response.metaData?.viewedData, screenName = screenName)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,33 +8,39 @@ import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.navi.amc.R
|
||||
import com.navi.amc.common.activity.CheckerActivity
|
||||
import com.navi.amc.common.listener.BackListener
|
||||
import com.navi.amc.common.listener.FooterInteractionListener
|
||||
import com.navi.amc.common.model.AmcCommonBottomSheetData
|
||||
import com.navi.amc.common.viewmodel.OrderStatusViewModel
|
||||
import com.navi.amc.databinding.OrderStatusLayoutBinding
|
||||
import com.navi.amc.utils.*
|
||||
import com.navi.amc.fundbuy.models.PaymentOrder
|
||||
import com.navi.amc.utils.AmcAnalytics.ORDER_STATUS_SCREEN
|
||||
import com.navi.amc.utils.Constant
|
||||
import com.navi.amc.utils.Constant.DATA
|
||||
import com.navi.amc.utils.Constant.INIT_REFUND
|
||||
import com.navi.amc.utils.Constant.ORDER_ID
|
||||
import com.navi.amc.utils.TempStorageHelper
|
||||
import com.navi.amc.utils.orFalse
|
||||
import com.navi.amc.utils.orValue
|
||||
import com.navi.base.model.ActionData
|
||||
import com.navi.common.firebasedb.FirebaseStatusType
|
||||
import com.navi.common.listeners.FragmentInterchangeListener
|
||||
import com.navi.common.listeners.HeaderInteractionListener
|
||||
import com.navi.common.model.UploadDataAsyncResponse
|
||||
import com.navi.common.utils.ApiPollScheduler
|
||||
import com.navi.common.utils.isNull
|
||||
import com.navi.common.utils.orFalse
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class OrderStatusFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
class OrderStatusFragment : AmcBaseFragment(), FooterInteractionListener, BackListener {
|
||||
private lateinit var binding: OrderStatusLayoutBinding
|
||||
private val viewModel by viewModels<OrderStatusViewModel>()
|
||||
private var apiPollScheduler: ApiPollScheduler? = null
|
||||
override val screenName: String
|
||||
get() = ORDER_STATUS_SCREEN
|
||||
private var isBackAllowed: Boolean = true
|
||||
private var learnMoreBottomSheetData: AmcCommonBottomSheetData? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@@ -100,7 +106,17 @@ class OrderStatusFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
onFooterBackPress(it.backCta)
|
||||
}
|
||||
} != null
|
||||
it.content?.learnMoreNote?.let { note ->
|
||||
binding.learnMoreNoteData = note
|
||||
learnMoreNote.action.setOnClickListener { view ->
|
||||
handleOnClick(note.actionText?.action)
|
||||
}
|
||||
learnMoreNote.icon.setOnClickListener { view ->
|
||||
handleOnClick(note.actionText?.action)
|
||||
}
|
||||
}
|
||||
}
|
||||
isBackAllowed = it.content?.exitBottomSheetData.isNull()
|
||||
}
|
||||
}
|
||||
viewModel.createOrderResponse.observe(viewLifecycleOwner) {
|
||||
@@ -120,6 +136,14 @@ class OrderStatusFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.refundStatus.observe(viewLifecycleOwner) {
|
||||
if(it?.success.orFalse()) {
|
||||
fetchData()
|
||||
} else {
|
||||
hideLoader()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onPollingResponse(response: UploadDataAsyncResponse?) {
|
||||
@@ -209,6 +233,67 @@ class OrderStatusFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun handleOnClick(action: ActionData?) {
|
||||
sendEvent(
|
||||
action?.metaData?.clickedData,
|
||||
)
|
||||
val url = action?.url
|
||||
if(url == Constant.SHOW_BOTTOMSHEET) {
|
||||
val data = action.parameters?.getOrNull(0)?.value
|
||||
val key = action.parameters?.getOrNull(0)?.key
|
||||
val bundle = Bundle().apply {
|
||||
putString(Constant.DATA, data)
|
||||
}
|
||||
learnMoreBottomSheetData = Gson().fromJson(data, AmcCommonBottomSheetData::class.java)
|
||||
key?.let {
|
||||
getBottomSheet(it, bundle, genericListener = ::actionListener)?.let {
|
||||
safelyShowBottomSheet(it, key)
|
||||
}
|
||||
}
|
||||
} else if (url == INIT_REFUND) {
|
||||
initiateRefund(action)
|
||||
} else {
|
||||
fragmentInterchangeListener?.navigateToNextScreen(actionData = action)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed(actionData: ActionData?): Boolean {
|
||||
return showExitBottomSheetIfAvailable()
|
||||
}
|
||||
|
||||
override fun onTopPressed(actionData: ActionData?): Boolean {
|
||||
return showExitBottomSheetIfAvailable()
|
||||
}
|
||||
|
||||
private fun showExitBottomSheetIfAvailable(): Boolean {
|
||||
if(!isBackAllowed) {
|
||||
viewModel.orderStatusScreenData.value?.content?.exitBottomSheetData?.let {
|
||||
isBackAllowed = true
|
||||
val bundle = Bundle()
|
||||
bundle.putString(DATA, Gson().toJson(it))
|
||||
getBottomSheet(SubPageStatusType.AMC_COMMON_BOTTOMSHEET, bundle, genericListener = ::actionListener)?.let {
|
||||
safelyShowBottomSheet(it, SubPageStatusType.AMC_COMMON_BOTTOMSHEET)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
isBackAllowed = true
|
||||
return false
|
||||
}
|
||||
|
||||
private fun initiateRefund(action: ActionData?) {
|
||||
val key = action?.parameters?.firstOrNull()?.key
|
||||
val value = action?.parameters?.firstOrNull()?.value
|
||||
if(key == ORDER_ID) {
|
||||
showLoader()
|
||||
viewModel.refundOrder(value.orEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
private fun actionListener(action : ActionData) {
|
||||
handleOnClick(action)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(bundle: Bundle): OrderStatusFragment {
|
||||
return OrderStatusFragment().apply {
|
||||
|
||||
@@ -7,10 +7,14 @@
|
||||
|
||||
package com.navi.amc.common.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.navi.base.model.ActionData
|
||||
import com.navi.base.model.GenericAnalytics
|
||||
import com.navi.design.textview.model.TextWithStyle
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class AmcCommonBottomSheetData(
|
||||
@SerializedName("title")
|
||||
val title: TextWithStyle? = null,
|
||||
@@ -19,5 +23,7 @@ data class AmcCommonBottomSheetData(
|
||||
@SerializedName("iconCode")
|
||||
val iconCode: String? = null,
|
||||
@SerializedName("action", alternate = ["actionData"])
|
||||
val actionData: ActionData? = null
|
||||
)
|
||||
val actionData: ActionData? = null,
|
||||
@SerializedName("metaData")
|
||||
val metaData: GenericAnalytics? = null,
|
||||
): Parcelable
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.navi.amc.fundbuy.models.SubItemData
|
||||
import com.navi.base.model.ActionData
|
||||
import com.navi.common.model.Header
|
||||
import com.navi.common.model.LabelData
|
||||
import com.navi.design.textview.model.NaviSpan
|
||||
import com.navi.design.textview.model.TextWithStyle
|
||||
import com.navi.naviwidgets.models.response.NoteWidget
|
||||
|
||||
data class OrderStatusScreenData(
|
||||
@@ -26,6 +28,10 @@ data class OrderStatusContent(
|
||||
val orderStatus : StatusTimeLineData ?= null ,
|
||||
@SerializedName("statusNote")
|
||||
val statusNote : InformationCardData ?= null,
|
||||
@SerializedName("learnMoreNote")
|
||||
val learnMoreNote : InformationCardData ?= null,
|
||||
@SerializedName("exitBottomSheetData")
|
||||
val exitBottomSheetData : AmcCommonBottomSheetData ?= null,
|
||||
@SerializedName("note")
|
||||
val note : NoteWidget ?= null,
|
||||
@SerializedName("actionData")
|
||||
@@ -44,3 +50,11 @@ data class OrderDetailsData(
|
||||
@SerializedName("label")
|
||||
val label : LabelData?= null
|
||||
)
|
||||
|
||||
data class TimerInfo(
|
||||
@SerializedName("bgColor") val bgColor: String? = null,
|
||||
@SerializedName("title") val title: TextWithStyle? = null,
|
||||
@SerializedName("timeLeft") val timeLeft: Long? = null,
|
||||
@SerializedName("timerSpan") val timerSpan: List<NaviSpan>? = null,
|
||||
@SerializedName("enableShimmer") val enableShimmer: Boolean? = null,
|
||||
)
|
||||
@@ -9,7 +9,9 @@ class StatusTimeLineData(
|
||||
@SerializedName("rightTitle")
|
||||
val rightTitle: TextWithStyle? = null,
|
||||
@SerializedName("items")
|
||||
val items: List<StatusData>? = null
|
||||
val items: List<StatusData>? = null,
|
||||
@SerializedName("footerTimerInfo")
|
||||
val footerTimerInfo : TimerInfo? = null,
|
||||
)
|
||||
|
||||
data class StatusData(
|
||||
|
||||
@@ -53,6 +53,9 @@ class CheckerRepository @Inject constructor(private val retrofitService: Retrofi
|
||||
suspend fun checkPennyDropPollStatus(requestId: String) =
|
||||
apiResponseCallback(retrofitService.fetchPennyDropAsyncRequestData(requestId))
|
||||
|
||||
suspend fun fetchKycRedirectCta(params: Map<String, String>) =
|
||||
apiResponseCallback(retrofitService.fetchKycRedirectCta(params))
|
||||
|
||||
suspend fun checkPLDisbursedJourneyStatus(requestId: String) =
|
||||
apiResponseCallback(retrofitService.fetchPLJourneyStatusAsyncRequestData(requestId))
|
||||
|
||||
|
||||
@@ -21,4 +21,7 @@ class OrderStatusRepository @Inject constructor(private val retrofitService: Ret
|
||||
|
||||
suspend fun postSameOrderPayment(details: PaymentOrder) =
|
||||
apiResponseCallback(retrofitService.postSameOrderPayment(details))
|
||||
|
||||
suspend fun refundOrder(orderId: String) =
|
||||
apiResponseCallback(retrofitService.refundOrder(orderId))
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.navi.amc.common.view
|
||||
|
||||
import android.content.Context
|
||||
import android.os.CountDownTimer
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
@@ -11,10 +11,19 @@ import androidx.core.view.isVisible
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import com.navi.amc.R
|
||||
import com.navi.amc.common.model.StatusTimeLineData
|
||||
import com.navi.amc.common.model.TimerInfo
|
||||
import com.navi.amc.databinding.StatusRowBinding
|
||||
import com.navi.amc.databinding.StatusTimelineLayoutBinding
|
||||
import com.navi.amc.utils.Constant.THOUSAND
|
||||
import com.navi.amc.utils.DateUtils
|
||||
import com.navi.common.utils.SPACE
|
||||
import com.navi.design.textview.model.SpanInterface
|
||||
import com.navi.design.utils.moveViewWithDistance
|
||||
import com.navi.design.utils.parseColorSafe
|
||||
import com.navi.design.utils.setSpannableString
|
||||
import com.navi.design.utils.spannedText
|
||||
import com.navi.naviwidgets.extensions.showWhenDataIsAvailable
|
||||
import com.navi.naviwidgets.utils.REWARDS_TOOLTIP_ANIMATION_DELAY
|
||||
|
||||
class StatusTimeLineView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
ConstraintLayout(context, attributeSet) {
|
||||
@@ -47,7 +56,49 @@ class StatusTimeLineView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
childBinding.root.layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT)
|
||||
binding.container.addView(childBinding.root)
|
||||
}
|
||||
setFooter(data.footerTimerInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setFooter(data: TimerInfo?) {
|
||||
data?.let {
|
||||
binding.footerTv.isVisible = true
|
||||
val difference = it.timeLeft ?: 0
|
||||
val timer = object : CountDownTimer(difference, THOUSAND) {
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
val timerText = DateUtils.instance.formatSecondsInDaysTimer(millisUntilFinished / 1000)
|
||||
val spanList: MutableList<SpanInterface> = mutableListOf()
|
||||
it.title?.style?.forEach {
|
||||
spanList.add(it)
|
||||
}
|
||||
it.timerSpan?.forEach {
|
||||
spanList.add(it)
|
||||
}
|
||||
val heading = it.title?.text.plus(SPACE).plus(timerText)
|
||||
binding.footerTv.text = heading.spannedText(context, spanList)
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
}
|
||||
}
|
||||
timer.start()
|
||||
binding.footerTv.setBackgroundColor(it.bgColor.parseColorSafe())
|
||||
if (it.enableShimmer == true) {
|
||||
binding.pgvShimmer.isVisible = true
|
||||
binding.root.post {
|
||||
moveViewWithDistance(
|
||||
binding.pgvShimmer,
|
||||
binding.footerTv.width,
|
||||
REWARDS_TOOLTIP_ANIMATION_DELAY
|
||||
)
|
||||
}
|
||||
} else {
|
||||
binding.pgvShimmer.isVisible = false
|
||||
}
|
||||
} ?: kotlin.run {
|
||||
binding.pgvShimmer.isVisible = false
|
||||
binding.footerTv.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ import com.navi.amc.common.model.CheckerResponse
|
||||
import com.navi.amc.common.model.NextCtaResponse
|
||||
import com.navi.amc.common.model.PostPaymentData
|
||||
import com.navi.amc.common.repo.CheckerRepository
|
||||
import com.navi.amc.utils.TempStorageHelper
|
||||
import com.navi.base.model.ActionData
|
||||
import com.navi.common.network.models.RepoResult
|
||||
import com.navi.common.network.models.SuccessResponse
|
||||
import com.navi.common.viewmodel.BaseVM
|
||||
@@ -37,6 +39,10 @@ class CheckerVM @Inject constructor(private val repository: CheckerRepository) :
|
||||
val postPaymentResponse: LiveData<RepoResult<SuccessResponse>>
|
||||
get() = _postPaymentResponse
|
||||
|
||||
private val _kycRedirectCta = MutableLiveData<ActionData?>()
|
||||
val kycRedirectCta: LiveData<ActionData?>
|
||||
get() = _kycRedirectCta
|
||||
|
||||
fun setInitData(data: CheckerResponse?) {
|
||||
_dataResponse.value = data
|
||||
}
|
||||
@@ -104,4 +110,14 @@ class CheckerVM @Inject constructor(private val repository: CheckerRepository) :
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun fetchKycRedirectCta() {
|
||||
coroutineScope.launch {
|
||||
val response = repository.fetchKycRedirectCta(TempStorageHelper.kycSourceInfo.orEmpty())
|
||||
if (response.error == null && response.errors.isNullOrEmpty()) {
|
||||
_kycRedirectCta.value = response.data
|
||||
TempStorageHelper.kycSourceInfo = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ import com.navi.amc.common.repo.OrderStatusRepository
|
||||
import com.navi.amc.fundbuy.models.PaymentOrder
|
||||
import com.navi.amc.utils.AmcAnalytics
|
||||
import com.navi.common.model.UploadDataAsyncResponse
|
||||
import com.navi.common.network.models.GenericResponse
|
||||
import com.navi.common.network.models.SuccessResponse
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
@@ -34,6 +36,10 @@ class OrderStatusViewModel @Inject constructor(private val repository: OrderStat
|
||||
val paymentInitiateData: LiveData<CheckerResponse?>
|
||||
get() = _paymentInitiateData
|
||||
|
||||
private val _refundStatus = MutableLiveData<SuccessResponse?>()
|
||||
val refundStatus: LiveData<SuccessResponse?>
|
||||
get() = _refundStatus
|
||||
|
||||
private var isInitEventTriggered = false
|
||||
|
||||
fun fetchScreenData(orderId: String, dataSource: String) {
|
||||
@@ -91,6 +97,17 @@ class OrderStatusViewModel @Inject constructor(private val repository: OrderStat
|
||||
}
|
||||
}
|
||||
|
||||
fun refundOrder(orderId: String) {
|
||||
viewModelScope.launch {
|
||||
val response = repository.refundOrder(orderId)
|
||||
if(response.error == null && response.errors.isNullOrEmpty()){
|
||||
_refundStatus.value = response.data
|
||||
} else {
|
||||
setErrorData(response.errors, response.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateData(data: AdditionalDataAsyncResponse<NextCtaResponse>?): CheckerResponse? {
|
||||
data?.data?.checkerData?.content?.asyncData = data
|
||||
return data?.data?.checkerData
|
||||
|
||||
@@ -44,7 +44,14 @@ class FundBuyActivity : AmcBaseActivity(), FragmentInterchangeListener, HeaderIn
|
||||
|
||||
override fun onBackPressed() {
|
||||
val cta = binding.headerView.getHeaderData()?.backCta
|
||||
navigateToNextScreen(cta, Bundle())
|
||||
val currentFragment = supportFragmentManager.findFragmentById(R.id.container)
|
||||
if (currentFragment is BackListener) {
|
||||
if ((currentFragment as BackListener).onTopPressed(cta).not()) {
|
||||
navigateToNextScreen(cta)
|
||||
}
|
||||
} else {
|
||||
navigateToNextScreen(cta)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
@@ -369,6 +369,11 @@ interface RetrofitService {
|
||||
@Body data: PaymentOrder
|
||||
): Response<GenericResponse<AdditionalDataAsyncResponse<NextCtaResponse>>>
|
||||
|
||||
@POST("/orders/refund-order/{orderId}")
|
||||
suspend fun refundOrder(
|
||||
@Path("orderId") orderId: String
|
||||
): Response<GenericResponse<SuccessResponse>>
|
||||
|
||||
@GET("/fund/fund-details-nfo")
|
||||
suspend fun fetchNfoDetails(@Query("isin") isin: String): Response<GenericResponse<NfoDetailsScreenData>>
|
||||
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
package com.navi.amc.portfolio.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Bundle
|
||||
import android.os.CountDownTimer
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -17,8 +19,11 @@ import androidx.core.view.isVisible
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import com.google.gson.Gson
|
||||
import com.navi.amc.R
|
||||
import com.navi.amc.common.fragment.AmcBaseFragment
|
||||
import com.navi.amc.common.model.AmcCommonBottomSheetData
|
||||
import com.navi.amc.common.model.TimerInfo
|
||||
import com.navi.amc.databinding.OrdersLayoutBinding
|
||||
import com.navi.amc.fundbuy.fragments.SelectOptionBottomSheet
|
||||
import com.navi.amc.fundbuy.models.ChipData
|
||||
@@ -26,22 +31,25 @@ import com.navi.amc.fundbuy.models.Identifier
|
||||
import com.navi.amc.fundbuy.models.SelectOptionsBottomSheetData
|
||||
import com.navi.amc.portfolio.adapters.OrdersAdapter
|
||||
import com.navi.amc.portfolio.models.IndividualOrderDetail
|
||||
import com.navi.amc.portfolio.models.OrderSummaryCard
|
||||
import com.navi.amc.portfolio.viewmodels.OrdersViewModel
|
||||
import com.navi.amc.utils.AmcAnalytics
|
||||
import com.navi.amc.utils.*
|
||||
import com.navi.amc.utils.AmcAnalytics.AMC_BTN_INVESTMENTS_INVEST_NOW
|
||||
import com.navi.amc.utils.ColorUtils
|
||||
import com.navi.amc.utils.Constant.DATA_SOURCE
|
||||
import com.navi.amc.utils.Constant.ORDER_ID
|
||||
import com.navi.amc.utils.Constant.RED
|
||||
import com.navi.amc.utils.Constant.THOUSAND
|
||||
import com.navi.base.model.ActionData
|
||||
import com.navi.common.listeners.FragmentInterchangeListener
|
||||
import com.navi.common.listeners.HeaderInteractionListener
|
||||
import com.navi.common.utils.orFalse
|
||||
import com.navi.design.font.FontWeightEnum
|
||||
import com.navi.design.textview.model.NaviSpan
|
||||
import com.navi.design.textview.model.SpanInterface
|
||||
import com.navi.design.textview.model.TextWithStyle
|
||||
import com.navi.design.utils.GradientOrientation
|
||||
import com.navi.design.utils.parseColorSafe
|
||||
import com.navi.design.utils.setSpannableString
|
||||
import com.navi.design.utils.*
|
||||
import com.navi.naviwidgets.utils.NaviWidgetIconUtils
|
||||
import com.navi.naviwidgets.utils.REWARDS_TOOLTIP_ANIMATION_DELAY
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -51,6 +59,7 @@ class OrdersFragment : AmcBaseFragment() {
|
||||
private val viewModel by viewModels<OrdersViewModel>()
|
||||
override val screenName: String
|
||||
get() = AmcAnalytics.ORDER_INIT_MY_INVESTMENT
|
||||
private var learnMoreBottomSheetData: AmcCommonBottomSheetData? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@@ -79,12 +88,13 @@ class OrdersFragment : AmcBaseFragment() {
|
||||
viewModel.orderDetails.observe(viewLifecycleOwner) {
|
||||
hideLoader()
|
||||
it?.let {
|
||||
binding.orderValue = it.orderSummary
|
||||
val orderSummary = it.orderSummary
|
||||
binding.orderValue = orderSummary
|
||||
binding.orderTitle.setSpannableString(it.orderTitle)
|
||||
val gradientColor =
|
||||
intArrayOf(
|
||||
it.orderSummary?.gradient?.startGradientColor.parseColorSafe(),
|
||||
it.orderSummary?.gradient?.endGradientColor.parseColorSafe()
|
||||
orderSummary?.gradient?.startGradientColor.parseColorSafe(),
|
||||
orderSummary?.gradient?.endGradientColor.parseColorSafe()
|
||||
)
|
||||
binding.orderView.root.background =
|
||||
ColorUtils.getGradientBackgroundGreyBorderDrawable(
|
||||
@@ -92,6 +102,7 @@ class OrdersFragment : AmcBaseFragment() {
|
||||
gradientColor,
|
||||
GradientOrientation.TOP_BOTTOM
|
||||
)
|
||||
binding.orderView.root.isVisible = (orderSummary?.totalOrders != null)
|
||||
binding.title.setSpannableString(it?.orderSummary?.title)
|
||||
it.orders?.let { initAdapter(it) }
|
||||
?: run {
|
||||
@@ -106,8 +117,102 @@ class OrdersFragment : AmcBaseFragment() {
|
||||
}
|
||||
}
|
||||
}
|
||||
setOrderSummaryCardProperties(orderSummary?.orderSummaryCard)
|
||||
binding.learnMoreNote.action.setOnClickListener { view ->
|
||||
handleOnClick(orderSummary?.learnMoreNote?.actionText?.action)
|
||||
}
|
||||
binding.learnMoreNote.icon.setOnClickListener { view ->
|
||||
handleOnClick(orderSummary?.learnMoreNote?.actionText?.action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.refundStatus.observe(viewLifecycleOwner) {
|
||||
if(it?.success.orFalse()) {
|
||||
fetchData()
|
||||
} else {
|
||||
hideLoader()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setOrderSummaryCardProperties(orderSummaryCard: OrderSummaryCard?) {
|
||||
orderSummaryCard?.let {
|
||||
binding.orderSummaryCard.root.isVisible = true
|
||||
binding.orderSummaryCard.cardTitle.setSpannableString(it.title)
|
||||
binding.orderSummaryCard.cardSubtitle.setSpannableString(it.subTitle)
|
||||
it.imageMargin?.let { margin ->
|
||||
val lp = binding.orderSummaryCard.cardIcon.layoutParams as? ViewGroup.MarginLayoutParams
|
||||
lp?.bottomMargin = dpToPxInInt(margin.bottomDp.toInt())
|
||||
lp?.marginEnd = dpToPxInInt(margin.endDp.toInt())
|
||||
binding.orderSummaryCard.cardIcon.layoutParams = lp
|
||||
}
|
||||
it.imageDetails?.let { imageDetails ->
|
||||
imageDetails.height?.let { height ->
|
||||
binding.orderSummaryCard.cardIcon.layoutParams.height = dpToPxInInt(height)
|
||||
}
|
||||
imageDetails.width?.let { width ->
|
||||
binding.orderSummaryCard.cardIcon.layoutParams.width = dpToPxInInt(width)
|
||||
}
|
||||
binding.orderSummaryCard.cardIcon.requestLayout()
|
||||
it.iconCode?.let { iconCode ->
|
||||
NaviWidgetIconUtils.updateIcon(iconCode, binding.orderSummaryCard.cardIcon)
|
||||
}
|
||||
} ?: kotlin.run {
|
||||
it.iconCode?.let { iconCode ->
|
||||
NaviWidgetIconUtils.updateIcon(iconCode, binding.orderSummaryCard.cardIcon)
|
||||
}
|
||||
}
|
||||
binding.orderSummaryCard.actionBtn.setProperties(it.actionData, null, it.actionTitle)
|
||||
binding.orderSummaryCard.root.setOnClickListener { view ->
|
||||
sendEvent(it.actionData?.metaData?.clickedData)
|
||||
fragmentInterchangeListener?.navigateToNextScreen(actionData = it.actionData)
|
||||
}
|
||||
binding.orderSummaryCard.summaryCard.setBackgroundColor(it.bgColor.parseColorSafe())
|
||||
setCardTimerProperties(it.timerInfo)
|
||||
} ?: kotlin.run {
|
||||
binding.orderSummaryCard.root.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun setCardTimerProperties(timerInfo: TimerInfo?) {
|
||||
timerInfo?.let {
|
||||
val difference = it.timeLeft ?: 0
|
||||
val timer = object : CountDownTimer(difference, THOUSAND) {
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
val timerText = DateUtils.instance.formatSecondsInDaysTimer(millisUntilFinished / 1000)
|
||||
val spanList: MutableList<SpanInterface> = mutableListOf()
|
||||
it.title?.style?.forEach {
|
||||
spanList.add(it)
|
||||
}
|
||||
it.timerSpan?.forEach {
|
||||
spanList.add(it)
|
||||
}
|
||||
val heading = it.title?.text.plus(" ").plus(timerText)
|
||||
binding.orderSummaryCard.footerTv.text = heading.spannedText(requireContext(), spanList)
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
}
|
||||
}
|
||||
timer.start()
|
||||
binding.orderSummaryCard.footerContainer.setBackgroundColor(it.bgColor.parseColorSafe())
|
||||
if (it.enableShimmer == true) {
|
||||
binding.orderSummaryCard.pgvShimmer.isVisible = true
|
||||
binding.root.post {
|
||||
moveViewWithDistance(
|
||||
binding.orderSummaryCard.pgvShimmer,
|
||||
binding.orderSummaryCard.footerContainer.width,
|
||||
REWARDS_TOOLTIP_ANIMATION_DELAY
|
||||
)
|
||||
}
|
||||
} else {
|
||||
binding.orderSummaryCard.pgvShimmer.isVisible = false
|
||||
}
|
||||
} ?: kotlin.run {
|
||||
binding.orderSummaryCard.pgvShimmer.isVisible = false
|
||||
binding.orderSummaryCard.footerContainer.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun openBottomSheet(data: SelectOptionsBottomSheetData?) {
|
||||
@@ -126,6 +231,30 @@ class OrdersFragment : AmcBaseFragment() {
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleOnClick(action: ActionData?) {
|
||||
sendEvent(
|
||||
action?.metaData?.clickedData,
|
||||
)
|
||||
val url = action?.url
|
||||
if(url == Constant.SHOW_BOTTOMSHEET) {
|
||||
val data = action.parameters?.getOrNull(0)?.value
|
||||
val key = action.parameters?.getOrNull(0)?.key
|
||||
val bundle = Bundle().apply {
|
||||
putString(Constant.DATA, data)
|
||||
}
|
||||
learnMoreBottomSheetData = Gson().fromJson(data, AmcCommonBottomSheetData::class.java)
|
||||
key?.let {
|
||||
getBottomSheet(it, bundle, genericListener = ::actionListener)?.let {
|
||||
safelyShowBottomSheet(it, key)
|
||||
}
|
||||
}
|
||||
} else if (url == Constant.INIT_REFUND) {
|
||||
initiateRefund(action)
|
||||
} else {
|
||||
fragmentInterchangeListener?.navigateToNextScreen(actionData = action)
|
||||
}
|
||||
}
|
||||
|
||||
private fun processData(list: List<Identifier>) {
|
||||
setFilterIcon(list)
|
||||
viewModel.bottomSheetData?.data?.forEach { data ->
|
||||
@@ -227,6 +356,19 @@ class OrdersFragment : AmcBaseFragment() {
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun initiateRefund(action: ActionData?) {
|
||||
val key = action?.parameters?.firstOrNull()?.key
|
||||
val value = action?.parameters?.firstOrNull()?.value
|
||||
if(key == ORDER_ID) {
|
||||
showLoader()
|
||||
viewModel.refundOrder(value.orEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
private fun actionListener(action : ActionData) {
|
||||
handleOnClick(action)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(bundle: Bundle? = null): OrdersFragment {
|
||||
return OrdersFragment().apply { arguments = bundle }
|
||||
|
||||
@@ -2,11 +2,17 @@ package com.navi.amc.portfolio.models
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.navi.amc.common.model.EmptyProductData
|
||||
import com.navi.amc.common.model.InformationCardData
|
||||
import com.navi.amc.common.model.TimerInfo
|
||||
import com.navi.amc.fundbuy.models.ChipData
|
||||
import com.navi.amc.fundbuy.models.IconData
|
||||
import com.navi.amc.fundbuy.models.SubItemData
|
||||
import com.navi.base.model.ActionData
|
||||
import com.navi.base.model.ImageDetails
|
||||
import com.navi.design.textview.model.TextWithStyle
|
||||
import com.navi.naviwidgets.models.response.Gradient
|
||||
import com.navi.naviwidgets.models.response.amc.LabelData
|
||||
import com.navi.naviwidgets.widgets.textdisplay.Margin
|
||||
|
||||
data class OrdersScreenData(
|
||||
@SerializedName("orderSummary")
|
||||
@@ -33,7 +39,11 @@ data class OrderSummary(
|
||||
@SerializedName("sellOrders")
|
||||
val sellOrders: SubItemData? = null,
|
||||
@SerializedName("gradient")
|
||||
val gradient: Gradient? = null
|
||||
val gradient: Gradient? = null,
|
||||
@SerializedName("orderSummaryCard")
|
||||
val orderSummaryCard: OrderSummaryCard? = null,
|
||||
@SerializedName("learnMoreNote")
|
||||
val learnMoreNote : InformationCardData?= null
|
||||
)
|
||||
|
||||
data class HeaderWithStyle(
|
||||
@@ -41,4 +51,16 @@ data class HeaderWithStyle(
|
||||
val item: TextWithStyle? = null,
|
||||
@SerializedName("bgColor")
|
||||
val bgColor: String? = null
|
||||
)
|
||||
|
||||
data class OrderSummaryCard(
|
||||
@SerializedName("iconCode") val iconCode: String? = null,
|
||||
@SerializedName("bgColor") val bgColor: String? = null,
|
||||
@SerializedName("imageDetails") val imageDetails: ImageDetails?,
|
||||
@SerializedName("imageMargin") val imageMargin: Margin?,
|
||||
@SerializedName("title") val title: TextWithStyle? = null,
|
||||
@SerializedName("subTitle") val subTitle: TextWithStyle? = null,
|
||||
@SerializedName("actionTitle") val actionTitle: TextWithStyle? = null,
|
||||
@SerializedName("actionData") val actionData: ActionData? = null,
|
||||
@SerializedName("footerTimerInfo") val timerInfo : TimerInfo? = null
|
||||
)
|
||||
@@ -15,8 +15,7 @@ class OrdersRepository @Inject constructor(private val retrofitService: Retrofit
|
||||
ResponseCallback() {
|
||||
|
||||
suspend fun fetchOrdersData() = apiResponseCallback(retrofitService.fetchOrders())
|
||||
/*suspend fun fetchOrdersData(): RepoResult<OrdersScreenData> {
|
||||
val type = object : TypeToken<OrdersScreenData>() {}.type
|
||||
return mockApiResponse(type, "orders_list")
|
||||
}*/
|
||||
|
||||
suspend fun refundOrder(orderId: String) =
|
||||
apiResponseCallback(retrofitService.refundOrder(orderId))
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.navi.amc.portfolio.models.OrdersScreenData
|
||||
import com.navi.amc.portfolio.repositories.OrdersRepository
|
||||
import com.navi.amc.utils.Constant.DATE_FORMAT_YYYY_MM_DD
|
||||
import com.navi.common.extensions.isNotNull
|
||||
import com.navi.common.network.models.SuccessResponse
|
||||
import com.navi.common.utils.log
|
||||
import com.navi.common.viewmodel.BaseVM
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
@@ -31,6 +32,10 @@ class OrdersViewModel @Inject constructor(private val repository: OrdersReposito
|
||||
|
||||
var filterList = mutableListOf<Identifier>()
|
||||
|
||||
private val _refundStatus = MutableLiveData<SuccessResponse?>()
|
||||
val refundStatus: LiveData<SuccessResponse?>
|
||||
get() = _refundStatus
|
||||
|
||||
fun fetchScreenData() {
|
||||
viewModelScope.launch {
|
||||
val response = repository.fetchOrdersData()
|
||||
@@ -65,6 +70,17 @@ class OrdersViewModel @Inject constructor(private val repository: OrdersReposito
|
||||
}?.sortedByDescending { sdf.parse(it.metaData?.timeStamp.orEmpty()) }
|
||||
}
|
||||
|
||||
fun refundOrder(orderId: String) {
|
||||
viewModelScope.launch {
|
||||
val response = repository.refundOrder(orderId)
|
||||
if(response.error == null && response.errors.isNullOrEmpty()){
|
||||
_refundStatus.value = response.data
|
||||
} else {
|
||||
setErrorData(response.errors, response.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun compareTimeStamp(time1: String, time2: String): Boolean {
|
||||
try {
|
||||
val timeStamp1 = sdf.parse(time1)
|
||||
|
||||
@@ -90,8 +90,10 @@ object Constant {
|
||||
const val CONFIRMED = "CONFIRMED"
|
||||
const val BUSINESS_VERTICAL_AMC = "AMC"
|
||||
const val UPI = "UPI"
|
||||
const val INIT_REFUND = "INIT_REFUND"
|
||||
const val BACK_PRESS = "backPress"
|
||||
const val DISMISS = "dismiss"
|
||||
const val PD = "PD"
|
||||
const val IS_INVESTMENT_ON_BOTTOM_NAV = "isInvestmentOnBottomNav"
|
||||
const val THOUSAND = 1000L
|
||||
}
|
||||
|
||||
@@ -62,6 +62,20 @@ class DateUtils {
|
||||
return dateFormat.format(convertedDate)
|
||||
}
|
||||
|
||||
fun formatSecondsInDaysTimer(timeInSeconds: Long): String {
|
||||
val secondsLeft = timeInSeconds % 3600 % 60
|
||||
val minutes = timeInSeconds % 3600 / 60
|
||||
val hours = (timeInSeconds / 3600) % 24
|
||||
val days = timeInSeconds / 24 / 3600
|
||||
|
||||
val DD = "${if(days < 10) "0" else ""}$days"
|
||||
val HH = "${if(hours < 10) "0" else ""}$hours"
|
||||
val MM = "${if(minutes < 10) "0" else ""}$minutes"
|
||||
val SS = "${if(secondsLeft < 10) "0" else ""}$secondsLeft"
|
||||
|
||||
return "$DD : $HH : $MM : $SS days"
|
||||
}
|
||||
|
||||
private object Holder {
|
||||
val INSTANCE = DateUtils()
|
||||
}
|
||||
|
||||
42
navi-amc/src/main/res/layout/learn_more_layout.xml
Normal file
42
navi-amc/src/main/res/layout/learn_more_layout.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<data>
|
||||
|
||||
<variable
|
||||
name="note"
|
||||
type="com.navi.amc.common.model.InformationCardData" />
|
||||
</data>
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center">
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
setTextWithStyle="@{note.title}"
|
||||
tools:text="Unable to set up account"/>
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/action"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
setTextWithStyle="@{note.actionText.title}"
|
||||
tools:text="Learn More"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/dp_16"
|
||||
android:layout_height="@dimen/dp_16"
|
||||
tools:src="@drawable/ic_right_arrow"
|
||||
setImageFromIconCode="@{note.rightIcon}"
|
||||
android:layout_gravity="center_vertical"/>
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
</layout>
|
||||
@@ -8,9 +8,15 @@
|
||||
name="response"
|
||||
type="com.navi.amc.common.model.OrderDetailsData" />
|
||||
|
||||
<variable
|
||||
name="learnMoreNoteData"
|
||||
type="com.navi.amc.common.model.InformationCardData" />
|
||||
|
||||
<variable
|
||||
name="footerResponse"
|
||||
type="com.navi.amc.common.model.Footer" />
|
||||
|
||||
<import type="android.view.View" />
|
||||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
@@ -56,23 +62,35 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_40"
|
||||
android:paddingBottom="@dimen/dp_8"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/order_details" />
|
||||
|
||||
<include
|
||||
android:id="@+id/learn_more_note"
|
||||
layout="@layout/learn_more_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/dp_16"
|
||||
android:visibility="@{learnMoreNoteData != null ? View.VISIBLE : View.GONE}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:note="@{learnMoreNoteData}"
|
||||
app:layout_constraintTop_toBottomOf="@id/timeline"/>
|
||||
|
||||
<com.navi.amc.common.view.InformationView
|
||||
android:id="@+id/status_note"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:paddingTop="@dimen/dp_32"
|
||||
android:paddingBottom="@dimen/dp_24"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/timeline" />
|
||||
app:layout_constraintTop_toBottomOf="@id/learn_more_note" />
|
||||
|
||||
<com.navi.naviwidgets.views.NoteViewWidgetLayout
|
||||
android:id="@+id/note"
|
||||
@@ -80,6 +98,7 @@
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:paddingTop="@dimen/dp_32"
|
||||
android:paddingBottom="@dimen/dp_24"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
||||
109
navi-amc/src/main/res/layout/order_summary_card_layout.xml
Normal file
109
navi-amc/src/main/res/layout/order_summary_card_layout.xml
Normal file
@@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/widget_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
android:layout_marginBottom="@dimen/dp_16"
|
||||
android:outlineSpotShadowColor="@color/outlineSpotShadowColor"
|
||||
app:cardCornerRadius="@dimen/dp_8"
|
||||
app:cardElevation="@dimen/dp_10"
|
||||
app:cardUseCompatPadding="false">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/summary_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/card_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
android:layout_marginTop="@dimen/dp_24"
|
||||
android:gravity="center_vertical"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Fill your basic details" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/card_subtitle"
|
||||
android:layout_width="@dimen/dp_0"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_2"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:gravity="center_vertical"
|
||||
app:layout_constraintStart_toStartOf="@id/card_title"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/card_title"
|
||||
tools:text="Start investing with" />
|
||||
|
||||
<com.navi.naviwidgets.views.ButtonViewLayout
|
||||
android:id="@+id/action_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
android:layout_marginTop="@dimen/dp_18"
|
||||
android:layout_marginBottom="@dimen/dp_16"
|
||||
app:layout_constraintBottom_toTopOf="@id/footer_container"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/card_subtitle"
|
||||
tools:text="Start investing with"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/cardIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dp_16"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/footer_container"
|
||||
tools:src="@drawable/person_tick" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/footer_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dp_32"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/footer_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="center"
|
||||
tools:text="Hurry up! your offer expires in 06 : 00 : 23 :43" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<com.navi.design.customview.ParallelogramView
|
||||
android:id="@+id/pgvShimmer"
|
||||
android:layout_width="@dimen/dp_32"
|
||||
android:layout_height="@dimen/dp_0"
|
||||
android:layout_gravity="start"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/footer_container"
|
||||
app:tilt_direction="forward" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
</FrameLayout>
|
||||
</layout>
|
||||
@@ -32,6 +32,27 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Order Overview" />
|
||||
|
||||
<include
|
||||
android:id="@+id/order_summary_card"
|
||||
layout="@layout/order_summary_card_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/learn_more_note"
|
||||
layout="@layout/learn_more_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="@{orderValue.learnMoreNote != null ? View.VISIBLE : View.GONE}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:note="@{orderValue.learnMoreNote}"
|
||||
app:layout_constraintTop_toBottomOf="@id/order_summary_card"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/order_view"
|
||||
layout="@layout/order_view"
|
||||
@@ -40,10 +61,10 @@
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:visibility="@{orderValue!=null ?View.VISIBLE : View.GONE }"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
app:layout_constraintTop_toBottomOf="@id/learn_more_note"
|
||||
app:orderValue="@{orderValue}" />
|
||||
|
||||
<com.navi.amc.common.view.EmptyProductView
|
||||
|
||||
@@ -38,16 +38,45 @@
|
||||
app:cardCornerRadius="@dimen/dp_8"
|
||||
app:cardElevation="@dimen/dp_8"
|
||||
app:cardUseCompatPadding="true"
|
||||
app:contentPadding="@dimen/dp_24"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/left_title">
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/container"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/dp_24"
|
||||
android:layout_marginVertical="@dimen/dp_24"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/footer_tv"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/footer_tv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingVertical="@dimen/dp_6"
|
||||
android:paddingHorizontal="@dimen/dp_16"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:gravity="center"
|
||||
tools:text="Hurry up! your offer expires in 06 : 00 : 23 :43" />
|
||||
|
||||
<com.navi.design.customview.ParallelogramView
|
||||
android:id="@+id/pgvShimmer"
|
||||
android:layout_width="@dimen/dp_32"
|
||||
android:layout_height="@dimen/dp_0"
|
||||
android:layout_gravity="start"
|
||||
app:layout_constraintBottom_toBottomOf="@id/footer_tv"
|
||||
app:layout_constraintStart_toStartOf="@id/footer_tv"
|
||||
app:layout_constraintTop_toTopOf="@id/footer_tv"
|
||||
app:tilt_direction="forward" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
@@ -28,6 +28,7 @@ class ParallelogramView(context: Context?, attrs: AttributeSet?) : View(context,
|
||||
|
||||
private var path: Path? = null
|
||||
private var paint: Paint? = null
|
||||
private var isReset = false
|
||||
|
||||
var opacity = defaultAlpha
|
||||
get() = field
|
||||
@@ -61,13 +62,7 @@ class ParallelogramView(context: Context?, attrs: AttributeSet?) : View(context,
|
||||
recycle()
|
||||
}
|
||||
}
|
||||
paint =
|
||||
Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
color = parallelogramColor
|
||||
style = Paint.Style.FILL_AND_STROKE
|
||||
alpha = opacity
|
||||
}
|
||||
path = Path()
|
||||
initView()
|
||||
}
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
@@ -102,6 +97,30 @@ class ParallelogramView(context: Context?, attrs: AttributeSet?) : View(context,
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
resetView()
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
if(isReset) {
|
||||
initView()
|
||||
requestLayout()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
paint =
|
||||
Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
color = parallelogramColor
|
||||
style = Paint.Style.FILL_AND_STROKE
|
||||
alpha = opacity
|
||||
}
|
||||
path = Path()
|
||||
isReset = false
|
||||
}
|
||||
|
||||
private fun resetView() {
|
||||
isReset = true
|
||||
path?.reset()
|
||||
paint?.reset()
|
||||
}
|
||||
|
||||
@@ -236,6 +236,7 @@ object NaviWidgetIconUtils {
|
||||
private const val CHEVRON_V2 = "CHEVRON_V2"
|
||||
private const val CHEVRON_V3 = "CHEVRON_V3"
|
||||
private const val CHEVRON_ICON_WITH_WHITE_BG = "CHEVRON_ICON_WITH_WHITE_BG"
|
||||
private const val CHEVRON_BLACK_RIGHT = "CHEVRON_BLACK_RIGHT"
|
||||
private const val TRENDING_ICON = "TRENDING_ICON"
|
||||
private const val ICON_BACK_ARROW = "ICON_BACK_ARROW"
|
||||
private const val ICON_CROSS_ARROW = "ICON_CROSS_ARROW"
|
||||
@@ -767,6 +768,7 @@ object NaviWidgetIconUtils {
|
||||
CHEVRON_V2-> R.drawable.ic_chevrons_v2
|
||||
CHEVRON_V3-> R.drawable.ic_chevron_v3
|
||||
CHEVRON_ICON_WITH_WHITE_BG -> R.drawable.ic_chevrons_with_white_bg_svg
|
||||
CHEVRON_BLACK_RIGHT -> R.drawable.ic_chevron_black_right
|
||||
CHAT_NEW_ICON -> R.drawable.ic_new_chat_svg
|
||||
CALL_NEW_ICON -> R.drawable.ic_new_phone_call_svg
|
||||
DOWNLOAD_ICON -> R.drawable.download
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="16dp"
|
||||
android:height="16dp"
|
||||
android:viewportWidth="16"
|
||||
android:viewportHeight="16">
|
||||
<path
|
||||
android:pathData="M5.531,3.529C5.792,3.268 6.214,3.268 6.474,3.529L10.474,7.529C10.734,7.789 10.734,8.211 10.474,8.471L6.474,12.471C6.214,12.732 5.792,12.732 5.531,12.471C5.271,12.211 5.271,11.789 5.531,11.529L9.06,8L5.531,4.471C5.271,4.211 5.271,3.789 5.531,3.529Z"
|
||||
android:fillColor="#2A0038"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
Reference in New Issue
Block a user