TP-38080: Preload Digital Gold Landing Page (#7530)

This commit is contained in:
Siddiboina Susai
2023-08-28 15:25:07 +05:30
committed by GitHub
parent 8b86af4547
commit a3206f7029
19 changed files with 425 additions and 32 deletions

View File

@@ -9,8 +9,11 @@ package com.naviapp.home.dashboard.models.response
import com.google.gson.annotations.SerializedName
import com.navi.naviwidgets.models.NaviWidget
import com.naviapp.common.navigator.NaviDeepLinkNavigator
class InvestmentsResponse(
@SerializedName("content")
val contentWidget: List<NaviWidget>? = null
val contentWidget: List<NaviWidget>? = null,
@SerializedName("preloadScreenNames")
val preloadScreenNames: List<String>? = listOf("gold", "amc")
)

View File

@@ -22,7 +22,11 @@ import com.navi.amc.utils.AmcAnalytics
import com.navi.amc.utils.Constant
import com.navi.amc.utils.TempStorageHelper
import com.navi.analytics.utils.NaviTrackEvent
import com.navi.base.model.*
import com.navi.base.model.ActionData
import com.navi.base.model.CtaData
import com.navi.base.model.LineItem
import com.navi.base.model.NaviClickAction
import com.navi.base.model.NaviWidgetClickWithActionData
import com.navi.base.utils.BaseUtils
import com.navi.base.utils.orFalse
import com.navi.common.listeners.FragmentInterchangeListener
@@ -132,10 +136,23 @@ class InvestmentsFragment() : BaseFragment(), WidgetCallback {
}
binding.items.visibility = View.VISIBLE
} ?: run { binding.items.visibility = View.GONE }
response?.preloadScreenNames?.let { preloadScreenNames ->
preloadScreenNames.forEach {
preloadScreen(it)
}
}
}
}
}
private fun preloadScreen(screenName: String) {
when(screenName){
NaviDeepLinkNavigator.GOLD -> viewModel.preloadDigitalGoldHomePage()
}
}
private fun fetchData(showLoader: Boolean = true, params: Map<String, String>? = null) {
if (showLoader) {
showLoader()

View File

@@ -11,9 +11,13 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.navi.base.utils.isNotNull
import com.navi.base.utils.isNull
import com.navi.common.utils.Constants.GOLD
import com.navi.common.utils.TemporaryStorageHelper
import com.navi.common.viewmodel.BaseVM
import com.navi.gold.repo.DigitalGoldHomeRepo
import com.navi.naviwidgets.models.response.HomeProductWidget
import com.naviapp.common.navigator.NaviDeepLinkNavigator
import com.naviapp.home.dashboard.models.response.InvestmentsResponse
import com.naviapp.home.respository.GlobalRepo
import com.naviapp.home.respository.InvestmentsRepository
@@ -26,6 +30,7 @@ import javax.inject.Inject
class InvestmentsVM @Inject constructor(
private val repository: InvestmentsRepository,
private val globalRepo: GlobalRepo,
private val goldHomeRepo: DigitalGoldHomeRepo,
) : BaseVM() {
private val _investmentsData = MutableLiveData<InvestmentsResponse>()
@@ -49,12 +54,15 @@ class InvestmentsVM @Inject constructor(
fun fetchData(params: Map<String, String>? = null) {
viewModelScope.launch {
val isDataModified = TemporaryStorageHelper.isDataModified(TemporaryStorageHelper.INVESTMENTS)
val isDataModified =
TemporaryStorageHelper.isDataModified(TemporaryStorageHelper.INVESTMENTS)
if (TemporaryStorageHelper.getApiResponse<InvestmentsResponse>(TemporaryStorageHelper.INVESTMENTS)
.isNotNull()
) {
_investmentsData.postValue(
TemporaryStorageHelper.getApiResponse<InvestmentsResponse>(TemporaryStorageHelper.INVESTMENTS)
TemporaryStorageHelper.getApiResponse<InvestmentsResponse>(
TemporaryStorageHelper.INVESTMENTS
)
)
TemporaryStorageHelper.clearResponse(TemporaryStorageHelper.INVESTMENTS)
if (isDataModified.not())
@@ -69,6 +77,23 @@ class InvestmentsVM @Inject constructor(
}
}
fun preloadDigitalGoldHomePage() {
if (!TemporaryStorageHelper.SOFT_REF_CACHE.contains(GOLD)) {
coroutineScope.launch {
val response = goldHomeRepo.fetchDigitalGoldHomeDetails(emptyMap())
if (response.error.isNull() && response.errors.isNullOrEmpty()) {
TemporaryStorageHelper.SOFT_REF_CACHE.add(
key = GOLD,
value = response.data as Any,
maxConsumptions = 3
)
} else {
//no-op as this api call's response is not critical
}
}
}
}
fun containsHomeProductWidget(): Boolean {
return _investmentsData.value?.contentWidget?.singleOrNull { it.widgetNameForBaseAdapter == HomeProductWidget.WIDGET_NAME } != null
}

View File

@@ -0,0 +1,167 @@
package com.navi.common.utils
import java.lang.ref.SoftReference
/**
* SoftRefLruCache is a memory cache implementation that combines Soft References with an LRU (Least Recently Used) eviction policy.
* This cache is designed to store key-value pairs where the values are held using soft references, allowing them to be reclaimed
* by the garbage collector when memory is limited. The cache also enforces a maximum size and a time-to-live (TTL) for entries.
*
* @param K The type of keys stored in the cache.
* @param V The type of values stored in the cache.
* @property maxSize The maximum number of entries the cache can hold.
*/
class SoftRefLruCache<K, V>(private val maxSize: Int = DEFAULT_CACHE_SIZE) {
companion object {
const val DEFAULT_TTL = 180_000L // 3 minutes
const val DEFAULT_MAX_CONSUMPTIONS = 1
const val DEFAULT_CACHE_SIZE = 5
}
// LinkedHashSet to maintain LRU order
private val order = LinkedHashSet<K>()
// Map to store cache entries
private val cache = mutableMapOf<K, CacheEntry<V>>()
/**
* Adds a key-value pair to the cache with optional parameters for time-to-live (TTL) and maximum consumptions.
*
* @param key The key associated with the value.
* @param value The value to be stored in the cache.
* @param maxTtl The maximum time (in milliseconds) the entry can live in the cache.
* @param maxConsumptions The maximum number of times the entry can be accessed.
*/
fun add(
key: K,
value: V,
maxTtl: Long = DEFAULT_TTL,
maxConsumptions: Int = DEFAULT_MAX_CONSUMPTIONS
) {
// Create a CacheEntry with a SoftReference to the value
CacheEntry(
value = SoftReference(value),
maxTtl = maxTtl,
maxConsumptions = maxConsumptions
).let {
// Remove existing entry if present
cache.remove(key)
order.remove(key)
// Add the new entry to the cache and LRU order
cache[key] = it
order.add(key)
}
// Clean up invalid and excess cache entries
removeInvalidItems()
}
/**
* Checks if the cache contains a specific key.
*
* @param key The key to check for in the cache.
* @return true if the key is present and the associated entry is valid, otherwise false.
*/
fun contains(key: K): Boolean {
return isValidEntry(key)
}
/**
* Retrieves the value associated with a given key from the cache.
*
* @param key The key to retrieve the value for.
* @return The value associated with the key if it's present and valid, otherwise null.
*/
fun get(key: K): V? {
return cache[key]?.let { entry ->
if (isValidEntry(key)) {
entry.consumptions++
order.remove(key)
order.add(key)
entry.value.get()
} else {
removeFromCacheInternal(key)
null
}
}
}
/**
* Removes an entry from the cache based on the provided key.
*
* @param key The key of the entry to be removed.
*/
fun remove(key: K) {
removeInvalidItems()
removeFromCacheInternal(key)
}
/**
* Clears the entire cache, removing all stored entries.
*/
fun clear() {
cache.clear()
order.clear()
}
/**
* Removes cache entries that are invalid (expired or no longer strongly referenced) until the cache size is within limits.
*/
private fun removeInvalidItems() {
// Remove expired or invalid entries
cache.keys.toList().forEach { key ->
if (!isValidEntry(key)) {
removeFromCacheInternal(key)
}
}
// Remove excess entries based on LRU order
while (order.size > maxSize) {
val key = order.first()
removeFromCacheInternal(key)
}
}
/**
* Checks if a cache entry is valid based on its TTL, consumptions, and soft reference status.
*
* @param key The key of the entry to check.
* @return true if the entry is valid, otherwise false.
*/
private fun isValidEntry(key: K): Boolean {
val entry = cache[key]
return (entry != null)
&& (entry.consumptions <= entry.maxConsumptions)
&& ((entry.entryTime + entry.maxTtl) >= System.currentTimeMillis())
&& (entry.value.get() != null)
}
/**
* Removes an entry from the cache and the LRU order.
*
* @param key The key of the entry to be removed.
*/
private fun removeFromCacheInternal(key: K) {
cache.remove(key)
order.remove(key)
}
/**
* Data class representing an entry in the cache.
*
* @property value SoftReference to the cached value.
* @property entryTime The time when the entry was added to the cache.
* @property maxTtl The maximum time-to-live for the entry.
* @property maxConsumptions The maximum number of times the entry can be accessed.
* @property consumptions The current number of times the entry has been accessed.
*/
data class CacheEntry<V>(
val value: SoftReference<V>,
val entryTime: Long = System.currentTimeMillis(),
val maxTtl: Long = DEFAULT_TTL,
val maxConsumptions: Int = DEFAULT_MAX_CONSUMPTIONS,
var consumptions: Int = 0
)
}

View File

@@ -24,6 +24,8 @@ object TemporaryStorageHelper {
const val BOTTOM_NAV = "BOTTOM_NAV"
const val LOAN_DASHBOARD = "LOAN_DASHBOARD"
val SOFT_REF_CACHE: SoftRefLruCache<String, Any> = SoftRefLruCache()
var apiResponse: HashMap<String, Any?> = HashMap()
private var viewVisible = HashMap<String, Boolean>()
private var screenDataNeedsToUpdate = ConcurrentHashMap<String, Boolean>()
@@ -37,6 +39,7 @@ object TemporaryStorageHelper {
apiResponse.clear()
viewVisible.clear()
screenDataNeedsToUpdate.clear()
SOFT_REF_CACHE.clear()
}
fun updateViewVisibility(screen: String, hidden: Boolean) {

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="-40%p"
android:toXDelta="0"
android:duration="300" />
</set>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="100%p"
android:toXDelta="0"
android:duration="300" />
</set>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="0"
android:toXDelta="-40%p"
android:duration="300" />
</set>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0"
android:toXDelta="100%p" />
</set>

View File

@@ -0,0 +1,81 @@
package com.navi.common.utils
import org.junit.Assert.*
import org.junit.Test
import java.lang.Thread.sleep
class SoftRefLruCacheTest {
@Test
fun testCacheAddAndGet() {
val cache = SoftRefLruCache<String, Int>()
cache.add("key1", 1)
assertEquals(1, cache.get("key1"))
}
@Test
fun testCacheAddAndUpdate() {
val cache = SoftRefLruCache<String, Int>()
cache.add("key1", 1)
cache.add("key1", 2)
assertEquals(2, cache.get("key1"))
}
@Test
fun testCacheExpiration() {
val cache = SoftRefLruCache<String, Int>()
val maxTtl = 1000L
cache.add("key1", 1, maxTtl)
sleep(maxTtl + 100) // Wait for entry to expire
assertNull(cache.get("key1"))
}
@Test
fun testCacheMaxConsumptions() {
val cache = SoftRefLruCache<String, Int>()
cache.add("key1", 1, maxConsumptions = 2)
cache.get("key1")
cache.get("key1")
cache.get("key1")
assertNull(cache.get("key1")) // Exceeds maxConsumptions
}
@Test
fun testCacheEviction() {
val cache = SoftRefLruCache<String, Int>(maxSize = 2)
cache.add("key1", 1)
cache.add("key2", 2)
cache.add("key3", 3)
assertNull(cache.get("key1")) // key1 should be evicted due to maxSize
}
@Test
fun testCacheRemove() {
val cache = SoftRefLruCache<String, Int>()
cache.add("key1", 1)
cache.remove("key1")
assertNull(cache.get("key1"))
}
@Test
fun testCacheClear() {
val cache = SoftRefLruCache<String, Int>()
cache.add("key1", 1)
cache.add("key2", 2)
cache.clear()
assertNull(cache.get("key1"))
assertNull(cache.get("key2"))
}
}

View File

@@ -7,6 +7,7 @@ import com.navi.base.model.CtaData
import com.navi.base.utils.isNotNullAndNotEmpty
import com.navi.base.utils.orFalse
import com.navi.base.utils.orZero
import com.navi.common.R
import com.navi.common.utils.Constants
import com.navi.gold.ui.DigitalGoldBuyActivity
import com.navi.gold.ui.DigitalGoldHomeActivity
@@ -15,6 +16,7 @@ import com.navi.gold.ui.DigitalGoldKycFragment
import com.navi.gold.ui.DigitalGoldSellActivity
import com.navi.gold.ui.DigitalGoldTransactionActivity
import com.navi.common.utils.log
import com.navi.gold.util.startEnterAnimation
import timber.log.Timber
object NaviDigitalGoldDeeplinkNavigator {
@@ -87,8 +89,12 @@ object NaviDigitalGoldDeeplinkNavigator {
}
if (needsResult.orFalse()) {
activity?.startActivityForResult(intent, requestCode.orZero())
} else activity?.startActivity(intent)
} else {
activity?.startActivity(intent)
}
if (finish.orFalse()) activity?.finish()
activity?.startEnterAnimation()
}
}
} catch (e: Exception) {

View File

@@ -29,6 +29,7 @@ import com.navi.gold.ui.CommonPermissionFragment
import com.navi.gold.util.Constants.AMOUNT_DATA
import com.navi.gold.util.Constants.TYPE
import com.navi.gold.util.GoldAnalytics.DIGITAL_GOLD_BUY_ACTIVITY
import com.navi.gold.util.startExitAnimation
import com.navi.gold.viewmodels.DigitalGoldBuySharedVM
import com.navi.naviwidgets.callbacks.WidgetCallback
import com.razorpay.PaymentData
@@ -61,8 +62,10 @@ class DigitalGoldBuyActivity : BaseActivity(), FragmentInterchangeListener,
isBackPressedConsumed = currentFragment.onBackPress()
}
if (!isBackPressedConsumed)
if (!isBackPressedConsumed) {
super.onBackPressed()
startExitAnimation()
}
}
override fun onClick(naviClickAction: NaviClickAction, widgetId: String?) {

View File

@@ -256,7 +256,7 @@ class DigitalGoldBuyFragment : BaseFragment(), WidgetCallback, NewBottomSheetLis
}
private fun navigateToNextScreen(paymentCheckResponse: DigitalGoldActionCheckResponse) {
TemporaryStorageHelper.setIsDataModified(GOLD, true)
TemporaryStorageHelper.SOFT_REF_CACHE.remove(GOLD)
paymentCheckViewModel.setActionCheckResponse(paymentCheckResponse.toActionCheckResponse())
val paymentCheckFragment = PaymentCheckFragment.newInstance(null)
stopTimer()

View File

@@ -124,6 +124,7 @@ import com.navi.gold.util.GoldAnalytics.DIGITAL_GOLD_FOMO_NUDGE_BOTTOM_SHEET_INI
import com.navi.gold.util.GoldAnalytics.DIGITAL_GOLD_HOME_SCREEN
import com.navi.gold.util.GoldAnalytics.DIGITAL_GOLD_LANDING_PAGE
import com.navi.gold.util.isTrue
import com.navi.gold.util.startExitAnimation
import com.navi.gold.util.toActionCheckResponse
import com.navi.gold.viewmodels.DigitalGoldBuySharedVM
import com.navi.gold.viewmodels.DigitalGoldBuyVM
@@ -270,7 +271,6 @@ class DigitalGoldHomeActivity : BaseActivity(), WidgetCallback, NewBottomSheetLi
override fun onNewIntent(newIntent: Intent?) {
super.onNewIntent(newIntent)
setIntent(newIntent)
homeVM.areNewParamsConsumed = false
}
private fun initObserver() {
@@ -394,7 +394,7 @@ class DigitalGoldHomeActivity : BaseActivity(), WidgetCallback, NewBottomSheetLi
}
private fun navigateToPaymentCheckScreen(paymentCheckResponse: DigitalGoldActionCheckResponse) {
TemporaryStorageHelper.setIsDataModified(GOLD, true)
TemporaryStorageHelper.SOFT_REF_CACHE.remove(GOLD)
paymentCheckViewModel.setActionCheckResponse(paymentCheckResponse.toActionCheckResponse())
val paymentCheckFragment = Bundle().apply {
@@ -708,28 +708,28 @@ class DigitalGoldHomeActivity : BaseActivity(), WidgetCallback, NewBottomSheetLi
}
}
private fun fetchDigitalHomePageDetails() {
private fun fetchDigitalHomePageDetails(forceRefresh: Boolean = true) {
timer?.cancel()
timer = null
showShimmer()
val params = mutableMapOf<String, String>()
if (!homeVM.areNewParamsConsumed) {
homeVM.areNewParamsConsumed = true
//this is because amount can be sent as a String or as a Double value
intent.getStringExtra(AMOUNT_DATA)?.let { amountString ->
if (amountString.isNotNullAndNotEmpty()) {
params[AMOUNT_DATA] = amountString
}
}
//this is because amount can be sent as a String or as a Double value
val doubleAmount = intent.getDoubleExtra(AMOUNT_DATA, -1.0)
if (doubleAmount > 0) {
params[AMOUNT_DATA] = doubleAmount.toString()
intent.getStringExtra(AMOUNT_DATA)?.let { amountString ->
if (amountString.isNotNullAndNotEmpty()) {
params[AMOUNT_DATA] = amountString
intent.removeExtra(AMOUNT_DATA)
}
}
homeVM.fetchDigitalGoldHomeDetails(params)
val doubleAmount = intent.getDoubleExtra(AMOUNT_DATA, -1.0)
if (doubleAmount > 0) {
params[AMOUNT_DATA] = doubleAmount.toString()
intent.removeExtra(AMOUNT_DATA)
}
homeVM.fetchDigitalGoldHomeDetails(params, forceRefresh)
}
private fun fetchDigitalGoldInvoiceDownloadUrl(trasactionId: String?) {
@@ -1046,6 +1046,7 @@ class DigitalGoldHomeActivity : BaseActivity(), WidgetCallback, NewBottomSheetLi
}
} else {
super.onBackPressed()
startExitAnimation()
if (isTaskRoot) {
DeepLinkManager.getDeepLinkListener()?.navigateTo(
this,
@@ -1077,9 +1078,9 @@ class DigitalGoldHomeActivity : BaseActivity(), WidgetCallback, NewBottomSheetLi
override fun onStart() {
super.onStart()
val isDataModified = TemporaryStorageHelper.isDataModified(GOLD)
TemporaryStorageHelper.setIsDataModified(GOLD, false)
if (homeVM.digitalGoldHomeWidgets.value == null || !homeVM.areNewParamsConsumed || isDataModified) {
if (homeVM.digitalGoldHomeWidgets.value == null) {
fetchDigitalHomePageDetails(forceRefresh = false)
} else if (!TemporaryStorageHelper.SOFT_REF_CACHE.contains(GOLD)) {
fetchDigitalHomePageDetails()
}
}

View File

@@ -38,6 +38,7 @@ import com.navi.common.ui.fragment.BaseFragment
import com.navi.common.ui.fragment.NewCommonBottomSheet
import com.navi.common.ui.fragment.PaymentCheckFragment
import com.navi.common.utils.Constants.REFRESH
import com.navi.common.utils.TemporaryStorageHelper
import com.navi.common.utils.observeNonNull
import com.navi.common.utils.toCtaData
import com.navi.common.viewmodel.PaymentCheckViewModel
@@ -85,6 +86,7 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import com.navi.base.utils.PAN_VERIFY
import com.navi.base.utils.PAN_VERIFY_POLLING
import com.navi.common.utils.Constants.GOLD
@AndroidEntryPoint
class DigitalGoldKycFragment : BaseFragment(), WidgetCallback, NewBottomSheetListener,
@@ -288,7 +290,7 @@ class DigitalGoldKycFragment : BaseFragment(), WidgetCallback, NewBottomSheetLis
}
private fun navigateToNextScreen(paymentCheckResponse: DigitalGoldActionCheckResponse) {
TemporaryStorageHelper.SOFT_REF_CACHE.remove(GOLD)
paymentCheckViewModel.setActionCheckResponse(paymentCheckResponse.toActionCheckResponse())
val paymentCheckFragment = PaymentCheckFragment.newInstance(null)
safelyShowDialogFragment(paymentCheckFragment, PaymentCheckFragment.TAG)

View File

@@ -79,6 +79,7 @@ import com.navi.gold.util.Constants.SELL_GOLD_UPI_FRAGMENT
import com.navi.gold.util.Constants.TYPE
import com.navi.gold.util.GoldAnalytics
import com.navi.gold.util.GoldAnalytics.DIGITAL_GOLD_SELL_SCREEN
import com.navi.gold.util.startExitAnimation
import com.navi.gold.util.toActionCheckResponse
import com.navi.gold.viewmodels.DigitalGoldSellSharedVM
import com.navi.gold.viewmodels.DigitalGoldSellVM
@@ -283,6 +284,7 @@ class DigitalGoldSellActivity : BaseActivity(), WidgetCallback, NewBottomSheetLi
when (it) {
CLOSE -> {
finish()
startExitAnimation()
}
else -> {
@@ -291,6 +293,7 @@ class DigitalGoldSellActivity : BaseActivity(), WidgetCallback, NewBottomSheetLi
}
} ?: run {
finish()
startExitAnimation()
}
}
@@ -384,7 +387,7 @@ class DigitalGoldSellActivity : BaseActivity(), WidgetCallback, NewBottomSheetLi
}
private fun navigateToPaymentCheckScreen(actionCheckResponse: DigitalGoldActionCheckResponse) {
TemporaryStorageHelper.setIsDataModified(GOLD, true)
TemporaryStorageHelper.SOFT_REF_CACHE.remove(GOLD)
paymentCheckViewModel.setActionCheckResponse(actionCheckResponse.toActionCheckResponse())
val paymentCheckFragment = PaymentCheckFragment.newInstance(null)

View File

@@ -59,6 +59,7 @@ import com.navi.gold.util.GoldAnalytics.FEEDBACK
import com.navi.gold.util.GoldAnalytics.GOLD_VAULT_CSAT_BOTTOMSHEET_CLOSE
import com.navi.gold.util.GoldAnalytics.GOLD_VAULT_CSAT_BOTTOMSHEET_INIT
import com.navi.gold.util.GoldAnalytics.GOLD_VAULT_CSAT_BOTTOMSHEET_SUBMIT
import com.navi.gold.util.startExitAnimation
import com.navi.naviwidgets.actions.DownloadClickAction
import com.navi.naviwidgets.actions.NaviWidgetClick
import com.navi.naviwidgets.adapters.NaviAdapter
@@ -136,14 +137,18 @@ class DigitalGoldTransactionActivity : BaseActivity(), WidgetCallback, CsatCompl
CtaType.GO_BACK.name,
null -> {
super.onBackPressed()
startExitAnimation()
}
else -> {
DeepLinkManager.getDeepLinkListener()?.navigateTo(
this,
actionData.toCtaData(),
finish = actionData.finish.orTrue()
)
startExitAnimation()
}
}
}

View File

@@ -0,0 +1,17 @@
package com.navi.gold.util
import android.app.Activity
import com.navi.common.R
fun Activity.startEnterAnimation() {
this.overridePendingTransition(
R.anim.parallax_slide_in_right,
R.anim.parallax_slide_out_left)
}
fun Activity.startExitAnimation() {
this.overridePendingTransition(
com.navi.gold.R.anim.parallax_slide_in_left,
com.navi.gold.R.anim.parallax_slide_out_right
)
}

View File

@@ -14,6 +14,7 @@ import com.navi.base.utils.orFalse
import com.androidx.lifecycle.SingleLiveEvent
import com.navi.common.model.common.WidgetBottomSheetData
import com.navi.common.model.common.WidgetResponse
import com.navi.common.utils.TemporaryStorageHelper
import com.navi.common.viewmodel.BaseVM
import com.navi.gold.model.AmountDataRequest
import com.navi.gold.model.GoldKycCheckResponse
@@ -22,6 +23,7 @@ import com.navi.gold.repo.DigitalGoldHomeRepo
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
import com.navi.common.utils.Constants.GOLD
@HiltViewModel
class DigitalGoldHomeVM @Inject constructor(private val goldHomeRepo: DigitalGoldHomeRepo) :
@@ -44,18 +46,47 @@ class DigitalGoldHomeVM @Inject constructor(private val goldHomeRepo: DigitalGol
private var _isBackBottomSheetShownOnce: Boolean = false
var areNewParamsConsumed = true
fun setActualSellAmount(actualSellAmount: Double) {
this.actualSellAmount = actualSellAmount
}
fun getActualSellAmount() = actualSellAmount
fun fetchDigitalGoldHomeDetails(params: Map<String, String>) {
fun fetchDigitalGoldHomeDetails(params: Map<String, String>, forceRefresh: Boolean = true) {
if (params.isNotEmpty() || forceRefresh) {
fetchDigitalGoldHomeDetailsRemote(params)
} else {
TemporaryStorageHelper.SOFT_REF_CACHE.get(GOLD)?.let {
it as? WidgetResponse
}?.let { cachedResponse ->
_digitalGoldHomeWidgets.value = cachedResponse
} ?: run {
fetchDigitalGoldHomeDetailsRemote(params)
}
}
}
private fun fetchDigitalGoldHomeDetailsRemote(params: Map<String, String>) {
coroutineScope.launch {
val response = goldHomeRepo.fetchDigitalGoldHomeDetails(params)
if (response.error.isNull() && response.errors.isNullOrEmpty()) {
if (params.isEmpty()) {
TemporaryStorageHelper.SOFT_REF_CACHE.add(
key = GOLD,
value = response.data as Any,
maxConsumptions = 3
)
}
_digitalGoldHomeWidgets.value = response.data
} else {
setErrorData(response.errors, response.error)
}
@@ -73,7 +104,7 @@ class DigitalGoldHomeVM @Inject constructor(private val goldHomeRepo: DigitalGol
}
}
fun fetchGoldBuyBottomSheetData(amountDataRequest: AmountDataRequest){
fun fetchGoldBuyBottomSheetData(amountDataRequest: AmountDataRequest) {
coroutineScope.launch {
val response = goldHomeRepo.fetchGoldBuyBottomSheetData(amountDataRequest)
if (response.error.isNull() && response.errors.isNullOrEmpty()) {
@@ -100,7 +131,8 @@ class DigitalGoldHomeVM @Inject constructor(private val goldHomeRepo: DigitalGol
}
fun showBackBottomSheet(): Boolean {
return !_isBackBottomSheetShownOnce && _digitalGoldHomeWidgets.value?.extraData?.backBottomSheetData?.data?.isNotEmpty().orFalse()
return !_isBackBottomSheetShownOnce && _digitalGoldHomeWidgets.value?.extraData?.backBottomSheetData?.data?.isNotEmpty()
.orFalse()
}
fun setIsBackBottomSheetShownOnce() {