TP-38080: Preload Digital Gold Landing Page (#7530)
This commit is contained in:
@@ -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")
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
7
navi-common/src/main/res/anim/parallax_slide_in_left.xml
Normal file
7
navi-common/src/main/res/anim/parallax_slide_in_left.xml
Normal 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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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"))
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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?) {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
navi-gold/src/main/java/com/navi/gold/util/AnimationUtil.kt
Normal file
17
navi-gold/src/main/java/com/navi/gold/util/AnimationUtil.kt
Normal 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
|
||||
)
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user