NTP-60797 | Redirect user to home page when returning from background (#16426)
This commit is contained in:
@@ -148,6 +148,9 @@ object FirebaseRemoteConfigHelper {
|
||||
"SHOULD_USE_GLOBAL_SCOPE_FOR_DASHBOARD_SYNC"
|
||||
const val NAVI_PAY_DOWNLOAD_HISTORY_AS_PDF_ENABLED = "NAVI_PAY_DOWNLOAD_HISTORY_AS_PDF_ENABLED"
|
||||
|
||||
const val AUTO_REDIRECT_TO_HOME_PAGE_LIMIT_TIME_IN_MIN =
|
||||
"AUTO_REDIRECT_TO_HOME_PAGE_LIMIT_TIME_IN_MIN"
|
||||
|
||||
// COMMON
|
||||
const val LITMUS_EXPERIMENTS_CACHE_DURATION_IN_MILLIS =
|
||||
"LITMUS_EXPERIMENTS_CACHE_DURATION_IN_MILLIS"
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.Spanned
|
||||
import android.text.TextPaint
|
||||
import android.text.format.DateUtils
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.text.style.ClickableSpan
|
||||
import android.text.style.ForegroundColorSpan
|
||||
@@ -62,6 +63,8 @@ import com.google.gson.JsonObject
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.navi.analytics.utils.NaviTrackEvent
|
||||
import com.navi.base.AppServiceManager
|
||||
import com.navi.base.deeplink.DeepLinkManager
|
||||
import com.navi.base.deeplink.util.DeeplinkConstants
|
||||
import com.navi.base.model.ActionData
|
||||
import com.navi.base.model.CtaData
|
||||
import com.navi.base.model.LineItem
|
||||
@@ -72,6 +75,7 @@ import com.navi.base.utils.orElse
|
||||
import com.navi.common.CommonRetrofitProvider
|
||||
import com.navi.common.R
|
||||
import com.navi.common.customview.CustomTypefaceSpan
|
||||
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper
|
||||
import com.navi.common.listeners.ClickableTextListener
|
||||
import com.navi.common.network.models.RepoResult
|
||||
import com.navi.common.network.retrofit.RetrofitService
|
||||
@@ -90,6 +94,7 @@ import java.util.zip.GZIPOutputStream
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
import kotlin.text.orEmpty
|
||||
import kotlin.time.Duration
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -759,3 +764,55 @@ fun Activity.handleTouchEvent(event: MotionEvent?, shouldDismissKeyboardOnFocusC
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user has been inactive on a screen for longer than a specified threshold, and
|
||||
* redirects to the Home screen if the limit is exceeded.
|
||||
*
|
||||
* This is useful for automatically navigating away from inactive screens to improve user experience
|
||||
* and maintain app context.
|
||||
*
|
||||
* @param screenName The name of the screen for logging and analytics purposes.
|
||||
* @param foregroundTime The timestamp (in milliseconds) when the screen came to the foreground.
|
||||
* @param backgroundTime The timestamp (in milliseconds) when the screen went to the background.
|
||||
*
|
||||
* If either `foregroundTime` or `backgroundTime` is 0, the function exits early.
|
||||
*
|
||||
* The threshold for inactivity is fetched from Remote Config
|
||||
* (`AUTO_REDIRECT_TO_HOME_PAGE_DEFAULT_TIME`), with a default value of 1 minute. If the calculated
|
||||
* inactivity duration exceeds this threshold, the user is automatically redirected to the Home
|
||||
* screen, and an event is logged.
|
||||
*/
|
||||
fun Activity.checkAndRedirectToHomeIfInactivityLimitCrossed(
|
||||
screenName: String,
|
||||
foregroundTime: Long,
|
||||
backgroundTime: Long,
|
||||
) {
|
||||
if (foregroundTime == 0L || backgroundTime == 0L) return
|
||||
|
||||
val inactivityDurationInMinutes = (foregroundTime - backgroundTime) / DateUtils.MINUTE_IN_MILLIS
|
||||
val thresholdInMinutes =
|
||||
FirebaseRemoteConfigHelper.getLong(
|
||||
FirebaseRemoteConfigHelper.AUTO_REDIRECT_TO_HOME_PAGE_LIMIT_TIME_IN_MIN,
|
||||
120,
|
||||
)
|
||||
|
||||
if (inactivityDurationInMinutes < thresholdInMinutes) return
|
||||
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
eventName = "Dev_Auto_Redirect_To_HomePage",
|
||||
eventValues =
|
||||
mapOf(
|
||||
"inactivityDurationInMinutes" to inactivityDurationInMinutes.toString(),
|
||||
"thresholdInMinutes" to thresholdInMinutes.toString(),
|
||||
"screenName" to screenName,
|
||||
),
|
||||
)
|
||||
|
||||
DeepLinkManager.getDeepLinkListener()
|
||||
?.navigateTo(
|
||||
activity = this,
|
||||
ctaData = CtaData(url = DeeplinkConstants.HOME),
|
||||
finish = true,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -50,15 +50,19 @@ import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.navi.analytics.utils.AlfredFacade
|
||||
import com.navi.base.utils.TrustedTimeAccessor
|
||||
import com.navi.common.lottie.LottieRepository
|
||||
import com.navi.common.model.NaviLottieCompositionSpecType
|
||||
import com.navi.common.utils.CommonUtils.getDisplayableAmount
|
||||
import com.navi.common.utils.CommonUtils.initFraudCheckSDK
|
||||
import com.navi.common.utils.checkAndRedirectToHomeIfInactivityLimitCrossed
|
||||
import com.navi.common.utils.navigateUp
|
||||
import com.navi.common.utils.setStatusBarColor
|
||||
import com.navi.design.font.FontWeightEnum
|
||||
import com.navi.pay.NavGraphs
|
||||
import com.navi.pay.R
|
||||
import com.navi.pay.analytics.NaviPayAnalytics
|
||||
import com.navi.pay.analytics.NaviPayAnalytics.Companion.NAVI_PAY_SEND_MONEY
|
||||
import com.navi.pay.common.model.view.NaviPayButtonAction
|
||||
import com.navi.pay.common.model.view.NaviPayScreenType
|
||||
import com.navi.pay.common.model.view.SetPinResult
|
||||
@@ -176,13 +180,22 @@ fun SendMoneyScreen(
|
||||
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
when (event) {
|
||||
Lifecycle.Event.ON_RESUME,
|
||||
Lifecycle.Event.ON_CREATE,
|
||||
Lifecycle.Event.ON_PAUSE -> {
|
||||
naviPayActivity.window.statusBarColor =
|
||||
ContextCompat.getColor(naviPayActivity, colorResId)
|
||||
Lifecycle.Event.ON_CREATE -> {
|
||||
naviPayActivity.setStatusBarColor(color = colorResId)
|
||||
sendMoneyViewModel.setBackgroundTime(0)
|
||||
}
|
||||
Lifecycle.Event.ON_RESUME -> {
|
||||
naviPayActivity.setStatusBarColor(color = colorResId)
|
||||
naviPayActivity.checkAndRedirectToHomeIfInactivityLimitCrossed(
|
||||
screenName = NAVI_PAY_SEND_MONEY,
|
||||
foregroundTime = TrustedTimeAccessor.getCurrentTimeMillis(),
|
||||
backgroundTime = sendMoneyViewModel.screenBackgroundTimestamp,
|
||||
)
|
||||
sendMoneyViewModel.setBackgroundTime(0)
|
||||
}
|
||||
Lifecycle.Event.ON_STOP -> {
|
||||
sendMoneyViewModel.setBackgroundTime(TrustedTimeAccessor.getCurrentTimeMillis())
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,6 +835,8 @@ constructor(
|
||||
|
||||
private var fetchOffersJob: Job? = null
|
||||
|
||||
var screenBackgroundTimestamp = 0L
|
||||
|
||||
val sortedOffersList =
|
||||
combine(
|
||||
paymentAmount.debounce(200.milliseconds).distinctUntilChanged(),
|
||||
@@ -5082,6 +5084,10 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun setBackgroundTime(timestamp: Long) {
|
||||
screenBackgroundTimestamp = timestamp
|
||||
}
|
||||
|
||||
private fun transactionLedgerEnabled(): Boolean =
|
||||
isTxnLedgerAvailable.value &&
|
||||
(source is SendMoneyScreenSource.BankDetailInput ||
|
||||
|
||||
Reference in New Issue
Block a user