From 11fe9b362a22a89d7864ff631454dce1727fae58 Mon Sep 17 00:00:00 2001 From: Varun Jain Date: Tue, 24 Dec 2024 16:57:38 +0530 Subject: [PATCH] NTP-18296 | Gold landing page revamp (#14205) --- .../navi/gold/ui/DigitalGoldHomeActivity.kt | 55 ++++++- .../gold/ui/DigitalGoldTransactionActivity.kt | 54 +++++++ .../navi/gold/ui/compose/OfferBottomSheet.kt | 7 +- .../com/navi/gold/ui/compose/OfferCard.kt | 46 +++++- .../java/com/navi/gold/util/CommonUtils.kt | 27 ++++ .../main/java/com/navi/gold/util/Constants.kt | 1 + .../navi/gold/viewmodels/DigitalGoldHomeVM.kt | 8 + .../viewmodels/DigitalGoldTransactionVM.kt | 10 ++ .../res/layout/activity_digital_gold_home.xml | 3 +- .../activity_digital_gold_transaction.xml | 2 +- .../interfaces/GoldConversionWidgetInfo.kt | 2 + .../models/DualActionButtonWidget.kt | 3 +- .../models/GoldConversionWidget.kt | 11 +- .../naviwidgets/models/GoldPortfolioWidget.kt | 55 +++++++ .../naviwidgets/models/OfferCardWidget.kt | 87 +++++++++++ .../naviwidgets/models/SimpleTextWidget.kt | 2 + .../navi/naviwidgets/models/SipCardWidget.kt | 59 +++++++ .../models/TextCardWithShimmerWidget.kt | 52 +------ .../models/response/HeaderItemListWidget.kt | 3 +- .../viewholder/GoldPortfolioWidgetVH.kt | 42 +++++ .../viewholder/OfferCardWidgetVH.kt | 42 +++++ .../naviwidgets/viewholder/SipCardWidgetVH.kt | 51 ++++++ .../viewholder/ViewHolderFactoryImpl.kt | 12 ++ .../naviwidgets/views/ButtonViewLayout.kt | 12 +- .../widgets/DualActionButtonWidgetLayout.kt | 23 ++- .../widgets/GoldConversionWidgetLayout.kt | 51 +++++- .../widgets/GoldPortfolioWidgetLayout.kt | 134 ++++++++++++++++ .../widgets/NaviWidgetJsonDeserializer.kt | 3 + .../widgets/NaviWidgetJsonSerializer.kt | 6 + .../widgets/OfferCardWidgetLayout.kt | 111 +++++++++++++ .../widgets/SimpleTextWidgetLayout.kt | 6 + .../widgets/SipCardWidgetLayout.kt | 147 ++++++++++++++++++ .../TextCardWithShimmerWidgetLayout.kt | 114 +++++++------- .../dual_action_button_widget_layout.xml | 12 ++ .../layout/gold_portfolio_widget_layout.xml | 81 ++++++++++ .../main/res/layout/graph_widget_layout.xml | 1 + .../res/layout/layout_gold_conversion.xml | 3 +- .../res/layout/offer_card_widget_layout.xml | 111 +++++++++++++ .../res/layout/portfolio_subtitle_item.xml | 90 +++++++++++ .../res/layout/simple_text_widget_layout.xml | 9 ++ .../res/layout/sip_card_widget_layout.xml | 109 +++++++++++++ .../text_card_with_shimmer_widget_layout.xml | 52 +++---- 42 files changed, 1548 insertions(+), 161 deletions(-) create mode 100644 android/navi-widgets/src/main/java/com/navi/naviwidgets/models/GoldPortfolioWidget.kt create mode 100644 android/navi-widgets/src/main/java/com/navi/naviwidgets/models/OfferCardWidget.kt create mode 100644 android/navi-widgets/src/main/java/com/navi/naviwidgets/models/SipCardWidget.kt create mode 100644 android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/GoldPortfolioWidgetVH.kt create mode 100644 android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/OfferCardWidgetVH.kt create mode 100644 android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/SipCardWidgetVH.kt create mode 100644 android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/GoldPortfolioWidgetLayout.kt create mode 100644 android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/OfferCardWidgetLayout.kt create mode 100644 android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SipCardWidgetLayout.kt create mode 100644 android/navi-widgets/src/main/res/layout/gold_portfolio_widget_layout.xml create mode 100644 android/navi-widgets/src/main/res/layout/offer_card_widget_layout.xml create mode 100644 android/navi-widgets/src/main/res/layout/portfolio_subtitle_item.xml create mode 100644 android/navi-widgets/src/main/res/layout/sip_card_widget_layout.xml diff --git a/android/navi-gold/src/main/java/com/navi/gold/ui/DigitalGoldHomeActivity.kt b/android/navi-gold/src/main/java/com/navi/gold/ui/DigitalGoldHomeActivity.kt index 0d1f81a3b3..2d64d65adc 100644 --- a/android/navi-gold/src/main/java/com/navi/gold/ui/DigitalGoldHomeActivity.kt +++ b/android/navi-gold/src/main/java/com/navi/gold/ui/DigitalGoldHomeActivity.kt @@ -33,6 +33,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.navi.analytics.utils.NaviTrackEvent import com.navi.analytics.utils.SCREEN_NAME import com.navi.base.AppServiceManager @@ -114,6 +115,7 @@ import com.navi.gold.navigator.NaviDigitalGoldDeeplinkNavigator import com.navi.gold.navigator.NaviDigitalGoldDeeplinkNavigator.GOLD import com.navi.gold.toOpenBottomSheet import com.navi.gold.util.CommonUtils +import com.navi.gold.util.CommonUtils.updateColorsBasedOnPosition import com.navi.gold.util.Constants import com.navi.gold.util.Constants.AMOUNT_DATA import com.navi.gold.util.Constants.APP_ACTION_OBJECTIVE_REWARDS_CAMPAIGN_ONBOARD @@ -140,6 +142,7 @@ import com.navi.gold.util.Constants.PAN_VERIFY_BOTTOM_SHEET import com.navi.gold.util.Constants.PD_RPD_SELECTION import com.navi.gold.util.Constants.SETTINGS import com.navi.gold.util.Constants.SETUP_SIP_REFRESH +import com.navi.gold.util.Constants.SETUP_SIP_WIDGET import com.navi.gold.util.Constants.SHOW_OFFER_BOTTOMSHEET import com.navi.gold.util.Constants.SHOW_WIDGET_BOTTOM_SHEET import com.navi.gold.util.Constants.SIP_SETUP_FAILED @@ -189,6 +192,7 @@ import com.navi.naviwidgets.models.GoldPortfolioCardWidget import com.navi.naviwidgets.models.NaviBaseAdapterModel import com.navi.naviwidgets.models.NaviWidget import com.navi.naviwidgets.models.ShareData +import com.navi.naviwidgets.models.SipCardWidget import com.navi.naviwidgets.models.TextCardWithShimmerWidget import com.navi.naviwidgets.models.WidgetChangedData import com.navi.naviwidgets.models.response.HomeProductWidget @@ -405,6 +409,7 @@ class DigitalGoldHomeActivity : onBackPressed() } } + setScrollListener() } private fun showShimmer() { @@ -1238,6 +1243,7 @@ class DigitalGoldHomeActivity : private fun processHeader(response: WidgetResponse?) { response?.header?.let { + homeVM.setStatusBarColor(it.backgroundColor.parseColorSafe(COLOR_WHITE)) it.title?.let { title -> it.leftIconCode?.let { leftIconCode -> binding.ivBack.showWhenDataIsAvailable(leftIconCode) @@ -1289,6 +1295,23 @@ class DigitalGoldHomeActivity : } } + private fun setScrollListener() { + binding.rvGoldItems.addOnScrollListener( + object : RecyclerView.OnScrollListener() { + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { + super.onScrolled(recyclerView, dx, dy) + updateColorsBasedOnPosition( + recyclerView = recyclerView, + activity = this@DigitalGoldHomeActivity, + headerView = binding.clHeaderView, + defaultColor = Color.WHITE, + statusBarColor = homeVM.getStatusBarColor() + ) + } + } + ) + } + private fun fetchDigitalHomePageDetails( forceRefresh: Boolean = true, setUpSipRefresh: Boolean = false @@ -1813,8 +1836,9 @@ class DigitalGoldHomeActivity : is GoldMinOfferSectionClickAction -> { if (naviClickAction.actionData?.url == SHOW_OFFER_BOTTOMSHEET) { val bundle = Bundle() - naviClickAction.offerSectionData?.content?.remainingAmount = - homeVM.getRemainingAmount().formatAmount() + naviClickAction.offerSectionData?.content?.offerTickets?.forEach { card -> + card.remainingAmount = homeVM.getRemainingAmount().formatAmount() + } bundle.putParcelable(DATA, naviClickAction.offerSectionData) GoldOfferBottomSheet.newInstance(bundle = bundle).apply { safelyShowBottomSheet(this, GoldOfferBottomSheet.TAG) @@ -1880,6 +1904,20 @@ class DigitalGoldHomeActivity : ) ) } + if ( + naviWidget is SipCardWidget && + (naviWidget.widgetId == SETUP_SIP_WIDGET && + (state && naviWidget.widgetId == widgetId || !state)) + ) { + + val sipCardWidget = naviWidget.widgetData + sipCardWidget?.buttonLoaderState = ButtonLoaderState(state) + isScreenBlocked = state + naviAdapter.notifyItemChanged( + index, + WidgetChangedData(WIDGET_STATE_CHANGE, sipCardWidget?.buttonLoaderState) + ) + } if (naviWidget is ContainerWidget) { val itemsOfContainerWidget = naviWidget.widgetData?.items @@ -2009,6 +2047,17 @@ class DigitalGoldHomeActivity : } startTimer() + binding.rvGoldItems.layoutManager?.let { layoutManager -> + if (layoutManager is LinearLayoutManager) { + updateColorsBasedOnPosition( + recyclerView = binding.rvGoldItems, + activity = this@DigitalGoldHomeActivity, + headerView = binding.clHeaderView, + defaultColor = Color.WHITE, + statusBarColor = homeVM.getStatusBarColor() + ) + } + } } private fun checkForLocationPermission(): Boolean { @@ -2178,6 +2227,8 @@ class DigitalGoldHomeActivity : super.onStop() timer?.cancel() timer = null + binding.clHeaderView.setBackgroundColor(Color.WHITE) + window?.statusBarColor = Color.WHITE } override fun onDestroy() { diff --git a/android/navi-gold/src/main/java/com/navi/gold/ui/DigitalGoldTransactionActivity.kt b/android/navi-gold/src/main/java/com/navi/gold/ui/DigitalGoldTransactionActivity.kt index 049cd5c6ce..fa9e78a9a8 100644 --- a/android/navi-gold/src/main/java/com/navi/gold/ui/DigitalGoldTransactionActivity.kt +++ b/android/navi-gold/src/main/java/com/navi/gold/ui/DigitalGoldTransactionActivity.kt @@ -19,6 +19,7 @@ import androidx.databinding.DataBindingUtil import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.google.gson.Gson import com.navi.analytics.utils.NaviTrackEvent import com.navi.analytics.utils.SCREEN_NAME @@ -62,11 +63,13 @@ import com.navi.design.utils.parseColorSafe import com.navi.gold.R import com.navi.gold.databinding.ActivityDigitalGoldTransactionBinding import com.navi.gold.util.CommonUtils +import com.navi.gold.util.CommonUtils.updateColorsBasedOnPosition import com.navi.gold.util.Constants import com.navi.gold.util.Constants.CSAT_POPUP_DELAY import com.navi.gold.util.Constants.CSAT_POPUP_DELAY_TIME import com.navi.gold.util.Constants.REDIRECTION_SOURCE import com.navi.gold.util.Constants.SHOW_REWARD_GRATIFICATION +import com.navi.gold.util.Constants.TYPE import com.navi.gold.util.GoldAnalytics import com.navi.gold.util.GoldAnalytics.DIGITAL_GOLD_TRANSACTION_SCREEN import com.navi.gold.util.GoldAnalytics.FEEDBACK @@ -85,6 +88,7 @@ import com.navi.naviwidgets.models.NaviWidget import com.navi.naviwidgets.models.response.CSATResponse import com.navi.naviwidgets.models.response.CsatWidget import com.navi.naviwidgets.viewholder.ViewHolderFactoryImpl +import com.navi.naviwidgets.widgets.InfoWithTimerWidgetLayout.Companion.COLOR_WHITE import com.navi.rr.scratchcard.ui.fragment.ScratchCardFragment import com.navi.rr.scratchcard.vm.ScratchCardSharedVm import dagger.hilt.android.AndroidEntryPoint @@ -179,6 +183,17 @@ class DigitalGoldTransactionActivity : BaseActivity(), WidgetCallback, CsatCompl viewModel.fetchDigitalGoldCSATResponse(DG_TRANSACTION, null, screenName = screenName) startCsat(0) } + binding.rvGoldItems.layoutManager?.let { layoutManager -> + if (layoutManager is LinearLayoutManager) { + updateColorsBasedOnPosition( + recyclerView = binding.rvGoldItems, + activity = this@DigitalGoldTransactionActivity, + headerView = binding.clHeaderView, + defaultColor = Color.WHITE, + statusBarColor = viewModel.getStatusBarColor() + ) + } + } } override fun onPause() { @@ -339,6 +354,7 @@ class DigitalGoldTransactionActivity : BaseActivity(), WidgetCallback, CsatCompl private fun setPageContent(pageContent: WidgetResponse) { processHeader(pageContent) + setScrollListener() pageContent.contentWidget?.let { listOfWidgets -> naviAdapter.setData(listOfWidgets) } } @@ -361,6 +377,7 @@ class DigitalGoldTransactionActivity : BaseActivity(), WidgetCallback, CsatCompl private fun processHeader(response: WidgetResponse?) { response?.header?.let { + viewModel.setStatusBarColor(it.backgroundColor.parseColorSafe(COLOR_WHITE)) viewModel.prefetchData(it.actionData?.url, screenName) it.title?.let { title -> it.leftIconCode?.let { leftIconCode -> @@ -380,6 +397,23 @@ class DigitalGoldTransactionActivity : BaseActivity(), WidgetCallback, CsatCompl } } + private fun setScrollListener() { + binding.rvGoldItems.addOnScrollListener( + object : RecyclerView.OnScrollListener() { + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { + super.onScrolled(recyclerView, dx, dy) + updateColorsBasedOnPosition( + recyclerView = recyclerView, + activity = this@DigitalGoldTransactionActivity, + headerView = binding.clHeaderView, + defaultColor = Color.WHITE, + statusBarColor = viewModel.getStatusBarColor() + ) + } + } + ) + } + private fun fetchData() { fetchDigitalTransactionPageDetails() viewModel.fetchDigitalGoldCSATResponse(DG_TRANSACTION, null, screenName = screenName) @@ -487,6 +521,20 @@ class DigitalGoldTransactionActivity : BaseActivity(), WidgetCallback, CsatCompl if (naviClickAction.actionData?.type == "DOWNLOAD_INVOICE") { fetchDigitalGoldInvoiceDownloadUrl(naviClickAction.actionData?.title) return + } else if (naviClickAction.actionData?.url == "back") { + onBackPressed() + return + } + val bundle = Bundle() + naviClickAction.actionData?.let { + bundle.putString(TYPE, it.type.orEmpty()) + DeepLinkManager.getDeepLinkListener() + ?.navigateTo( + this, + it.toCtaData(), + bundle = bundle, + finish = naviClickAction.isFinish + ) } } is ActionData -> { @@ -571,6 +619,12 @@ class DigitalGoldTransactionActivity : BaseActivity(), WidgetCallback, CsatCompl } } + override fun onStop() { + super.onStop() + binding.clHeaderView.setBackgroundColor(Color.WHITE) + window?.statusBarColor = Color.WHITE + } + override fun onDestroy() { super.onDestroy() binding.unbind() diff --git a/android/navi-gold/src/main/java/com/navi/gold/ui/compose/OfferBottomSheet.kt b/android/navi-gold/src/main/java/com/navi/gold/ui/compose/OfferBottomSheet.kt index b32da52a1f..e1fe442c1c 100644 --- a/android/navi-gold/src/main/java/com/navi/gold/ui/compose/OfferBottomSheet.kt +++ b/android/navi-gold/src/main/java/com/navi/gold/ui/compose/OfferBottomSheet.kt @@ -55,7 +55,12 @@ fun OfferBottomSheet( onDismiss = { onDismiss() }, modifier = Modifier.padding(bottom = 16.dp) ) - OfferCard(offerContentData = bottomSheetData?.content) + repeat(bottomSheetData?.content?.offerTickets?.size ?: 0) { index -> + OfferCard(offerContentData = bottomSheetData?.content?.offerTickets?.get(index)) + if (index != bottomSheetData?.content?.offerTickets?.size?.minus(1)) { + Spacer(modifier = Modifier.height(16.dp)) + } + } BottomSheetFooter(footerData = bottomSheetData?.footer) } } diff --git a/android/navi-gold/src/main/java/com/navi/gold/ui/compose/OfferCard.kt b/android/navi-gold/src/main/java/com/navi/gold/ui/compose/OfferCard.kt index 460d19116f..6f291215cf 100644 --- a/android/navi-gold/src/main/java/com/navi/gold/ui/compose/OfferCard.kt +++ b/android/navi-gold/src/main/java/com/navi/gold/ui/compose/OfferCard.kt @@ -42,6 +42,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.unit.dp import com.navi.common.uitron.render.TicketWithDividerRenderer +import com.navi.design.R import com.navi.naviwidgets.extensions.NaviImage import com.navi.naviwidgets.extensions.NaviTextWidgetized import com.navi.naviwidgets.models.OfferContentData @@ -92,6 +93,26 @@ fun OfferCard( ) { Spacer(modifier = Modifier.width(17.dp)) NaviTextWidgetized(textFieldData = offerContentData?.title) + Spacer(modifier = Modifier.width(3.dp)) + NaviImage( + imageFieldData = offerContentData?.titleIcon, + modifier = + Modifier.width( + (offerContentData?.titleIcon?.iconWidth + ?: R.integer.integer_16) + .dp + ) + .height( + (offerContentData?.titleIcon?.iconHeight + ?: R.integer.integer_16) + .dp + ) + .align(Alignment.CenterVertically) + ) + Spacer(modifier = Modifier.width(2.dp)) + NaviTextWidgetized( + textFieldData = offerContentData?.titleSuffix, + ) } Box( @@ -112,13 +133,24 @@ fun OfferCard( Spacer(modifier = Modifier.height(8.dp)) NaviTextWidgetized(textFieldData = offerContentData?.subTitle) - Spacer(modifier = Modifier.height(6.dp)) - Row() { - NaviTextWidgetized(textFieldData = offerContentData?.additionalInfoPrefix) - offerContentData?.additionalInfoAmount?.text = - " ₹${offerContentData?.remainingAmount} " - NaviTextWidgetized(textFieldData = offerContentData?.additionalInfoAmount) - NaviTextWidgetized(textFieldData = offerContentData?.additionalInfoSuffix) + if ( + offerContentData?.additionalInfoAmount != null && + (offerContentData.remainingAmount?.toDoubleOrNull() ?: 0.0) > 0.0 + ) { + Spacer(modifier = Modifier.height(6.dp)) + Row() { + NaviTextWidgetized( + textFieldData = offerContentData.additionalInfoPrefix + ) + offerContentData.additionalInfoAmount?.text = + " ₹${offerContentData.remainingAmount} " + NaviTextWidgetized( + textFieldData = offerContentData.additionalInfoAmount + ) + NaviTextWidgetized( + textFieldData = offerContentData.additionalInfoSuffix + ) + } } Spacer(modifier = Modifier.height(12.dp)) } diff --git a/android/navi-gold/src/main/java/com/navi/gold/util/CommonUtils.kt b/android/navi-gold/src/main/java/com/navi/gold/util/CommonUtils.kt index 4f4f56e100..5ca58468eb 100644 --- a/android/navi-gold/src/main/java/com/navi/gold/util/CommonUtils.kt +++ b/android/navi-gold/src/main/java/com/navi/gold/util/CommonUtils.kt @@ -10,8 +10,11 @@ package com.navi.gold.util import android.app.Activity import android.content.Intent import android.os.Bundle +import android.view.View import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.navi.analytics.utils.NaviTrackEvent import com.navi.base.deeplink.DeepLinkManager import com.navi.base.model.ActionData @@ -139,4 +142,28 @@ object CommonUtils { TemporaryStorageHelper.SOFT_REF_CACHE.remove(NaviDigitalGoldDeeplinkNavigator.GOLD) TemporaryStorageHelper.setIsDataModified(NaviDigitalGoldDeeplinkNavigator.GOLD, true) } + + fun updateColorsBasedOnPosition( + recyclerView: RecyclerView, + activity: Activity, + headerView: View?, + defaultColor: Int, + statusBarColor: Int + ) { + val layoutManager = recyclerView.layoutManager as? LinearLayoutManager + val firstVisibleItemPosition = + layoutManager?.findFirstVisibleItemPosition() ?: RecyclerView.NO_POSITION + + if (firstVisibleItemPosition == RecyclerView.NO_POSITION) { + return + } + + val colorToSet = if (firstVisibleItemPosition == 0) statusBarColor else defaultColor + headerView?.let { updateStatusBarAndHeaderColor(activity, colorToSet, it) } + } + + private fun updateStatusBarAndHeaderColor(activity: Activity, color: Int, headerView: View) { + activity.window?.let { it.statusBarColor = color } + headerView.setBackgroundColor(color) + } } diff --git a/android/navi-gold/src/main/java/com/navi/gold/util/Constants.kt b/android/navi-gold/src/main/java/com/navi/gold/util/Constants.kt index e07bf96546..f585325916 100644 --- a/android/navi-gold/src/main/java/com/navi/gold/util/Constants.kt +++ b/android/navi-gold/src/main/java/com/navi/gold/util/Constants.kt @@ -64,6 +64,7 @@ object Constants { const val GOLD_INVESTMENT_PLAN_WIDGET = "GOLD_INVESTMENT_PLAN_WIDGET" const val SIP_SETUP_SUCCESS_CARD = "SIP_SETUP_SUCCESS_CARD" const val SIP_SETUP_IN_PROGRESS = "SIP_SETUP_IN_PROGRESS" + const val SETUP_SIP_WIDGET = "SETUP_SIP_WIDGET" const val BUY_SUMMARY_BOTTOM_SHEET = "buy-summary-bottomsheet" const val PAN_VERIFY_BOTTOM_SHEET = "pan_verify_bottom_sheet" const val LOADER = "loader" diff --git a/android/navi-gold/src/main/java/com/navi/gold/viewmodels/DigitalGoldHomeVM.kt b/android/navi-gold/src/main/java/com/navi/gold/viewmodels/DigitalGoldHomeVM.kt index b54651cb30..27c34c5ebf 100644 --- a/android/navi-gold/src/main/java/com/navi/gold/viewmodels/DigitalGoldHomeVM.kt +++ b/android/navi-gold/src/main/java/com/navi/gold/viewmodels/DigitalGoldHomeVM.kt @@ -7,6 +7,7 @@ package com.navi.gold.viewmodels +import android.graphics.Color import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope @@ -74,6 +75,7 @@ constructor( private var actualSellAmount: Double = 0.0 private var remainingAmount: Double = 0.0 + private var statusBarColor: Int = Color.WHITE private val _buyBottomSheetData = SingleLiveEvent() val buyBottomSheetData: LiveData @@ -119,6 +121,12 @@ constructor( fun getRemainingAmount() = remainingAmount + fun setStatusBarColor(color: Int) { + statusBarColor = color + } + + fun getStatusBarColor() = statusBarColor + fun setUserEnteredGoldValue(userEnteredGoldValue: String) { _goldValueState.value = userEnteredGoldValue } diff --git a/android/navi-gold/src/main/java/com/navi/gold/viewmodels/DigitalGoldTransactionVM.kt b/android/navi-gold/src/main/java/com/navi/gold/viewmodels/DigitalGoldTransactionVM.kt index 9c6ba50523..7b170e1b04 100644 --- a/android/navi-gold/src/main/java/com/navi/gold/viewmodels/DigitalGoldTransactionVM.kt +++ b/android/navi-gold/src/main/java/com/navi/gold/viewmodels/DigitalGoldTransactionVM.kt @@ -7,6 +7,7 @@ package com.navi.gold.viewmodels +import android.graphics.Color import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope @@ -59,6 +60,7 @@ constructor( get() = isCsatCoroutineScopeCancelled private var isAutoClickConsumed: Boolean = false + private var statusBarColor: Int = Color.WHITE private val _scratchCardResponse = SingleLiveEvent() val scratchCardResponse: LiveData @@ -210,4 +212,12 @@ constructor( } } } + + fun setStatusBarColor(color: Int) { + statusBarColor = color + } + + fun getStatusBarColor(): Int { + return statusBarColor + } } diff --git a/android/navi-gold/src/main/res/layout/activity_digital_gold_home.xml b/android/navi-gold/src/main/res/layout/activity_digital_gold_home.xml index 7b2dc46be0..d8c418da82 100644 --- a/android/navi-gold/src/main/res/layout/activity_digital_gold_home.xml +++ b/android/navi-gold/src/main/res/layout/activity_digital_gold_home.xml @@ -37,9 +37,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:clipToPadding="false" - android:shadowColor="@color/shadowColorTwo" app:cardBackgroundColor="@color/white" - app:cardElevation="@dimen/dp_6" + app:cardElevation="@dimen/dp_0" app:layout_constraintBottom_toTopOf="@id/rvGoldItems" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/android/navi-gold/src/main/res/layout/activity_digital_gold_transaction.xml b/android/navi-gold/src/main/res/layout/activity_digital_gold_transaction.xml index 0879b9c5f7..11cb9fa5c3 100644 --- a/android/navi-gold/src/main/res/layout/activity_digital_gold_transaction.xml +++ b/android/navi-gold/src/main/res/layout/activity_digital_gold_transaction.xml @@ -24,7 +24,7 @@ android:clipToPadding="false" android:shadowColor="@color/shadowColorTwo" app:cardBackgroundColor="@color/white" - app:cardElevation="@dimen/dp_6" + app:cardElevation="@dimen/dp_0" app:layout_constraintBottom_toTopOf="@id/rvGoldItems" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/GoldConversionWidgetInfo.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/GoldConversionWidgetInfo.kt index e7a5372fcf..8b4ac7afb8 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/GoldConversionWidgetInfo.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/GoldConversionWidgetInfo.kt @@ -91,4 +91,6 @@ interface GoldConversionWidgetInfo { fun rewardInfoData(): RewardInfoData? fun fallbackRewardInfoData(): RewardInfoData? + + fun minOfferText(): NaviTextComponent? } diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/DualActionButtonWidget.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/DualActionButtonWidget.kt index b981f64e00..4dcab185b0 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/DualActionButtonWidget.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/DualActionButtonWidget.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022-2023 by Navi Technologies Limited + * * Copyright © 2022-2024 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -33,5 +33,6 @@ data class DualActionButtonWidgetData( @SerializedName("ctaRadius") val ctaRadius: Boolean? = null, @SerializedName("alignment") val alignment: String? = null, @SerializedName("showBtnLoader") var showBtnLoader: Boolean? = null, + @SerializedName("showDivider") var showDivider: Boolean? = false, var isPrimaryCtaClick: Boolean = true ) : Serializable diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/GoldConversionWidget.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/GoldConversionWidget.kt index b080d15c9d..96b2da5ed9 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/GoldConversionWidget.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/GoldConversionWidget.kt @@ -113,6 +113,8 @@ data class GoldConversionWidget( override fun rewardInfoData(): RewardInfoData? = widgetData?.rewardInfoData override fun fallbackRewardInfoData(): RewardInfoData? = widgetData?.fallbackRewardInfoData + + override fun minOfferText(): NaviTextComponent? = widgetData?.minOfferText } data class GoldConversionData( @@ -149,7 +151,8 @@ data class GoldConversionData( @SerializedName("dynamicText") val dynamicText: DynamicText? = null, @SerializedName("isRoundOffSavingsEnabled") val isRoundOffSavingsEnabled: Boolean? = false, @SerializedName("rewardInfoData") val rewardInfoData: RewardInfoData? = null, - @SerializedName("fallbackRewardInfoData") val fallbackRewardInfoData: RewardInfoData? = null + @SerializedName("fallbackRewardInfoData") val fallbackRewardInfoData: RewardInfoData? = null, + @SerializedName("minOfferText") val minOfferText: NaviTextComponent? = null ) : Serializable data class AmountConstraint( @@ -183,7 +186,11 @@ data class AmountChipData( data class ActionButtonStyle( @SerializedName("bgColor") val bgColor: String? = null, @SerializedName("radius") val radius: Radius? = null, - @SerializedName("padding") val padding: Padding? = null + @SerializedName("padding") val padding: Padding? = null, + @SerializedName("borderWidth") val borderWidth: Int? = null, + @SerializedName("borderColor") val borderColor: String? = null, + @SerializedName("width") val width: Int? = null, + @SerializedName("height") val height: Int? = null ) : Parcelable @Parcelize diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/GoldPortfolioWidget.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/GoldPortfolioWidget.kt new file mode 100644 index 0000000000..b367a96252 --- /dev/null +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/GoldPortfolioWidget.kt @@ -0,0 +1,55 @@ +/* + * + * * Copyright © 2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.ActionData +import com.navi.design.textview.model.TextWithStyle +import com.navi.naviwidgets.models.response.ImageFieldData +import com.navi.naviwidgets.models.response.WidgetError + +data class GoldPortfolioWidget( + @SerializedName("widgetId") override val widgetId: String? = null, + @SerializedName("widgetName") override var widgetNameForBaseAdapter: String? = WIDGET_NAME, + @SerializedName("widgetLayoutParams") val widgetLayoutParams: WidgetLayoutParams? = null, + @SerializedName("widgetData") val widgetData: GoldPortfolioInfoWidgetData? = null, + @SerializedName("isDependentWidget") override val isDependentWidget: Boolean? = null, + @SerializedName("dependencyWidgetId") override val dependencyWidgetId: String? = null, + override var isDependencyWidgetShowing: Boolean? = null, + override var widgetError: WidgetError? = null +) : NaviWidget() { + companion object { + const val WIDGET_NAME = "GOLD_PORTFOLIO_INFO_WIDGET" + } +} + +data class GoldPortfolioInfoWidgetData( + @SerializedName("widgetLayoutParams") val widgetLayoutParams: WidgetLayoutParams? = null, + @SerializedName("topTextData") val topTextData: TitleSubtitleDataV2? = null, + @SerializedName("bottomTextData") val bottomTextData: TitleSubtitleDataV2? = null, + @SerializedName("actionData") val actionData: ActionData? = null, + @SerializedName("properties") val properties: CardProperties? = null, + @SerializedName("showDivider") val showDivider: Boolean? = false +) + +data class TitleSubtitleDataV2( + @SerializedName("titleData") val titleData: TextWithStyle? = null, + @SerializedName("subtitleData") val subtitleData: TitleData? = null +) + +data class TitleData( + @SerializedName("startInfo") val startInfo: TitleItem? = null, + @SerializedName("middleInfo") val middleInfo: TitleItem? = null, + @SerializedName("endInfo") val endInfo: TitleItem? = null +) + +data class TitleItem( + @SerializedName("leftText") val leftText: TextWithStyle? = null, + @SerializedName("rightText") val rightText: TextWithStyle? = null, + @SerializedName("middleIcon") val middleIcon: ImageFieldData? = null +) diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/OfferCardWidget.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/OfferCardWidget.kt new file mode 100644 index 0000000000..0d14410ba3 --- /dev/null +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/OfferCardWidget.kt @@ -0,0 +1,87 @@ +/* + * + * * Copyright © 2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models + +import android.os.Parcelable +import com.google.gson.annotations.SerializedName +import com.navi.base.model.ActionData +import com.navi.design.textview.model.TextWithStyle +import com.navi.naviwidgets.models.response.CardProperties +import com.navi.naviwidgets.models.response.Gradient +import com.navi.naviwidgets.models.response.ImageFieldData +import com.navi.naviwidgets.models.response.TextFieldData +import com.navi.naviwidgets.models.response.WidgetError +import java.io.Serializable +import kotlinx.parcelize.Parcelize + +data class OfferCardWidget( + @SerializedName("widgetId") override val widgetId: String?, + @SerializedName("widgetName") override var widgetNameForBaseAdapter: String? = WIDGET_NAME, + @SerializedName("widgetData") val widgetData: OfferCardWidgetData? = null, + override val isDependentWidget: Boolean?, + override val dependencyWidgetId: String?, + override var isDependencyWidgetShowing: Boolean?, + override var widgetError: WidgetError? +) : NaviWidget(), Serializable { + companion object { + const val WIDGET_NAME = "OFFER_CARD_WIDGET" + } +} + +data class OfferCardWidgetData( + @SerializedName("title") val title: TextWithStyle? = null, + @SerializedName("subTitle", alternate = ["subtitle"]) val subTitle: TextWithStyle? = null, + @SerializedName("rightTitleTag") val rightTitleTag: TagData? = null, + @SerializedName("rightText") val rightText: TextWithStyle? = null, + @SerializedName("leftIcon") val leftIcon: ImageFieldData? = null, + @SerializedName("rightIcon") val rightIcon: ImageFieldData? = null, + @SerializedName("actionData") val actionData: ActionData? = null, + @SerializedName("offerBottomSheetData") val offerBottomSheetData: OfferBottomSheetData? = null, + @SerializedName("minOfferAmount") val minOfferAmount: Double? = null, + var userEnteredAmount: Double? = null +) + +@Parcelize +data class OfferBottomSheetData( + @SerializedName("header") val header: OfferHeaderData? = null, + @SerializedName("contentList") val content: OfferSectionData? = null, + @SerializedName("footer") val footer: OfferFooterData? = null, + @SerializedName("extraProperties") val extraProperties: CardProperties? = null +) : Parcelable + +@Parcelize +data class OfferSectionData( + @SerializedName("offerTickets") val offerTickets: List? = null +) : Parcelable + +@Parcelize +data class OfferHeaderData( + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("leftIcon") val leftIcon: ImageFieldData? = null, + @SerializedName("rightIcon") val rightIcon: ImageFieldData? = null +) : Parcelable + +@Parcelize +data class OfferContentData( + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("titleIcon") val titleIcon: ImageFieldData? = null, + @SerializedName("titleSuffix") val titleSuffix: TextFieldData? = null, + @SerializedName("titleBgGradient") val titleBgGradient: Gradient? = null, + @SerializedName("startIcon") val startIcon: ImageFieldData? = null, + @SerializedName("subTitle") val subTitle: TextFieldData? = null, + @SerializedName("additionalInfoPrefix") val additionalInfoPrefix: TextFieldData? = null, + @SerializedName("additionalInfoAmount") val additionalInfoAmount: TextFieldData? = null, + @SerializedName("additionalInfoSuffix") val additionalInfoSuffix: TextFieldData? = null, + @SerializedName("showDivider") val showDivider: Boolean? = null, + @SerializedName("applicableInfo") val applicableInfo: List? = null, + @SerializedName("cardProperties") val cardProperties: ContainerWidgetData? = null, + var remainingAmount: String? = null +) : Parcelable + +@Parcelize +data class OfferFooterData(@SerializedName("icon") val icon: ImageFieldData? = null) : Parcelable diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/SimpleTextWidget.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/SimpleTextWidget.kt index 1fbf551244..12b79210a1 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/SimpleTextWidget.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/SimpleTextWidget.kt @@ -12,6 +12,7 @@ import com.google.gson.annotations.SerializedName import com.navi.base.model.ActionData import com.navi.design.common.Padding import com.navi.naviwidgets.models.response.Gradient +import com.navi.naviwidgets.models.response.ImageFieldData import com.navi.naviwidgets.models.response.WidgetError import com.navi.naviwidgets.widgets.textdisplay.Margin import java.io.Serializable @@ -44,6 +45,7 @@ data class SimpleTextWidgetData( @SerializedName("lottieDimen") val lottieDimen: LottieDimen? = null, @SerializedName("lottieMargin") val lottieMargin: Margin? = null, @SerializedName("startIconCode") val startIconCode: String? = null, + @SerializedName("startIconData") val startIconData: ImageFieldData? = null, @SerializedName("startIconPadding") val startIconPadding: Int? = null, @SerializedName("endIconStartMargin") val endIconStartMargin: Float? = null, @SerializedName("isPadding") val isPadding: Boolean? = true, diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/SipCardWidget.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/SipCardWidget.kt new file mode 100644 index 0000000000..20901a6b29 --- /dev/null +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/SipCardWidget.kt @@ -0,0 +1,59 @@ +/* + * + * * Copyright © 2022-2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +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.design.textview.model.TextWithStyle +import com.navi.naviwidgets.models.response.Gradient +import com.navi.naviwidgets.models.response.ImageFieldData +import com.navi.naviwidgets.models.response.WidgetError +import java.io.Serializable + +data class SipCardWidget( + @SerializedName("widgetId") override val widgetId: String? = null, + @SerializedName("widgetName") override var widgetNameForBaseAdapter: String? = WIDGET_NAME, + @SerializedName("widgetData") val widgetData: SipCardData? = null, + override val isDependentWidget: Boolean? = null, + override val dependencyWidgetId: String? = null, + override var isDependencyWidgetShowing: Boolean? = null, + override var widgetError: WidgetError? = null +) : NaviWidget(), Serializable { + companion object { + const val WIDGET_NAME = "SETUP_SIP_WIDGET" + } +} + +data class SipCardData( + @SerializedName("title") val title: TextWithStyle? = null, + @SerializedName("subtitle") val subTitle: TextWithStyle? = null, + @SerializedName("actionData") val actionData: ActionData? = null, + @SerializedName("actionButtonStyle") val actionButtonStyle: ActionButtonStyle? = null, + @SerializedName("image") val image: ImageFieldData? = null, + @SerializedName("cardProperties") val cardProperties: CardProperties? = null, + @SerializedName("footer") val footer: Footer? = null, + @SerializedName("btnTitle") val btnTitle: TextWithStyle? = null, + var buttonLoaderState: ButtonLoaderState? = null +) + +data class Footer( + @SerializedName("title") val title: TextWithStyle? = null, + @SerializedName("startIcon") val startIcon: ImageFieldData? = null, + @SerializedName("bgColor") val bgColor: String? = null, + @SerializedName("radius") val radius: Radius? = null +) + +data class CardProperties( + @SerializedName("gradient") val gradientProperties: Gradient? = null, + @SerializedName("padding") val padding: Padding? = null, + @SerializedName("bgColor") val bgColor: String? = null, + @SerializedName("radius") val radius: Radius? = null, + @SerializedName("borderWidth") val borderWidth: Int? = null, + @SerializedName("borderColor") val borderColor: String? = null +) diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/TextCardWithShimmerWidget.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/TextCardWithShimmerWidget.kt index 77c6a25477..6ec14d3131 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/TextCardWithShimmerWidget.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/TextCardWithShimmerWidget.kt @@ -7,20 +7,13 @@ package com.navi.naviwidgets.models -import android.os.Parcelable import com.google.gson.annotations.SerializedName import com.navi.base.model.ActionData -import com.navi.base.model.ImageDetail import com.navi.design.textview.model.TextWithStyle import com.navi.design.textview.model.TextWithStyleVariation -import com.navi.naviwidgets.models.response.CardProperties -import com.navi.naviwidgets.models.response.Gradient -import com.navi.naviwidgets.models.response.ImageFieldData import com.navi.naviwidgets.models.response.TagData -import com.navi.naviwidgets.models.response.TextFieldData import com.navi.naviwidgets.models.response.WidgetError import java.io.Serializable -import kotlinx.parcelize.Parcelize data class TextCardWithShimmerWidget( @SerializedName("widgetId") override val widgetId: String?, @@ -54,7 +47,7 @@ data class TextCardWithShimmerWidgetData( @SerializedName("isShimmerEnabled") val isShimmerEnabled: Boolean? = null, @SerializedName("isDisabled") val isDisabled: Boolean? = null, @SerializedName("removeElevation") val removeElevation: Boolean? = null, - @SerializedName("offerDetails") val offerDetails: OfferDetails? = null, + @SerializedName("elevation") val elevation: Float? = null, @SerializedName("marketPriceData") val marketPriceData: PriceData? = null, @SerializedName("naviPriceData") val naviPriceData: PriceData? = null, @SerializedName("comparisonData") val comparisonData: TextWithStyle? = null, @@ -68,46 +61,3 @@ data class PriceData( @SerializedName("priceValue") var priceValue: TextWithStyleVariation? = null, @SerializedName("isShimmerEnabled") var isShimmerEnabled: Boolean? = null ) - -data class OfferDetails( - @SerializedName("title") val title: TextWithStyle? = null, - @SerializedName("subTitle") val subTitle: TextWithStyle? = null, - @SerializedName("rightText") val rightText: TextWithStyle? = null, - @SerializedName("leftIcon") val leftIcon: ImageDetail? = null, - @SerializedName("rightIcon") val rightIcon: ImageDetail? = null, - @SerializedName("actionData") val actionData: ActionData? = null, - @SerializedName("offerBottomSheetData") val offerBottomSheetData: OfferBottomSheetData? = null -) - -@Parcelize -data class OfferBottomSheetData( - @SerializedName("header") val header: OfferHeaderData? = null, - @SerializedName("content") val content: OfferContentData? = null, - @SerializedName("footer") val footer: OfferFooterData? = null, - @SerializedName("extraProperties") val extraProperties: CardProperties? = null -) : Parcelable - -@Parcelize -data class OfferHeaderData( - @SerializedName("title") val title: TextFieldData? = null, - @SerializedName("leftIcon") val leftIcon: ImageFieldData? = null, - @SerializedName("rightIcon") val rightIcon: ImageFieldData? = null -) : Parcelable - -@Parcelize -data class OfferContentData( - @SerializedName("title") val title: TextFieldData? = null, - @SerializedName("titleBgGradient") val titleBgGradient: Gradient? = null, - @SerializedName("startIcon") val startIcon: ImageFieldData? = null, - @SerializedName("subTitle") val subTitle: TextFieldData? = null, - @SerializedName("additionalInfoPrefix") val additionalInfoPrefix: TextFieldData? = null, - @SerializedName("additionalInfoAmount") val additionalInfoAmount: TextFieldData? = null, - @SerializedName("additionalInfoSuffix") val additionalInfoSuffix: TextFieldData? = null, - @SerializedName("showDivider") val showDivider: Boolean? = null, - @SerializedName("applicableInfo") val applicableInfo: List? = null, - @SerializedName("cardProperties") val cardProperties: ContainerWidgetData? = null, - var remainingAmount: String? = null -) : Parcelable - -@Parcelize -data class OfferFooterData(@SerializedName("icon") val icon: ImageFieldData? = null) : Parcelable diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HeaderItemListWidget.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HeaderItemListWidget.kt index cfd6795bf9..32d0d1e41b 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HeaderItemListWidget.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HeaderItemListWidget.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019-2023 by Navi Technologies Limited + * * Copyright © 2019-2024 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -50,6 +50,7 @@ data class TagData( @SerializedName("titleMargin") val titleMargin: Margin? = null, @SerializedName("bgColor") val bgColor: String? = null, @SerializedName("lottieFileName") val lottieFileName: String? = null, + @SerializedName("lottieUrl") val lottieUrl: String? = null, @SerializedName("radius") val radius: Radius? = null, @SerializedName("bgGradient") val bgGradient: Gradient? = null, @SerializedName("margin") val margin: Margin? = null, diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/GoldPortfolioWidgetVH.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/GoldPortfolioWidgetVH.kt new file mode 100644 index 0000000000..50a7cd044d --- /dev/null +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/GoldPortfolioWidgetVH.kt @@ -0,0 +1,42 @@ +/* + * + * * Copyright © 2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.GoldPortfolioWidgetLayoutBinding +import com.navi.naviwidgets.models.GoldPortfolioWidget +import com.navi.naviwidgets.widgets.GoldPortfolioWidgetLayout + +class GoldPortfolioWidgetVH(private val viewBinding: ViewDataBinding) : + BaseViewHolder(view = viewBinding.root) { + + override fun bind( + model: GoldPortfolioWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if (itemView is GoldPortfolioWidgetLayout) { + (itemView as GoldPortfolioWidgetLayout).update( + binding = (viewBinding as GoldPortfolioWidgetLayoutBinding), + widgetData = model, + widgetCallback = widgetCallback, + position = position + ) + } + } + + override fun bindError(errorData: Any?) { + /*No-op*/ + } + + override fun bindWidgetStateChanged(payload: Any?) { + /*No-op*/ + } +} diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/OfferCardWidgetVH.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/OfferCardWidgetVH.kt new file mode 100644 index 0000000000..97e9db8da2 --- /dev/null +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/OfferCardWidgetVH.kt @@ -0,0 +1,42 @@ +/* + * + * * Copyright © 2022-2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.OfferCardWidgetLayoutBinding +import com.navi.naviwidgets.models.OfferCardWidget +import com.navi.naviwidgets.widgets.OfferCardWidgetLayout + +class OfferCardWidgetVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(viewDataBinding.root) { + + override fun bind( + model: OfferCardWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if (itemView is OfferCardWidgetLayout) { + (itemView as OfferCardWidgetLayout).update( + widgetData = model, + binding = viewDataBinding as OfferCardWidgetLayoutBinding, + widgetCallback = widgetCallback, + position = position + ) + } + } + + override fun bindError(errorData: Any?) { + /*No-op*/ + } + + override fun bindWidgetStateChanged(payload: Any?) { + /*No-op*/ + } +} diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/SipCardWidgetVH.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/SipCardWidgetVH.kt new file mode 100644 index 0000000000..5045754d81 --- /dev/null +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/SipCardWidgetVH.kt @@ -0,0 +1,51 @@ +/* + * + * * Copyright © 2019-2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.SipCardWidgetLayoutBinding +import com.navi.naviwidgets.models.ButtonLoaderState +import com.navi.naviwidgets.models.SipCardWidget +import com.navi.naviwidgets.widgets.SipCardWidgetLayout + +class SipCardWidgetVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(viewDataBinding.root) { + + override fun bind( + model: SipCardWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if (itemView is SipCardWidgetLayout) { + (itemView as SipCardWidgetLayout).update( + widgetData = model, + binding = viewDataBinding as SipCardWidgetLayoutBinding, + widgetCallback = widgetCallback, + position = position + ) + } + } + + override fun bindError(errorData: Any?) { + /*No-op*/ + } + + override fun bindWidgetStateChanged(payload: Any?) { + if (itemView is SipCardWidgetLayout) { + when (payload) { + is ButtonLoaderState -> { + (itemView as SipCardWidgetLayout).updateButtonLoader( + buttonLoaderState = payload + ) + } + } + } + } +} diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ViewHolderFactoryImpl.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ViewHolderFactoryImpl.kt index b49461d8c6..2e7191a5f9 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ViewHolderFactoryImpl.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ViewHolderFactoryImpl.kt @@ -51,6 +51,7 @@ import com.navi.naviwidgets.models.GenericWidgetDataInfo import com.navi.naviwidgets.models.GoldConversionWidget import com.navi.naviwidgets.models.GoldImageCarousalWidget import com.navi.naviwidgets.models.GoldPortfolioCardWidget +import com.navi.naviwidgets.models.GoldPortfolioWidget import com.navi.naviwidgets.models.GraphWidget import com.navi.naviwidgets.models.GridCustomBannerWidget import com.navi.naviwidgets.models.GridCustomBannerWidgetItem @@ -80,6 +81,7 @@ import com.navi.naviwidgets.models.LottieTextCardWidget import com.navi.naviwidgets.models.LottieWidget import com.navi.naviwidgets.models.NaviBaseAdapterModel import com.navi.naviwidgets.models.OfferBannerWidget +import com.navi.naviwidgets.models.OfferCardWidget import com.navi.naviwidgets.models.OptionsWithIconWidget import com.navi.naviwidgets.models.PaymentWidget import com.navi.naviwidgets.models.PostDisbursalSuccessWidget @@ -94,6 +96,7 @@ import com.navi.naviwidgets.models.RewardEarnWidget import com.navi.naviwidgets.models.RewardsBackgroundWidget import com.navi.naviwidgets.models.ShimmerAdvertisementWidget import com.navi.naviwidgets.models.SimpleTextWidget +import com.navi.naviwidgets.models.SipCardWidget import com.navi.naviwidgets.models.SpannableTitleTextWithButtonAndImageWidget import com.navi.naviwidgets.models.StaggeredBgImageTextWidget import com.navi.naviwidgets.models.StepsWidget @@ -637,6 +640,9 @@ class ViewHolderFactoryImpl : ViewHolderTypeFactory R.layout.spannable_title_text_with_button_and_image private val REWARD_CALLOUT_WIDGET = R.layout.reward_callout_widget_layout private val ADVERSE_WIDGET = R.layout.adverse_content_view + private val OFFER_CARD_WIDGET = R.layout.offer_card_widget_layout + private val GOLD_PORTFOLIO_WIDGET = R.layout.gold_portfolio_widget_layout + private val SIP_CARD_WIDGET = R.layout.sip_card_widget_layout } override fun type(item: NaviBaseAdapterModel?): Int = @@ -922,6 +928,9 @@ class ViewHolderFactoryImpl : ViewHolderTypeFactory SPANNABLE_TITLE_TEXT_WITH_BUTTON_AND_IMAGE_WIDGET is RewardCalloutWidget -> REWARD_CALLOUT_WIDGET is AdverseWidget -> ADVERSE_WIDGET + is OfferCardWidget -> OFFER_CARD_WIDGET + is GoldPortfolioWidget -> GOLD_PORTFOLIO_WIDGET + is SipCardWidget -> SIP_CARD_WIDGET // Default case, add all widgets above this is GenericWidgetDataInfo -> GENERIC_WIDGET else -> { @@ -1224,6 +1233,9 @@ class ViewHolderFactoryImpl : ViewHolderTypeFactory SpannableTextTitleWithButtonAndImageVH(parent) REWARD_CALLOUT_WIDGET -> RewardCalloutWidgetVH(parent) ADVERSE_WIDGET -> AdverseWidgetVH(parent) + OFFER_CARD_WIDGET -> OfferCardWidgetVH(parent) + GOLD_PORTFOLIO_WIDGET -> GoldPortfolioWidgetVH(parent) + SIP_CARD_WIDGET -> SipCardWidgetVH(parent) else -> UnknownWidgetVH(parent) } as BaseViewHolder diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/views/ButtonViewLayout.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/views/ButtonViewLayout.kt index f090aed346..0a07a214f3 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/views/ButtonViewLayout.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/views/ButtonViewLayout.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2023 by Navi Technologies Limited + * * Copyright © 2023-2024 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -18,6 +18,7 @@ import androidx.databinding.DataBindingUtil import com.navi.base.model.ActionData import com.navi.base.utils.orFalse import com.navi.base.utils.orZero +import com.navi.design.common.Padding import com.navi.design.textview.model.TextWithStyle import com.navi.design.utils.CornerRadius import com.navi.design.utils.dpToPx @@ -47,6 +48,7 @@ class ButtonViewLayout(context: Context, attributeSet: AttributeSet) : widgetCallback: WidgetCallback? = null, title: TextWithStyle? = null, radius: Int? = null, + padding: Padding? = null, widgetId: String? = null, buttonLoaderState: ButtonLoaderState? = null ) { @@ -56,6 +58,14 @@ class ButtonViewLayout(context: Context, attributeSet: AttributeSet) : binding.title.text = actionData?.title binding.title.setTextColor(Color.parseColor(actionData?.titleColor)) } + padding?.let { + binding.rootLayout.setPadding( + dpToPxInInt(padding.start ?: 16), + dpToPxInInt(padding.top ?: 10), + dpToPxInInt(padding.end ?: 16), + dpToPxInInt(padding.bottom ?: 10) + ) + } radius?.let { binding.rootLayout.background = getNaviDrawable( diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/DualActionButtonWidgetLayout.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/DualActionButtonWidgetLayout.kt index 1e08b185a4..9413f76924 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/DualActionButtonWidgetLayout.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/DualActionButtonWidgetLayout.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2023 by Navi Technologies Limited + * * Copyright © 2023-2024 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -94,8 +94,21 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 rightTop = dpToPx(btnStyle.radius?.rightTop.orZero()), leftBottom = dpToPx(btnStyle.radius?.leftBottom.orZero()), rightBottom = dpToPx(btnStyle.radius?.rightBottom.orZero()) - ) + ), + strokeWidth = dpToPxInInt(btnStyle.borderWidth.orZero()), + strokeColor = + if (btnStyle.borderColor.isNotNull()) btnStyle.borderColor.parseColorSafe() + else null ) + btnStyle.height?.let { tvAction.layoutParams.height = dpToPxInInt(it) } + btnStyle.padding?.let { padding -> + tvAction.setPadding( + padding.start ?: 16, + padding.top ?: 8, + padding.end ?: 16, + padding.bottom ?: 8 + ) + } } if (removeText == true) { @@ -142,6 +155,9 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 widgetCallback.parentClicked() } else { info.widgetData?.isPrimaryCtaClick = isPrimaryCta + widgetCallback.widgetAnalytics( + genericAnalyticsData = btnWidgetData?.actionData?.metaData?.clickedData + ) widgetCallback.onClick( NaviWidgetClickWithActionData( actionData = btnWidgetData?.actionData, @@ -174,6 +190,9 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 info.widgetData?.secondaryCta, isPrimaryCta = false ) + if (info.widgetData?.showDivider == true) { + divider.visibility = View.VISIBLE + } if (info.widgetData?.alignment.equals("VERTICAL")) { diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/GoldConversionWidgetLayout.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/GoldConversionWidgetLayout.kt index df09ff66b3..368e879ca7 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/GoldConversionWidgetLayout.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/GoldConversionWidgetLayout.kt @@ -215,6 +215,32 @@ constructor( ivError.showWhenDataIsAvailable(imageDetail = ImageDetail(url = info.errorIconCode())) tvError.text = info.errorText()?.text.spannedText(context = context, span = info.errorText()?.span) + + info.amountConstraint()?.minOfferAmount?.let { + val offerAmount = info.amountConstraint()?.minOfferAmount ?: 0.0 + val minAmount = info.amountConstraint()?.min ?: 0.0 + val maxAmount = info.amountConstraint()?.max ?: 0.0 + val amountEntered = info.actualAmount() ?: 0.0 + if ( + amountEntered >= minAmount && + amountEntered < offerAmount && + info.minOfferText()?.text.isNotNullAndNotEmpty() + ) { + updateOfferNotAppliedText() + setBackgroundForAmountLayout() + setActionButtonState() + } else if ( + amountEntered in offerAmount..maxAmount && + info.offerText()?.text.isNotNullAndNotEmpty() + ) { + updateOfferAppliedText() + setBackgroundForAmountLayout() + setActionButtonState() + } else { + resetErrorState() + } + } + if (info.enableSellableAmount() == true) { cbSellAmount.isVisible = true cbSellAmount.text = @@ -793,7 +819,6 @@ constructor( fun updatePollingAmountAndWeight(goldConversionData: GoldConversionData?) { goldConversionData?.let { - resetErrorState() binding.apply { val amount = info.actualAmount() ?: 0.0 if (amount > 0.0) { @@ -863,9 +888,21 @@ constructor( this.info = info info.amountConstraint()?.minOfferAmount?.let { val offerAmount = info.amountConstraint()?.minOfferAmount ?: 0.0 + val minAmount = info.amountConstraint()?.min ?: 0.0 val maxAmount = info.amountConstraint()?.max ?: 0.0 val amountEntered = info.actualAmount() ?: 0.0 - if (amountEntered in offerAmount..maxAmount) { + if ( + amountEntered >= minAmount && + amountEntered < offerAmount && + info.minOfferText()?.text.isNotNullAndNotEmpty() + ) { + updateOfferNotAppliedText() + setBackgroundForAmountLayout() + setActionButtonState() + } else if ( + amountEntered in offerAmount..maxAmount && + info.offerText()?.text.isNotNullAndNotEmpty() + ) { updateOfferAppliedText() setBackgroundForAmountLayout() setActionButtonState() @@ -906,6 +943,16 @@ constructor( binding.ivError.showWhenDataIsAvailable(info.offerIcon()) } + private fun updateOfferNotAppliedText() { + binding.clError.isVisible = true + binding.tvError.text = + info + .minOfferText() + ?.text + .spannedText(context = context, span = info.minOfferText()?.span) + binding.ivError.showWhenDataIsAvailable(info.offerIcon()) + } + private fun chipGroupViewInit( items: List? = null, isDisabled: Boolean? = false diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/GoldPortfolioWidgetLayout.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/GoldPortfolioWidgetLayout.kt new file mode 100644 index 0000000000..5f3ea90806 --- /dev/null +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/GoldPortfolioWidgetLayout.kt @@ -0,0 +1,134 @@ +/* + * + * * Copyright © 2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible +import com.navi.base.model.ActionData +import com.navi.design.utils.CornerRadius +import com.navi.design.utils.GradientOrientation +import com.navi.design.utils.dpToPxInInt +import com.navi.design.utils.getNaviDrawable +import com.navi.design.utils.parseColorSafe +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.GoldPortfolioWidgetLayoutBinding +import com.navi.naviwidgets.databinding.PortfolioSubtitleItemBinding +import com.navi.naviwidgets.extensions.setImageFieldData +import com.navi.naviwidgets.extensions.showWhenDataIsAvailable +import com.navi.naviwidgets.models.GoldPortfolioWidget +import com.navi.naviwidgets.models.TitleData +import com.navi.naviwidgets.models.TitleSubtitleDataV2 +import com.navi.naviwidgets.utils.setPadding +import com.navi.naviwidgets.utils.setWidgetLayoutParams + +class GoldPortfolioWidgetLayout +@JvmOverloads +constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + ConstraintLayout(context, attrs, defStyleAttr) { + + private lateinit var binding: GoldPortfolioWidgetLayoutBinding + private var widgetData: GoldPortfolioWidget? = null + private lateinit var widgetCallback: WidgetCallback + private var widgetPosition: Int = Int.MAX_VALUE + + fun update( + binding: GoldPortfolioWidgetLayoutBinding, + widgetData: GoldPortfolioWidget?, + widgetCallback: WidgetCallback, + position: Int + ) { + this.binding = binding + this.widgetData = widgetData + this.widgetCallback = widgetCallback + this.widgetPosition = position + setProperties() + } + + private fun setProperties() { + binding.apply { + widgetData?.widgetData?.let { data -> + widgetCallback.widgetAnalytics( + genericAnalyticsData = data.actionData?.metaData?.viewedData + ) + data.widgetLayoutParams?.let { setWidgetLayoutParams(it, root) } + data.properties?.padding?.let { padding -> + container.setPadding( + dpToPxInInt(padding.start ?: 0), + dpToPxInInt(padding.top ?: 0), + dpToPxInInt(padding.end ?: 0), + dpToPxInInt(padding.bottom ?: 0), + ) + } + data.properties?.gradientProperties?.let { gradientData -> + rootLayout.background = + getNaviDrawable( + gradientColors = + intArrayOf( + gradientData.startGradientColor.parseColorSafe(), + gradientData.endGradientColor.parseColorSafe() + ), + gradientOrientation = + GradientOrientation.valueOf( + gradientData.orientation ?: GradientOrientation.LEFT_RIGHT.name + ), + radii = CornerRadius(0f, 0f, 0f, 0f) + ) + } + data.topTextData?.let { topTextData -> + setupTopTextData(topTextData, data.actionData) + } + data.bottomTextData?.let { bottomTextData -> setupBottomTextData(bottomTextData) } + divider.isVisible = data.showDivider == true + } + } + } + + private fun setupTopTextData(topTextData: TitleSubtitleDataV2?, actionData: ActionData?) { + binding.apply { + topDataTitle.showWhenDataIsAvailable(topTextData?.titleData) + topTextData?.subtitleData?.let { subtitleData -> + topDataSubtitle.root.isVisible = true + setupSubtitleData(topDataSubtitle, subtitleData) + topDataSubtitle.root.setOnClickListener { + actionData?.let { + widgetCallback.onClick(it) + widgetCallback.widgetAnalytics( + genericAnalyticsData = it.metaData?.clickedData + ) + } + } + } + } + } + + private fun setupBottomTextData(bottomTextData: TitleSubtitleDataV2?) { + binding.apply { + bottomDataTitle.showWhenDataIsAvailable(bottomTextData?.titleData) + bottomTextData?.subtitleData?.let { subtitleData -> + bottomDataSubtitle.root.isVisible = true + setupSubtitleData(bottomDataSubtitle, subtitleData) + } + } + } + + private fun setupSubtitleData( + subtitle: PortfolioSubtitleItemBinding, + subtitleData: TitleData? + ) { + subtitle.apply { + startInfoLeftTitle.showWhenDataIsAvailable(subtitleData?.startInfo?.leftText) + startInfoMiddleIcon.setImageFieldData(subtitleData?.startInfo?.middleIcon) + startInfoRightTitle.showWhenDataIsAvailable(subtitleData?.startInfo?.rightText) + middleInfoLeftIcon.setImageFieldData(subtitleData?.middleInfo?.middleIcon) + middleText.showWhenDataIsAvailable(subtitleData?.middleInfo?.rightText) + endIcon.setImageFieldData(subtitleData?.endInfo?.middleIcon) + } + } +} diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviWidgetJsonDeserializer.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviWidgetJsonDeserializer.kt index c38aa8291a..b935b4fdca 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviWidgetJsonDeserializer.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviWidgetJsonDeserializer.kt @@ -349,6 +349,9 @@ class NaviWidgetJsonDeserializer : JsonDeserializer { SpannableTitleTextWithButtonAndImageWidget::class.java RewardCalloutWidget.WIDGET_NAME -> RewardCalloutWidget::class.java AdverseWidget.WIDGET_NAME -> AdverseWidget::class.java + GoldPortfolioWidget.WIDGET_NAME -> GoldPortfolioWidget::class.java + OfferCardWidget.WIDGET_NAME -> OfferCardWidget::class.java + SipCardWidget.WIDGET_NAME -> SipCardWidget::class.java else -> null } return if (className != null) { diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviWidgetJsonSerializer.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviWidgetJsonSerializer.kt index 089ab0324c..7d5ad6809b 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviWidgetJsonSerializer.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviWidgetJsonSerializer.kt @@ -33,6 +33,7 @@ import com.navi.naviwidgets.models.FundManagerWidget import com.navi.naviwidgets.models.GoldConversionWidget import com.navi.naviwidgets.models.GoldImageCarousalWidget import com.navi.naviwidgets.models.GoldPortfolioCardWidget +import com.navi.naviwidgets.models.GoldPortfolioWidget import com.navi.naviwidgets.models.GraphWidget import com.navi.naviwidgets.models.GridCustomBannerWidget import com.navi.naviwidgets.models.GridCustomBannerWidgetItem @@ -60,6 +61,7 @@ import com.navi.naviwidgets.models.LottieTextCardWidget import com.navi.naviwidgets.models.LottieWidget import com.navi.naviwidgets.models.NaviWidget import com.navi.naviwidgets.models.OfferBannerWidget +import com.navi.naviwidgets.models.OfferCardWidget import com.navi.naviwidgets.models.OptionsWithIconWidget import com.navi.naviwidgets.models.PaymentWidget import com.navi.naviwidgets.models.PostDisbursalSuccessWidget @@ -73,6 +75,7 @@ import com.navi.naviwidgets.models.RewardEarnWidget import com.navi.naviwidgets.models.RewardsBackgroundWidget import com.navi.naviwidgets.models.ShimmerAdvertisementWidget import com.navi.naviwidgets.models.SimpleTextWidget +import com.navi.naviwidgets.models.SipCardWidget import com.navi.naviwidgets.models.SpannableTitleTextWithButtonAndImageWidget import com.navi.naviwidgets.models.StaggeredBgImageTextWidget import com.navi.naviwidgets.models.StepsWidget @@ -545,6 +548,9 @@ class NaviWidgetJsonSerializer : JsonSerializer { SpannableTitleTextWithButtonAndImageWidget.WIDGET_NAME -> SpannableTitleTextWithButtonAndImageWidget::class.java AdverseWidget.WIDGET_NAME -> AdverseWidget::class.java + GoldPortfolioWidget.WIDGET_NAME -> GoldPortfolioWidget::class.java + OfferCardWidget.WIDGET_NAME -> OfferCardWidget::class.java + SipCardWidget.WIDGET_NAME -> SipCardWidget::class.java else -> null } return if (className != null) { diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/OfferCardWidgetLayout.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/OfferCardWidgetLayout.kt new file mode 100644 index 0000000000..23fbb4520e --- /dev/null +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/OfferCardWidgetLayout.kt @@ -0,0 +1,111 @@ +/* + * + * * Copyright © 2022-2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.cardview.widget.CardView +import androidx.core.view.isVisible +import com.navi.design.R as DesignR +import com.navi.design.utils.CornerRadius +import com.navi.design.utils.dpToPx +import com.navi.design.utils.getNaviDrawable +import com.navi.design.utils.parseColorSafe +import com.navi.design.utils.spannedText +import com.navi.naviwidgets.actions.GoldMinOfferSectionClickAction +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.OfferCardWidgetLayoutBinding +import com.navi.naviwidgets.extensions.setImageFieldData +import com.navi.naviwidgets.extensions.setVisibilityState +import com.navi.naviwidgets.extensions.showWhenDataIsAvailable +import com.navi.naviwidgets.models.OfferCardWidget + +class OfferCardWidgetLayout +@JvmOverloads +constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + CardView(context, attrs, defStyleAttr) { + + private lateinit var binding: OfferCardWidgetLayoutBinding + private lateinit var widgetCallback: WidgetCallback + private var widgetPosition: Int = Int.MAX_VALUE + private var offerCardWidget: OfferCardWidget? = null + + fun update( + widgetData: OfferCardWidget, + binding: OfferCardWidgetLayoutBinding, + widgetCallback: WidgetCallback, + position: Int + ) { + this.offerCardWidget = widgetData + this.binding = binding + this.widgetCallback = widgetCallback + this.widgetPosition = position + setProperties() + } + + private fun setProperties() { + binding.apply { + offerCardWidget?.widgetData?.let { data -> + widgetCallback.widgetAnalytics( + genericAnalyticsData = data.actionData?.metaData?.viewedData + ) + offerSectionLayout.visibility = VISIBLE + offerIcon.setImageFieldData(data.leftIcon) + offerTitle.showWhenDataIsAvailable(data.title) + data.rightTitleTag?.let { + binding.rightTitleTag.apply { + isVisible = true + rightTitleTag.text = + it.title?.text.spannedText(context = context, span = it.title?.span) + background = + getNaviDrawable( + backgroundColor = it.bgColor.parseColorSafe(), + radii = + CornerRadius( + leftBottom = + dpToPx( + it.radius?.leftBottom + ?: resources.getInteger(DesignR.integer.zero) + ), + leftTop = + dpToPx( + it.radius?.leftTop + ?: resources.getInteger(DesignR.integer.zero) + ), + rightBottom = + dpToPx( + it.radius?.rightBottom + ?: resources.getInteger(DesignR.integer.zero) + ), + rightTop = + dpToPx( + it.radius?.rightTop + ?: resources.getInteger(DesignR.integer.zero) + ) + ) + ) + } + } ?: binding.rightTitleTag.setVisibilityState(GONE) + offerSubTitle.showWhenDataIsAvailable(data.subTitle) + details.showWhenDataIsAvailable(data.rightText) + endIcon.setImageFieldData(data.rightIcon) + root.setOnClickListener { + widgetCallback.widgetAnalytics( + genericAnalyticsData = data.actionData?.metaData?.clickedData + ) + widgetCallback.onClick( + GoldMinOfferSectionClickAction( + offerSectionData = data.offerBottomSheetData, + actionData = data.actionData + ) + ) + } + } + } + } +} diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SimpleTextWidgetLayout.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SimpleTextWidgetLayout.kt index b3e3886b7f..d88aa95160 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SimpleTextWidgetLayout.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SimpleTextWidgetLayout.kt @@ -35,6 +35,7 @@ import com.navi.design.utils.spannedText import com.navi.naviwidgets.callbacks.WidgetCallback import com.navi.naviwidgets.databinding.SimpleTextWidgetLayoutBinding import com.navi.naviwidgets.extensions.setDrawables +import com.navi.naviwidgets.extensions.setImageFieldData import com.navi.naviwidgets.extensions.showWhenDataIsAvailable import com.navi.naviwidgets.models.SimpleTextWidget import com.navi.naviwidgets.models.TextGravity @@ -191,6 +192,7 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 } icon.showWhenDataIsAvailable(simpleTextWidget?.widgetData?.endIconCode) tagLottie.showWhenDataIsAvailable(simpleTextWidget?.widgetData?.lottieFileName) + startIcon.setImageFieldData(simpleTextWidget?.widgetData?.startIconData) simpleTextWidget?.widgetData?.lottieDimen?.let { lottieDimen -> tagLottie.updateLayoutParams { if (lottieDimen.width.isNotNull() && lottieDimen.height.isNotNull()) { @@ -208,6 +210,10 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 tagLottie.setMargin(lottieMargin) } + simpleTextWidget?.widgetData?.startIconPadding?.let { padding -> + startIcon.setMargin(Margin(startDp = padding.toFloat())) + } + simpleTextWidget?.widgetData?.gradient?.let { gradient -> binding.container.background = getNaviDrawable( diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SipCardWidgetLayout.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SipCardWidgetLayout.kt new file mode 100644 index 0000000000..3cb92f039b --- /dev/null +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SipCardWidgetLayout.kt @@ -0,0 +1,147 @@ +/* + * + * * Copyright © 2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible +import com.navi.base.utils.orZero +import com.navi.design.utils.CornerRadius +import com.navi.design.utils.dpToPx +import com.navi.design.utils.dpToPxInInt +import com.navi.design.utils.getNaviDrawable +import com.navi.design.utils.parseColorSafe +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.SipCardWidgetLayoutBinding +import com.navi.naviwidgets.extensions.setImageFieldData +import com.navi.naviwidgets.extensions.showWhenDataIsAvailable +import com.navi.naviwidgets.models.ButtonLoaderState +import com.navi.naviwidgets.models.Footer +import com.navi.naviwidgets.models.SipCardWidget + +class SipCardWidgetLayout +@JvmOverloads +constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + ConstraintLayout(context, attrs, defStyleAttr) { + + private lateinit var binding: SipCardWidgetLayoutBinding + private lateinit var widgetData: SipCardWidget + private lateinit var widgetCallback: WidgetCallback + private var widgetPosition: Int = Int.MAX_VALUE + + fun update( + binding: SipCardWidgetLayoutBinding, + widgetData: SipCardWidget, + widgetCallback: WidgetCallback, + position: Int + ) { + this.binding = binding + this.widgetData = widgetData + this.widgetCallback = widgetCallback + this.widgetPosition = position + setProperties() + } + + private fun setProperties() { + binding.apply { + widgetData?.widgetData?.let { data -> + widgetCallback.widgetAnalytics( + genericAnalyticsData = data.actionData?.metaData?.viewedData + ) + rootLayout.background = + getNaviDrawable( + backgroundColor = data.cardProperties?.bgColor.parseColorSafe(), + radii = + CornerRadius( + leftTop = dpToPx(data.cardProperties?.radius?.leftTop.orZero()), + rightTop = dpToPx(data.cardProperties?.radius?.rightTop.orZero()), + leftBottom = + dpToPx(data.cardProperties?.radius?.leftBottom.orZero()), + rightBottom = + dpToPx(data.cardProperties?.radius?.rightBottom.orZero()) + ), + strokeWidth = dpToPxInInt(data.cardProperties?.borderWidth.orZero()), + strokeColor = data.cardProperties?.borderColor?.parseColorSafe() + ) + title.showWhenDataIsAvailable(data.title) + subTitle.showWhenDataIsAvailable(data.subTitle) + rightIcon.setImageFieldData(data.image) + data.actionData?.let { actionData -> + actionBtn.visibility = View.VISIBLE + actionBtn.setProperties( + title = data.btnTitle, + actionData = actionData, + padding = data.actionButtonStyle?.padding, + widgetCallback = widgetCallback, + widgetId = widgetData.widgetId + ) + data.actionButtonStyle?.let { btnStyle -> + actionBtn.background = + getNaviDrawable( + backgroundColor = btnStyle.bgColor.parseColorSafe(), + radii = + CornerRadius( + leftTop = dpToPx(btnStyle.radius?.leftTop.orZero()), + rightTop = dpToPx(btnStyle.radius?.rightTop.orZero()), + leftBottom = dpToPx(btnStyle.radius?.leftBottom.orZero()), + rightBottom = dpToPx(btnStyle.radius?.rightBottom.orZero()) + ), + strokeWidth = dpToPxInInt(btnStyle.borderWidth.orZero()), + strokeColor = btnStyle.borderColor?.parseColorSafe() + ) + } + rootLayout.setOnClickListener { + data.actionData.let { action -> + widgetCallback.widgetAnalytics( + genericAnalyticsData = action.metaData?.clickedData + ) + widgetCallback.onClick(action, widgetId = widgetData.widgetId) + } + } + } + data.footer?.let { footer -> setupFooterSection(footer) } + } + } + } + + private fun setupFooterSection(footer: Footer?) { + footer?.let { + binding.apply { + footerSection.isVisible = true + footerText.showWhenDataIsAvailable(footer.title) + footerStartIcon.setImageFieldData(footer.startIcon) + footerSection.background = + getNaviDrawable( + backgroundColor = footer.bgColor.parseColorSafe(), + radii = + CornerRadius( + leftTop = dpToPx(footer.radius?.leftTop.orZero()), + rightTop = dpToPx(footer.radius?.rightTop.orZero()), + leftBottom = dpToPx(footer.radius?.leftBottom.orZero()), + rightBottom = dpToPx(footer.radius?.rightBottom.orZero()) + ) + ) + } + } + } + + fun updateButtonLoader(buttonLoaderState: ButtonLoaderState?) { + widgetData.widgetData?.actionData?.let { + binding.actionBtn.setProperties( + title = widgetData.widgetData?.btnTitle, + actionData = it, + padding = widgetData.widgetData?.actionButtonStyle?.padding, + widgetCallback = widgetCallback, + buttonLoaderState = buttonLoaderState, + widgetId = widgetData.widgetId + ) + } + } +} diff --git a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TextCardWithShimmerWidgetLayout.kt b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TextCardWithShimmerWidgetLayout.kt index ddf9f813de..8acfcf718d 100644 --- a/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TextCardWithShimmerWidgetLayout.kt +++ b/android/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TextCardWithShimmerWidgetLayout.kt @@ -24,13 +24,12 @@ import com.navi.base.utils.orFalse import com.navi.base.utils.orZero import com.navi.design.R as DesignR import com.navi.design.utils.* -import com.navi.naviwidgets.actions.GoldMinOfferSectionClickAction import com.navi.naviwidgets.callbacks.WidgetCallback import com.navi.naviwidgets.databinding.TextCardWithShimmerWidgetLayoutBinding import com.navi.naviwidgets.extensions.setVisibilityState import com.navi.naviwidgets.extensions.showWhenDataIsAvailable -import com.navi.naviwidgets.models.OfferDetails import com.navi.naviwidgets.models.TextCardWithShimmerWidget +import com.navi.naviwidgets.models.TextCardWithShimmerWidgetData import com.navi.naviwidgets.utils.REWARDS_TOOLTIP_ANIMATION_DELAY import com.navi.naviwidgets.widgets.GraphWidgetLayout.Companion.KEY_COLOR_SELECTED @@ -68,6 +67,7 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 private fun setProperties() { binding.apply { textCardWithShimmerWidget?.widgetData?.let { data -> + data.elevation?.let { binding.rootLayout.elevation = dpToPx(it.toInt()) } if (data.removeElevation.orFalse()) binding.rootLayout.elevation = resources.getDimension(DesignR.dimen.dp_0) if (data?.minOfferAmount != null) { @@ -79,12 +79,12 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 } } } - setOfferCardData(offerCardData = data?.offerDetails) data.tag?.let { binding.tvTag.apply { isVisible = true tvTagTitle.text = it.title?.text.spannedText(context = context, span = it.title?.span) + tvTag.translationX = dpToPx(it.titleMargin?.startDp?.toInt() ?: 0) background = getNaviDrawable( backgroundColor = it.bgColor.parseColorSafe(), @@ -112,7 +112,15 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) ) ) - tagLottie.showWhenDataIsAvailable(it.lottieFileName) + it.lottieUrl?.let { lottieUrl -> + tagLottie.showWhenDataIsAvailable( + lottieName = null, + lottieUrl = lottieUrl + ) + } + ?: run { + tagLottie.showWhenDataIsAvailable(lottieName = it.lottieFileName) + } } } ?: binding.tvTag.setVisibilityState(GONE) data?.title?.let { @@ -264,54 +272,58 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 if (previousUserEnteredAmount != currentAmount) { previousUserEnteredAmount = currentAmount if ( - widgetData?.minOfferAmount != null && - widgetData?.userEnteredAmount.orZero() < + widgetData.minOfferAmount != null && + widgetData.userEnteredAmount.orZero() < widgetData.minOfferAmount.orZero() ) { - userEnteredAmountLessThanOfferAmount = true - naviPriceShimmer.stopShimmer() - naviPriceShimmer.setShimmer(null) - marketPriceValue.setSpannableString( - widgetData.marketPriceData?.priceValue, - KEY_COLOR_SELECTED - ) - naviPriceValue.setSpannableString( - widgetData.naviPriceData?.priceValue, - KEY_COLOR_SELECTED - ) - marketPriceTitle.setSpannableString( - widgetData.marketPriceData?.priceTitle, - KEY_COLOR_SELECTED - ) - naviPriceTitle.setSpannableString( - widgetData.naviPriceData?.priceTitle, - KEY_COLOR_SELECTED - ) - offerSection.root.isVisible = true - discountConfetti.isVisible = false + handleUserEnteredAmountLessThanOfferAmount(widgetData) } else { - marketPriceValue.setSpannableString( - widgetData.marketPriceData?.priceValue - ) - naviPriceValue.setSpannableString( - widgetData.naviPriceData?.priceValue - ) - marketPriceTitle.setSpannableString( - widgetData.marketPriceData?.priceTitle - ) - naviPriceTitle.setSpannableString( - widgetData.naviPriceData?.priceTitle - ) - showShimmerAndConfetti(widgetData?.offerLottie) - offerSection.root.isVisible = false + handleUserEnteredAmountValidForOffer(widgetData) } } - } + } ?: run { handleUserEnteredAmountValidForOffer(widgetData) } } } } } + private fun handleUserEnteredAmountLessThanOfferAmount( + widgetData: TextCardWithShimmerWidgetData? + ) { + userEnteredAmountLessThanOfferAmount = true + binding.apply { + naviPriceShimmer.stopShimmer() + naviPriceShimmer.setShimmer(null) + marketPriceValue.setSpannableString( + widgetData?.marketPriceData?.priceValue, + KEY_COLOR_SELECTED + ) + naviPriceValue.setSpannableString( + widgetData?.naviPriceData?.priceValue, + KEY_COLOR_SELECTED + ) + marketPriceTitle.setSpannableString( + widgetData?.marketPriceData?.priceTitle, + KEY_COLOR_SELECTED + ) + naviPriceTitle.setSpannableString( + widgetData?.naviPriceData?.priceTitle, + KEY_COLOR_SELECTED + ) + discountConfetti.isVisible = false + } + } + + private fun handleUserEnteredAmountValidForOffer(widgetData: TextCardWithShimmerWidgetData?) { + binding.apply { + marketPriceValue.setSpannableString(widgetData?.marketPriceData?.priceValue) + naviPriceValue.setSpannableString(widgetData?.naviPriceData?.priceValue) + marketPriceTitle.setSpannableString(widgetData?.marketPriceData?.priceTitle) + naviPriceTitle.setSpannableString(widgetData?.naviPriceData?.priceTitle) + showShimmerAndConfetti(widgetData?.offerLottie) + } + } + private fun showShimmerAndConfetti(offerLottie: String?) { binding.apply { pricesContainer.apply { @@ -345,24 +357,6 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 } } - private fun setOfferCardData(offerCardData: OfferDetails? = null) { - binding.offerSection.apply { - offerIcon.showWhenDataIsAvailable(offerCardData?.leftIcon) - offerTitle.showWhenDataIsAvailable(offerCardData?.title) - offerSubTitle.showWhenDataIsAvailable(offerCardData?.subTitle) - details.showWhenDataIsAvailable(offerCardData?.rightText) - endIcon.showWhenDataIsAvailable(offerCardData?.rightIcon) - root.setOnClickListener { - widgetCallback.onClick( - GoldMinOfferSectionClickAction( - offerSectionData = offerCardData?.offerBottomSheetData, - actionData = offerCardData?.actionData - ) - ) - } - } - } - private fun handleShimmer() { binding.apply { textCardWithShimmerWidget?.widgetData?.let { data -> diff --git a/android/navi-widgets/src/main/res/layout/dual_action_button_widget_layout.xml b/android/navi-widgets/src/main/res/layout/dual_action_button_widget_layout.xml index 37951344ce..6221997098 100644 --- a/android/navi-widgets/src/main/res/layout/dual_action_button_widget_layout.xml +++ b/android/navi-widgets/src/main/res/layout/dual_action_button_widget_layout.xml @@ -92,6 +92,18 @@ app:lottie_rawRes="@raw/cta_loader_purple" app:lottie_speed="1.0" /> + + \ No newline at end of file diff --git a/android/navi-widgets/src/main/res/layout/gold_portfolio_widget_layout.xml b/android/navi-widgets/src/main/res/layout/gold_portfolio_widget_layout.xml new file mode 100644 index 0000000000..2932392069 --- /dev/null +++ b/android/navi-widgets/src/main/res/layout/gold_portfolio_widget_layout.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/navi-widgets/src/main/res/layout/graph_widget_layout.xml b/android/navi-widgets/src/main/res/layout/graph_widget_layout.xml index 1c003cd612..45836a7823 100644 --- a/android/navi-widgets/src/main/res/layout/graph_widget_layout.xml +++ b/android/navi-widgets/src/main/res/layout/graph_widget_layout.xml @@ -29,6 +29,7 @@ android:layout_width="@dimen/dp_0" android:layout_height="wrap_content" android:layout_marginStart="@dimen/dp_8" + app:layout_goneMarginStart="@dimen/dp_16" android:layout_marginEnd="@dimen/dp_4" app:layout_constraintBottom_toTopOf="@id/chart" app:layout_constraintEnd_toStartOf="@id/right_title" diff --git a/android/navi-widgets/src/main/res/layout/layout_gold_conversion.xml b/android/navi-widgets/src/main/res/layout/layout_gold_conversion.xml index 427b26cc21..ae09a9324a 100644 --- a/android/navi-widgets/src/main/res/layout/layout_gold_conversion.xml +++ b/android/navi-widgets/src/main/res/layout/layout_gold_conversion.xml @@ -390,13 +390,14 @@ android:orientation="horizontal" android:background="@drawable/rounded_purple_color_enabled_state" android:layout_marginTop="@dimen/dp_32" + app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@id/chip_group_view"> + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/navi-widgets/src/main/res/layout/portfolio_subtitle_item.xml b/android/navi-widgets/src/main/res/layout/portfolio_subtitle_item.xml new file mode 100644 index 0000000000..b15c0e7c61 --- /dev/null +++ b/android/navi-widgets/src/main/res/layout/portfolio_subtitle_item.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + diff --git a/android/navi-widgets/src/main/res/layout/simple_text_widget_layout.xml b/android/navi-widgets/src/main/res/layout/simple_text_widget_layout.xml index 94764b25d7..2f4a490be7 100644 --- a/android/navi-widgets/src/main/res/layout/simple_text_widget_layout.xml +++ b/android/navi-widgets/src/main/res/layout/simple_text_widget_layout.xml @@ -34,6 +34,15 @@ app:lottie_autoPlay="true" app:lottie_loop="true" /> + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/navi-widgets/src/main/res/layout/text_card_with_shimmer_widget_layout.xml b/android/navi-widgets/src/main/res/layout/text_card_with_shimmer_widget_layout.xml index a0eb47d60d..bb99214122 100644 --- a/android/navi-widgets/src/main/res/layout/text_card_with_shimmer_widget_layout.xml +++ b/android/navi-widgets/src/main/res/layout/text_card_with_shimmer_widget_layout.xml @@ -25,7 +25,6 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" app:lottie_autoPlay="true" app:lottie_loop="false" app:lottie_speed="1.0" @@ -35,7 +34,6 @@ android:id="@+id/container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingHorizontal="@dimen/dp_16" android:paddingBottom="@dimen/dp_16" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" @@ -47,6 +45,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingHorizontal="@dimen/dp_8" + android:layout_marginStart="@dimen/dp_16" android:paddingVertical="@dimen/dp_2" android:visibility="gone" tools:visibility="visible" @@ -75,6 +74,15 @@ tools:text="In Progress" /> + + @@ -181,11 +189,11 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/dp_8" android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" android:layout_marginStart="@dimen/dp_12" - app:layout_constraintBottom_toTopOf="@id/offerSection" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/tvTag" + app:layout_constraintTop_toTopOf="parent" tools:visibility="visible"> @@ -209,7 +217,7 @@ android:layout_marginTop="@dimen/dp_4" android:text="₹4.521/mg" android:textColor="@color/black" - android:textSize="16sp" + android:textSize="@dimen/sp_16" android:visibility="gone" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/marketPriceTitle" @@ -219,16 +227,15 @@ android:id="@+id/comparisonText" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/dp_8" - android:layout_marginEnd="@dimen/dp_8" + android:layout_marginStart="@dimen/dp_24" android:lineSpacingExtra="4sp" android:text="vs." android:textColor="@color/black" - android:textSize="14sp" + android:textSize="@dimen/sp_14" android:visibility="gone" app:layout_constraintBottom_toBottomOf="@id/marketPriceValue" app:layout_constraintEnd_toStartOf="@id/naviPriceTitle" - app:layout_constraintStart_toEndOf="@id/marketPriceValue" + app:layout_constraintStart_toEndOf="@id/marketPriceTitle" app:layout_constraintTop_toTopOf="parent" tools:visibility="visible" /> @@ -239,7 +246,7 @@ android:lineSpacingExtra="1sp" android:text="Navi price (2.25% off)" android:textColor="@color/black" - android:textSize="14sp" + android:textSize="@dimen/sp_12" android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@id/marketPriceTitle" @@ -263,11 +270,11 @@ android:id="@+id/naviPriceValue" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="4dp" + android:layout_marginTop="@dimen/dp_4" android:lineSpacingExtra="3sp" android:text="₹4.420/mg" android:textColor="@color/black" - android:textSize="16sp" + android:textSize="@dimen/sp_16" android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@id/naviPriceTitle" @@ -276,17 +283,8 @@ - - +