Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-10 18:25:23 +04:00
parent 96a748c904
commit a950ca16b7
8 changed files with 55 additions and 24 deletions

View file

@ -11,10 +11,11 @@ import com.tangem.features.disclaimer.api.components.DisclaimerComponent
import com.tangem.features.managetokens.component.ManageTokensComponent
import com.tangem.features.managetokens.component.ManageTokensSource
import com.tangem.features.markets.details.MarketsTokenDetailsComponent
import com.tangem.features.onramp.component.BuyCryptoComponent
import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent
import com.tangem.features.onramp.component.BuyCryptoComponent
import com.tangem.features.onramp.component.OnrampComponent
import com.tangem.features.onramp.component.SellCryptoComponent
import com.tangem.features.onramp.component.SwapSelectTokensComponent
import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter
import com.tangem.features.send.api.navigation.SendRouter
import com.tangem.features.staking.api.navigation.StakingRouter
@ -53,6 +54,7 @@ internal class ChildFactory @Inject constructor(
private val onrampComponentFactory: OnrampComponent.Factory,
private val buyCryptoComponentFactory: BuyCryptoComponent.Factory,
private val sellCryptoComponentFactory: SellCryptoComponent.Factory,
private val swapSelectTokensComponentFactory: SwapSelectTokensComponent.Factory,
private val onboardingEntryComponentFactory: OnboardingEntryComponent.Factory,
private val sendRouter: SendRouter,
private val tokenDetailsRouter: TokenDetailsRouter,
@ -215,6 +217,13 @@ internal class ChildFactory @Inject constructor(
componentFactory = sellCryptoComponentFactory,
)
}
is AppRoute.SwapCrypto -> {
route.asComponentChild(
contextProvider = contextProvider(route, contextFactory),
params = SwapSelectTokensComponent.Params(userWalletId = route.userWalletId),
componentFactory = swapSelectTokensComponentFactory,
)
}
is AppRoute.Onboarding -> {
route.asComponentChild(
contextProvider = contextProvider(route, contextFactory),

View file

@ -299,6 +299,11 @@ sealed class AppRoute(val path: String) : Route {
val userWalletId: UserWalletId,
) : AppRoute(path = "/sell_crypto/${userWalletId.stringValue}")
@Serializable
data class SwapCrypto(
val userWalletId: UserWalletId,
) : AppRoute(path = "/swap_crypto/${userWalletId.stringValue}")
// Onboarding V2
data class Onboarding(
val scanResponse: ScanResponse,

View file

@ -36,7 +36,8 @@ internal class DefaultSwapServiceLoader @Inject constructor(
private val dispatchers: CoroutineDispatcherProvider,
) : SwapServiceLoader {
private val initializationStatuses: Map<UserWalletId, InitializationStatusFlow> = mapOf()
private val initializationStatuses =
MutableStateFlow<Map<UserWalletId, InitializationStatusFlow>>(value = emptyMap())
override suspend fun update(userWalletId: UserWalletId, userTokens: UserTokensResponse) {
withContext(dispatchers.io) {
@ -73,9 +74,18 @@ internal class DefaultSwapServiceLoader @Inject constructor(
}
private fun getInitializationStatusInternal(userWalletId: UserWalletId): InitializationStatusFlow {
return initializationStatuses.getOrDefault(
key = userWalletId,
defaultValue = MutableStateFlow(value = lceLoading()),
)
val initializationStatus = initializationStatuses.value.get(key = userWalletId)
if (initializationStatus != null) return initializationStatus
val default: InitializationStatusFlow = MutableStateFlow(value = lceLoading())
initializationStatuses.update {
it.toMutableMap().apply {
put(key = userWalletId, value = default)
}
}
return default
}
}

View file

@ -24,6 +24,7 @@ dependencies {
implementation(projects.core.featuretoggles)
/** Project - Common */
implementation(projects.common.routing)
implementation(projects.common.ui)
/** Project - Domain */

View file

@ -8,10 +8,11 @@ import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.child
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.features.onramp.component.SwapSelectTokensComponent
import com.tangem.features.onramp.tokenlist.entity.OnrampOperation
import com.tangem.features.onramp.swap.availablepairs.AvailableSwapPairsComponent
import com.tangem.features.onramp.swap.model.SwapSelectTokensModel
import com.tangem.features.onramp.swap.ui.SwapSelectTokens
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
import com.tangem.features.onramp.tokenlist.entity.OnrampOperation
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@ -19,11 +20,12 @@ import dagger.assisted.AssistedInject
@Stable
internal class DefaultSwapSelectTokensComponent @AssistedInject constructor(
tokenListComponentFactory: OnrampTokenListComponent.Factory,
availableSwapPairsComponentFactory: AvailableSwapPairsComponent.Factory,
@Assisted private val appComponentContext: AppComponentContext,
@Assisted private val params: SwapSelectTokensComponent.Params,
) : AppComponentContext by appComponentContext, SwapSelectTokensComponent {
private val model: SwapSelectTokensModel = getOrCreateModel()
private val model: SwapSelectTokensModel = getOrCreateModel(params)
private val selectFromTokenListComponent: OnrampTokenListComponent = tokenListComponentFactory.create(
context = child(key = "select_from_token_list"),
@ -35,15 +37,15 @@ internal class DefaultSwapSelectTokensComponent @AssistedInject constructor(
),
)
private val selectToTokenListComponent: OnrampTokenListComponent = tokenListComponentFactory.create(
context = child(key = "select_to_token_list"),
params = OnrampTokenListComponent.Params(
filterOperation = OnrampOperation.SWAP,
hasSearchBar = true,
userWalletId = params.userWalletId,
onTokenClick = model::selectToToken,
),
)
private val selectToTokenListComponent: AvailableSwapPairsComponent =
availableSwapPairsComponentFactory.create(
context = child(key = "select_to_token_list"),
params = AvailableSwapPairsComponent.Params(
userWalletId = params.userWalletId,
selectedStatus = model.fromCurrencyStatus,
onTokenClick = model::selectToToken,
),
)
@Composable
override fun Content(modifier: Modifier) {

View file

@ -9,6 +9,7 @@ import com.tangem.features.onramp.swap.entity.transformer.RemoveSelectedFromToke
import com.tangem.features.onramp.swap.entity.transformer.SelectFromTokenTransformer
import com.tangem.features.onramp.swap.entity.transformer.SelectToTokenTransformer
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject
@ -20,8 +21,10 @@ internal class SwapSelectTokensModel @Inject constructor(
val state: StateFlow<SwapSelectTokensUM> = controller.state
private var fromCurrencyStatus: CryptoCurrencyStatus? = null
private var toCurrencyStatus: CryptoCurrencyStatus? = null
val fromCurrencyStatus: StateFlow<CryptoCurrencyStatus?> get() = _fromCurrencyStatus
private val _fromCurrencyStatus = MutableStateFlow<CryptoCurrencyStatus?>(value = null)
private val _toCurrencyStatus = MutableStateFlow<CryptoCurrencyStatus?>(value = null)
/**
* Select "from" token
@ -30,7 +33,7 @@ internal class SwapSelectTokensModel @Inject constructor(
* @param status crypto currency status
*/
fun selectFromToken(selectedTokenItemState: TokenItemState, status: CryptoCurrencyStatus) {
fromCurrencyStatus = status
_fromCurrencyStatus.value = status
controller.update(
transformer = SelectFromTokenTransformer(
@ -47,7 +50,7 @@ internal class SwapSelectTokensModel @Inject constructor(
* @param status crypto currency status
*/
fun selectToToken(selectedTokenItemState: TokenItemState, status: CryptoCurrencyStatus) {
toCurrencyStatus = status
_toCurrencyStatus.value = status
controller.update(transformer = SelectToTokenTransformer(selectedTokenItemState))
@ -55,7 +58,7 @@ internal class SwapSelectTokensModel @Inject constructor(
}
private fun onRemoveClick() {
fromCurrencyStatus = null
_fromCurrencyStatus.value = null
controller.update(transformer = RemoveSelectedFromTokenTransformer)
}

View file

@ -15,6 +15,7 @@ import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.swap.availablepairs.AvailableSwapPairsComponent
import com.tangem.features.onramp.swap.entity.ExchangeCardUM
import com.tangem.features.onramp.swap.entity.SwapSelectTokensUM
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
@ -34,7 +35,7 @@ import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
internal fun SwapSelectTokens(
state: SwapSelectTokensUM,
selectFromTokenListComponent: OnrampTokenListComponent,
selectToTokenListComponent: OnrampTokenListComponent,
selectToTokenListComponent: AvailableSwapPairsComponent,
modifier: Modifier = Modifier,
) {
BackHandler(onBack = state.onBackClick)

View file

@ -445,7 +445,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
override fun onMultiWalletSwapClick(userWalletId: UserWalletId) {
// TODO [REDACTED_JIRA]
// appRouter.push(route = AppRoute.SwapCrypto(userWalletId = userWalletId))
appRouter.push(route = AppRoute.SwapCrypto(userWalletId = userWalletId))
}
override fun onMultiWalletBuyClick(userWalletId: UserWalletId) {