TP-00000 | Improve UPI home screen experience (#8830)
This commit is contained in:
@@ -85,6 +85,12 @@ object PreferenceManager {
|
||||
editor.apply()
|
||||
}
|
||||
|
||||
fun remove(key: String) {
|
||||
val editor = sharedPreferencesForSession.edit()
|
||||
editor.remove(key)
|
||||
editor.apply()
|
||||
}
|
||||
|
||||
fun getIntPreference(key: String): Int {
|
||||
return sharedPreferencesForSession.getInt(key, 0)
|
||||
}
|
||||
@@ -257,6 +263,14 @@ object PreferenceManager {
|
||||
} else setStringPreference(key, value)
|
||||
}
|
||||
|
||||
fun saveIntSecurely(key: String, value: Int) {
|
||||
if (shouldUseEncryptedSharedPref()) {
|
||||
val editor = secureSharedPreferencesForSession?.edit()
|
||||
editor?.putInt(key, value)
|
||||
editor?.apply()
|
||||
} else setIntPreference(key, value)
|
||||
}
|
||||
|
||||
fun getSecureString(key: String): String? {
|
||||
if (shouldUseEncryptedSharedPref()) {
|
||||
return secureSharedPreferencesForSession?.getString(key, null)
|
||||
@@ -264,6 +278,13 @@ object PreferenceManager {
|
||||
return null
|
||||
}
|
||||
|
||||
fun getSecureInt(key: String): Int? {
|
||||
if (shouldUseEncryptedSharedPref()) {
|
||||
return secureSharedPreferencesForSession?.getInt(key, 0)
|
||||
} else getIntPreference(key)
|
||||
return null
|
||||
}
|
||||
|
||||
fun getSecureStringApp(key: String): String? {
|
||||
if (shouldUseEncryptedSharedPref()) {
|
||||
return secureSharedPreferencesForApp?.getString(key, null)
|
||||
|
||||
@@ -71,6 +71,7 @@ object FirebaseRemoteConfigHelper {
|
||||
const val LIGHT_SENSOR_DISABLE = "LIGHT_SENSOR_DISABLE"
|
||||
const val INTENT_DATA_INSERT_DISABLED = "INTENT_DATA_INSERT_DISABLED"
|
||||
const val UPI_NUMBER_DISABLED = "UPI_NUMBER_DISABLED"
|
||||
const val UPI_HOME_JSON_MODIFICATION_DISABLED = "UPI_HOME_JSON_MODIFICATION_DISABLED"
|
||||
const val ENABLE_CHAT_V2 = "ENABLE_CHAT_V2"
|
||||
const val UW_INGESTION_POLLING = "UW_INGESTION_POLLING"
|
||||
const val PD_SPLASH_BUTTON_TEXT = "PD_SPLASH_BUTTON_TEXT"
|
||||
|
||||
@@ -22,6 +22,15 @@ class SharedPreferenceRepository {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun saveIntValue(key: String, value: Int, encrypt: Boolean = false) =
|
||||
withContext(Dispatchers.IO) {
|
||||
if (encrypt) {
|
||||
PreferenceManager.saveIntSecurely(key = key, value = value)
|
||||
} else {
|
||||
PreferenceManager.setIntPreference(key = key, value = value)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getStringValue(key: String, defValue: String = "", encrypt: Boolean = false) =
|
||||
withContext(Dispatchers.IO) {
|
||||
if (encrypt) {
|
||||
@@ -66,4 +75,11 @@ class SharedPreferenceRepository {
|
||||
} else {
|
||||
PreferenceManager.getStringPreference(key = key) ?: defValue
|
||||
}
|
||||
|
||||
fun getIntValueOnMainThread(key: String, defValue: Int = 0, encrypt: Boolean = false) =
|
||||
if (encrypt) {
|
||||
PreferenceManager.getSecureInt(key = key) ?: defValue
|
||||
} else {
|
||||
PreferenceManager.getIntPreference(key = key)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.navi.pay.onboarding.account.detail.model.view.LinkedAccountEntity
|
||||
import com.navi.pay.onboarding.account.linked.model.network.CheckBalanceRequest
|
||||
import com.navi.pay.utils.BANK_ACCOUNT_UNIQUE_ID
|
||||
import com.navi.pay.utils.NAVI_PAY_LOADER
|
||||
import com.navi.pay.utils.removeMoreOptionQrSharedPrefData
|
||||
import com.ramcosta.composedestinations.spec.Direction
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -237,7 +238,7 @@ class LinkedAccountDetailViewModel @Inject constructor(
|
||||
notifyError(deleteAccountAPIResponse, tag = "onRemoveAccountFailure")
|
||||
return@launch
|
||||
}
|
||||
|
||||
removeMoreOptionQrSharedPrefData()
|
||||
refreshLinkedAccountsUseCase.execute()
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
updateUIState(uiState = LinkedAccountDetailScreenUIState.RemoveAccountSuccess)
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.navi.analytics.utils.NaviTrackEvent
|
||||
import com.navi.base.cache.model.NaviCacheAltSourceEntity
|
||||
import com.navi.base.cache.repository.NaviCacheRepository
|
||||
import com.navi.base.utils.EMPTY
|
||||
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper
|
||||
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.UPI_HOME_JSON_MODIFICATION_DISABLED
|
||||
import com.navi.common.network.models.isSuccessWithData
|
||||
import com.navi.common.uitron.model.action.CtaAction
|
||||
import com.navi.pay.analytics.NaviPayAnalytics
|
||||
@@ -43,6 +45,10 @@ import com.navi.pay.utils.BANK_ACCOUNT_TEXT_LAYOUT_ID
|
||||
import com.navi.pay.utils.HOME_SCREEN_PRIMARY_VPA_LAYOUT_ID
|
||||
import com.navi.pay.utils.INDICATOR_IMAGE_PENDING_REQUEST_LAYOUT_ID
|
||||
import com.navi.pay.utils.KEY_MORE_OPTIONS_ACCOUNT_ID
|
||||
import com.navi.pay.utils.KEY_MORE_OPTIONS_ACCOUNT_NAME
|
||||
import com.navi.pay.utils.KEY_MORE_OPTIONS_ACCOUNT_QR_LINK
|
||||
import com.navi.pay.utils.KEY_MORE_OPTIONS_ACCOUNT_VPA
|
||||
import com.navi.pay.utils.KEY_MORE_OPTIONS_SAVING_ACCOUNT_COUNT
|
||||
import com.navi.pay.utils.NAVI_PAY_HOME_PAGE_CACHE_KEY
|
||||
import com.navi.pay.utils.PENDING_REQUEST
|
||||
import com.navi.pay.utils.PENDING_REQUESTS
|
||||
@@ -58,6 +64,7 @@ import com.navi.pay.utils.UPI_LITE_NON_BOARDED_STATE
|
||||
import com.navi.pay.utils.USER_VPA_INFO_COLUMN_LAYOUT_ID
|
||||
import com.navi.pay.utils.USER_VPA_PLACEHOLDER_IMAGE
|
||||
import com.navi.pay.utils.VPA_MAX_LENGTH_TO_ELLIPSIZE
|
||||
import com.navi.pay.utils.updateNaviPayHomeScreenJson
|
||||
import com.navi.pay.utils.getFormattedAmountWithDecimal
|
||||
import com.navi.uitron.model.action.AnalyticsAction
|
||||
import com.navi.uitron.model.action.UpdateDataAction
|
||||
@@ -223,21 +230,49 @@ class NaviPayHomeViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
private suspend fun saveDefaultSelectedVpa() {
|
||||
|
||||
for (vpa in vpaList) {
|
||||
if (vpa.linkedAccountEntity.isAccountPrimary) {
|
||||
vpa.isSelected.value = true
|
||||
selectedVpaEntity = vpa
|
||||
sharedPreferenceRepository.saveStringValue(
|
||||
key = KEY_MORE_OPTIONS_ACCOUNT_ID,
|
||||
value = vpa.linkedAccountEntity.accountId
|
||||
)
|
||||
saveDataInSharedPref(vpa)
|
||||
} else {
|
||||
vpa.isSelected.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun saveDataInSharedPref(vpa: QrVpaEntity) {
|
||||
val vpaId = vpa.linkedAccountEntity.vpa
|
||||
val vpaToDisplay = if (vpaId.length > VPA_MAX_LENGTH_TO_ELLIPSIZE) {
|
||||
vpaId.substring(0, VPA_MAX_LENGTH_TO_ELLIPSIZE - 3) + "..."
|
||||
} else {
|
||||
vpaId
|
||||
}
|
||||
val bankName =
|
||||
vpa.linkedAccountEntity.bankName + " " + vpa.linkedAccountEntity.maskedAccountNumber
|
||||
val qrUri = vpa.qrCodeUri.toString()
|
||||
sharedPreferenceRepository.saveStringValue(
|
||||
key = KEY_MORE_OPTIONS_ACCOUNT_ID,
|
||||
value = vpa.linkedAccountEntity.accountId
|
||||
)
|
||||
sharedPreferenceRepository.saveStringValue(
|
||||
key = KEY_MORE_OPTIONS_ACCOUNT_NAME,
|
||||
value = bankName
|
||||
)
|
||||
sharedPreferenceRepository.saveStringValue(
|
||||
key = KEY_MORE_OPTIONS_ACCOUNT_VPA,
|
||||
value = vpaToDisplay
|
||||
)
|
||||
sharedPreferenceRepository.saveStringValue(
|
||||
key = KEY_MORE_OPTIONS_ACCOUNT_QR_LINK,
|
||||
value = qrUri
|
||||
)
|
||||
sharedPreferenceRepository.saveIntValue(
|
||||
key = KEY_MORE_OPTIONS_SAVING_ACCOUNT_COUNT,
|
||||
value = getNonCreditVpaListSize()
|
||||
)
|
||||
}
|
||||
|
||||
fun updateBottomSheetUIState(
|
||||
showBottomSheet: Boolean? = null,
|
||||
bottomSheetUIState: HomeBottomSheetType? = null
|
||||
@@ -368,6 +403,12 @@ class NaviPayHomeViewModel @Inject constructor(
|
||||
.uiTronConfig[UiTronScreenName.NAVI_PAY_HOME.value]?.uiTronScreenContent
|
||||
|
||||
uiTronScreenContent?.let { screenContent ->
|
||||
if (FirebaseRemoteConfigHelper.getBoolean(UPI_HOME_JSON_MODIFICATION_DISABLED).not()) {
|
||||
updateNaviPayHomeScreenJson(
|
||||
sharedPreferenceRepository,
|
||||
screenContent.content?.widgets?.firstOrNull()?.parentComposeView?.firstOrNull()?.childrenViews
|
||||
)
|
||||
}
|
||||
updateUiState(uiState = NaviPayHomeScreenUIState.Loaded(uiTronScreenContent = screenContent))
|
||||
}
|
||||
}
|
||||
@@ -660,10 +701,7 @@ class NaviPayHomeViewModel @Inject constructor(
|
||||
updateBottomSheetUIState(showBottomSheet = false)
|
||||
qrVpaEntity.isSelected.value = true
|
||||
selectedVpaEntity = qrVpaEntity
|
||||
sharedPreferenceRepository.saveStringValue(
|
||||
key = KEY_MORE_OPTIONS_ACCOUNT_ID,
|
||||
value = qrVpaEntity.linkedAccountEntity.accountId
|
||||
)
|
||||
saveDataInSharedPref(qrVpaEntity)
|
||||
vpaList.forEach {
|
||||
it.isSelected.value =
|
||||
it.linkedAccountEntity.accountId == qrVpaEntity.linkedAccountEntity.accountId
|
||||
|
||||
@@ -44,6 +44,10 @@ const val KEY_PROVIDER_NAME = "naviPayKeyProviderName"
|
||||
const val KEY_EXTERNAL_CUSTOMER_ID = "naviPayKeyMerchantCustomerId"
|
||||
const val KEY_CUSTOMER_STATUS = "customerStatus"
|
||||
const val KEY_MORE_OPTIONS_ACCOUNT_ID = "moreOptionsAccountId"
|
||||
const val KEY_MORE_OPTIONS_ACCOUNT_NAME = "moreOptionsAccountName"
|
||||
const val KEY_MORE_OPTIONS_ACCOUNT_VPA = "moreOptionsAccountVpa"
|
||||
const val KEY_MORE_OPTIONS_ACCOUNT_QR_LINK = "moreOptionsAccountQrLink"
|
||||
const val KEY_MORE_OPTIONS_SAVING_ACCOUNT_COUNT = "moreOptionsSavingAccountCount"
|
||||
const val KEY_IS_FIRST_TRANSACTION_SUCCESSFUL = "naviPayIsFirstTransactionSuccessful"
|
||||
const val KEY_DB_ENCRYPTION = "naviPayKeyDbEncryption"
|
||||
|
||||
@@ -64,11 +68,22 @@ const val KEY_NPCI_TOKEN_EXPIRY_IN_DAYS = "npciTokenExpriyInDays"
|
||||
const val KEY_BANK_LIST_DB_LAST_REFRESHED_TIMESTAMP = "bankListLastRefreshedTimestamp"
|
||||
const val KEY_CONFIG_DB_LAST_REFRESHED_TIMESTAMP = "naviPayConfigDbLastRefreshedTimestamp"
|
||||
|
||||
const val BANK_ACCOUNT_TEXT = "bankAccountText"
|
||||
const val UPI_ID_TEXT = "upiIdText"
|
||||
const val QR_CODE_IMAGE = "qrCodeImage"
|
||||
const val USER_VPA_INFO_COLUMN = "userVPAInfoColumn"
|
||||
const val VPA_PLACE_HOLDER_IMAGE = "vpaPlaceholderImage"
|
||||
const val BANK_ACCOUNT_DOWN_ARROW = "bankAccountDownArrow"
|
||||
|
||||
val NAVI_PAY_NON_ENCRYPT_SHARED_PREF_DATA_KEYS = listOf(
|
||||
KEY_NPCI_TOKEN,
|
||||
KEY_NPCI_TOKEN_STORED_TIME,
|
||||
KEY_BANK_LIST_DB_LAST_REFRESHED_TIMESTAMP,
|
||||
KEY_CONFIG_DB_LAST_REFRESHED_TIMESTAMP
|
||||
KEY_CONFIG_DB_LAST_REFRESHED_TIMESTAMP,
|
||||
KEY_MORE_OPTIONS_ACCOUNT_NAME,
|
||||
KEY_MORE_OPTIONS_ACCOUNT_VPA,
|
||||
KEY_MORE_OPTIONS_ACCOUNT_QR_LINK,
|
||||
KEY_MORE_OPTIONS_SAVING_ACCOUNT_COUNT
|
||||
)
|
||||
// Shared Preference constants ends here
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.graphics.Rect
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewTreeObserver
|
||||
@@ -55,6 +56,7 @@ import coil.request.ImageRequest
|
||||
import com.google.zxing.BarcodeFormat
|
||||
import com.google.zxing.EncodeHintType
|
||||
import com.google.zxing.qrcode.QRCodeWriter
|
||||
import com.navi.base.sharedpref.PreferenceManager
|
||||
import com.navi.base.utils.EMPTY
|
||||
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper
|
||||
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.NAVI_PAY_INTENT_VPA
|
||||
@@ -64,9 +66,15 @@ import com.navi.common.utils.capitalize
|
||||
import com.navi.common.utils.get
|
||||
import com.navi.pay.R
|
||||
import com.navi.pay.common.exception.NaviPayApiException
|
||||
import com.navi.pay.common.repository.SharedPreferenceRepository
|
||||
import com.navi.pay.common.theme.color.NaviPayColor
|
||||
import com.navi.pay.common.viewmodel.NaviPayBaseVM
|
||||
import com.navi.pay.onboarding.account.add.model.view.AccountType
|
||||
import com.navi.uitron.model.data.ImageData
|
||||
import com.navi.uitron.model.data.TextData
|
||||
import com.navi.uitron.model.data.UiTronData
|
||||
import com.navi.uitron.model.ui.BaseProperty
|
||||
import com.navi.uitron.model.ui.UiTronView
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
@@ -448,6 +456,96 @@ fun SoftwareKeyboardController?.customHide(context: Context, view: View) {
|
||||
this?.hide()
|
||||
}
|
||||
|
||||
fun updateNaviPayHomeScreenJson(
|
||||
sharedPreferenceRepository: SharedPreferenceRepository,
|
||||
uiTronData: List<UiTronView>?
|
||||
) {
|
||||
val bankName =
|
||||
sharedPreferenceRepository.getStringValueOnMainThread(KEY_MORE_OPTIONS_ACCOUNT_NAME)
|
||||
if (bankName.isEmpty())
|
||||
return
|
||||
val vpa =
|
||||
sharedPreferenceRepository.getStringValueOnMainThread(KEY_MORE_OPTIONS_ACCOUNT_VPA)
|
||||
val qrLink = sharedPreferenceRepository.getStringValueOnMainThread(
|
||||
KEY_MORE_OPTIONS_ACCOUNT_QR_LINK
|
||||
)
|
||||
val savingAccountCount = sharedPreferenceRepository.getIntValueOnMainThread(
|
||||
KEY_MORE_OPTIONS_SAVING_ACCOUNT_COUNT
|
||||
)
|
||||
updateHomePageJson(uiTronData, bankName, vpa, qrLink, savingAccountCount)
|
||||
}
|
||||
|
||||
private fun updateHomePageJson(
|
||||
uiTronData: List<UiTronView>?,
|
||||
bankName: String,
|
||||
vpa: String,
|
||||
qrLink: String,
|
||||
savingAccountCount: Int
|
||||
) {
|
||||
uiTronData?.forEach { childView ->
|
||||
updateHomePageJsonData(childView.data, bankName, vpa, qrLink)
|
||||
updateHomePageJsonProperty(childView.property, savingAccountCount)
|
||||
updateHomePageJson(childView.childrenViews, bankName, vpa, qrLink, savingAccountCount)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateHomePageJsonData(
|
||||
data: MutableMap<String, UiTronData?>?,
|
||||
bankName: String,
|
||||
vpa: String,
|
||||
qrLink: String,
|
||||
) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
data?.forEach { (key, value) ->
|
||||
when (key) {
|
||||
BANK_ACCOUNT_TEXT -> {
|
||||
(value as TextData).text = bankName
|
||||
}
|
||||
|
||||
UPI_ID_TEXT -> {
|
||||
(value as TextData).text = vpa
|
||||
}
|
||||
|
||||
QR_CODE_IMAGE -> {
|
||||
if (value is ImageData) {
|
||||
data[QR_CODE_IMAGE] = ImageData(qrLink)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateHomePageJsonProperty(
|
||||
data: BaseProperty?,
|
||||
savingAccountCount: Int,
|
||||
) {
|
||||
when (data?.layoutId) {
|
||||
USER_VPA_INFO_COLUMN -> {
|
||||
data.visible = true
|
||||
}
|
||||
|
||||
VPA_PLACE_HOLDER_IMAGE -> {
|
||||
data.visible = false
|
||||
}
|
||||
|
||||
BANK_ACCOUNT_DOWN_ARROW -> {
|
||||
data.visible = savingAccountCount > 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun removeMoreOptionQrSharedPrefData() {
|
||||
PreferenceManager.clearKeyBasedSessionPreferenceData(
|
||||
listOf(
|
||||
KEY_MORE_OPTIONS_ACCOUNT_NAME,
|
||||
KEY_MORE_OPTIONS_ACCOUNT_VPA,
|
||||
KEY_MORE_OPTIONS_ACCOUNT_QR_LINK,
|
||||
KEY_MORE_OPTIONS_SAVING_ACCOUNT_COUNT
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun isNaviPayOriginatedIntent(uri: Uri): Boolean {
|
||||
try {
|
||||
val decodeUri = Uri.decode(uri.toString())
|
||||
|
||||
Reference in New Issue
Block a user