NTP-19371 | Added experiment for controlling frequent contact feature in QR scanner screen (#14129)

This commit is contained in:
Ujjwal Kumar
2024-12-16 14:00:10 +05:30
committed by GitHub
parent 99c3d27e99
commit 72b72db025
5 changed files with 81 additions and 45 deletions

View File

@@ -125,7 +125,6 @@ object FirebaseRemoteConfigHelper {
const val NAVI_PAY_EXTERNAL_APP_SHARE_CONFIGURABLE_TEXT =
"NAVI_PAY_EXTERNAL_APP_SHARE_CONFIGURABLE_TEXT"
const val NAVI_PAY_BBPS_SHARE_RECEIPT_DEEPLINK = "NAVI_PAY_BBPS_SHARE_RECEIPT_DEEPLINK"
const val NAVI_PAY_BANK_LOGOS_V2_ENABLED = "NAVI_PAY_BANK_LOGOS_V2_ENABLED"
const val NAVI_PAY_BANK_LOGOS_V2_URL = "NAVI_PAY_BANK_LOGOS_V2_URL"
const val NAVI_PAY_AUTO_FLASH_DISABLED = "NAVI_PAY_AUTO_FLASH_DISABLED"
const val NAVI_PAY_AUTO_FLASH_LIGHT_LUX_THRESHOLD = "NAVI_PAY_AUTO_FLASH_LIGHT_LUX_THRESHOLD"

View File

@@ -55,7 +55,6 @@ import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableFloatStateOf
@@ -169,6 +168,8 @@ fun QrScannerScreen(
qrScannerViewModel.frequentOrdersHeading.collectAsStateWithLifecycle()
val rewardsNudgeDetailEntity by
qrScannerViewModel.rewardsNudgeDetailEntity.collectAsStateWithLifecycle()
val isFrequentTransactionsEnabled by
qrScannerViewModel.isFrequentTransactionsEnabled.collectAsStateWithLifecycle()
val onBackClick = { navigator.navigateUp(naviPayActivity) }
@@ -391,14 +392,12 @@ fun QrScannerScreen(
}
}
val colorAdjustedContent by
val colorAdjustedContent =
remember(cameraPermissionsState.allPermissionsGranted) {
derivedStateOf {
if (cameraPermissionsState.allPermissionsGranted) {
NaviPayColor.black.copy(alpha = 0.5f)
} else {
NaviPayColor.bgDefault
}
if (cameraPermissionsState.allPermissionsGranted) {
NaviPayColor.black.copy(alpha = 0.5f)
} else {
NaviPayColor.bgDefault
}
}
@@ -537,27 +536,29 @@ fun QrScannerScreen(
cameraPermissionsGranted = cameraPermissionsState.allPermissionsGranted
)
FrequentOrdersListView(
modifier =
Modifier.fillMaxWidth().height(IntrinsicSize.Min).align(Alignment.BottomCenter),
frequentOrders = frequentOrders,
onFrequentOrderSelected = { orderEntity ->
qrScannerViewModel.initiatePayment(orderEntity = orderEntity)
naviPayAnalytics.onContactSelected(
source = NaviPayScreenType.NAVI_PAY_QR_SCANNER_SCREEN.name,
inContactList = false,
isFromFrequentOrderList = true,
currentSearchQuery = "",
naviPaySessionAttributes = qrScannerViewModel.getNaviPaySessionAttributes(),
isPermissionGranted = cameraPermissionsState.allPermissionsGranted,
orderOfOrderItem = frequentOrders.indexOf(orderEntity)
)
},
navigateToPayToContactsScreen = navigateToPayToContactsScreen,
showLoader = showLoader,
clickedContactPhoneNumber = clickedContactPhoneNumber,
frequentOrdersHeading = frequentOrdersHeading
)
if (isFrequentTransactionsEnabled) {
FrequentOrdersListView(
modifier =
Modifier.fillMaxWidth().height(IntrinsicSize.Min).align(Alignment.BottomCenter),
frequentOrders = frequentOrders,
onFrequentOrderSelected = { orderEntity ->
qrScannerViewModel.initiatePayment(orderEntity = orderEntity)
naviPayAnalytics.onContactSelected(
source = NaviPayScreenType.NAVI_PAY_QR_SCANNER_SCREEN.name,
inContactList = false,
isFromFrequentOrderList = true,
currentSearchQuery = "",
naviPaySessionAttributes = qrScannerViewModel.getNaviPaySessionAttributes(),
isPermissionGranted = cameraPermissionsState.allPermissionsGranted,
orderOfOrderItem = frequentOrders.indexOf(orderEntity)
)
},
navigateToPayToContactsScreen = navigateToPayToContactsScreen,
showLoader = showLoader,
clickedContactPhoneNumber = clickedContactPhoneNumber,
frequentOrdersHeading = frequentOrdersHeading
)
}
}
}

View File

@@ -20,6 +20,7 @@ import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.NAVI_PAY_
import com.navi.common.model.common.NudgeDetailEntity
import com.navi.common.network.models.RepoResult
import com.navi.common.network.models.isSuccessWithData
import com.navi.common.usecase.LitmusExperimentsUseCase
import com.navi.common.usecase.RewardsNudgeEntityFetchUseCase
import com.navi.pay.R
import com.navi.pay.analytics.NaviPayAnalytics
@@ -51,13 +52,17 @@ import com.navi.pay.management.moneytransfer.scanpay.util.UpiUriParser
import com.navi.pay.tstore.list.model.view.OrderEntity
import com.navi.pay.utils.DEFAULT_CONFIG
import com.navi.pay.utils.INVALID_VPA
import com.navi.pay.utils.LITMUS_EXPERIMENT_NAVIPAY_FREQUENT_CONTACT_IN_QR_SCANNER
import com.navi.pay.utils.NAVI_PAY_SCAN_AND_PAY_WIDGET_ANALYTICS_EVENT_KEY
import com.navi.pay.utils.NOT_LINKED_TO_UPI
import com.ramcosta.composedestinations.spec.Direction
import dagger.hilt.android.lifecycle.HiltViewModel
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -83,7 +88,8 @@ constructor(
private val naviPayNetworkConnectivity: NaviPayNetworkConnectivity,
private val validateVpaUseCase: ValidateVpaUseCase,
private val lightSensorManager: LightSensorManager,
private val naviPayActivityDataProvider: NaviPayActivityDataProvider
private val naviPayActivityDataProvider: NaviPayActivityDataProvider,
private val litmusExperimentsUseCase: LitmusExperimentsUseCase
) : NaviPayBaseVM() {
private var naviPayDefaultConfig = NaviPayDefaultConfig()
@@ -145,6 +151,9 @@ constructor(
private val lightSensorLuxValue = MutableStateFlow(Float.MAX_VALUE)
private val _isFrequentTransactionsEnabled = MutableStateFlow(false)
val isFrequentTransactionsEnabled = _isFrequentTransactionsEnabled.asStateFlow()
init {
fetchRewardsNudgeDetail()
updateNaviPaySessionId()
@@ -240,13 +249,42 @@ constructor(
}
private fun updateFrequentOrdersList() {
viewModelScope.safeLaunch(coroutineDispatcherProvider.io) {
updateFrequentOrders(
frequentOrdersHelper.getFrequentOrderList(
frequentOrdersTotalEntries = frequentOrdersTotalEntries.value,
frequentOrdersDays = frequentOrdersDays.value
)
viewModelScope.launch(coroutineDispatcherProvider.io) {
val frequentOrderJobs = mutableListOf<Deferred<Unit>>()
frequentOrderJobs.add(
async {
updateFrequentOrders(
frequentOrdersHelper.getFrequentOrderList(
frequentOrdersTotalEntries = frequentOrdersTotalEntries.value,
frequentOrdersDays = frequentOrdersDays.value
)
)
}
)
frequentOrderJobs.add(
async {
// This experiment is for disabling frequent transactions in QR scanner &
// default is enabled
val isFrequentTransactionEnabledLitmusResponse =
litmusExperimentsUseCase
.execute(
experimentName =
LITMUS_EXPERIMENT_NAVIPAY_FREQUENT_CONTACT_IN_QR_SCANNER
)
?.variant
?.enabled
?.not() ?: true
_isFrequentTransactionsEnabled.update {
isFrequentTransactionEnabledLitmusResponse
}
}
)
frequentOrderJobs.awaitAll()
_isFrequentOrderListUpdated.emit(value = true)
}
}

View File

@@ -9,7 +9,6 @@ package com.navi.pay.onboarding.account.add.model.network
import com.google.gson.annotations.SerializedName
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.NAVI_PAY_BANK_LOGOS_V2_ENABLED
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.NAVI_PAY_BANK_LOGOS_V2_URL
import com.navi.pay.onboarding.account.add.model.view.BankEntity
import com.navi.pay.utils.NAVI_PAY_BANK_LOGOS_V2_URL_BANK_IDENTIFIER_KEY
@@ -31,12 +30,8 @@ data class BankItemResponse(
fun BankItemResponse.toBankEntity(): BankEntity {
val iconUrl =
if (FirebaseRemoteConfigHelper.getBoolean(NAVI_PAY_BANK_LOGOS_V2_ENABLED)) {
FirebaseRemoteConfigHelper.getString(NAVI_PAY_BANK_LOGOS_V2_URL)
.replace(oldValue = NAVI_PAY_BANK_LOGOS_V2_URL_BANK_IDENTIFIER_KEY, newValue = code)
} else {
this.iconUrl
}
FirebaseRemoteConfigHelper.getString(NAVI_PAY_BANK_LOGOS_V2_URL)
.replace(oldValue = NAVI_PAY_BANK_LOGOS_V2_URL_BANK_IDENTIFIER_KEY, newValue = code)
return BankEntity(
code = code,

View File

@@ -176,6 +176,8 @@ const val LITMUS_EXPERIMENT_NAVIPAY_UPI_NUMBER = "NaviPay-exp-upi-number-page"
const val LITMUS_EXPERIMENT_NAVIPAY_CHECK_BALANCE_DURING_TRANSACTION =
"NaviPay-exp-check-balance-during-transaction"
const val LITMUS_EXPERIMENT_NAVIPAY_CHRISTMAS_CELEBRATION = "NaviPay-exp-rwd-holiday-animation"
const val LITMUS_EXPERIMENT_NAVIPAY_FREQUENT_CONTACT_IN_QR_SCANNER =
"NaviPay-frequent-contact-in-qr-scanner"
val NAVI_PAY_LITMUS_EXPERIMENTS =
listOf(
LITMUS_EXPERIMENT_NAVIPAY_LITE_AUTO_TOP_UP,
@@ -183,7 +185,8 @@ val NAVI_PAY_LITMUS_EXPERIMENTS =
LITMUS_EXPERIMENT_NAVIPAY_ORDER_TAG_SUMMARY,
LITMUS_EXPERIMENT_NAVIPAY_UPI_NUMBER,
LITMUS_EXPERIMENT_NAVIPAY_CHECK_BALANCE_DURING_TRANSACTION,
LITMUS_EXPERIMENT_NAVIPAY_CHRISTMAS_CELEBRATION
LITMUS_EXPERIMENT_NAVIPAY_CHRISTMAS_CELEBRATION,
LITMUS_EXPERIMENT_NAVIPAY_FREQUENT_CONTACT_IN_QR_SCANNER
)
// Generic