diff --git a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt index 70338653b9..ad15758549 100644 --- a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt +++ b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt @@ -5,7 +5,6 @@ import com.tangem.core.decompose.context.AppComponentContext import com.tangem.feature.qrscanning.QrScanningRouter import com.tangem.feature.referral.ReferralFragment import com.tangem.feature.stories.api.StoriesComponent -import com.tangem.feature.swap.presentation.SwapFragment import com.tangem.feature.walletsettings.component.WalletSettingsComponent import com.tangem.features.details.component.DetailsComponent import com.tangem.features.disclaimer.api.components.DisclaimerComponent @@ -16,6 +15,7 @@ import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent import com.tangem.features.onramp.component.* import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter import com.tangem.features.send.api.navigation.SendRouter +import com.tangem.features.swap.SwapComponent import com.tangem.features.staking.api.StakingComponent import com.tangem.features.tester.api.TesterRouter import com.tangem.features.tokendetails.navigation.TokenDetailsRouter @@ -59,6 +59,7 @@ internal class ChildFactory @Inject constructor( private val welcomeComponentFactory: WelcomeComponent.Factory, private val storiesComponentFactory: StoriesComponent.Factory, private val stakingComponentFactory: StakingComponent.Factory, + private val swapComponentFactory: SwapComponent.Factory, private val sendRouter: SendRouter, private val tokenDetailsRouter: TokenDetailsRouter, private val walletRouter: WalletRouter, @@ -222,6 +223,18 @@ internal class ChildFactory @Inject constructor( componentFactory = stakingComponentFactory, ) } + is AppRoute.Swap -> { + createComponentChild( + contextProvider = contextProvider(route, contextFactory), + params = SwapComponent.Params( + currencyFrom = route.currencyFrom, + currencyTo = route.currencyTo, + userWalletId = route.userWalletId, + isInitialReverseOrder = route.isInitialReverseOrder, + ), + componentFactory = swapComponentFactory, + ) + } is AppRoute.AccessCodeRecovery, is AppRoute.AppCurrencySelector, is AppRoute.SaveWallet, @@ -237,7 +250,6 @@ internal class ChildFactory @Inject constructor( is AppRoute.QrScanning, is AppRoute.ReferralProgram, is AppRoute.ResetToFactory, - is AppRoute.Swap, is AppRoute.Wallet, is AppRoute.WalletConnectSessions, is AppRoute.CurrencyDetails, @@ -329,7 +341,16 @@ internal class ChildFactory @Inject constructor( route.asFragmentChild(Provider { ResetCardFragment() }) } is AppRoute.Swap -> { - route.asFragmentChild(Provider { SwapFragment() }) + route.asComponentChild( + contextProvider = contextProvider(route, contextFactory), + params = SwapComponent.Params( + currencyFrom = route.currencyFrom, + currencyTo = route.currencyTo, + userWalletId = route.userWalletId, + isInitialReverseOrder = route.isInitialReverseOrder, + ), + componentFactory = swapComponentFactory, + ) } is AppRoute.Wallet -> { route.asFragmentChild(Provider { walletRouter.getEntryFragment() }) diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/DefaultSwapComponent.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/DefaultSwapComponent.kt index c98473a08e..65c5f62d82 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/DefaultSwapComponent.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/DefaultSwapComponent.kt @@ -1,8 +1,19 @@ package com.tangem.feature.swap +import androidx.compose.animation.Crossfade +import androidx.compose.foundation.background import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import com.arkivanov.essenty.lifecycle.subscribe +import com.tangem.common.ui.swapStoriesScreen.SwapStoriesScreen import com.tangem.core.decompose.context.AppComponentContext +import com.tangem.core.decompose.model.getOrCreateModel +import com.tangem.core.ui.res.TangemTheme +import com.tangem.feature.swap.model.SwapModel +import com.tangem.feature.swap.router.SwapNavScreen +import com.tangem.feature.swap.ui.SwapScreen +import com.tangem.feature.swap.ui.SwapSelectTokenScreen +import com.tangem.feature.swap.ui.SwapSuccessScreen import com.tangem.features.swap.SwapComponent import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -14,9 +25,50 @@ internal class DefaultSwapComponent @AssistedInject constructor( @Assisted params: SwapComponent.Params, ) : SwapComponent, AppComponentContext by appComponentContext { + private val model: SwapModel = getOrCreateModel(params) + + init { + lifecycle.subscribe( + onStart = model::onStart, + onStop = model::onStop, + ) + } + @Composable override fun Content(modifier: Modifier) { - TODO("Not yet implemented") + Crossfade( + modifier = Modifier.background(TangemTheme.colors.background.secondary), + targetState = model.currentScreen, + label = "", + ) { screen -> + when (screen) { + SwapNavScreen.PromoStories -> { + val storiesConfig = model.uiState.storiesConfig + if (storiesConfig != null) { + SwapStoriesScreen(config = storiesConfig) + } else { + SwapScreen(stateHolder = model.uiState) + } + } + SwapNavScreen.Main -> SwapScreen(stateHolder = model.uiState) + SwapNavScreen.Success -> { + val successState = model.uiState.successState + if (successState != null) { + SwapSuccessScreen(state = successState, model.uiState.onBackClicked) + } else { + SwapScreen(stateHolder = model.uiState) + } + } + SwapNavScreen.SelectToken -> { + val tokenState = model.uiState.selectTokenState + if (tokenState != null) { + SwapSelectTokenScreen(state = tokenState, onBack = model.uiState.onBackClicked) + } else { + SwapScreen(stateHolder = model.uiState) + } + } + } + } } @AssistedFactory diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/di/SwapModelModule.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/di/SwapModelModule.kt new file mode 100644 index 0000000000..911918e2b6 --- /dev/null +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/di/SwapModelModule.kt @@ -0,0 +1,20 @@ +package com.tangem.feature.swap.di + +import com.tangem.core.decompose.di.DecomposeComponent +import com.tangem.core.decompose.model.Model +import com.tangem.feature.swap.model.SwapModel +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap + +@Module +@InstallIn(DecomposeComponent::class) +internal interface SwapModelModule { + + @Binds + @IntoMap + @ClassKey(SwapModel::class) + fun provideSwapModel(model: SwapModel): Model +} \ No newline at end of file diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt similarity index 95% rename from features/swap/impl/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt rename to features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt index d3e551ea25..7da70ff432 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt @@ -1,20 +1,20 @@ -package com.tangem.feature.swap.viewmodels +package com.tangem.feature.swap.model -import android.os.Bundle +import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue -import androidx.lifecycle.* import arrow.core.Either import arrow.core.getOrElse -import com.tangem.common.routing.AppRoute import com.tangem.common.routing.AppRouter -import com.tangem.common.routing.bundle.unbundle import com.tangem.common.ui.bottomsheet.permission.state.ApproveType import com.tangem.common.ui.bottomsheet.permission.state.GiveTxPermissionState.InProgress.getApproveTypeOrNull import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.analytics.models.Basic +import com.tangem.core.decompose.di.ComponentScoped +import com.tangem.core.decompose.model.Model +import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.navigation.url.UrlOpener import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference @@ -53,11 +53,11 @@ import com.tangem.feature.swap.router.SwapNavScreen import com.tangem.feature.swap.router.SwapRouter import com.tangem.feature.swap.ui.StateBuilder import com.tangem.feature.swap.utils.formatToUIRepresentation +import com.tangem.features.swap.SwapComponent import com.tangem.features.swap.SwapFeatureToggles import com.tangem.utils.Provider import com.tangem.utils.coroutines.* import com.tangem.utils.isNullOrZero -import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch @@ -73,11 +73,13 @@ import kotlin.properties.Delegates typealias SuccessLoadedSwapData = Map -@Suppress("LargeClass", "LongParameterList") -@HiltViewModel -internal class SwapViewModel @Inject constructor( +@Suppress("LongParameterList", "LargeClass") +@Stable +@ComponentScoped +internal class SwapModel @Inject constructor( + paramsContainer: ParamsContainer, + override val dispatchers: CoroutineDispatcherProvider, private val blockchainInteractor: BlockchainInteractor, - private val dispatchers: CoroutineDispatcherProvider, private val analyticsEventHandler: AnalyticsEventHandler, private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase, private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, @@ -94,27 +96,16 @@ internal class SwapViewModel @Inject constructor( private val getStoryContentUseCase: GetStoryContentUseCase, private val featureToggles: SwapFeatureToggles, swapInteractorFactory: SwapInteractor.Factory, - private val savedStateHandle: SavedStateHandle, private val urlOpener: UrlOpener, router: AppRouter, -) : ViewModel(), DefaultLifecycleObserver { +) : Model() { - private val initialCurrencyFrom: CryptoCurrency - get() { - return savedStateHandle.get(AppRoute.Swap.CURRENCY_FROM_KEY) - ?.unbundle(CryptoCurrency.serializer()) - ?: error("no expected parameter CryptoCurrency (from) found") - } + private val params = paramsContainer.require() - private val initialCurrencyTo: CryptoCurrency? = savedStateHandle.get(AppRoute.Swap.CURRENCY_TO_KEY) - ?.unbundle(CryptoCurrency.serializer()) - - private val userWalletId: UserWalletId = savedStateHandle.get(AppRoute.Swap.USER_WALLET_ID_KEY) - ?.unbundle(UserWalletId.serializer()) - ?: error("no expected parameter UserWalletId found") - - private val isInitiallyReversed: Boolean = savedStateHandle.get(AppRoute.Swap.IS_INITIAL_REVERSE_ORDER) - ?: false + private val initialCurrencyFrom = params.currencyFrom + private val initialCurrencyTo = params.currencyTo + private val userWalletId = params.userWalletId + private val isInitiallyReversed = params.isInitialReverseOrder private val swapInteractor = swapInteractorFactory.create(userWalletId) @@ -171,13 +162,13 @@ internal class SwapViewModel @Inject constructor( get() = swapRouter.currentScreen init { - viewModelScope.launch { + modelScope.launch { if (featureToggles.isPromoStoriesEnabled) { initStories() swapRouter.openScreen(SwapNavScreen.PromoStories) } } - viewModelScope.launch(dispatchers.io) { + modelScope.launch(dispatchers.io) { val fromStatus = getCryptoCurrencyStatusUseCase(userWalletId, initialCurrencyFrom.id).getOrNull() val toStatus = initialCurrencyTo?.let { getCryptoCurrencyStatusUseCase(userWalletId, it.id).getOrNull() } val wallet = getUserWalletUseCase(userWalletId).getOrNull() @@ -191,32 +182,28 @@ internal class SwapViewModel @Inject constructor( initTokens(isInitiallyReversed) } } - } - override fun onCreate(owner: LifecycleOwner) { - getBalanceHidingSettingsUseCase().flowWithLifecycle(owner.lifecycle).onEach { - isBalanceHidden = it.isBalanceHidden - withContext(dispatchers.main) { + analyticsEventHandler.send(SwapEvents.SwapScreenOpened(initialCurrencyFrom.symbol)) + + getBalanceHidingSettingsUseCase() + .onEach { + isBalanceHidden = it.isBalanceHidden uiState = stateBuilder.updateBalanceHiddenState(uiState, isBalanceHidden) } - }.launchIn(viewModelScope) + .launchIn(modelScope) } - override fun onStart(owner: LifecycleOwner) { + fun onStart() { startLoadingQuotesFromLastState(true) } - override fun onStop(owner: LifecycleOwner) { + fun onStop() { singleTaskScheduler.cancelTask() } - override fun onCleared() { + override fun onDestroy() { singleTaskScheduler.cancelTask() - super.onCleared() - } - - fun onScreenOpened() { - analyticsEventHandler.send(SwapEvents.SwapScreenOpened(initialCurrencyFrom.symbol)) + super.onDestroy() } private fun sendSelectTokenScreenOpenedEvent() { @@ -227,7 +214,7 @@ internal class SwapViewModel @Inject constructor( } private fun initTokens(isReverseFromTo: Boolean) { - viewModelScope.launch(dispatchers.main) { + modelScope.launch(dispatchers.main) { runCatching(dispatchers.io) { swapInteractor.getTokensDataState(initialCurrencyFrom) }.onSuccess { state -> @@ -286,7 +273,7 @@ internal class SwapViewModel @Inject constructor( } private fun initStories() { - viewModelScope.launch { + modelScope.launch { getStoryContentUseCase.invokeSync(StoryContentIds.STORY_FIRST_TIME_SWAP.id).fold( ifLeft = { Timber.e("Unable to load stories for ${StoryContentIds.STORY_FIRST_TIME_SWAP.id}") @@ -361,7 +348,7 @@ internal class SwapViewModel @Inject constructor( ) } singleTaskScheduler.scheduleTask( - viewModelScope, + modelScope, loadQuotesTask( fromToken = fromToken, toToken = toToken, @@ -602,7 +589,7 @@ internal class SwapViewModel @Inject constructor( makeDefaultAlert(resourceReference(R.string.swapping_fee_estimation_error_text)) return } - viewModelScope.launch(dispatchers.main) { + modelScope.launch(dispatchers.main) { runCatching(dispatchers.io) { swapInteractor.onSwap( swapProvider = provider, @@ -691,7 +678,7 @@ internal class SwapViewModel @Inject constructor( } private fun givePermissionsToSwap() { - viewModelScope.launch(dispatchers.main) { + modelScope.launch(dispatchers.main) { runCatching { val fromToken = requireNotNull(dataState.fromCryptoCurrency?.currency) { "dataState.fromCurrency might not be null" @@ -756,7 +743,7 @@ internal class SwapViewModel @Inject constructor( } private fun onSearchEntered(searchQuery: String) { - viewModelScope.launch(dispatchers.io) { + modelScope.launch(dispatchers.io) { val tokenDataState = dataState.tokensDataState ?: return@launch val group = if (isOrderReversed) { tokenDataState.fromGroup @@ -892,12 +879,12 @@ internal class SwapViewModel @Inject constructor( startLoadingQuotesFromLastState(isSilent = true) } .flowOn(dispatchers.main) - .launchIn(viewModelScope) + .launchIn(modelScope) .saveIn(if (isFromCurrency) fromTokenBalanceJobHolder else toTokenBalanceJobHolder) } private fun onChangeCardsClicked() { - viewModelScope.launch { + modelScope.launch { val newFromToken = dataState.toCryptoCurrency val newToToken = dataState.fromCryptoCurrency @@ -943,7 +930,7 @@ internal class SwapViewModel @Inject constructor( forceQuotesUpdate: Boolean = false, reduceBalanceBy: BigDecimal = BigDecimal.ZERO, ) { - viewModelScope.launch { + modelScope.launch { val fromToken = dataState.fromCryptoCurrency val toToken = dataState.toCryptoCurrency if (fromToken != null) { @@ -968,7 +955,7 @@ internal class SwapViewModel @Inject constructor( isAmountChangedByUser = true } - amountDebouncer.debounce(viewModelScope, DEBOUNCE_AMOUNT_DELAY, forceUpdate = forceQuotesUpdate) { + amountDebouncer.debounce(modelScope, DEBOUNCE_AMOUNT_DELAY, forceUpdate = forceQuotesUpdate) { startLoadingQuotes( fromToken = fromToken, toToken = toToken, @@ -1085,7 +1072,7 @@ internal class SwapViewModel @Inject constructor( onSelectFeeType = { uiState = stateBuilder.dismissBottomSheet(uiState) dataState = dataState.copy(selectedFee = it) - viewModelScope.launch(dispatchers.io) { + modelScope.launch(dispatchers.io) { startLoadingQuotesFromLastState(false) } }, @@ -1145,7 +1132,7 @@ internal class SwapViewModel @Inject constructor( swapRouter.openScreen(SwapNavScreen.Success) }, onStoriesClose = { - viewModelScope.launch { shouldShowStoriesUseCase.neverToShow(StoryContentIds.STORY_FIRST_TIME_SWAP.id) } + modelScope.launch { shouldShowStoriesUseCase.neverToShow(StoryContentIds.STORY_FIRST_TIME_SWAP.id) } swapRouter.openScreen(SwapNavScreen.Main) }, ) @@ -1227,7 +1214,7 @@ internal class SwapViewModel @Inject constructor( return getSelectedAppCurrencyUseCase().map { maybeAppCurrency -> maybeAppCurrency.getOrElse { AppCurrency.Default } }.stateIn( - scope = viewModelScope, + scope = modelScope, started = SharingStarted.Eagerly, initialValue = AppCurrency.Default, ) @@ -1295,7 +1282,7 @@ internal class SwapViewModel @Inject constructor( private fun updateWalletBalance() { dataState.fromCryptoCurrency?.currency?.network?.let { network -> - viewModelScope.launch { + modelScope.launch { withContext(NonCancellable) { updateForBalance(userWalletId, network) } @@ -1336,7 +1323,7 @@ internal class SwapViewModel @Inject constructor( } private fun onFailedTxEmailClick(errorMessage: String) { - viewModelScope.launch { + modelScope.launch { val transaction = dataState.swapDataModel?.transaction val fromCurrencyStatus = dataState.fromCryptoCurrency ?: initialFromStatus val network = fromCurrencyStatus.currency.network diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/presentation/SwapNotificationsFactory.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapNotificationsFactory.kt similarity index 99% rename from features/swap/impl/src/main/java/com/tangem/feature/swap/presentation/SwapNotificationsFactory.kt rename to features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapNotificationsFactory.kt index 28f045bb1e..249fdce71d 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/presentation/SwapNotificationsFactory.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapNotificationsFactory.kt @@ -1,4 +1,4 @@ -package com.tangem.feature.swap.presentation +package com.tangem.feature.swap.model import com.tangem.common.ui.notifications.NotificationUM import com.tangem.common.ui.notifications.NotificationsFactory.addDustWarningNotification diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/viewmodels/SwapProcessDataState.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapProcessDataState.kt similarity index 96% rename from features/swap/impl/src/main/java/com/tangem/feature/swap/viewmodels/SwapProcessDataState.kt rename to features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapProcessDataState.kt index 3d53f18f52..86a8a33195 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/viewmodels/SwapProcessDataState.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapProcessDataState.kt @@ -1,4 +1,4 @@ -package com.tangem.feature.swap.viewmodels +package com.tangem.feature.swap.model import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.feature.swap.domain.models.domain.SwapDataModel diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt deleted file mode 100644 index 58316f8c11..0000000000 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt +++ /dev/null @@ -1,82 +0,0 @@ -package com.tangem.feature.swap.presentation - -import android.os.Bundle -import androidx.compose.animation.Crossfade -import androidx.compose.foundation.background -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.fragment.app.viewModels -import com.tangem.common.ui.swapStoriesScreen.SwapStoriesScreen -import com.tangem.core.ui.UiDependencies -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.screen.ComposeFragment -import com.tangem.feature.swap.router.SwapNavScreen -import com.tangem.feature.swap.ui.SwapScreen -import com.tangem.feature.swap.ui.SwapSelectTokenScreen -import com.tangem.feature.swap.ui.SwapSuccessScreen -import com.tangem.feature.swap.viewmodels.SwapViewModel -import dagger.hilt.android.AndroidEntryPoint -import javax.inject.Inject - -@AndroidEntryPoint -class SwapFragment : ComposeFragment() { - - @Inject - override lateinit var uiDependencies: UiDependencies - - private val viewModel by viewModels() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - lifecycle.addObserver(viewModel) - } - - @Composable - override fun ScreenContent(modifier: Modifier) { - viewModel.onScreenOpened() - ScreenContent(viewModel = viewModel) - } - - @Suppress("TopLevelComposableFunctions") - @Composable - private fun ScreenContent(viewModel: SwapViewModel) { - Crossfade( - modifier = Modifier.background(TangemTheme.colors.background.secondary), - targetState = viewModel.currentScreen, - label = "", - ) { screen -> - when (screen) { - SwapNavScreen.PromoStories -> { - val storiesConfig = viewModel.uiState.storiesConfig - if (storiesConfig != null) { - SwapStoriesScreen(config = storiesConfig) - } else { - SwapScreen(stateHolder = viewModel.uiState) - } - } - SwapNavScreen.Main -> SwapScreen(stateHolder = viewModel.uiState) - SwapNavScreen.Success -> { - val successState = viewModel.uiState.successState - if (successState != null) { - SwapSuccessScreen(state = successState, viewModel.uiState.onBackClicked) - } else { - SwapScreen(stateHolder = viewModel.uiState) - } - } - SwapNavScreen.SelectToken -> { - val tokenState = viewModel.uiState.selectTokenState - if (tokenState != null) { - SwapSelectTokenScreen(state = tokenState, onBack = viewModel.uiState.onBackClicked) - } else { - SwapScreen(stateHolder = viewModel.uiState) - } - } - } - } - } - - override fun onDestroy() { - lifecycle.removeObserver(viewModel) - super.onDestroy() - } -} \ No newline at end of file diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt index 3e7157f83e..c586e0bf5a 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt @@ -33,9 +33,9 @@ import com.tangem.feature.swap.models.* import com.tangem.feature.swap.models.states.* import com.tangem.feature.swap.models.states.events.SwapEvent import com.tangem.feature.swap.presentation.R -import com.tangem.feature.swap.presentation.SwapNotificationsFactory +import com.tangem.feature.swap.model.SwapNotificationsFactory import com.tangem.feature.swap.utils.formatToUIRepresentation -import com.tangem.feature.swap.viewmodels.SwapProcessDataState +import com.tangem.feature.swap.model.SwapProcessDataState import com.tangem.utils.Provider import com.tangem.utils.StringsSigns.DASH_SIGN import com.tangem.utils.StringsSigns.PERCENT