Updated on 2026-08-14
This commit is contained in:
parent
ed11011f07
commit
a8744eb429
13 changed files with 130 additions and 1 deletions
|
|
@ -3,4 +3,5 @@ package com.tangem.features.swap
|
|||
interface SwapFeatureToggles {
|
||||
val isSwapSwitchToTransferEnabled: Boolean
|
||||
val isSwapIntegratedApproveEnabled: Boolean
|
||||
val isSwapAbEnabled: Boolean
|
||||
}
|
||||
|
|
@ -19,6 +19,8 @@ import com.tangem.datasource.api.express.models.response.TxDetails
|
|||
import com.tangem.datasource.crypto.DataSignatureVerifier
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressUtils
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.express.models.ExpressOperationType
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
|
|
@ -413,4 +415,8 @@ internal class DefaultSwapRepository(
|
|||
ExpressDataError.UnknownError
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getStoredSwapUiMode(): SwapUIMode? {
|
||||
return appPreferencesStore.getObjectSyncOrNull(PreferencesKeys.SWAP_UI_MODE_KEY)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.feature.swap.domain
|
||||
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
import com.tangem.features.swap.SwapFeatureToggles
|
||||
|
||||
class GetSwapUiModeUseCase(
|
||||
private val swapFeatureToggles: SwapFeatureToggles,
|
||||
private val swapRepository: SwapRepository,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(): SwapUIMode {
|
||||
if (!swapFeatureToggles.isSwapAbEnabled) return SwapUIMode.Detailed
|
||||
// TODO: take default from Amplitude (true -> Detailed, false -> Simple).
|
||||
// Until then default is Detailed.
|
||||
return swapRepository.getStoredSwapUiMode() ?: SwapUIMode.Detailed
|
||||
}
|
||||
}
|
||||
|
|
@ -75,4 +75,6 @@ interface SwapRepository {
|
|||
txHash: String,
|
||||
payInExtraId: String?,
|
||||
): Either<ExpressDataError, Unit>
|
||||
|
||||
suspend fun getStoredSwapUiMode(): SwapUIMode?
|
||||
}
|
||||
|
|
@ -2,8 +2,11 @@ package com.tangem.feature.swap.domain.di
|
|||
|
||||
import com.tangem.feature.swap.domain.AllowPermissionsHandler
|
||||
import com.tangem.feature.swap.domain.AllowPermissionsHandlerImpl
|
||||
import com.tangem.feature.swap.domain.GetSwapUiModeUseCase
|
||||
import com.tangem.feature.swap.domain.SwapInteractor
|
||||
import com.tangem.feature.swap.domain.SwapInteractorImpl
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
import com.tangem.features.swap.SwapFeatureToggles
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -20,6 +23,16 @@ internal class SwapDomainModule {
|
|||
fun provideAllowPermissionsHandler(): AllowPermissionsHandler {
|
||||
return AllowPermissionsHandlerImpl()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetSwapUiModeUseCase(
|
||||
swapFeatureToggles: SwapFeatureToggles,
|
||||
swapRepository: SwapRepository,
|
||||
): GetSwapUiModeUseCase = GetSwapUiModeUseCase(
|
||||
swapFeatureToggles = swapFeatureToggles,
|
||||
swapRepository = swapRepository,
|
||||
)
|
||||
}
|
||||
|
||||
@Module
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
package com.tangem.feature.swap.domain.models.domain
|
||||
|
||||
enum class SwapUIMode {
|
||||
Simple,
|
||||
Detailed,
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package com.tangem.feature.swap.domain
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
import com.tangem.features.swap.SwapFeatureToggles
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class GetSwapUiModeUseCaseTest {
|
||||
|
||||
private val swapFeatureToggles: SwapFeatureToggles = mockk()
|
||||
private val swapRepository: SwapRepository = mockk()
|
||||
|
||||
private val sut = GetSwapUiModeUseCase(
|
||||
swapFeatureToggles = swapFeatureToggles,
|
||||
swapRepository = swapRepository,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `GIVEN feature toggle is disabled WHEN invoke THEN returns Detailed without reading repository`() = runTest {
|
||||
coEvery { swapFeatureToggles.isSwapAbEnabled } returns false
|
||||
|
||||
val actual = sut.invoke()
|
||||
|
||||
assertThat(actual).isEqualTo(SwapUIMode.Detailed)
|
||||
coVerify(exactly = 0) { swapRepository.getStoredSwapUiMode() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN toggle enabled and repository has Detailed WHEN invoke THEN returns Detailed`() = runTest {
|
||||
coEvery { swapFeatureToggles.isSwapAbEnabled } returns true
|
||||
coEvery { swapRepository.getStoredSwapUiMode() } returns SwapUIMode.Detailed
|
||||
|
||||
val actual = sut.invoke()
|
||||
|
||||
assertThat(actual).isEqualTo(SwapUIMode.Detailed)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN toggle enabled and repository has Simple WHEN invoke THEN returns Simple`() = runTest {
|
||||
coEvery { swapFeatureToggles.isSwapAbEnabled } returns true
|
||||
coEvery { swapRepository.getStoredSwapUiMode() } returns SwapUIMode.Simple
|
||||
|
||||
val actual = sut.invoke()
|
||||
|
||||
assertThat(actual).isEqualTo(SwapUIMode.Simple)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN toggle enabled and repository has no value WHEN invoke THEN returns Detailed`() = runTest {
|
||||
coEvery { swapFeatureToggles.isSwapAbEnabled } returns true
|
||||
coEvery { swapRepository.getStoredSwapUiMode() } returns null
|
||||
|
||||
val actual = sut.invoke()
|
||||
|
||||
assertThat(actual).isEqualTo(SwapUIMode.Detailed)
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,12 @@ internal class DefaultSwapFeatureToggles @Inject constructor(
|
|||
override val isSwapSwitchToTransferEnabled: Boolean = featureTogglesManager.isFeatureEnabled(
|
||||
toggle = FeatureToggles.SWAP_SWITCH_TO_TRANSFER_ENABLED,
|
||||
)
|
||||
|
||||
override val isSwapIntegratedApproveEnabled: Boolean = featureTogglesManager.isFeatureEnabled(
|
||||
toggle = FeatureToggles.SWAP_INTEGRATED_APPROVE,
|
||||
)
|
||||
|
||||
override val isSwapAbEnabled: Boolean = featureTogglesManager.isFeatureEnabled(
|
||||
toggle = FeatureToggles.SWAP_AB_ENABLED,
|
||||
)
|
||||
}
|
||||
|
|
@ -73,6 +73,7 @@ import com.tangem.feature.swap.analytics.SwapQuotePerformanceTracker
|
|||
import com.tangem.feature.swap.component.SwapFeeSelectorBlockComponent
|
||||
import com.tangem.feature.swap.converters.SwapTransactionErrorStateConverter
|
||||
import com.tangem.feature.swap.domain.AllowPermissionsHandler
|
||||
import com.tangem.feature.swap.domain.GetSwapUiModeUseCase
|
||||
import com.tangem.feature.swap.domain.SwapInteractor
|
||||
import com.tangem.feature.swap.domain.TransactionFeeResult
|
||||
import com.tangem.feature.swap.domain.TxFeeSealedState
|
||||
|
|
@ -153,6 +154,7 @@ internal class SwapModel @Inject constructor(
|
|||
private val initialCurrenciesResolver: InitialCurrenciesResolver,
|
||||
private val allowPermissionsHandler: AllowPermissionsHandler,
|
||||
private val swapFeatureToggles: SwapFeatureToggles,
|
||||
private val getSwapUiModeUseCase: GetSwapUiModeUseCase,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<SwapComponent.Params>()
|
||||
|
|
@ -284,6 +286,10 @@ internal class SwapModel @Inject constructor(
|
|||
isBalanceHidden = settings.isBalanceHidden
|
||||
uiState = stateBuilder.updateBalanceHiddenState(uiState, isBalanceHidden)
|
||||
}.launchIn(modelScope)
|
||||
|
||||
modelScope.launch {
|
||||
uiState = uiState.copy(swapUIMode = getSwapUiModeUseCase())
|
||||
}
|
||||
}
|
||||
|
||||
fun onStart() {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.common.ui.notifications.NotificationUM
|
|||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
import com.tangem.feature.swap.domain.models.ui.PriceImpact
|
||||
import com.tangem.feature.swap.models.states.FeeItemState
|
||||
import com.tangem.feature.swap.models.states.ProviderState
|
||||
|
|
@ -31,6 +32,7 @@ internal data class SwapStateHolder(
|
|||
val swapButton: SwapButton,
|
||||
val shouldShowMaxAmount: Boolean,
|
||||
val tosState: TosState? = null,
|
||||
val swapUIMode: SwapUIMode = SwapUIMode.Detailed,
|
||||
|
||||
val onRefresh: () -> Unit,
|
||||
val onBackClicked: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import com.tangem.feature.swap.domain.models.domain.ExchangeProviderType
|
|||
import com.tangem.feature.swap.domain.models.domain.IncludeFeeInAmount
|
||||
import com.tangem.feature.swap.domain.models.domain.RateType
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapProvider
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
import com.tangem.feature.swap.domain.models.ui.*
|
||||
import com.tangem.feature.swap.model.SwapNotificationsFactory
|
||||
import com.tangem.feature.swap.model.SwapProcessDataState
|
||||
|
|
@ -65,7 +66,7 @@ internal class StateBuilder(
|
|||
SwapNotificationsFactory(actions, isGaslessFeeSupportedForNetwork)
|
||||
}
|
||||
|
||||
fun createInitialLoadingState(): SwapStateHolder {
|
||||
fun createInitialLoadingState(swapUIMode: SwapUIMode = SwapUIMode.Detailed): SwapStateHolder {
|
||||
return SwapStateHolder(
|
||||
sendCardData = getEmptyCardState(
|
||||
isFromCard = true,
|
||||
|
|
@ -95,6 +96,7 @@ internal class StateBuilder(
|
|||
shouldShowMaxAmount = false,
|
||||
priceImpact = PriceImpact.Empty,
|
||||
isInsufficientFunds = false,
|
||||
swapUIMode = swapUIMode,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue