TP-84905 | Naman Khurmi | Fixing MVI set effect and scoping for the relevant functions (#12662)
Signed-off-by: namankhurmi <naman.khurmi@navi.com>
This commit is contained in:
@@ -456,9 +456,7 @@ class HomePageActivity :
|
||||
}
|
||||
}
|
||||
if (redirectionUseCase.isUpiNuxRedirection(intent.extras).not()) {
|
||||
homeVM.sendEffect(homeVM.coroutineScope) {
|
||||
HpEffects.ShowNotificationPermissions(permissionsManager)
|
||||
}
|
||||
homeVM.sendEffect { HpEffects.ShowNotificationPermissions(permissionsManager) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -913,7 +911,7 @@ class HomePageActivity :
|
||||
}
|
||||
|
||||
private fun trackLaunchEvents() {
|
||||
homeVM.sendEffect(homeVM.coroutineScope) { HpEffects.TrackBottomBarEvents }
|
||||
homeVM.sendEffect { HpEffects.TrackBottomBarEvents }
|
||||
}
|
||||
|
||||
private fun initHomeScreenActions() {
|
||||
|
||||
@@ -80,9 +80,7 @@ fun NavGraphNavigationItem(
|
||||
)
|
||||
}
|
||||
is HomeScreenCallbackListener.InitiatePaymentOnHomePage -> {
|
||||
homeVM().sendEffect(homeVM().coroutineScope) {
|
||||
HpEffects.InitiatePayment(it.paymentData)
|
||||
}
|
||||
homeVM().sendEffect { HpEffects.InitiatePayment(it.paymentData) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,8 +54,6 @@ import com.naviapp.home.reducer.HpEvents
|
||||
import com.naviapp.home.reducer.HpStates
|
||||
import com.naviapp.home.utils.getHomeWidgetAnimationSpec
|
||||
import com.naviapp.home.viewmodel.HomeViewModel
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
@Composable
|
||||
@OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
|
||||
@@ -176,9 +174,7 @@ private fun RenderUiTronContent(
|
||||
}
|
||||
LaunchedEffect(hpStates().renderingFirstTime) {
|
||||
if (hpStates().renderingFirstTime) {
|
||||
homeVM.sendEffect(CoroutineScope(Dispatchers.Main)) {
|
||||
HpEffects.OnPrioritySectionRendered
|
||||
}
|
||||
homeVM.sendEffect { HpEffects.OnPrioritySectionRendered }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ import com.naviapp.home.reducer.HpEffects
|
||||
import com.naviapp.home.reducer.HpEvents
|
||||
import com.naviapp.home.reducer.HpStates
|
||||
import com.naviapp.home.viewmodel.HomeViewModel
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
@Composable
|
||||
fun HomeScreenDialog(homeVM: () -> HomeViewModel, hpStates: () -> HpStates) {
|
||||
@@ -42,9 +40,7 @@ fun HomeScreenDialog(homeVM: () -> HomeViewModel, hpStates: () -> HpStates) {
|
||||
LaunchedEffect(dialogStateHolder.state) {
|
||||
if (dialogStateHolder.state == HpDialogStateHolder.HpDialogState.Hidden) {
|
||||
dialogStateHolder.dialogUIContent?.onDismissAction?.let {
|
||||
homeVM().sendEffect(CoroutineScope(Dispatchers.Default)) {
|
||||
HpEffects.OnActionData(it)
|
||||
}
|
||||
homeVM().sendEffect { HpEffects.OnActionData(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,9 +47,7 @@ fun handleCtaActionEvents(
|
||||
)
|
||||
}
|
||||
is HomeScreenCallbackListener.InitiatePaymentOnHomePage -> {
|
||||
homeVM.sendEffect(homeVM.coroutineScope) {
|
||||
HpEffects.InitiatePayment(callback.paymentData)
|
||||
}
|
||||
homeVM.sendEffect { HpEffects.InitiatePayment(callback.paymentData) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,6 @@ import com.naviapp.home.reducer.HpStates
|
||||
import com.naviapp.home.viewmodel.HomeViewModel
|
||||
import com.naviapp.home.viewmodel.SharedVM
|
||||
import com.naviapp.payment.viewmodel.PaymentVM
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
@Composable
|
||||
fun InitLifecycleListener(
|
||||
@@ -49,21 +47,13 @@ fun InitLifecycleListener(
|
||||
AlfredManager.setCurrentScreenName(screenName = activity.screenName)
|
||||
homeVM()
|
||||
.observeUPIVpa(
|
||||
onAction = {
|
||||
homeVM().sendEffect(CoroutineScope(Dispatchers.Default)) {
|
||||
HpEffects.OnUitronAction(it)
|
||||
}
|
||||
},
|
||||
onActionData = {
|
||||
homeVM().sendEffect(CoroutineScope(Dispatchers.Default)) {
|
||||
HpEffects.OnActionData(it)
|
||||
}
|
||||
}
|
||||
onAction = { homeVM().sendEffect { HpEffects.OnUitronAction(it) } },
|
||||
onActionData = { homeVM().sendEffect { HpEffects.OnActionData(it) } }
|
||||
)
|
||||
}
|
||||
Lifecycle.Event.ON_RESUME -> {
|
||||
if (homeVM().shouldRefreshHomeApi) {
|
||||
homeVM().sendEffect(homeVM().coroutineScope) { HpEffects.OnRenderActions }
|
||||
homeVM().sendEffect { HpEffects.OnRenderActions }
|
||||
callBackToActivityScreen.invoke(
|
||||
HomeScreenCallbackListener.ApiCallingWithCondition
|
||||
)
|
||||
|
||||
@@ -28,8 +28,6 @@ import com.naviapp.home.viewmodel.HomeViewModel
|
||||
import com.naviapp.home.viewmodel.NotificationVM
|
||||
import com.naviapp.home.viewmodel.SharedVM
|
||||
import com.naviapp.utils.toast
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
@Composable
|
||||
fun InitHomeScreenComponents(
|
||||
@@ -68,9 +66,7 @@ fun InitHomeScreenComponents(
|
||||
LaunchedEffect(key1 = Unit) {
|
||||
sharedVM.uiTronActionHandler.collect { uiTronActionHandler ->
|
||||
uiTronActionHandler?.let {
|
||||
homeVM().sendEffect(CoroutineScope(Dispatchers.Default)) {
|
||||
HpEffects.OnActionsFromJson(it)
|
||||
}
|
||||
homeVM().sendEffect { HpEffects.OnActionsFromJson(it) }
|
||||
sharedVM.updateUiTronAction(uiTronActionHandler = null)
|
||||
}
|
||||
}
|
||||
@@ -85,9 +81,7 @@ fun InitHomeScreenComponents(
|
||||
LaunchedEffect(key1 = Unit) {
|
||||
notificationVM.unReadNotificationCount.collect { count ->
|
||||
if (count > 0) naviAnalyticsEventTracker.onInAppNotificationsCountUpdate(count)
|
||||
homeVM().sendEffect(CoroutineScope(Dispatchers.Default)) {
|
||||
HpEffects.OnNotificationUpdatedCount(count)
|
||||
}
|
||||
homeVM().sendEffect { HpEffects.OnNotificationUpdatedCount(count) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ import com.naviapp.home.model.HpDialogStateHolder
|
||||
import com.naviapp.home.model.HpDialogStateHolder.HpDialogState
|
||||
import com.naviapp.models.response.HomeFeatureResponse
|
||||
|
||||
class HomeReducer : BaseReducer<HpStates, HpEvents, HpEffects> {
|
||||
class HomeReducer : BaseReducer<HpStates, HpEvents> {
|
||||
|
||||
override fun reduce(previousState: HpStates, event: HpEvents): HpStates {
|
||||
return when (event) {
|
||||
|
||||
@@ -51,11 +51,8 @@ import com.naviapp.utils.Constants.HomePageConstants.FETCH_HOME_ITEMS_TIMEOUT
|
||||
import dagger.Lazy
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.TimeoutCancellationException
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -63,7 +60,6 @@ import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withTimeout
|
||||
|
||||
@HiltViewModel
|
||||
@@ -101,20 +97,17 @@ constructor(
|
||||
private val _internetConnectivity = MutableSharedFlow<ConnectivityObserver.Status>()
|
||||
val internetConnectivity: SharedFlow<ConnectivityObserver.Status> = _internetConnectivity
|
||||
|
||||
private fun vmScope(context: CoroutineContext = Dispatchers.IO) =
|
||||
CoroutineScope(context + SupervisorJob())
|
||||
|
||||
init {
|
||||
vmScope().safeLaunch { observeActionCallback() }
|
||||
vmScope().safeLaunch { observeInternetConnectivity() }
|
||||
viewModelScope.safeLaunch((Dispatchers.IO)) { observeActionCallback() }
|
||||
viewModelScope.safeLaunch((Dispatchers.IO)) { observeInternetConnectivity() }
|
||||
}
|
||||
|
||||
private suspend fun observeActionCallback() {
|
||||
getActionCallback().collect { action ->
|
||||
ctaHandler.onActionTriggered(
|
||||
uiTronAction = action,
|
||||
shouldFetchHomeApi = { sendEffect(vmScope()) { HpEffects.FetchHomeApi } },
|
||||
onCtaActionEvent = { sendEffect(vmScope()) { HpEffects.HandleCtaActionEvents(it) } }
|
||||
shouldFetchHomeApi = { sendEffect { HpEffects.FetchHomeApi } },
|
||||
onCtaActionEvent = { sendEffect { HpEffects.HandleCtaActionEvents(it) } }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -124,7 +117,7 @@ constructor(
|
||||
}
|
||||
|
||||
fun updateBackdropScaffoldProgress(offset: Float) {
|
||||
viewModelScope.launch { _backdropScaffoldProgress.update { offset } }
|
||||
viewModelScope.safeLaunch { _backdropScaffoldProgress.update { offset } }
|
||||
}
|
||||
|
||||
fun setHomeApiRefreshFlag(shouldRefresh: Boolean) {
|
||||
@@ -162,10 +155,10 @@ constructor(
|
||||
installedModules = getInstalledDynamicModulesCommaSeparated(),
|
||||
screenHash = null,
|
||||
onFailure = { errorMessage, errors ->
|
||||
sendEffect(vmScope()) { HpEffects.OnApiFailure(errorMessage, errors) }
|
||||
sendEffect { HpEffects.OnApiFailure(errorMessage, errors) }
|
||||
},
|
||||
noInternetCallback = {
|
||||
viewModelScope.launch {
|
||||
viewModelScope.safeLaunch(Dispatchers.IO) {
|
||||
_internetConnectivity.emit(ConnectivityObserver.Status.Unavailable)
|
||||
}
|
||||
}
|
||||
@@ -225,7 +218,7 @@ constructor(
|
||||
) {
|
||||
if (homePageRefreshJob?.isActive == true) return
|
||||
homePageRefreshJob =
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
viewModelScope.safeLaunch(Dispatchers.IO) {
|
||||
handleDataModification()
|
||||
val screenHash = state.value.screenDefinition?.screenMetaData?.get(SCREEN_HASH)
|
||||
fetchAndHandleCacheData(
|
||||
@@ -264,10 +257,10 @@ constructor(
|
||||
installedModules = installedModules,
|
||||
screenHash = screenHash,
|
||||
onFailure = { errorMessage, errors ->
|
||||
sendEffect(vmScope()) { HpEffects.OnApiFailure(errorMessage, errors) }
|
||||
sendEffect { HpEffects.OnApiFailure(errorMessage, errors) }
|
||||
},
|
||||
noInternetCallback = {
|
||||
viewModelScope.launch {
|
||||
viewModelScope.safeLaunch(Dispatchers.IO) {
|
||||
_internetConnectivity.emit(ConnectivityObserver.Status.Unavailable)
|
||||
}
|
||||
}
|
||||
@@ -307,7 +300,7 @@ constructor(
|
||||
}
|
||||
|
||||
private fun finishProcessing(data: NaviCacheEntity) {
|
||||
sendEffect(vmScope(Dispatchers.Default)) { HpEffects.OnRenderActions }
|
||||
sendEffect { HpEffects.OnRenderActions }
|
||||
updateHomeApiTimestamp()
|
||||
data.updatedAt.let { homeTabLastUpdateTimestamp = it }
|
||||
selectiveRefreshHandler.handleSuccessState(this@HomeViewModel)
|
||||
@@ -331,13 +324,13 @@ constructor(
|
||||
}
|
||||
|
||||
fun fetchNuxScreenDataForEligibleUsers(navigateToNuxScreen: () -> Unit) {
|
||||
vmScope().launch {
|
||||
viewModelScope.safeLaunch((Dispatchers.IO)) {
|
||||
nuxHandler.fetchNuxScreenDataForEligibleUsers(UPI_NUX_SCREEN, navigateToNuxScreen)
|
||||
}
|
||||
}
|
||||
|
||||
fun fetchHomeFeature(type: String) {
|
||||
viewModelScope.launch {
|
||||
viewModelScope.safeLaunch((Dispatchers.IO)) {
|
||||
val response = homeRepository.fetchHomeFeature(type)
|
||||
if (response.error == null && response.errors.isNullOrEmpty()) {
|
||||
sendEvent(HpEvents.UpdateHpFeatures(response.data))
|
||||
@@ -347,17 +340,13 @@ constructor(
|
||||
|
||||
fun handleUpiAdaptations() {
|
||||
upiUseCase.updateUPI(
|
||||
onAction = {
|
||||
sendEffect(vmScope(Dispatchers.Default)) { HpEffects.OnUitronAction(it) }
|
||||
},
|
||||
onActionData = {
|
||||
sendEffect(vmScope(Dispatchers.Default)) { HpEffects.OnActionData(it) }
|
||||
}
|
||||
onAction = { sendEffect { HpEffects.OnUitronAction(it) } },
|
||||
onActionData = { sendEffect { HpEffects.OnActionData(it) } }
|
||||
)
|
||||
}
|
||||
|
||||
fun observeUPIVpa(onAction: (UiTronAction) -> Unit, onActionData: (UiTronActionData) -> Unit) {
|
||||
vmScope().launch {
|
||||
viewModelScope.safeLaunch((Dispatchers.IO)) {
|
||||
upiUseCase.naviPayManager.getVpaOfPrimaryAccount().collect { upiId ->
|
||||
upiUseCase.handleVpa(upiId, onAction, onActionData)
|
||||
}
|
||||
|
||||
@@ -8,12 +8,10 @@
|
||||
package com.naviapp.nux.reducer
|
||||
|
||||
import com.navi.common.basemvi.BaseReducer
|
||||
import com.naviapp.nux.model.MainScreenUiEffect
|
||||
import com.naviapp.nux.model.MainScreenUiState
|
||||
import com.naviapp.nux.model.NuxGenericScreenUiEvent
|
||||
|
||||
class NuxGenericScreenReducer :
|
||||
BaseReducer<MainScreenUiState, NuxGenericScreenUiEvent, MainScreenUiEffect> {
|
||||
class NuxGenericScreenReducer : BaseReducer<MainScreenUiState, NuxGenericScreenUiEvent> {
|
||||
|
||||
override fun reduce(
|
||||
previousState: MainScreenUiState,
|
||||
|
||||
@@ -42,11 +42,7 @@ fun NuxGenericScreen(
|
||||
}
|
||||
LaunchedEffect(Unit) { getViewModel.invoke().getScreenDefinition() }
|
||||
|
||||
BackHandler {
|
||||
getViewModel().sendEffect(getViewModel().coroutineScope) {
|
||||
MainScreenUiEffect.Navigation.Back
|
||||
}
|
||||
}
|
||||
BackHandler { getViewModel().sendEffect { MainScreenUiEffect.Navigation.Back } }
|
||||
|
||||
Box(modifier = Modifier.navigationBarsPadding()) {
|
||||
if (state.isLoading) {
|
||||
|
||||
@@ -34,7 +34,7 @@ class NuxViewModel @Inject constructor(val nuxHandler: NewUserExperienceHandler)
|
||||
nuxHandler.getNuxScreenDefinition(
|
||||
queryMap = queryMap,
|
||||
onSuccess = { sendEvent(NuxGenericScreenUiEvent.RenderUI(it)) },
|
||||
onFailure = { sendEffect(coroutineScope) { MainScreenUiEffect.Navigation.Back } }
|
||||
onFailure = { sendEffect { MainScreenUiEffect.Navigation.Back } }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,9 +196,7 @@ class RegistrationActivity :
|
||||
content.viewTreeObserver.addOnPreDrawListener(
|
||||
object : ViewTreeObserver.OnPreDrawListener {
|
||||
override fun onPreDraw(): Boolean {
|
||||
homeVM.sendEffect(homeVM.coroutineScope) {
|
||||
HpEffects.LogAppLaunchTime(LOGIN_SCREEN)
|
||||
}
|
||||
homeVM.sendEffect { HpEffects.LogAppLaunchTime(LOGIN_SCREEN) }
|
||||
content.viewTreeObserver.removeOnPreDrawListener(this)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -7,37 +7,31 @@
|
||||
|
||||
package com.navi.common.basemvi
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.navi.common.viewmodel.BaseVM
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
abstract class BaseMviViewModel<State : UiState, Event : UiEvent, Effect : UiEffect>(
|
||||
initialState: State,
|
||||
private val reducer: BaseReducer<State, Event, Effect>
|
||||
private val reducer: BaseReducer<State, Event>
|
||||
) : BaseVM() {
|
||||
|
||||
private val _state: MutableStateFlow<State> = MutableStateFlow(initialState)
|
||||
val state: StateFlow<State>
|
||||
get() = _state.asStateFlow()
|
||||
|
||||
private val _event: MutableSharedFlow<Event> = MutableSharedFlow()
|
||||
val event: SharedFlow<Event>
|
||||
get() = _event.asSharedFlow()
|
||||
|
||||
private val _effects = Channel<Effect>(capacity = Channel.CONFLATED)
|
||||
val effect = _effects.receiveAsFlow()
|
||||
|
||||
fun sendEffect(scope: CoroutineScope, effect: () -> Effect) {
|
||||
scope.launch { _effects.send(effect()) }
|
||||
fun sendEffect(dispatcher: CoroutineContext? = null, effect: () -> Effect) {
|
||||
viewModelScope.safeLaunch(dispatcher ?: Dispatchers.IO) { _effects.send(effect()) }
|
||||
}
|
||||
|
||||
fun sendEvent(event: Event) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
package com.navi.common.basemvi
|
||||
|
||||
interface BaseReducer<State : UiState, Event : UiEvent, Effect : UiEffect> {
|
||||
interface BaseReducer<State : UiState, Event : UiEvent> {
|
||||
|
||||
fun reduce(previousState: State, event: Event): State
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user