From 35022e4d31ce5179f6f6f8b8e4f06b56d6d4fc43 Mon Sep 17 00:00:00 2001 From: Hitesh Kumar Date: Thu, 29 May 2025 11:33:32 +0530 Subject: [PATCH] NTP-67834 replace launch with safe launch in mm module (#16360) --- .../presentation/ui/details/BillListView.kt | 4 ++-- .../presentation/ui/details/DateHeading.kt | 4 ++-- .../ui/screen/BillCalendarScreen.kt | 4 ++-- .../viewmodel/AddBillViewModel.kt | 23 ++++++++++--------- .../viewmodel/BillCalendarViewModel.kt | 6 ++--- .../common/manager/MMLibManager.kt | 10 ++++---- .../ui/DashboardContainerAnimatingEffect.kt | 14 +++++------ .../dashboard/ui/FeedbackBottomSheet.kt | 4 ++-- .../usecase/RefreshAndSyncDataUseCase.kt | 3 +-- .../bottomsheet/CategoryCommonBottomSheet.kt | 8 +++---- 10 files changed, 41 insertions(+), 39 deletions(-) diff --git a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/ui/details/BillListView.kt b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/ui/details/BillListView.kt index 7669ebeb16..37b0fa39f9 100644 --- a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/ui/details/BillListView.kt +++ b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/ui/details/BillListView.kt @@ -38,6 +38,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.navi.base.utils.isNotNull import com.navi.base.utils.orZero +import com.navi.common.utils.safeLaunch import com.navi.elex.theme.elexColors import com.navi.moneymanager.R import com.navi.moneymanager.billcalendar.domain.model.data.BillModel @@ -48,7 +49,6 @@ import com.navi.moneymanager.billcalendar.domain.model.data.CalendarDay import com.navi.moneymanager.billcalendar.domain.model.response.BillData import com.navi.moneymanager.billcalendar.presentation.model.data.BillModificationData import com.navi.moneymanager.billcalendar.presentation.model.data.BillTab -import kotlinx.coroutines.launch import kotlinx.datetime.LocalDate @Composable @@ -157,7 +157,7 @@ private fun BillListContent( contentPadding = PaddingValues(4.dp), onTabSelected = { index -> if (index != pagerState.currentPage) { - scope.launch { pagerState.animateScrollToPage(index) } + scope.safeLaunch { pagerState.animateScrollToPage(index) } scrollToTop = false } else { scrollToTop = true diff --git a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/ui/details/DateHeading.kt b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/ui/details/DateHeading.kt index b4a71aaad9..ebd9f3ea57 100644 --- a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/ui/details/DateHeading.kt +++ b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/ui/details/DateHeading.kt @@ -35,6 +35,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.navi.common.utils.SPACE +import com.navi.common.utils.safeLaunch import com.navi.elex.atoms.ElexText import com.navi.elex.font.FontWeightEnum import com.navi.elex.theme.elexColors @@ -42,7 +43,6 @@ import com.navi.moneymanager.R import com.navi.moneymanager.billcalendar.presentation.utils.constants.BillCalendarConstants.Strings.SEPARATOR import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay -import kotlinx.coroutines.launch import kotlinx.datetime.LocalDate @Composable @@ -58,7 +58,7 @@ fun DateHeading( LaunchedEffect(isSelected) { if (isSelected) { - coroutineScope.launch(Dispatchers.IO) { + coroutineScope.safeLaunch(Dispatchers.IO) { showGreenIndication = true delay(1500) showGreenIndication = false diff --git a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/ui/screen/BillCalendarScreen.kt b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/ui/screen/BillCalendarScreen.kt index a0b8805395..394f16310d 100644 --- a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/ui/screen/BillCalendarScreen.kt +++ b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/ui/screen/BillCalendarScreen.kt @@ -41,6 +41,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.navi.base.model.CtaData import com.navi.base.utils.isNotNullAndNotEmpty +import com.navi.common.utils.safeLaunch import com.navi.elex.theme.elexColors import com.navi.moneymanager.billcalendar.domain.model.data.CalendarDay import com.navi.moneymanager.billcalendar.presentation.model.data.BillModificationData @@ -80,7 +81,6 @@ import com.navi.moneymanager.entry.ui.activity.MMActivity import com.navi.moneymanager.postonboard.monthlysummary.ui.bottomsheet.CustomToastView import com.ramcosta.composedestinations.annotation.Destination import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch @Destination @Composable @@ -330,7 +330,7 @@ fun BillCalendarScreen( ) }, updateBackdropState = { state -> - scope.launch(Dispatchers.IO) { + scope.safeLaunch(Dispatchers.IO) { if (state) { backdropScaffoldState.conceal() } else { diff --git a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/viewmodel/AddBillViewModel.kt b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/viewmodel/AddBillViewModel.kt index 55c585d331..2983b6f6a3 100644 --- a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/viewmodel/AddBillViewModel.kt +++ b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/viewmodel/AddBillViewModel.kt @@ -12,6 +12,7 @@ import androidx.lifecycle.viewModelScope import com.google.gson.Gson import com.navi.base.utils.EMPTY import com.navi.common.network.models.isSuccessWithData +import com.navi.common.utils.safeLaunch import com.navi.moneymanager.base.viewmodel.MMBaseViewModel import com.navi.moneymanager.billcalendar.data.helper.BillCalendarDataHelper import com.navi.moneymanager.billcalendar.data.repo.AddBillRepository @@ -29,7 +30,6 @@ import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.launch @HiltViewModel class AddBillViewModel @@ -47,7 +47,7 @@ constructor( private val _addNewBillScreenData = MutableStateFlow(null) fun getAddNewBillScreenData(billId: String?) { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.safeLaunch(Dispatchers.IO) { repository.getAddNewBillScreenData(billId).collect { _addNewBillScreenData.value = it sendEvent(AddBillUiEvent.UpdateAddNewBillScreenData(it)) @@ -56,7 +56,7 @@ constructor( } fun getSelectBillIconBottomSheetData() { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.safeLaunch(Dispatchers.IO) { repository.getSelectBillIconBottomSheetData().collect { sendEvent( AddBillUiEvent.ShowBottomSheet( @@ -68,7 +68,7 @@ constructor( } fun setBillIconFromCategory(categoryId: String) { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.safeLaunch(Dispatchers.IO) { repository.getSelectBillIconBottomSheetData().collect { it.generalIconsList ?.firstOrNull { icon -> icon.iconId == categoryId } @@ -78,7 +78,7 @@ constructor( } fun getSelectBillCategoryBottomSheetData() { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.safeLaunch(Dispatchers.IO) { repository.getSelectBillCategoryBottomSheetData().collect { sendEvent( AddBillUiEvent.ShowBottomSheet( @@ -90,7 +90,7 @@ constructor( } fun submitBill(actionType: BillActionType, billId: String? = null) { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.safeLaunch(Dispatchers.IO) { sendEvent(AddBillUiEvent.UpdateFooterLoadingState(true)) val requestBody = getAddBillRequestBody(state.value.data?.content) @@ -98,7 +98,8 @@ constructor( val response = when (actionType) { BillActionType.ADD -> repository.addBill(requestBody) - BillActionType.EDIT -> repository.editBill(requestBody, billId ?: return@launch) + BillActionType.EDIT -> + repository.editBill(requestBody, billId ?: return@safeLaunch) } sendEvent(AddBillUiEvent.UpdateFooterLoadingState(false)) @@ -146,9 +147,9 @@ constructor( } fun onBillAmountChanged(billAmount: TextFieldValue) { - viewModelScope.launch { + viewModelScope.safeLaunch { val inputText = billAmount.text.trimStart { it == '0' } - if (containsInvalidNumberInput(inputText)) return@launch + if (containsInvalidNumberInput(inputText)) return@safeLaunch val filtered = inputText.replace(Regex("[^\\d.]"), "") val parts = filtered.split('.', limit = 2) val integerPart = parts.getOrNull(0) ?: EMPTY @@ -170,9 +171,9 @@ constructor( } fun onBillNameChanged(billName: TextFieldValue) { - viewModelScope.launch { + viewModelScope.safeLaunch { val inputText = billName.text - if (containsInvalidNameInput(inputText)) return@launch + if (containsInvalidNameInput(inputText)) return@safeLaunch if (inputText.length <= 100) { sendEvent( AddBillUiEvent.UpdateBillName( diff --git a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/viewmodel/BillCalendarViewModel.kt b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/viewmodel/BillCalendarViewModel.kt index 92cdb02373..b064155580 100644 --- a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/viewmodel/BillCalendarViewModel.kt +++ b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/billcalendar/presentation/viewmodel/BillCalendarViewModel.kt @@ -12,6 +12,7 @@ import com.google.gson.Gson import com.navi.base.utils.orFalse import com.navi.common.network.models.isSuccessWithData import com.navi.common.utils.log +import com.navi.common.utils.safeLaunch import com.navi.moneymanager.R import com.navi.moneymanager.base.viewmodel.MMBaseViewModel import com.navi.moneymanager.billcalendar.data.analytics.BillCalendarEventTracker @@ -40,7 +41,6 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch @HiltViewModel class BillCalendarViewModel @@ -101,7 +101,7 @@ constructor( } fun deleteBill(billId: String) { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.safeLaunch(Dispatchers.IO) { sendEvent( BillCalendarUiEvent.UpdateDeleteBillBottomSheetState( DeleteBillBottomSheetState.Loading @@ -141,7 +141,7 @@ constructor( } fun markBillAsPaid(billId: String) { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.safeLaunch(Dispatchers.IO) { sendEvent( BillCalendarUiEvent.UpdateMarkBillAsPaidBottomSheetState( MarkBillAsPaidBottomSheetState.Loading diff --git a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/common/manager/MMLibManager.kt b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/common/manager/MMLibManager.kt index b762674600..9b5ca5e264 100644 --- a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/common/manager/MMLibManager.kt +++ b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/common/manager/MMLibManager.kt @@ -9,6 +9,7 @@ package com.navi.moneymanager.common.manager import com.navi.base.cache.repository.NaviCacheRepository import com.navi.base.sharedpref.PreferenceManager +import com.navi.common.utils.safeLaunch import com.navi.moneymanager.billcalendar.data.local.database.BillCalendarDatabase import com.navi.moneymanager.common.db.database.MMDatabase import com.navi.moneymanager.common.db.upi.database.UpiSpendDatabase @@ -20,7 +21,6 @@ import javax.inject.Inject import javax.inject.Singleton import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch @Singleton class MMLibManager @@ -32,17 +32,19 @@ constructor( private val naviCacheRepository: NaviCacheRepository, ) { fun initMoneyManagerDB() { - CoroutineScope(Dispatchers.IO).launch { mmDatabase.get().accountsDao().getAccountsCount() } + CoroutineScope(Dispatchers.IO).safeLaunch { + mmDatabase.get().accountsDao().getAccountsCount() + } } fun initUpiSpendAnalyserDB() { - CoroutineScope(Dispatchers.IO).launch { + CoroutineScope(Dispatchers.IO).safeLaunch { upiSpendDatabase.get().transactionsDao().getTransactionCount() } } fun clearMoneyManagerData() { - CoroutineScope(Dispatchers.IO).launch { + CoroutineScope(Dispatchers.IO).safeLaunch { PreferenceManager.setBooleanPreference(MM_IS_USER_ONBOARDED, false) naviCacheRepository.clear(key = MONEY_MANAGER_VALUE_PROPOSITION_SCREEN_KEY) naviCacheRepository.clear(key = MONEY_MANAGER_CONFIG_RESPONSE_KEY) diff --git a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/dashboard/ui/DashboardContainerAnimatingEffect.kt b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/dashboard/ui/DashboardContainerAnimatingEffect.kt index 0fd0ac0a79..07fb721ed7 100644 --- a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/dashboard/ui/DashboardContainerAnimatingEffect.kt +++ b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/dashboard/ui/DashboardContainerAnimatingEffect.kt @@ -28,6 +28,7 @@ import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.dp import com.navi.base.sharedpref.PreferenceManager +import com.navi.common.utils.safeLaunch import com.navi.moneymanager.common.utils.Constants.MM_IS_USER_ONBOARDED import com.navi.moneymanager.postonboard.dashboard.model.BankSectionData import com.navi.moneymanager.postonboard.dashboard.model.CurrentItemOnDashboardState @@ -44,7 +45,6 @@ import com.navi.moneymanager.postonboard.dashboard.viewmodel.DashboardViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.joinAll -import kotlinx.coroutines.launch @Composable internal fun DashboardContainerAnimatingEffect( @@ -84,7 +84,7 @@ internal fun DashboardContainerAnimatingEffect( suspend fun handleCurrentItemFadeOut(scope: CoroutineScope) { val currentItemAlphaFinalJob = - scope.launch { + scope.safeLaunch { currentItemAlpha.animateTo( targetValue = INVISIBLE_ALPHA, animationSpec = tween(durationMillis = FADE_OUT_DURATION_MS), @@ -92,7 +92,7 @@ internal fun DashboardContainerAnimatingEffect( } val animationEffectCompleteJob = - scope.launch { + scope.safeLaunch { delay(DELAY_BEFORE_COMPLETION_MS) onEvent(DashboardScreenUiEvent.MarkOnBoardingAnimationStatusSuccess) } @@ -106,7 +106,7 @@ internal fun DashboardContainerAnimatingEffect( suspend fun animateItemTransitions(scope: CoroutineScope) { val currentItemOffsetJob = - scope.launch { + scope.safeLaunch { currentItemOffset.animateTo( targetValue = -screenHeightPx.toFloat(), animationSpec = tween(durationMillis = SLIDE_UP_DURATION_MS), @@ -114,7 +114,7 @@ internal fun DashboardContainerAnimatingEffect( } val nextItemOffsetJob = - scope.launch { + scope.safeLaunch { nextItemOffset.animateTo( targetValue = 0f, animationSpec = tween(durationMillis = FADE_OUT_DURATION_MS), @@ -122,7 +122,7 @@ internal fun DashboardContainerAnimatingEffect( } val currentItemAlphaJob = - scope.launch { + scope.safeLaunch { currentItemAlpha.animateTo( targetValue = 0f, animationSpec = tween(durationMillis = FADE_OUT_DURATION_MS), @@ -130,7 +130,7 @@ internal fun DashboardContainerAnimatingEffect( } val nextItemAlphaJob = - scope.launch { + scope.safeLaunch { nextItemAlpha.animateTo( targetValue = 1f, animationSpec = tween(durationMillis = NEXT_FADE_IN_DURATION_MS), diff --git a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/dashboard/ui/FeedbackBottomSheet.kt b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/dashboard/ui/FeedbackBottomSheet.kt index 1378fc7d51..d0b99a2e70 100644 --- a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/dashboard/ui/FeedbackBottomSheet.kt +++ b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/dashboard/ui/FeedbackBottomSheet.kt @@ -37,6 +37,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import com.navi.common.utils.safeLaunch import com.navi.design.font.FontWeightEnum import com.navi.elex.atoms.ElexButton import com.navi.elex.theme.elexColors @@ -47,7 +48,6 @@ import com.navi.moneymanager.common.ui.composable.base.MMTextField import com.navi.moneymanager.postonboard.dashboard.model.FeedBackBottomSheetData import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay -import kotlinx.coroutines.launch @Composable fun FeedbackBottomSheet( @@ -115,7 +115,7 @@ fun FeedbackBottomSheet( ), onClick = { focusManager.clearFocus() - coroutineScope.launch(Dispatchers.IO) { + coroutineScope.safeLaunch(Dispatchers.IO) { delay(200) onSubmit(feedback.text) } diff --git a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/dashboard/usecase/RefreshAndSyncDataUseCase.kt b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/dashboard/usecase/RefreshAndSyncDataUseCase.kt index 86c3a9df2b..4c5c3a8828 100644 --- a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/dashboard/usecase/RefreshAndSyncDataUseCase.kt +++ b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/dashboard/usecase/RefreshAndSyncDataUseCase.kt @@ -31,7 +31,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch @ViewModelScoped class RefreshAndSyncDataUseCase @@ -88,7 +87,7 @@ constructor( initialDelaySeconds = configResponse.dataSyncPollingConfig?.initialDelaySeconds ?: 0, taskIntervalSeconds = configResponse.dataSyncPollingConfig?.taskIntervalSeconds ?: 5, onTimeout = { - CoroutineScope(Dispatchers.IO).launch { + CoroutineScope(Dispatchers.IO).safeLaunch { dbDataStoreProvider.saveStringData( Constants.ACCOUNT_SYNC_STATUS, SyncStatus.FAILED.name, diff --git a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/monthlysummary/ui/bottomsheet/CategoryCommonBottomSheet.kt b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/monthlysummary/ui/bottomsheet/CategoryCommonBottomSheet.kt index 429ffa8670..11ea04d947 100644 --- a/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/monthlysummary/ui/bottomsheet/CategoryCommonBottomSheet.kt +++ b/android/navi-money-manager/src/main/kotlin/com/navi/moneymanager/postonboard/monthlysummary/ui/bottomsheet/CategoryCommonBottomSheet.kt @@ -54,6 +54,7 @@ import com.navi.base.utils.orFalse import com.navi.base.utils.orZero import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper import com.navi.common.utils.EMPTY +import com.navi.common.utils.safeLaunch import com.navi.design.font.FontWeightEnum import com.navi.elex.atoms.ElexBottomSheet import com.navi.elex.theme.elexColors @@ -88,7 +89,6 @@ import com.navi.moneymanager.postonboard.monthlysummary.ui.composable.Transactio import com.navi.moneymanager.postonboard.monthlysummary.viewmodel.CategoryBottomSheetViewModel import com.navi.moneymanager.postonboard.transactiondetails.model.TransactionSummary import kotlinx.coroutines.delay -import kotlinx.coroutines.launch @Composable fun CategoryCommonBottomSheet( @@ -257,7 +257,7 @@ fun CategoryCommonBottomSheet( currentContentType.value = contentType }, onTransactionDetailsClicked = { transactionSummary -> - coroutineScope.launch { + coroutineScope.safeLaunch { transactionDetailsBottomSheetData = transactionSummary showBottomSheet.value = false delay(300) @@ -298,7 +298,7 @@ fun CategoryCommonBottomSheet( ElexBottomSheet( visible = showTransactionDetailsBottomSheet, onDismissRequest = { - coroutineScope.launch { + coroutineScope.safeLaunch { showTransactionDetailsBottomSheet = false showBottomSheet.value = true } @@ -317,7 +317,7 @@ fun CategoryCommonBottomSheet( TransactionDetailsBottomSheet( transactionSummary = transactionDetailsBottomSheetData, onDismiss = { - coroutineScope.launch { + coroutineScope.safeLaunch { showTransactionDetailsBottomSheet = false delay(300) if (!showTransactionDetailsBottomSheet) {