diff --git a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt index 71f04d42af..22932d20e9 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt @@ -1,22 +1,22 @@ package com.tangem.tap.common.redux.legacy +import com.tangem.domain.apptheme.model.AppThemeMode import com.tangem.domain.redux.LegacyAction import com.tangem.tap.common.extensions.dispatchWithMain import com.tangem.tap.common.extensions.inject import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction +import com.tangem.tap.features.details.redux.AppSettingsState import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.onboarding.products.wallet.redux.BackupStartedSource import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.scope import com.tangem.tap.store +import com.tangem.tap.tangemSdkManager import com.tangem.utils.coroutines.JobHolder import com.tangem.utils.coroutines.saveIn import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.* import org.rekotlin.Middleware internal object LegacyMiddleware { @@ -42,10 +42,13 @@ internal object LegacyMiddleware { userWalletsListManager.selectedUserWallet .distinctUntilChanged() .onEach { selectedUserWallet -> + val initializedAppSettingsStateContent = initializeAppSettingsState( + shouldSaveUserWallets = walletsRepository.shouldSaveUserWalletsSync(), + ) store.dispatchWithMain( DetailsAction.PrepareScreen( scanResponse = selectedUserWallet.scanResponse, - shouldSaveUserWallets = walletsRepository.shouldSaveUserWalletsSync(), + initializedAppSettingsState = initializedAppSettingsStateContent, ), ) } @@ -58,4 +61,22 @@ internal object LegacyMiddleware { } } } + + /** + * LEGACY: We need to initialize [AppSettingsState] async to avoid drawing blocking + * previously it was initialized in runBlocking and blocked details screen + */ + private suspend fun initializeAppSettingsState(shouldSaveUserWallets: Boolean): AppSettingsState { + return AppSettingsState( + isBiometricsAvailable = tangemSdkManager.checkCanUseBiometry(), + saveWallets = shouldSaveUserWallets, + saveAccessCodes = store.inject(DaggerGraphState::settingsRepository).shouldSaveAccessCodes(), + selectedAppCurrency = store.state.globalState.appCurrency, + selectedThemeMode = store.inject(DaggerGraphState::appThemeModeRepository).getAppThemeMode().firstOrNull() + ?: AppThemeMode.DEFAULT, + isHidingEnabled = store.inject(DaggerGraphState::balanceHidingRepository) + .getBalanceHidingSettings().isHidingEnabledInSettings, + needEnrollBiometrics = runCatching(tangemSdkManager::needEnrollBiometrics).getOrNull() ?: false, + ) + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt index 6b648b7c0d..56b822cc8e 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt @@ -10,7 +10,7 @@ sealed class DetailsAction : Action { data class PrepareScreen( val scanResponse: ScanResponse, - val shouldSaveUserWallets: Boolean, + val initializedAppSettingsState: AppSettingsState, ) : DetailsAction() sealed class AppSettings : DetailsAction() { diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt index e9b44c3240..a6f2b28868 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt @@ -1,13 +1,6 @@ package com.tangem.tap.features.details.redux -import com.tangem.domain.apptheme.model.AppThemeMode -import com.tangem.tap.common.extensions.inject import com.tangem.tap.common.redux.AppState -import com.tangem.tap.proxy.redux.DaggerGraphState -import com.tangem.tap.store -import com.tangem.tap.tangemSdkManager -import kotlinx.coroutines.flow.firstOrNull -import kotlinx.coroutines.runBlocking import org.rekotlin.Action object DetailsReducer { @@ -36,27 +29,7 @@ private fun internalReduce(action: Action, state: AppState): DetailsState { private fun handlePrepareScreen(action: DetailsAction.PrepareScreen): DetailsState { return DetailsState( scanResponse = action.scanResponse, - appSettingsState = AppSettingsState( - isBiometricsAvailable = runBlocking { - tangemSdkManager.checkCanUseBiometry() - }, - saveWallets = action.shouldSaveUserWallets, - saveAccessCodes = runBlocking { - store.inject(DaggerGraphState::settingsRepository).shouldSaveAccessCodes() - }, - selectedAppCurrency = store.state.globalState.appCurrency, - selectedThemeMode = runBlocking { - store.inject(DaggerGraphState::appThemeModeRepository).getAppThemeMode().firstOrNull() - ?: AppThemeMode.DEFAULT - }, - isHidingEnabled = runBlocking { - store.inject(DaggerGraphState::balanceHidingRepository) - .getBalanceHidingSettings().isHidingEnabledInSettings - }, - needEnrollBiometrics = runBlocking { - runCatching(tangemSdkManager::needEnrollBiometrics).getOrNull() ?: false - }, - ), + appSettingsState = action.initializedAppSettingsState, ) } diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt index 99def3ec10..4ccf6cdd01 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt @@ -23,12 +23,12 @@ import com.tangem.features.details.utils.SocialsBuilder import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.version.AppVersionProvider import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import timber.log.Timber import javax.inject.Inject @@ -52,42 +52,45 @@ internal class DetailsModel @Inject constructor( private val params: DetailsComponent.Params = paramsContainer.require() - private val items: MutableStateFlow> = MutableStateFlow(value = persistentListOf()) + private val items: MutableStateFlow> - val state: MutableStateFlow = MutableStateFlow( - value = DetailsUM( - items = items.value, - footer = DetailsFooterUM( - socials = socialsBuilder.buildAll(), - appVersion = getAppVersion(), - ), - popBack = router::pop, - ), - ) + val state: MutableStateFlow init { // Use to save compatibility with screens that using Redux states bootstrapScreenState() + val isWalletConnectAvailable = runBlocking { + // danger region, this works immediately, but will be refactored later with WC + checkIsWalletConnectAvailableUseCase(params.userWalletId).getOrElse { + Timber.w("Unable to check WalletConnect availability: $it") + + false + } + } + + items = MutableStateFlow( + itemsBuilder.buildAll( + isWalletConnectAvailable = isWalletConnectAvailable, + onSupportClick = ::sendFeedback, + onBuyClick = ::onBuyClick, + ), + ) + + state = MutableStateFlow( + value = DetailsUM( + items = items.value, + footer = DetailsFooterUM( + socials = socialsBuilder.buildAll(), + appVersion = getAppVersion(), + ), + popBack = router::pop, + ), + ) + items .onEach(::updateState) .launchIn(modelScope) - - checkWalletConnectAvailability() - } - - private fun checkWalletConnectAvailability() = modelScope.launch { - val isWalletConnectAvailable = checkIsWalletConnectAvailableUseCase(params.userWalletId).getOrElse { - Timber.w("Unable to check WalletConnect availability: $it") - - false - } - - items.value = itemsBuilder.buildAll( - isWalletConnectAvailable = isWalletConnectAvailable, - onSupportClick = ::sendFeedback, - onBuyClick = ::onBuyClick, - ) } private fun bootstrapScreenState() {