Updated on 2026-08-14

This commit is contained in:
Tangem 2025-03-20 14:28:26 +03:00
parent 242d1173fa
commit 03366c87ee
4 changed files with 59 additions and 62 deletions

View file

@ -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,
)
}
}

View file

@ -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() {

View file

@ -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,
)
}

View file

@ -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<ImmutableList<DetailsItemUM>> = MutableStateFlow(value = persistentListOf())
private val items: MutableStateFlow<ImmutableList<DetailsItemUM>>
val state: MutableStateFlow<DetailsUM> = MutableStateFlow(
value = DetailsUM(
items = items.value,
footer = DetailsFooterUM(
socials = socialsBuilder.buildAll(),
appVersion = getAppVersion(),
),
popBack = router::pop,
),
)
val state: MutableStateFlow<DetailsUM>
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() {