Updated on 2026-08-14
This commit is contained in:
parent
0896f80f53
commit
f57a7ecac9
13 changed files with 6 additions and 192 deletions
|
|
@ -1,8 +1,6 @@
|
|||
package com.tangem.tap.common.redux
|
||||
|
||||
import com.tangem.tap.common.redux.global.GlobalMiddleware
|
||||
import com.tangem.tap.common.redux.global.GlobalState
|
||||
import com.tangem.tap.common.redux.legacy.LegacyMiddleware
|
||||
import com.tangem.tap.features.details.redux.DetailsMiddleware
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphMiddleware
|
||||
|
|
@ -20,12 +18,10 @@ data class AppState(
|
|||
fun getMiddleware(): List<Middleware<AppState>> {
|
||||
return listOf(
|
||||
logMiddleware,
|
||||
GlobalMiddleware.handler,
|
||||
DetailsMiddleware().detailsMiddleware,
|
||||
LockUserWalletsTimerMiddleware().middleware,
|
||||
AccessCodeRequestPolicyMiddleware().middleware,
|
||||
DaggerGraphMiddleware.daggerGraphMiddleware,
|
||||
LegacyMiddleware.legacyMiddleware,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.tap.common.redux.global
|
||||
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import org.rekotlin.Action
|
||||
|
||||
|
|
@ -8,10 +7,5 @@ sealed class GlobalAction : Action {
|
|||
|
||||
data class SaveScanResponse(val scanResponse: ScanResponse) : GlobalAction()
|
||||
|
||||
data class ChangeAppCurrency(val appCurrency: AppCurrency) : GlobalAction()
|
||||
object RestoreAppCurrency : GlobalAction() {
|
||||
data class Success(val appCurrency: AppCurrency) : GlobalAction()
|
||||
}
|
||||
|
||||
data class IsSignWithRing(val isSignWithRing: Boolean) : GlobalAction()
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
package com.tangem.tap.common.redux.global
|
||||
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
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.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
import org.rekotlin.Action
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
object GlobalMiddleware {
|
||||
val handler = globalMiddlewareHandler
|
||||
}
|
||||
|
||||
private val globalMiddlewareHandler: Middleware<AppState> = { _, _ ->
|
||||
{ nextDispatch ->
|
||||
{ action ->
|
||||
handleAction(action)
|
||||
nextDispatch(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleAction(action: Action) {
|
||||
when (action) {
|
||||
is GlobalAction.RestoreAppCurrency -> restoreAppCurrency()
|
||||
}
|
||||
}
|
||||
|
||||
private fun restoreAppCurrency() {
|
||||
scope.launch {
|
||||
val currency = store.inject(DaggerGraphState::appCurrencyRepository)
|
||||
.getSelectedAppCurrency()
|
||||
.firstOrNull()
|
||||
?: AppCurrency.Default
|
||||
|
||||
store.dispatchWithMain(GlobalAction.RestoreAppCurrency.Success(currency))
|
||||
}
|
||||
}
|
||||
|
|
@ -13,13 +13,6 @@ fun globalReducer(action: Action, state: AppState): GlobalState {
|
|||
is GlobalAction.SaveScanResponse -> {
|
||||
globalState.copy(scanResponse = action.scanResponse)
|
||||
}
|
||||
is GlobalAction.ChangeAppCurrency -> {
|
||||
globalState.copy(appCurrency = action.appCurrency)
|
||||
}
|
||||
is GlobalAction.RestoreAppCurrency.Success -> {
|
||||
globalState.copy(appCurrency = action.appCurrency)
|
||||
}
|
||||
is GlobalAction.IsSignWithRing -> globalState.copy(isLastSignWithRing = action.isSignWithRing)
|
||||
else -> globalState
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.tap.common.redux.global
|
||||
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.tap.domain.TapWalletManager
|
||||
import org.rekotlin.StateType
|
||||
|
|
@ -9,7 +8,6 @@ data class GlobalState(
|
|||
@Deprecated("Use scan response from selected user wallet")
|
||||
val scanResponse: ScanResponse? = null,
|
||||
val tapWalletManager: TapWalletManager = TapWalletManager(),
|
||||
val appCurrency: AppCurrency = AppCurrency.Default,
|
||||
val isLastSignWithRing: Boolean = false,
|
||||
) : StateType
|
||||
|
||||
|
|
|
|||
|
|
@ -1,79 +0,0 @@
|
|||
package com.tangem.tap.common.redux.legacy
|
||||
|
||||
import com.tangem.domain.apptheme.model.AppThemeMode
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
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.features.details.redux.AppSettingsState
|
||||
import com.tangem.tap.features.details.redux.DetailsAction
|
||||
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.*
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
@Suppress("MemberNameEqualsClassName")
|
||||
internal object LegacyMiddleware {
|
||||
private val prepareDetailsScreenJobHolder = JobHolder()
|
||||
|
||||
val legacyMiddleware: Middleware<AppState> = { _, _ ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
when (action) {
|
||||
is LegacyAction.PrepareDetailsScreen -> {
|
||||
selectedUserWallet()
|
||||
.distinctUntilChanged { old, new ->
|
||||
if (old is UserWallet.Cold && new is UserWallet.Cold) {
|
||||
old.walletId == new.walletId &&
|
||||
old.scanResponse == new.scanResponse
|
||||
} else {
|
||||
old.walletId == new.walletId
|
||||
}
|
||||
}
|
||||
.onEach { selectedUserWallet ->
|
||||
val initializedAppSettingsStateContent = initializeAppSettingsState()
|
||||
store.dispatchWithMain(
|
||||
DetailsAction.PrepareScreen(
|
||||
scanResponse = (selectedUserWallet as? UserWallet.Cold)?.scanResponse,
|
||||
initializedAppSettingsState = initializedAppSettingsStateContent,
|
||||
),
|
||||
)
|
||||
}
|
||||
.flowOn(Dispatchers.IO)
|
||||
.launchIn(scope)
|
||||
.saveIn(prepareDetailsScreenJobHolder)
|
||||
}
|
||||
}
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun selectedUserWallet(): Flow<UserWallet> {
|
||||
return store.inject(DaggerGraphState::userWalletsListRepository).selectedUserWallet.filterNotNull()
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(): AppSettingsState {
|
||||
return AppSettingsState(
|
||||
selectedAppCurrency = store.state.globalState.appCurrency,
|
||||
selectedThemeMode = store.inject(DaggerGraphState::appThemeModeRepository).getAppThemeMode().firstOrNull()
|
||||
?: AppThemeMode.DEFAULT,
|
||||
requireAccessCode = store.inject(DaggerGraphState::walletsRepository).requireAccessCode(),
|
||||
useBiometricAuthentication = store.inject(DaggerGraphState::walletsRepository).useBiometricAuthentication(),
|
||||
isHidingEnabled = store.inject(DaggerGraphState::balanceHidingRepository)
|
||||
.getBalanceHidingSettings().isHidingEnabledInSettings,
|
||||
needEnrollBiometrics = runCatching(tangemSdkManager::needEnrollBiometrics).getOrNull() == true,
|
||||
hasSecuredWallets = store.inject(DaggerGraphState::userWalletsListRepository).hasSecuredWallets(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,18 +2,12 @@ package com.tangem.tap.features.details.redux
|
|||
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.apptheme.model.AppThemeMode
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import org.rekotlin.Action
|
||||
|
||||
@Suppress("BooleanPropertyNaming")
|
||||
sealed class DetailsAction : Action {
|
||||
|
||||
data class PrepareScreen(
|
||||
val scanResponse: ScanResponse?,
|
||||
val initializedAppSettingsState: AppSettingsState,
|
||||
) : DetailsAction()
|
||||
|
||||
sealed class AppSettings : DetailsAction() {
|
||||
data class SwitchPrivacySetting(
|
||||
val enable: Boolean,
|
||||
|
|
@ -50,6 +44,4 @@ sealed class DetailsAction : Action {
|
|||
|
||||
data class Prepare(val state: AppSettingsState) : AppSettings()
|
||||
}
|
||||
|
||||
data class ChangeAppCurrency(val currency: AppCurrency) : DetailsAction()
|
||||
}
|
||||
|
|
@ -12,7 +12,6 @@ import com.tangem.tap.common.analytics.events.Settings
|
|||
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.demo.DemoHelper
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.scope
|
||||
|
|
@ -78,10 +77,7 @@ class DetailsMiddleware {
|
|||
is DetailsAction.AppSettings.ChangeBalanceHiding -> {
|
||||
changeBalanceHiding(action.shouldHideBalance)
|
||||
}
|
||||
is DetailsAction.AppSettings.ChangeAppCurrency -> {
|
||||
store.dispatch(GlobalAction.ChangeAppCurrency(action.currency))
|
||||
store.dispatch(DetailsAction.ChangeAppCurrency(action.currency))
|
||||
}
|
||||
is DetailsAction.AppSettings.ChangeAppCurrency,
|
||||
is DetailsAction.AppSettings.SwitchPrivacySetting.Success,
|
||||
is DetailsAction.AppSettings.SwitchPrivacySetting.Failure,
|
||||
is DetailsAction.AppSettings.BiometricsStatusChanged,
|
||||
|
|
|
|||
|
|
@ -12,27 +12,12 @@ private fun internalReduce(action: Action, state: AppState): DetailsState {
|
|||
if (action !is DetailsAction) return state.detailsState
|
||||
val detailsState = state.detailsState
|
||||
return when (action) {
|
||||
is DetailsAction.PrepareScreen -> {
|
||||
handlePrepareScreen(action)
|
||||
}
|
||||
is DetailsAction.AppSettings -> {
|
||||
handlePrivacyAction(action, detailsState)
|
||||
}
|
||||
is DetailsAction.ChangeAppCurrency -> detailsState.copy(
|
||||
appSettingsState = detailsState.appSettingsState.copy(
|
||||
selectedAppCurrency = action.currency,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePrepareScreen(action: DetailsAction.PrepareScreen): DetailsState {
|
||||
return DetailsState(
|
||||
scanResponse = action.scanResponse,
|
||||
appSettingsState = action.initializedAppSettingsState,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||
private fun handlePrivacyAction(action: DetailsAction.AppSettings, state: DetailsState): DetailsState {
|
||||
return when (action) {
|
||||
|
|
@ -94,6 +79,7 @@ private fun handlePrivacyAction(action: DetailsAction.AppSettings, state: Detail
|
|||
useBiometricAuthentication = action.state.useBiometricAuthentication,
|
||||
requireAccessCode = action.state.requireAccessCode,
|
||||
hasSecuredWallets = action.state.hasSecuredWallets,
|
||||
needEnrollBiometrics = action.state.needEnrollBiometrics,
|
||||
),
|
||||
)
|
||||
is DetailsAction.AppSettings.EnrollBiometrics,
|
||||
|
|
|
|||
|
|
@ -2,12 +2,9 @@ package com.tangem.tap.features.details.redux
|
|||
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.apptheme.model.AppThemeMode
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import org.rekotlin.StateType
|
||||
|
||||
data class DetailsState(
|
||||
@Deprecated("Delete after onboarding refactoring")
|
||||
val scanResponse: ScanResponse? = null,
|
||||
val appSettingsState: AppSettingsState = AppSettingsState(),
|
||||
) : StateType
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import com.tangem.domain.apptheme.model.AppThemeMode
|
|||
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
|
||||
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.Settings
|
||||
|
|
@ -54,6 +55,7 @@ internal class AppSettingsModel @Inject constructor(
|
|||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val appThemeModeRepository: AppThemeModeRepository,
|
||||
private val appSettingsItemsAnalyticsSender: AppSettingsItemsAnalyticsSender,
|
||||
private val tangemSdkManager: TangemSdkManager,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
) : Model(), StoreSubscriber<DetailsState> {
|
||||
|
||||
|
|
@ -251,9 +253,8 @@ internal class AppSettingsModel @Inject constructor(
|
|||
private fun bootstrapAppCurrencyUpdates() {
|
||||
appCurrencyRepository
|
||||
.getSelectedAppCurrency()
|
||||
.distinctUntilChanged()
|
||||
.onEach { appCurrency ->
|
||||
if (appCurrency.code == store.state.globalState.appCurrency.code) return@onEach
|
||||
|
||||
store.dispatchWithMain(DetailsAction.AppSettings.ChangeAppCurrency(appCurrency))
|
||||
}
|
||||
.launchIn(scope)
|
||||
|
|
@ -267,6 +268,7 @@ internal class AppSettingsModel @Inject constructor(
|
|||
isHidingEnabled = balanceHidingRepository.getBalanceHidingSettings().isHidingEnabledInSettings,
|
||||
selectedAppCurrency = appCurrencyRepository.getSelectedAppCurrency().firstOrNull() ?: AppCurrency.Default,
|
||||
selectedThemeMode = appThemeModeRepository.getAppThemeMode().firstOrNull() ?: AppThemeMode.DEFAULT,
|
||||
needEnrollBiometrics = runCatching(tangemSdkManager::needEnrollBiometrics).getOrNull() == true,
|
||||
hasSecuredWallets = userWalletsListRepository.hasSecuredWallets(),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
package com.tangem.domain.redux
|
||||
|
||||
import org.rekotlin.Action
|
||||
|
||||
sealed interface LegacyAction : Action {
|
||||
|
||||
data object PrepareDetailsScreen : LegacyAction
|
||||
}
|
||||
|
|
@ -22,8 +22,6 @@ import com.tangem.domain.feedback.repository.FeedbackFeatureToggles
|
|||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.pay.TangemPayEligibilityManager
|
||||
import com.tangem.domain.pay.model.TangemPayEntryPoint
|
||||
import com.tangem.domain.redux.LegacyAction
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.tangempay.GetTangemPayCustomerIdUseCase
|
||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||
import com.tangem.domain.walletconnect.CheckIsWalletConnectAvailableUseCase
|
||||
|
|
@ -61,7 +59,6 @@ internal class DetailsModel @Inject constructor(
|
|||
private val router: Router,
|
||||
private val urlOpener: UrlOpener,
|
||||
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
|
||||
private val appStateHolder: ReduxStateHolder,
|
||||
private val getWalletMetaInfoUseCase: GetWalletMetaInfoUseCase,
|
||||
private val getTangemPayCustomerIdUseCase: GetTangemPayCustomerIdUseCase,
|
||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
|
|
@ -79,9 +76,6 @@ internal class DetailsModel @Inject constructor(
|
|||
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 { throwable ->
|
||||
|
|
@ -122,10 +116,6 @@ internal class DetailsModel @Inject constructor(
|
|||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun bootstrapScreenState() {
|
||||
appStateHolder.dispatch(LegacyAction.PrepareDetailsScreen)
|
||||
}
|
||||
|
||||
private fun sendFeedback() {
|
||||
modelScope.launch {
|
||||
val userWallets = getWalletsUseCase.invokeSync()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue