Updated on 2026-08-14
This commit is contained in:
parent
e250ecd508
commit
dfc3dbc324
30 changed files with 574 additions and 369 deletions
|
|
@ -2,12 +2,11 @@ package com.tangem.features.managetokens.component
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
interface AddCustomTokenComponent : ComposableBottomSheetComponent {
|
||||
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val mode: AddCustomTokenMode,
|
||||
val source: ManageTokensSource,
|
||||
val onDismiss: () -> Unit,
|
||||
val onCurrencyAdded: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -7,9 +7,16 @@ import com.tangem.domain.models.wallet.UserWalletId
|
|||
interface ManageTokensComponent : ComposableContentComponent {
|
||||
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId?,
|
||||
val mode: ManageTokensMode,
|
||||
val source: ManageTokensSource,
|
||||
)
|
||||
) {
|
||||
constructor(userWalletId: UserWalletId?, source: ManageTokensSource) : this(
|
||||
source = source,
|
||||
mode = userWalletId
|
||||
?.let { ManageTokensMode.Wallet(userWalletId) }
|
||||
?: ManageTokensMode.None,
|
||||
)
|
||||
}
|
||||
|
||||
interface Factory : ComponentFactory<Params, ManageTokensComponent>
|
||||
}
|
||||
|
|
@ -1,8 +1,22 @@
|
|||
package com.tangem.features.managetokens.component
|
||||
|
||||
import com.tangem.domain.models.account.AccountId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
enum class ManageTokensSource(val analyticsName: String) {
|
||||
STORIES(analyticsName = "Stories"),
|
||||
ONBOARDING(analyticsName = "Onboarding"),
|
||||
SETTINGS(analyticsName = "Settings"),
|
||||
SEND_VIA_SWAP(analyticsName = "SendViaSwap"),
|
||||
}
|
||||
|
||||
sealed interface ManageTokensMode {
|
||||
data class Wallet(val userWalletId: UserWalletId) : ManageTokensMode
|
||||
data class Account(val accountId: AccountId) : ManageTokensMode
|
||||
data object None : ManageTokensMode
|
||||
}
|
||||
|
||||
sealed interface AddCustomTokenMode {
|
||||
data class Wallet(val userWalletId: UserWalletId) : AddCustomTokenMode
|
||||
data class Account(val accountId: AccountId) : AddCustomTokenMode
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@ import com.tangem.features.managetokens.choosetoken.entity.ChooseManageTokensBot
|
|||
import com.tangem.features.managetokens.choosetoken.entity.ChooseManagedTokenUM
|
||||
import com.tangem.features.managetokens.component.ChooseManagedTokensComponent
|
||||
import com.tangem.features.managetokens.component.ChooseManagedTokensComponent.Source
|
||||
import com.tangem.features.managetokens.component.ManageTokensMode
|
||||
import com.tangem.features.managetokens.component.ManageTokensSource
|
||||
import com.tangem.features.managetokens.component.analytics.CommonManageTokensAnalyticEvents
|
||||
import com.tangem.features.managetokens.entity.item.CurrencyItemUM
|
||||
|
|
@ -29,6 +30,7 @@ import com.tangem.features.managetokens.entity.managetokens.ManageTokensTopBarUM
|
|||
import com.tangem.features.managetokens.entity.managetokens.ManageTokensUM
|
||||
import com.tangem.features.managetokens.impl.R
|
||||
import com.tangem.features.managetokens.utils.list.ManageTokensListManager
|
||||
import com.tangem.features.managetokens.utils.list.ManageTokensUseCasesFacade
|
||||
import com.tangem.features.managetokens.utils.list.getLoadingItems
|
||||
import com.tangem.pagination.BatchFetchResult
|
||||
import com.tangem.pagination.PaginationStatus
|
||||
|
|
@ -51,12 +53,19 @@ internal class ChooseManagedTokensModel @Inject constructor(
|
|||
private val setShouldShowNotificationUseCase: SetShouldShowNotificationUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
paramsContainer: ParamsContainer,
|
||||
manageTokensUseCasesFacadeFactory: ManageTokensUseCasesFacade.Factory,
|
||||
manageTokensListManagerFactory: ManageTokensListManager.Factory,
|
||||
) : Model() {
|
||||
|
||||
private val params: ChooseManagedTokensComponent.Params = paramsContainer.require()
|
||||
private val useCasesFacade: ManageTokensUseCasesFacade = manageTokensUseCasesFacadeFactory
|
||||
.create(mode = ManageTokensMode.None)
|
||||
|
||||
private val manageTokensListManager = manageTokensListManagerFactory.create(
|
||||
scope = modelScope,
|
||||
source = ManageTokensSource.SEND_VIA_SWAP,
|
||||
mode = ManageTokensMode.None,
|
||||
useCasesFacade = useCasesFacade,
|
||||
onCurrencySelect = { token ->
|
||||
bottomSheetNavigation.activate(
|
||||
ChooseManageTokensBottomSheetConfig.SwapTokensBottomSheetConfig(
|
||||
|
|
@ -86,7 +95,7 @@ internal class ChooseManagedTokensModel @Inject constructor(
|
|||
observeSearchQueryChanges()
|
||||
|
||||
modelScope.launch {
|
||||
manageTokensListManager.launchPagination(source = ManageTokensSource.SEND_VIA_SWAP, userWalletId = null)
|
||||
manageTokensListManager.launchPagination()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +168,7 @@ internal class ChooseManagedTokensModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
.sample(periodMillis = 1_000)
|
||||
.onEach { query -> manageTokensListManager.search(userWalletId = null, query = query) }
|
||||
.onEach { query -> manageTokensListManager.search(query = query) }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
|
|
@ -295,7 +304,7 @@ internal class ChooseManagedTokensModel @Inject constructor(
|
|||
if (state.readContent.isInitialBatchLoading || state.readContent.isNextBatchLoading) return false
|
||||
|
||||
modelScope.launch {
|
||||
manageTokensListManager.loadMore(userWalletId = null, query = state.readContent.search.query)
|
||||
manageTokensListManager.loadMore(query = state.readContent.search.query)
|
||||
}
|
||||
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -2,13 +2,12 @@ package com.tangem.features.managetokens.component
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableDialogComponent
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.entity.customtoken.SelectedDerivationPath
|
||||
|
||||
internal interface CustomTokenDerivationInputComponent : ComposableDialogComponent {
|
||||
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val mode: AddCustomTokenMode,
|
||||
val onConfirm: (SelectedDerivationPath) -> Unit,
|
||||
val onDismiss: () -> Unit,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.tangem.features.managetokens.component
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.entity.customtoken.CustomTokenFormValues
|
||||
import com.tangem.features.managetokens.entity.customtoken.SelectedDerivationPath
|
||||
import com.tangem.features.managetokens.entity.customtoken.SelectedNetwork
|
||||
|
|
@ -10,7 +9,7 @@ import com.tangem.features.managetokens.entity.customtoken.SelectedNetwork
|
|||
internal interface CustomTokenFormComponent : ComposableContentComponent {
|
||||
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val mode: AddCustomTokenMode,
|
||||
val network: SelectedNetwork,
|
||||
val derivationPath: SelectedDerivationPath?,
|
||||
val formValues: CustomTokenFormValues,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.tangem.features.managetokens.component
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.entity.customtoken.SelectedDerivationPath
|
||||
import com.tangem.features.managetokens.entity.customtoken.SelectedNetwork
|
||||
|
||||
|
|
@ -11,13 +10,13 @@ internal interface CustomTokenSelectorComponent : ComposableContentComponent {
|
|||
sealed class Params {
|
||||
|
||||
data class NetworkSelector(
|
||||
val userWalletId: UserWalletId,
|
||||
val mode: AddCustomTokenMode,
|
||||
val selectedNetwork: SelectedNetwork?,
|
||||
val onNetworkSelected: (SelectedNetwork) -> Unit,
|
||||
) : Params()
|
||||
|
||||
data class DerivationPathSelector(
|
||||
val userWalletId: UserWalletId,
|
||||
val mode: AddCustomTokenMode,
|
||||
val selectedNetwork: SelectedNetwork,
|
||||
val selectedDerivationPath: SelectedDerivationPath?,
|
||||
val onDerivationPathSelected: (SelectedDerivationPath) -> Unit,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ internal class DefaultAddCustomTokenComponent @AssistedInject constructor(
|
|||
) : AddCustomTokenComponent, AppComponentContext by context {
|
||||
|
||||
private val initialConfiguration = AddCustomTokenConfig(
|
||||
userWalletId = params.userWalletId,
|
||||
mode = params.mode,
|
||||
step = AddCustomTokenConfig.Step.INITIAL_NETWORK_SELECTOR,
|
||||
)
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ internal class DefaultAddCustomTokenComponent @AssistedInject constructor(
|
|||
selectorComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = CustomTokenSelectorComponent.Params.NetworkSelector(
|
||||
userWalletId = config.userWalletId,
|
||||
mode = config.mode,
|
||||
selectedNetwork = null,
|
||||
onNetworkSelected = ::changeSelectedNetwork,
|
||||
),
|
||||
|
|
@ -115,7 +115,7 @@ internal class DefaultAddCustomTokenComponent @AssistedInject constructor(
|
|||
selectorComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = CustomTokenSelectorComponent.Params.NetworkSelector(
|
||||
userWalletId = config.userWalletId,
|
||||
mode = config.mode,
|
||||
selectedNetwork = config.selectedNetwork,
|
||||
onNetworkSelected = ::changeSelectedNetwork,
|
||||
),
|
||||
|
|
@ -125,7 +125,7 @@ internal class DefaultAddCustomTokenComponent @AssistedInject constructor(
|
|||
selectorComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = CustomTokenSelectorComponent.Params.DerivationPathSelector(
|
||||
userWalletId = config.userWalletId,
|
||||
mode = config.mode,
|
||||
selectedNetwork = requireNotNull(config.selectedNetwork) {
|
||||
"Network is not selected"
|
||||
},
|
||||
|
|
@ -138,7 +138,7 @@ internal class DefaultAddCustomTokenComponent @AssistedInject constructor(
|
|||
formComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = CustomTokenFormComponent.Params(
|
||||
userWalletId = config.userWalletId,
|
||||
mode = config.mode,
|
||||
network = requireNotNull(config.selectedNetwork) {
|
||||
"Network is not selected"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ internal class DefaultCustomTokenSelectorComponent @AssistedInject constructor(
|
|||
is CustomTokenSelectorDialogConfig.CustomDerivationInput -> customTokenDerivationInputComponentFactory.create(
|
||||
context = childByContext(context),
|
||||
params = CustomTokenDerivationInputComponent.Params(
|
||||
userWalletId = config.userWalletId,
|
||||
mode = config.mode,
|
||||
onConfirm = model::selectCustomDerivationPath,
|
||||
onDismiss = model.dialogNavigation::dismiss,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.core.decompose.context.childByContext
|
|||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.features.managetokens.component.AddCustomTokenComponent
|
||||
import com.tangem.features.managetokens.component.AddCustomTokenMode
|
||||
import com.tangem.features.managetokens.component.ManageTokensComponent
|
||||
import com.tangem.features.managetokens.entity.managetokens.ManageTokensBottomSheetConfig
|
||||
import com.tangem.features.managetokens.model.ManageTokensModel
|
||||
|
|
@ -52,18 +53,20 @@ internal class DefaultManageTokensComponent @AssistedInject constructor(
|
|||
private fun bottomSheetChild(
|
||||
config: ManageTokensBottomSheetConfig,
|
||||
componentContext: ComponentContext,
|
||||
): ComposableBottomSheetComponent = when (config) {
|
||||
is ManageTokensBottomSheetConfig.AddCustomToken -> {
|
||||
addCustomTokenComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = AddCustomTokenComponent.Params(
|
||||
userWalletId = config.userWalletId,
|
||||
source = params.source,
|
||||
onDismiss = model.bottomSheetNavigation::dismiss,
|
||||
onCurrencyAdded = model::reloadList,
|
||||
),
|
||||
)
|
||||
): ComposableBottomSheetComponent {
|
||||
val mode = when (config) {
|
||||
is ManageTokensBottomSheetConfig.AddWalletCustomToken -> AddCustomTokenMode.Wallet(config.userWalletId)
|
||||
is ManageTokensBottomSheetConfig.AddAccountCustomToken -> AddCustomTokenMode.Account(config.accountId)
|
||||
}
|
||||
return addCustomTokenComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = AddCustomTokenComponent.Params(
|
||||
mode = mode,
|
||||
source = params.source,
|
||||
onDismiss = model.bottomSheetNavigation::dismiss,
|
||||
onCurrencyAdded = model::reloadList,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.component.AddCustomTokenComponent
|
||||
import com.tangem.features.managetokens.component.AddCustomTokenMode
|
||||
import com.tangem.features.managetokens.component.CustomTokenSelectorComponent
|
||||
import com.tangem.features.managetokens.entity.customtoken.AddCustomTokenConfig
|
||||
import com.tangem.features.managetokens.ui.AddCustomTokenBottomSheet
|
||||
|
|
@ -14,7 +15,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
|
||||
internal class PreviewAddCustomTokenComponent(
|
||||
initialState: AddCustomTokenConfig = AddCustomTokenConfig(
|
||||
userWalletId = UserWalletId(stringValue = "321"),
|
||||
mode = AddCustomTokenMode.Wallet(UserWalletId(stringValue = "321")),
|
||||
step = AddCustomTokenConfig.Step.INITIAL_NETWORK_SELECTOR,
|
||||
),
|
||||
) : AddCustomTokenComponent {
|
||||
|
|
@ -41,7 +42,7 @@ internal class PreviewAddCustomTokenComponent(
|
|||
AddCustomTokenConfig.Step.INITIAL_NETWORK_SELECTOR -> {
|
||||
PreviewCustomTokenSelectorComponent(
|
||||
params = CustomTokenSelectorComponent.Params.NetworkSelector(
|
||||
userWalletId = config.userWalletId,
|
||||
mode = config.mode,
|
||||
selectedNetwork = null,
|
||||
onNetworkSelected = {},
|
||||
),
|
||||
|
|
@ -50,7 +51,7 @@ internal class PreviewAddCustomTokenComponent(
|
|||
AddCustomTokenConfig.Step.NETWORK_SELECTOR -> {
|
||||
PreviewCustomTokenSelectorComponent(
|
||||
params = CustomTokenSelectorComponent.Params.NetworkSelector(
|
||||
userWalletId = config.userWalletId,
|
||||
mode = config.mode,
|
||||
selectedNetwork = config.selectedNetwork,
|
||||
onNetworkSelected = {},
|
||||
),
|
||||
|
|
@ -59,7 +60,7 @@ internal class PreviewAddCustomTokenComponent(
|
|||
AddCustomTokenConfig.Step.DERIVATION_PATH_SELECTOR -> {
|
||||
PreviewCustomTokenSelectorComponent(
|
||||
params = CustomTokenSelectorComponent.Params.DerivationPathSelector(
|
||||
userWalletId = config.userWalletId,
|
||||
mode = config.mode,
|
||||
selectedNetwork = config.selectedNetwork!!,
|
||||
selectedDerivationPath = config.selectedDerivationPath!!,
|
||||
onDerivationPathSelected = {},
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import androidx.compose.ui.Modifier
|
|||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.component.AddCustomTokenMode
|
||||
import com.tangem.features.managetokens.component.CustomTokenSelectorComponent
|
||||
import com.tangem.features.managetokens.component.CustomTokenSelectorComponent.Params
|
||||
import com.tangem.features.managetokens.entity.customtoken.CustomTokenSelectorUM
|
||||
|
|
@ -18,7 +19,7 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
|
||||
internal class PreviewCustomTokenSelectorComponent(
|
||||
private val params: Params = Params.NetworkSelector(
|
||||
userWalletId = UserWalletId(stringValue = "321"),
|
||||
mode = AddCustomTokenMode.Wallet(UserWalletId(stringValue = "321")),
|
||||
selectedNetwork = null,
|
||||
onNetworkSelected = {},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.core.ui.extensions.resourceReference
|
|||
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.features.managetokens.component.ManageTokensComponent
|
||||
import com.tangem.features.managetokens.component.ManageTokensMode
|
||||
import com.tangem.features.managetokens.entity.item.CurrencyItemUM
|
||||
import com.tangem.features.managetokens.entity.item.CurrencyNetworkUM
|
||||
import com.tangem.features.managetokens.entity.managetokens.ManageTokensTopBarUM
|
||||
|
|
@ -38,8 +39,10 @@ internal class PreviewManageTokensComponent(
|
|||
value = ManageTokensUM.ManageContent(
|
||||
popBack = {},
|
||||
items = items,
|
||||
topBar = if (params.userWalletId != null) {
|
||||
ManageTokensTopBarUM.ManageContent(
|
||||
topBar = when (params.mode) {
|
||||
is ManageTokensMode.Account,
|
||||
is ManageTokensMode.Wallet,
|
||||
-> ManageTokensTopBarUM.ManageContent(
|
||||
title = resourceReference(id = R.string.main_manage_tokens),
|
||||
onBackButtonClick = {},
|
||||
endButton = TopAppBarButtonUM.Icon(
|
||||
|
|
@ -47,8 +50,7 @@ internal class PreviewManageTokensComponent(
|
|||
onClicked = {},
|
||||
),
|
||||
)
|
||||
} else {
|
||||
ManageTokensTopBarUM.ReadContent(
|
||||
ManageTokensMode.None -> ManageTokensTopBarUM.ReadContent(
|
||||
title = resourceReference(R.string.common_search_tokens),
|
||||
onBackButtonClick = {},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
package com.tangem.features.managetokens.entity.customtoken
|
||||
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.component.AddCustomTokenMode
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
internal data class AddCustomTokenConfig(
|
||||
val step: Step,
|
||||
val userWalletId: UserWalletId,
|
||||
val mode: AddCustomTokenMode,
|
||||
val selectedNetwork: SelectedNetwork? = null,
|
||||
val selectedDerivationPath: SelectedDerivationPath? = null,
|
||||
val formValues: CustomTokenFormValues = CustomTokenFormValues(),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.features.managetokens.entity.customtoken
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.component.AddCustomTokenMode
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
|
|
@ -8,6 +8,6 @@ internal sealed class CustomTokenSelectorDialogConfig {
|
|||
|
||||
@Serializable
|
||||
data class CustomDerivationInput(
|
||||
val userWalletId: UserWalletId,
|
||||
val mode: AddCustomTokenMode,
|
||||
) : CustomTokenSelectorDialogConfig()
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.managetokens.entity.managetokens
|
||||
|
||||
import com.tangem.domain.models.account.AccountId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
|
@ -7,7 +8,12 @@ import kotlinx.serialization.Serializable
|
|||
internal sealed class ManageTokensBottomSheetConfig {
|
||||
|
||||
@Serializable
|
||||
data class AddCustomToken(
|
||||
data class AddWalletCustomToken(
|
||||
val userWalletId: UserWalletId,
|
||||
) : ManageTokensBottomSheetConfig()
|
||||
|
||||
@Serializable
|
||||
data class AddAccountCustomToken(
|
||||
val accountId: AccountId,
|
||||
) : ManageTokensBottomSheetConfig()
|
||||
}
|
||||
|
|
@ -12,9 +12,6 @@ import com.tangem.core.ui.message.DialogMessage
|
|||
import com.tangem.domain.managetokens.model.exceptoin.CustomTokenFormValidationException
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase
|
||||
import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase
|
||||
import com.tangem.features.managetokens.analytics.CustomTokenAnalyticsEvent
|
||||
import com.tangem.features.managetokens.component.CustomTokenFormComponent
|
||||
import com.tangem.features.managetokens.entity.customtoken.ClickableFieldUM
|
||||
|
|
@ -25,6 +22,7 @@ import com.tangem.features.managetokens.entity.customtoken.TextInputFieldUM
|
|||
import com.tangem.features.managetokens.impl.R
|
||||
import com.tangem.features.managetokens.utils.CustomCurrencyFormBuilder
|
||||
import com.tangem.features.managetokens.utils.CustomCurrencyValidator
|
||||
import com.tangem.features.managetokens.utils.list.CustomTokenFormUseCasesFacade
|
||||
import com.tangem.features.managetokens.utils.mapper.mapToDomainModel
|
||||
import com.tangem.features.managetokens.utils.ui.*
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -40,18 +38,17 @@ import javax.inject.Inject
|
|||
@ModelScoped
|
||||
internal class CustomTokenFormModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val customCurrencyValidator: CustomCurrencyValidator,
|
||||
private val addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase,
|
||||
private val derivePublicKeysUseCase: DerivePublicKeysUseCase,
|
||||
private val hasMissedDerivationsUseCase: HasMissedDerivationsUseCase,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val customTokenFormManager: CustomCurrencyFormBuilder,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
paramsContainer: ParamsContainer,
|
||||
customTokenFormUseCasesFacadeFactory: CustomTokenFormUseCasesFacade.Factory,
|
||||
) : Model() {
|
||||
|
||||
private val params: CustomTokenFormComponent.Params = paramsContainer.require()
|
||||
private var createdCurrency: CryptoCurrency? = null
|
||||
private var useCasesFacade: CustomTokenFormUseCasesFacade = customTokenFormUseCasesFacadeFactory.create(params.mode)
|
||||
private val customCurrencyValidator = CustomCurrencyValidator(useCasesFacade)
|
||||
|
||||
val state: MutableStateFlow<CustomTokenFormUM> = MutableStateFlow(
|
||||
value = getInitialState(),
|
||||
|
|
@ -117,7 +114,6 @@ internal class CustomTokenFormModel @Inject constructor(
|
|||
.drop(count = 1) // Skip initial state
|
||||
.onEach { formValues ->
|
||||
customCurrencyValidator.validateForm(
|
||||
userWalletId = params.userWalletId,
|
||||
networkId = params.network.id,
|
||||
derivationPath = getDerivationPath(),
|
||||
formValues = formValues,
|
||||
|
|
@ -156,7 +152,6 @@ internal class CustomTokenFormModel @Inject constructor(
|
|||
|
||||
private fun validatePrefilledForm() = modelScope.launch {
|
||||
customCurrencyValidator.validateForm(
|
||||
userWalletId = params.userWalletId,
|
||||
networkId = params.network.id,
|
||||
derivationPath = getDerivationPath(),
|
||||
formValues = state.value.tokenForm.mapToDomainModel(),
|
||||
|
|
@ -169,8 +164,7 @@ internal class CustomTokenFormModel @Inject constructor(
|
|||
isAlreadyAdded: Boolean,
|
||||
isCustom: Boolean,
|
||||
) = modelScope.launch {
|
||||
val needToAddDerivation = hasMissedDerivationsUseCase(
|
||||
userWalletId = params.userWalletId,
|
||||
val needToAddDerivation = useCasesFacade.hasMissedDerivationsUseCase(
|
||||
networksWithDerivationPath = mapOf(currency.network.backendId to getDerivationPath().value),
|
||||
)
|
||||
|
||||
|
|
@ -343,13 +337,13 @@ internal class CustomTokenFormModel @Inject constructor(
|
|||
)
|
||||
analyticsEventHandler.send(event)
|
||||
|
||||
derivePublicKeysUseCase(params.userWalletId, listOf(currency)).getOrElse {
|
||||
useCasesFacade.derivePublicKeysUseCase(listOf(currency)).getOrElse {
|
||||
Timber.e(it, "Failed to derive public keys")
|
||||
showErrorDialog()
|
||||
return@resource
|
||||
}
|
||||
|
||||
addCryptoCurrenciesUseCase(params.userWalletId, currency).getOrElse {
|
||||
useCasesFacade.addCryptoCurrenciesUseCase(currency).getOrElse {
|
||||
Timber.e(it, "Failed to add currency")
|
||||
showErrorDialog()
|
||||
return@resource
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import com.tangem.core.ui.extensions.resourceReference
|
|||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.managetokens.GetSupportedNetworksUseCase
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.component.AddCustomTokenMode
|
||||
import com.tangem.features.managetokens.component.CustomTokenSelectorComponent
|
||||
import com.tangem.features.managetokens.component.CustomTokenSelectorComponent.Params.DerivationPathSelector
|
||||
import com.tangem.features.managetokens.component.CustomTokenSelectorComponent.Params.NetworkSelector
|
||||
|
|
@ -83,7 +83,7 @@ internal class CustomTokenSelectorModel @Inject constructor(
|
|||
}
|
||||
|
||||
private suspend fun loadNetworks(selector: NetworkSelector): List<SelectableItemUM> {
|
||||
return getSupportedNetworks(selector.userWalletId).map { network ->
|
||||
return getSupportedNetworks(selector.mode).map { network ->
|
||||
network.toCurrencyNetworkModel(
|
||||
isSelected = network.id == selector.selectedNetwork?.id,
|
||||
onSelectedStateChange = {
|
||||
|
|
@ -122,7 +122,7 @@ internal class CustomTokenSelectorModel @Inject constructor(
|
|||
derivationPaths.add(defaultPath)
|
||||
}
|
||||
|
||||
getSupportedNetworks(selector.userWalletId)
|
||||
getSupportedNetworks(selector.mode)
|
||||
.mapNotNullTo(derivationPaths) { network ->
|
||||
if (network.id == selector.selectedNetwork.id) {
|
||||
return@mapNotNullTo null // Skip default path
|
||||
|
|
@ -146,8 +146,9 @@ internal class CustomTokenSelectorModel @Inject constructor(
|
|||
return derivationPaths
|
||||
}
|
||||
|
||||
private suspend fun getSupportedNetworks(userWalletId: UserWalletId): List<Network> {
|
||||
return getSupportedNetworksUseCase(userWalletId).getOrElse { e ->
|
||||
private suspend fun getSupportedNetworks(mode: AddCustomTokenMode): List<Network> = when (mode) {
|
||||
is AddCustomTokenMode.Account -> TODO("Account")
|
||||
is AddCustomTokenMode.Wallet -> getSupportedNetworksUseCase(mode.userWalletId).getOrElse { e ->
|
||||
val message = SnackbarMessage(message = resourceReference(R.string.common_unknown_error))
|
||||
messageSender.send(message)
|
||||
|
||||
|
|
@ -158,7 +159,7 @@ internal class CustomTokenSelectorModel @Inject constructor(
|
|||
private fun showCustomDerivationInput() {
|
||||
val config = when (params) {
|
||||
is NetworkSelector -> return
|
||||
is DerivationPathSelector -> CustomTokenSelectorDialogConfig.CustomDerivationInput(params.userWalletId)
|
||||
is DerivationPathSelector -> CustomTokenSelectorDialogConfig.CustomDerivationInput(params.mode)
|
||||
}
|
||||
|
||||
dialogNavigation.activate(config)
|
||||
|
|
|
|||
|
|
@ -17,12 +17,10 @@ import com.tangem.core.ui.event.triggeredEvent
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.managetokens.SaveManagedTokensUseCase
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase
|
||||
import com.tangem.features.managetokens.analytics.CustomTokenAnalyticsEvent
|
||||
import com.tangem.features.managetokens.analytics.ManageTokensAnalyticEvent
|
||||
import com.tangem.features.managetokens.component.ManageTokensComponent
|
||||
import com.tangem.features.managetokens.component.ManageTokensMode
|
||||
import com.tangem.features.managetokens.entity.item.CurrencyItemUM
|
||||
import com.tangem.features.managetokens.entity.managetokens.ManageTokensBottomSheetConfig
|
||||
import com.tangem.features.managetokens.entity.managetokens.ManageTokensTopBarUM
|
||||
|
|
@ -30,6 +28,7 @@ import com.tangem.features.managetokens.entity.managetokens.ManageTokensUM
|
|||
import com.tangem.features.managetokens.impl.R
|
||||
import com.tangem.features.managetokens.utils.list.ChangedCurrencies
|
||||
import com.tangem.features.managetokens.utils.list.ManageTokensListManager
|
||||
import com.tangem.features.managetokens.utils.list.ManageTokensUseCasesFacade
|
||||
import com.tangem.pagination.BatchFetchResult
|
||||
import com.tangem.pagination.PaginationStatus
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -47,18 +46,24 @@ internal class ManageTokensModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val router: Router,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val hasMissedDerivationsUseCase: HasMissedDerivationsUseCase,
|
||||
private val saveManagedTokensUseCase: SaveManagedTokensUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
manageTokensListManagerFactory: ManageTokensListManager.Factory,
|
||||
manageTokensUseCasesFacadeFactory: ManageTokensUseCasesFacade.Factory,
|
||||
paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
||||
private val params: ManageTokensComponent.Params = paramsContainer.require()
|
||||
private val useCasesFacade: ManageTokensUseCasesFacade = manageTokensUseCasesFacadeFactory
|
||||
.create(mode = params.mode)
|
||||
|
||||
private val manageTokensListManager = manageTokensListManagerFactory.create()
|
||||
private val manageTokensListManager = manageTokensListManagerFactory.create(
|
||||
scope = modelScope,
|
||||
source = params.source,
|
||||
mode = params.mode,
|
||||
useCasesFacade = useCasesFacade,
|
||||
)
|
||||
|
||||
val state: MutableStateFlow<ManageTokensUM> = MutableStateFlow(getInitialState(params.userWalletId))
|
||||
val state: MutableStateFlow<ManageTokensUM> = MutableStateFlow(getInitialState())
|
||||
val bottomSheetNavigation: SlotNavigation<ManageTokensBottomSheetConfig> = SlotNavigation()
|
||||
|
||||
init {
|
||||
|
|
@ -79,23 +84,24 @@ internal class ManageTokensModel @Inject constructor(
|
|||
observeSearchQueryChanges()
|
||||
|
||||
modelScope.launch {
|
||||
manageTokensListManager.launchPagination(source = params.source, userWalletId = params.userWalletId)
|
||||
manageTokensListManager.launchPagination()
|
||||
}
|
||||
}
|
||||
|
||||
fun reloadList() {
|
||||
modelScope.launch {
|
||||
manageTokensListManager.reload(params.userWalletId)
|
||||
manageTokensListManager.reload()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInitialState(userWalletId: UserWalletId?): ManageTokensUM {
|
||||
private fun getInitialState(): ManageTokensUM {
|
||||
analyticsEventHandler.send(ManageTokensAnalyticEvent.ScreenOpened(params.source))
|
||||
|
||||
return if (userWalletId == null) {
|
||||
createReadContentModel()
|
||||
} else {
|
||||
createManageContentModel()
|
||||
return when (params.mode) {
|
||||
is ManageTokensMode.Wallet,
|
||||
is ManageTokensMode.Account,
|
||||
-> createManageContentModel()
|
||||
ManageTokensMode.None -> createReadContentModel()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -164,7 +170,7 @@ internal class ManageTokensModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
.sample(periodMillis = 1_000)
|
||||
.onEach { query -> manageTokensListManager.search(userWalletId = params.userWalletId, query = query) }
|
||||
.onEach { query -> manageTokensListManager.search(query = query) }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
|
|
@ -261,19 +267,16 @@ internal class ManageTokensModel @Inject constructor(
|
|||
|
||||
private fun updateChangedItems(currenciesToAdd: ChangedCurrencies, currenciesToRemove: ChangedCurrencies) {
|
||||
modelScope.launch {
|
||||
val hasMissedDerivations = params.userWalletId?.let { walletId ->
|
||||
val networks = currenciesToAdd.values
|
||||
.flatten()
|
||||
.toSet()
|
||||
.associate { it.backendId to null }
|
||||
|
||||
hasMissedDerivationsUseCase(walletId, networks)
|
||||
}
|
||||
val networks = currenciesToAdd.values
|
||||
.flatten()
|
||||
.toSet()
|
||||
.associate { it.backendId to null }
|
||||
val hasMissedDerivations = useCasesFacade.hasMissedDerivationsUseCase(networks)
|
||||
|
||||
state.update { state ->
|
||||
state.copySealed(
|
||||
hasChanges = currenciesToAdd.isNotEmpty() || currenciesToRemove.isNotEmpty(),
|
||||
needToAddDerivations = hasMissedDerivations ?: false,
|
||||
needToAddDerivations = hasMissedDerivations,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -284,7 +287,7 @@ internal class ManageTokensModel @Inject constructor(
|
|||
if (state.isInitialBatchLoading || state.isNextBatchLoading) return false
|
||||
|
||||
modelScope.launch {
|
||||
manageTokensListManager.loadMore(userWalletId = params.userWalletId, query = state.search.query)
|
||||
manageTokensListManager.loadMore(query = state.search.query)
|
||||
}
|
||||
|
||||
return true
|
||||
|
|
@ -292,9 +295,14 @@ internal class ManageTokensModel @Inject constructor(
|
|||
|
||||
private fun navigateToAddCustomToken() {
|
||||
analyticsEventHandler.send(CustomTokenAnalyticsEvent.ButtonCustomToken(params.source))
|
||||
|
||||
params.userWalletId?.let {
|
||||
bottomSheetNavigation.activate(ManageTokensBottomSheetConfig.AddCustomToken(it))
|
||||
when (val portfolio = params.mode) {
|
||||
is ManageTokensMode.Wallet ->
|
||||
bottomSheetNavigation
|
||||
.activate(ManageTokensBottomSheetConfig.AddWalletCustomToken(portfolio.userWalletId))
|
||||
is ManageTokensMode.Account ->
|
||||
bottomSheetNavigation
|
||||
.activate(ManageTokensBottomSheetConfig.AddAccountCustomToken(portfolio.accountId))
|
||||
ManageTokensMode.None -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -308,8 +316,7 @@ internal class ManageTokensModel @Inject constructor(
|
|||
)
|
||||
analyticsEventHandler.send(event)
|
||||
|
||||
saveManagedTokensUseCase(
|
||||
userWalletId = requireNotNull(params.userWalletId),
|
||||
useCasesFacade.saveManagedTokensUseCase(
|
||||
currenciesToAdd = manageTokensListManager.currenciesToAdd.value,
|
||||
currenciesToRemove = manageTokensListManager.currenciesToRemove.value,
|
||||
).getOrElse {
|
||||
|
|
|
|||
|
|
@ -13,11 +13,10 @@ import com.tangem.core.ui.event.triggeredEvent
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.managetokens.SaveManagedTokensUseCase
|
||||
import com.tangem.domain.redux.OnboardingManageTokensAction
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase
|
||||
import com.tangem.features.managetokens.analytics.ManageTokensAnalyticEvent
|
||||
import com.tangem.features.managetokens.component.ManageTokensMode
|
||||
import com.tangem.features.managetokens.component.ManageTokensSource
|
||||
import com.tangem.features.managetokens.component.OnboardingManageTokensComponent
|
||||
import com.tangem.features.managetokens.entity.item.CurrencyItemUM
|
||||
|
|
@ -25,6 +24,7 @@ import com.tangem.features.managetokens.entity.managetokens.OnboardingManageToke
|
|||
import com.tangem.features.managetokens.impl.R
|
||||
import com.tangem.features.managetokens.utils.list.ChangedCurrencies
|
||||
import com.tangem.features.managetokens.utils.list.ManageTokensListManager
|
||||
import com.tangem.features.managetokens.utils.list.ManageTokensUseCasesFacade
|
||||
import com.tangem.pagination.BatchFetchResult
|
||||
import com.tangem.pagination.PaginationStatus
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -42,15 +42,22 @@ internal class OnboardingManageTokensModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val reduxStateHolder: ReduxStateHolder,
|
||||
private val saveManagedTokensUseCase: SaveManagedTokensUseCase,
|
||||
private val hasMissedDerivationsUseCase: HasMissedDerivationsUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
manageTokensListManagerFactory: ManageTokensListManager.Factory,
|
||||
manageTokensUseCasesFacadeFactory: ManageTokensUseCasesFacade.Factory,
|
||||
paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
||||
private val params: OnboardingManageTokensComponent.Params = paramsContainer.require()
|
||||
private val manageTokensListManager = manageTokensListManagerFactory.create()
|
||||
private val portfolio = ManageTokensMode.Wallet(params.userWalletId)
|
||||
private val useCasesFacade: ManageTokensUseCasesFacade = manageTokensUseCasesFacadeFactory
|
||||
.create(mode = portfolio)
|
||||
private val manageTokensListManager = manageTokensListManagerFactory.create(
|
||||
scope = modelScope,
|
||||
source = ManageTokensSource.ONBOARDING,
|
||||
useCasesFacade = useCasesFacade,
|
||||
mode = portfolio,
|
||||
)
|
||||
|
||||
val state: MutableStateFlow<OnboardingManageTokensUM> = MutableStateFlow(getInitialState())
|
||||
val returnToParentComponentFlow = MutableSharedFlow<Unit>()
|
||||
|
|
@ -73,10 +80,7 @@ internal class OnboardingManageTokensModel @Inject constructor(
|
|||
observeSearchQueryChanges()
|
||||
|
||||
modelScope.launch {
|
||||
manageTokensListManager.launchPagination(
|
||||
source = ManageTokensSource.ONBOARDING,
|
||||
userWalletId = params.userWalletId,
|
||||
)
|
||||
manageTokensListManager.launchPagination()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +123,7 @@ internal class OnboardingManageTokensModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
.sample(periodMillis = 1_000)
|
||||
.onEach { query -> manageTokensListManager.search(userWalletId = params.userWalletId, query = query) }
|
||||
.onEach { query -> manageTokensListManager.search(query = query) }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
|
|
@ -208,13 +212,11 @@ internal class OnboardingManageTokensModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
} else {
|
||||
val hasMissedDerivations = hasMissedDerivationsUseCase.invoke(
|
||||
userWalletId = params.userWalletId,
|
||||
networksWithDerivationPath = currenciesToAdd.values
|
||||
.flatten()
|
||||
.toSet()
|
||||
.associate { it.backendId to null },
|
||||
)
|
||||
val network = currenciesToAdd.values
|
||||
.flatten()
|
||||
.toSet()
|
||||
.associate { it.backendId to null }
|
||||
val hasMissedDerivations = useCasesFacade.hasMissedDerivationsUseCase(network = network)
|
||||
state.update { state ->
|
||||
state.copy(
|
||||
actionButtonConfig = OnboardingManageTokensUM.ActionButtonConfig.Continue(
|
||||
|
|
@ -231,7 +233,7 @@ internal class OnboardingManageTokensModel @Inject constructor(
|
|||
if (state.isInitialBatchLoading || state.isNextBatchLoading) return false
|
||||
|
||||
modelScope.launch {
|
||||
manageTokensListManager.loadMore(userWalletId = params.userWalletId, query = state.search.query)
|
||||
manageTokensListManager.loadMore(query = state.search.query)
|
||||
}
|
||||
|
||||
return true
|
||||
|
|
@ -255,8 +257,7 @@ internal class OnboardingManageTokensModel @Inject constructor(
|
|||
)
|
||||
analyticsEventHandler.send(event)
|
||||
|
||||
saveManagedTokensUseCase(
|
||||
userWalletId = requireNotNull(params.userWalletId),
|
||||
useCasesFacade.saveManagedTokensUseCase(
|
||||
currenciesToAdd = manageTokensListManager.currenciesToAdd.value,
|
||||
currenciesToRemove = manageTokensListManager.currenciesToRemove.value,
|
||||
).getOrElse {
|
||||
|
|
@ -281,8 +282,7 @@ internal class OnboardingManageTokensModel @Inject constructor(
|
|||
) {
|
||||
analyticsEventHandler.send(ManageTokensAnalyticEvent.ButtonLater)
|
||||
|
||||
saveManagedTokensUseCase(
|
||||
userWalletId = requireNotNull(params.userWalletId),
|
||||
useCasesFacade.saveManagedTokensUseCase(
|
||||
currenciesToAdd = manageTokensListManager.currenciesToAdd.value,
|
||||
currenciesToRemove = manageTokensListManager.currenciesToRemove.value,
|
||||
).getOrElse {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import com.tangem.core.ui.res.TangemThemePreview
|
|||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.component.AddCustomTokenComponent
|
||||
import com.tangem.features.managetokens.component.AddCustomTokenMode
|
||||
import com.tangem.features.managetokens.component.preview.PreviewAddCustomTokenComponent
|
||||
import com.tangem.features.managetokens.entity.customtoken.AddCustomTokenConfig
|
||||
import com.tangem.features.managetokens.entity.customtoken.AddCustomTokenUM
|
||||
|
|
@ -68,12 +69,13 @@ private fun Preview_AddCustomTokenBottomSheet(
|
|||
}
|
||||
|
||||
private class AddCustomTokenComponentPreviewProvider : PreviewParameterProvider<AddCustomTokenComponent> {
|
||||
private val mode: AddCustomTokenMode get() = AddCustomTokenMode.Wallet(UserWalletId(stringValue = "321"))
|
||||
override val values: Sequence<AddCustomTokenComponent>
|
||||
get() = sequenceOf(
|
||||
PreviewAddCustomTokenComponent(),
|
||||
PreviewAddCustomTokenComponent(
|
||||
initialState = AddCustomTokenConfig(
|
||||
userWalletId = UserWalletId(stringValue = "321"),
|
||||
mode = mode,
|
||||
step = AddCustomTokenConfig.Step.FORM,
|
||||
selectedNetwork = SelectedNetwork(
|
||||
id = Network.ID(value = "1", derivationPath = Network.DerivationPath.None),
|
||||
|
|
@ -85,7 +87,7 @@ private class AddCustomTokenComponentPreviewProvider : PreviewParameterProvider<
|
|||
),
|
||||
PreviewAddCustomTokenComponent(
|
||||
initialState = AddCustomTokenConfig(
|
||||
userWalletId = UserWalletId(stringValue = "321"),
|
||||
mode = mode,
|
||||
step = AddCustomTokenConfig.Step.NETWORK_SELECTOR,
|
||||
selectedNetwork = SelectedNetwork(
|
||||
id = Network.ID(value = "0", derivationPath = Network.DerivationPath.None),
|
||||
|
|
@ -97,7 +99,7 @@ private class AddCustomTokenComponentPreviewProvider : PreviewParameterProvider<
|
|||
),
|
||||
PreviewAddCustomTokenComponent(
|
||||
initialState = AddCustomTokenConfig(
|
||||
userWalletId = UserWalletId(stringValue = "321"),
|
||||
mode = mode,
|
||||
step = AddCustomTokenConfig.Step.DERIVATION_PATH_SELECTOR,
|
||||
selectedDerivationPath = SelectedDerivationPath(
|
||||
id = Network.ID(value = "0", derivationPath = Network.DerivationPath.None),
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import com.tangem.core.ui.res.TangemTheme
|
|||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.component.AddCustomTokenMode
|
||||
import com.tangem.features.managetokens.component.CustomTokenSelectorComponent
|
||||
import com.tangem.features.managetokens.component.preview.PreviewCustomTokenSelectorComponent
|
||||
import com.tangem.features.managetokens.entity.customtoken.CustomTokenSelectorUM
|
||||
|
|
@ -268,12 +269,13 @@ private class CustomTokenNetworkSelectorComponentPreviewProvider :
|
|||
PreviewParameterProvider<CustomTokenSelectorComponent> {
|
||||
|
||||
private val derivationPath = Network.DerivationPath.Card("m/44'/0'/0'/0/0")
|
||||
private val mode: AddCustomTokenMode get() = AddCustomTokenMode.Wallet(UserWalletId(stringValue = "321"))
|
||||
|
||||
override val values: Sequence<CustomTokenSelectorComponent>
|
||||
get() = sequenceOf(
|
||||
PreviewCustomTokenSelectorComponent(
|
||||
params = CustomTokenSelectorComponent.Params.DerivationPathSelector(
|
||||
userWalletId = UserWalletId(stringValue = "321"),
|
||||
mode = mode,
|
||||
selectedNetwork = SelectedNetwork(
|
||||
id = Network.ID(value = "0", derivationPath = derivationPath),
|
||||
name = "Ethereum",
|
||||
|
|
@ -291,7 +293,7 @@ private class CustomTokenNetworkSelectorComponentPreviewProvider :
|
|||
),
|
||||
PreviewCustomTokenSelectorComponent(
|
||||
params = CustomTokenSelectorComponent.Params.NetworkSelector(
|
||||
userWalletId = UserWalletId(stringValue = "321"),
|
||||
mode = mode,
|
||||
selectedNetwork = SelectedNetwork(
|
||||
id = Network.ID(value = "0", derivationPath = derivationPath),
|
||||
name = "Ethereum",
|
||||
|
|
|
|||
|
|
@ -1,31 +1,21 @@
|
|||
package com.tangem.features.managetokens.utils
|
||||
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.domain.managetokens.CheckIsCurrencyNotAddedUseCase
|
||||
import com.tangem.domain.managetokens.CreateCryptoCurrencyUseCase
|
||||
import com.tangem.domain.managetokens.FindTokenUseCase
|
||||
import com.tangem.domain.managetokens.ValidateTokenFormUseCase
|
||||
import com.tangem.domain.managetokens.model.AddCustomTokenForm
|
||||
import com.tangem.domain.managetokens.model.exceptoin.CustomTokenFormValidationException
|
||||
import com.tangem.domain.managetokens.model.exceptoin.FindTokenException
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.utils.list.CustomTokenFormUseCasesFacade
|
||||
import com.tangem.utils.coroutines.JobHolder
|
||||
import com.tangem.utils.coroutines.saveInAndJoin
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ModelScoped
|
||||
internal class CustomCurrencyValidator @Inject constructor(
|
||||
private val validateTokenFormUseCase: ValidateTokenFormUseCase,
|
||||
private val createCryptoCurrencyUseCase: CreateCryptoCurrencyUseCase,
|
||||
private val findTokenUseCase: FindTokenUseCase,
|
||||
private val checkIsCurrencyNotAddedUseCase: CheckIsCurrencyNotAddedUseCase,
|
||||
internal class CustomCurrencyValidator(
|
||||
private val useCasesFacade: CustomTokenFormUseCasesFacade,
|
||||
) {
|
||||
|
||||
private val validateFormJobHolder = JobHolder()
|
||||
|
|
@ -45,14 +35,13 @@ internal class CustomCurrencyValidator @Inject constructor(
|
|||
}
|
||||
|
||||
suspend fun validateForm(
|
||||
userWalletId: UserWalletId,
|
||||
networkId: Network.ID,
|
||||
derivationPath: Network.DerivationPath,
|
||||
formValues: AddCustomTokenForm.Raw,
|
||||
) = coroutineScope {
|
||||
updateStatus(Status.Validating)
|
||||
|
||||
val result = validateTokenFormUseCase(
|
||||
val result = useCasesFacade.validateTokenFormUseCase(
|
||||
networkId = networkId,
|
||||
formValues = formValues,
|
||||
)
|
||||
|
|
@ -73,20 +62,19 @@ internal class CustomCurrencyValidator @Inject constructor(
|
|||
launch {
|
||||
when (validatedForm) {
|
||||
is AddCustomTokenForm.Validated.All -> {
|
||||
findOrCreateCurrency(userWalletId, networkId, derivationPath, validatedForm)
|
||||
findOrCreateCurrency(networkId, derivationPath, validatedForm)
|
||||
}
|
||||
is AddCustomTokenForm.Validated.ContractAddressOnly -> {
|
||||
findToken(userWalletId, networkId, derivationPath, validatedForm)
|
||||
findToken(networkId, derivationPath, validatedForm)
|
||||
}
|
||||
is AddCustomTokenForm.Validated.Empty -> {
|
||||
createCurrency(userWalletId, networkId, derivationPath, validatedForm = null)
|
||||
createCurrency(networkId, derivationPath, validatedForm = null)
|
||||
}
|
||||
}
|
||||
}.saveInAndJoin(validateFormJobHolder)
|
||||
}
|
||||
|
||||
private suspend fun findOrCreateCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
networkId: Network.ID,
|
||||
derivationPath: Network.DerivationPath,
|
||||
validatedForm: AddCustomTokenForm.Validated.All,
|
||||
|
|
@ -96,14 +84,13 @@ internal class CustomCurrencyValidator @Inject constructor(
|
|||
currentState.prevFoundOrCreatedCurrency.contractAddress == validatedForm.contractAddress
|
||||
) {
|
||||
// No need to search for token again if contract address is not changed
|
||||
createCurrency(userWalletId, networkId, derivationPath, validatedForm)
|
||||
createCurrency(networkId, derivationPath, validatedForm)
|
||||
return
|
||||
}
|
||||
|
||||
updateStatus(Status.SearchingToken)
|
||||
|
||||
val foundToken = findTokenUseCase(
|
||||
userWalletId = userWalletId,
|
||||
val foundToken = useCasesFacade.findTokenUseCase(
|
||||
contractAddress = validatedForm.contractAddress,
|
||||
networkId = networkId,
|
||||
derivationPath = derivationPath,
|
||||
|
|
@ -121,22 +108,20 @@ internal class CustomCurrencyValidator @Inject constructor(
|
|||
}
|
||||
|
||||
if (foundToken != null) {
|
||||
updateStateToValidated(userWalletId, foundToken, fillForm = true, isCustom = false)
|
||||
updateStateToValidated(foundToken, fillForm = true, isCustom = false)
|
||||
} else {
|
||||
createCurrency(userWalletId, networkId, derivationPath, validatedForm)
|
||||
createCurrency(networkId, derivationPath, validatedForm)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun findToken(
|
||||
userWalletId: UserWalletId,
|
||||
networkId: Network.ID,
|
||||
derivationPath: Network.DerivationPath,
|
||||
validatedForm: AddCustomTokenForm.Validated.ContractAddressOnly,
|
||||
) {
|
||||
updateStatus(Status.SearchingToken)
|
||||
|
||||
val token = findTokenUseCase(
|
||||
userWalletId = userWalletId,
|
||||
val token = useCasesFacade.findTokenUseCase(
|
||||
contractAddress = validatedForm.contractAddress,
|
||||
networkId = networkId,
|
||||
derivationPath = derivationPath,
|
||||
|
|
@ -155,17 +140,15 @@ internal class CustomCurrencyValidator @Inject constructor(
|
|||
return
|
||||
}
|
||||
|
||||
updateStateToValidated(userWalletId, token, fillForm = true, isCustom = false)
|
||||
updateStateToValidated(token, fillForm = true, isCustom = false)
|
||||
}
|
||||
|
||||
private suspend fun createCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
networkId: Network.ID,
|
||||
derivationPath: Network.DerivationPath,
|
||||
validatedForm: AddCustomTokenForm.Validated.All?,
|
||||
) {
|
||||
val currency = createCryptoCurrencyUseCase(
|
||||
userWalletId = userWalletId,
|
||||
val currency = useCasesFacade.createCryptoCurrencyUseCase(
|
||||
networkId = networkId,
|
||||
derivationPath = derivationPath,
|
||||
formValues = validatedForm,
|
||||
|
|
@ -175,20 +158,14 @@ internal class CustomCurrencyValidator @Inject constructor(
|
|||
return
|
||||
}
|
||||
|
||||
updateStateToValidated(userWalletId, currency, fillForm = false, isCustom = validatedForm != null)
|
||||
updateStateToValidated(currency, fillForm = false, isCustom = validatedForm != null)
|
||||
}
|
||||
|
||||
private suspend fun updateStateToValidated(
|
||||
userWalletId: UserWalletId,
|
||||
currency: CryptoCurrency,
|
||||
fillForm: Boolean,
|
||||
isCustom: Boolean,
|
||||
) {
|
||||
private suspend fun updateStateToValidated(currency: CryptoCurrency, fillForm: Boolean, isCustom: Boolean) {
|
||||
val currentStatus = state.value.status
|
||||
if (currentStatus is Status.Validated && currentStatus.currency == currency) return
|
||||
|
||||
val isNotAdded = checkIsCurrencyNotAddedUseCase(
|
||||
userWalletId = userWalletId,
|
||||
val isNotAdded = useCasesFacade.checkIsCurrencyNotAddedUseCase(
|
||||
networkId = currency.network.id,
|
||||
derivationPath = currency.network.derivationPath,
|
||||
contractAddress = when (currency) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
package com.tangem.features.managetokens.utils.list
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.NonEmptyList
|
||||
import com.tangem.domain.managetokens.CheckIsCurrencyNotAddedUseCase
|
||||
import com.tangem.domain.managetokens.CreateCryptoCurrencyUseCase
|
||||
import com.tangem.domain.managetokens.FindTokenUseCase
|
||||
import com.tangem.domain.managetokens.ValidateTokenFormUseCase
|
||||
import com.tangem.domain.managetokens.model.AddCustomTokenForm
|
||||
import com.tangem.domain.managetokens.model.exceptoin.CustomTokenFormValidationException
|
||||
import com.tangem.domain.managetokens.model.exceptoin.FindTokenException
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.wallets.usecase.BackendId
|
||||
import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase
|
||||
import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase
|
||||
import com.tangem.features.managetokens.component.AddCustomTokenMode
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class CustomTokenFormUseCasesFacade @AssistedInject constructor(
|
||||
private val hasMissedDerivationsUseCase: HasMissedDerivationsUseCase,
|
||||
private val addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase,
|
||||
private val derivePublicKeysUseCase: DerivePublicKeysUseCase,
|
||||
private val validateTokenFormUseCase: ValidateTokenFormUseCase,
|
||||
private val createCryptoCurrencyUseCase: CreateCryptoCurrencyUseCase,
|
||||
private val findTokenUseCase: FindTokenUseCase,
|
||||
private val checkIsCurrencyNotAddedUseCase: CheckIsCurrencyNotAddedUseCase,
|
||||
@Assisted private val mode: AddCustomTokenMode,
|
||||
) {
|
||||
|
||||
suspend fun hasMissedDerivationsUseCase(networksWithDerivationPath: Map<BackendId, String?>): Boolean =
|
||||
when (mode) {
|
||||
is AddCustomTokenMode.Account -> TODO("Account")
|
||||
is AddCustomTokenMode.Wallet -> hasMissedDerivationsUseCase.invoke(
|
||||
userWalletId = mode.userWalletId,
|
||||
networksWithDerivationPath = networksWithDerivationPath,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun addCryptoCurrenciesUseCase(currency: CryptoCurrency): Either<Throwable, Unit> = when (mode) {
|
||||
is AddCustomTokenMode.Account -> TODO("Account")
|
||||
is AddCustomTokenMode.Wallet -> addCryptoCurrenciesUseCase.invoke(
|
||||
userWalletId = mode.userWalletId,
|
||||
currency = currency,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun derivePublicKeysUseCase(currencies: List<CryptoCurrency>): Either<Throwable, Unit> = when (mode) {
|
||||
is AddCustomTokenMode.Account -> TODO("Account")
|
||||
is AddCustomTokenMode.Wallet -> derivePublicKeysUseCase.invoke(
|
||||
userWalletId = mode.userWalletId,
|
||||
currencies = currencies,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun checkIsCurrencyNotAddedUseCase(
|
||||
networkId: Network.ID,
|
||||
derivationPath: Network.DerivationPath,
|
||||
contractAddress: String?,
|
||||
): Either<Throwable, Boolean> = when (mode) {
|
||||
is AddCustomTokenMode.Account -> TODO("Account")
|
||||
is AddCustomTokenMode.Wallet -> checkIsCurrencyNotAddedUseCase.invoke(
|
||||
userWalletId = mode.userWalletId,
|
||||
networkId = networkId,
|
||||
derivationPath = derivationPath,
|
||||
contractAddress = contractAddress,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun createCryptoCurrencyUseCase(
|
||||
networkId: Network.ID,
|
||||
derivationPath: Network.DerivationPath,
|
||||
formValues: AddCustomTokenForm.Validated.All?,
|
||||
): Either<Throwable, CryptoCurrency> = when (mode) {
|
||||
is AddCustomTokenMode.Account -> TODO("Account")
|
||||
is AddCustomTokenMode.Wallet -> createCryptoCurrencyUseCase.invoke(
|
||||
userWalletId = mode.userWalletId,
|
||||
networkId = networkId,
|
||||
derivationPath = derivationPath,
|
||||
formValues = formValues,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun findTokenUseCase(
|
||||
contractAddress: String,
|
||||
networkId: Network.ID,
|
||||
derivationPath: Network.DerivationPath,
|
||||
): Either<FindTokenException, CryptoCurrency.Token> = when (mode) {
|
||||
is AddCustomTokenMode.Account -> TODO("Account")
|
||||
is AddCustomTokenMode.Wallet -> findTokenUseCase.invoke(
|
||||
userWalletId = mode.userWalletId,
|
||||
contractAddress = contractAddress,
|
||||
networkId = networkId,
|
||||
derivationPath = derivationPath,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun validateTokenFormUseCase(
|
||||
networkId: Network.ID,
|
||||
formValues: AddCustomTokenForm.Raw,
|
||||
): Either<NonEmptyList<CustomTokenFormValidationException>, AddCustomTokenForm.Validated> = when (mode) {
|
||||
is AddCustomTokenMode.Account -> TODO("Account")
|
||||
is AddCustomTokenMode.Wallet -> validateTokenFormUseCase.invoke(
|
||||
networkId = networkId,
|
||||
formValues = formValues,
|
||||
)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(mode: AddCustomTokenMode): CustomTokenFormUseCasesFacade
|
||||
}
|
||||
}
|
||||
|
|
@ -9,13 +9,14 @@ import com.tangem.core.ui.extensions.resourceReference
|
|||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.core.ui.message.EventMessageAction
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.managetokens.*
|
||||
import com.tangem.domain.managetokens.model.*
|
||||
import com.tangem.domain.managetokens.model.CurrencyUnsupportedState
|
||||
import com.tangem.domain.managetokens.model.ManageTokensListBatchingContext
|
||||
import com.tangem.domain.managetokens.model.ManageTokensUpdateAction
|
||||
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.analytics.ManageTokensAnalyticEvent
|
||||
import com.tangem.features.managetokens.component.ManageTokensMode
|
||||
import com.tangem.features.managetokens.component.ManageTokensSource
|
||||
import com.tangem.features.managetokens.entity.item.CurrencyItemUM
|
||||
import com.tangem.features.managetokens.impl.R
|
||||
|
|
@ -24,7 +25,6 @@ import com.tangem.pagination.Batch
|
|||
import com.tangem.pagination.BatchAction
|
||||
import com.tangem.pagination.BatchListState
|
||||
import com.tangem.pagination.PaginationStatus
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.JobHolder
|
||||
import com.tangem.utils.coroutines.saveIn
|
||||
|
|
@ -42,37 +42,36 @@ import timber.log.Timber
|
|||
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
internal class ManageTokensListManager @AssistedInject constructor(
|
||||
private val getManagedTokensUseCase: GetManagedTokensUseCase,
|
||||
private val getDistinctManagedTokensUseCase: GetDistinctManagedCurrenciesUseCase,
|
||||
private val checkHasLinkedTokensUseCase: CheckHasLinkedTokensUseCase,
|
||||
private val removeCustomCurrencyUseCase: RemoveCustomManagedCryptoCurrencyUseCase,
|
||||
private val checkCurrencyUnsupportedUseCase: CheckCurrencyUnsupportedUseCase,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val clipboardManager: ClipboardManager,
|
||||
manageTokensWarningDelegateFactory: ManageTokensWarningDelegate.Factory,
|
||||
@Assisted private val useCasesFacade: ManageTokensUseCasesFacade,
|
||||
@Assisted private val source: ManageTokensSource,
|
||||
@Assisted private val mode: ManageTokensMode,
|
||||
@Assisted private val scope: CoroutineScope,
|
||||
@Assisted private val onCurrencySelect: (ManagedCryptoCurrency.Token) -> Unit = {},
|
||||
) : ManageTokensUiActions {
|
||||
|
||||
private lateinit var scope: CoroutineScope
|
||||
private lateinit var source: ManageTokensSource
|
||||
|
||||
private val jobHolder = JobHolder()
|
||||
private val actionsFlow: MutableSharedFlow<ManageTokensBatchAction> = MutableSharedFlow(
|
||||
replay = 1,
|
||||
onBufferOverflow = BufferOverflow.DROP_OLDEST,
|
||||
)
|
||||
|
||||
private val state: MutableStateFlow<ManageTokensListState> = MutableStateFlow(ManageTokensListState())
|
||||
private val state: MutableStateFlow<ManageTokensListState> =
|
||||
MutableStateFlow(ManageTokensListState(mode = mode))
|
||||
|
||||
private val manageTokensWarningDelegate: ManageTokensWarningDelegate = manageTokensWarningDelegateFactory
|
||||
.create(mode, source, this)
|
||||
private val changedCurrenciesManager = ChangedCurrenciesManager()
|
||||
private val uiManager = ManageTokensUiManager(
|
||||
state = state,
|
||||
messageSender = messageSender,
|
||||
manageTokensWarningDelegate = manageTokensWarningDelegate,
|
||||
dispatchers = dispatchers,
|
||||
actions = this,
|
||||
scopeProvider = Provider { scope },
|
||||
sourceProvider = Provider { source },
|
||||
scope = scope,
|
||||
)
|
||||
|
||||
val currenciesToAdd: StateFlow<ChangedCurrencies> = changedCurrenciesManager.currenciesToAdd.asStateFlow()
|
||||
|
|
@ -84,62 +83,61 @@ internal class ManageTokensListManager @AssistedInject constructor(
|
|||
.distinctUntilChanged()
|
||||
val uiItems: Flow<ImmutableList<CurrencyItemUM>> = uiManager.items
|
||||
|
||||
suspend fun launchPagination(source: ManageTokensSource, userWalletId: UserWalletId?) = coroutineScope {
|
||||
scope = this
|
||||
this@ManageTokensListManager.source = source
|
||||
|
||||
val batchFlow = getManagedTokensUseCase(
|
||||
suspend fun launchPagination() = coroutineScope {
|
||||
val loadUserTokensFromRemote = when (mode) {
|
||||
is ManageTokensMode.Wallet -> source == ManageTokensSource.ONBOARDING
|
||||
is ManageTokensMode.Account,
|
||||
ManageTokensMode.None,
|
||||
-> false
|
||||
}
|
||||
val batchFlow = useCasesFacade.getManagedTokensUseCase(
|
||||
context = ManageTokensListBatchingContext(
|
||||
actionsFlow = actionsFlow,
|
||||
coroutineScope = this,
|
||||
),
|
||||
// only for onboarding case, change carefully and check repository implementation
|
||||
loadUserTokensFromRemote = userWalletId != null && source == ManageTokensSource.ONBOARDING,
|
||||
loadUserTokensFromRemote = loadUserTokensFromRemote,
|
||||
)
|
||||
|
||||
batchFlow.state
|
||||
.onEach { state -> updateState(state, userWalletId) }
|
||||
.onEach { state -> updateState(state) }
|
||||
.flowOn(dispatchers.default)
|
||||
.launchIn(scope = this)
|
||||
.saveIn(jobHolder)
|
||||
|
||||
// Initial load
|
||||
reload(userWalletId)
|
||||
reload()
|
||||
}
|
||||
|
||||
suspend fun reload(userWalletId: UserWalletId?) {
|
||||
state.value = ManageTokensListState()
|
||||
suspend fun reload() {
|
||||
state.value = ManageTokensListState(mode = mode)
|
||||
actionsFlow.emit(
|
||||
BatchAction.Reload(
|
||||
requestParams = ManageTokensListConfig(userWalletId, searchText = null),
|
||||
requestParams = useCasesFacade.manageTokensListConfig(searchText = null),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun loadMore(userWalletId: UserWalletId?, query: String) {
|
||||
suspend fun loadMore(query: String) {
|
||||
actionsFlow.emit(
|
||||
BatchAction.LoadMore(
|
||||
requestParams = ManageTokensListConfig(userWalletId, query),
|
||||
requestParams = useCasesFacade.manageTokensListConfig(query),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun search(userWalletId: UserWalletId?, query: String) {
|
||||
state.value = ManageTokensListState(searchQuery = query)
|
||||
suspend fun search(query: String) {
|
||||
state.value = ManageTokensListState(mode = mode, searchQuery = query)
|
||||
actionsFlow.emit(
|
||||
BatchAction.Reload(
|
||||
requestParams = ManageTokensListConfig(
|
||||
userWalletId = userWalletId,
|
||||
requestParams = useCasesFacade.manageTokensListConfig(
|
||||
searchText = query,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateState(
|
||||
batchListState: BatchListState<Int, List<ManagedCryptoCurrency>>,
|
||||
userWalletId: UserWalletId?,
|
||||
) {
|
||||
private fun updateState(batchListState: BatchListState<Int, List<ManagedCryptoCurrency>>) {
|
||||
state.update { state ->
|
||||
state.copy(
|
||||
status = batchListState.status,
|
||||
|
|
@ -154,7 +152,6 @@ internal class ManageTokensListManager @AssistedInject constructor(
|
|||
) {
|
||||
state.update { state ->
|
||||
state.copy(
|
||||
userWalletId = userWalletId,
|
||||
currencyBatches = emptyList(),
|
||||
uiBatches = listOf(
|
||||
Batch(
|
||||
|
|
@ -170,7 +167,7 @@ internal class ManageTokensListManager @AssistedInject constructor(
|
|||
|
||||
scope.launch {
|
||||
state.update { state ->
|
||||
val newBatches = getDistinctManagedTokensUseCase(batchListState.data)
|
||||
val newBatches = useCasesFacade.getDistinctManagedTokensUseCase(batchListState.data)
|
||||
val currentBatches = state.currencyBatches
|
||||
|
||||
// Distinct until changed
|
||||
|
|
@ -181,9 +178,13 @@ internal class ManageTokensListManager @AssistedInject constructor(
|
|||
return@launch
|
||||
}
|
||||
|
||||
val canEditItems = userWalletId != null
|
||||
val canEditItems = when (state.mode) {
|
||||
is ManageTokensMode.Account,
|
||||
is ManageTokensMode.Wallet,
|
||||
-> true
|
||||
ManageTokensMode.None -> false
|
||||
}
|
||||
state.copy(
|
||||
userWalletId = userWalletId,
|
||||
currencyBatches = newBatches,
|
||||
uiBatches = uiManager.createOrUpdateUiBatches(newBatches, canEditItems),
|
||||
canEditItems = canEditItems,
|
||||
|
|
@ -216,10 +217,10 @@ internal class ManageTokensListManager @AssistedInject constructor(
|
|||
sendSelectCurrencyAnalyticsEvent(currency, isSelected = false)
|
||||
}
|
||||
|
||||
override fun removeCustomCurrency(userWalletId: UserWalletId, currency: ManagedCryptoCurrency.Custom) {
|
||||
override fun removeCustomCurrency(currency: ManagedCryptoCurrency.Custom) {
|
||||
scope.launch {
|
||||
removeCustomCurrencyUseCase.invoke(userWalletId, currency)
|
||||
.onRight { reload(userWalletId) }
|
||||
useCasesFacade.removeCustomCurrencyUseCase(currency)
|
||||
.onRight { reload() }
|
||||
.onLeft { Timber.e(it) }
|
||||
}
|
||||
}
|
||||
|
|
@ -258,9 +259,8 @@ internal class ManageTokensListManager @AssistedInject constructor(
|
|||
actionsFlow.tryEmit(action)
|
||||
}
|
||||
|
||||
override suspend fun checkHasLinkedTokens(userWalletId: UserWalletId, network: Network): Boolean {
|
||||
return checkHasLinkedTokensUseCase(
|
||||
userWalletId = userWalletId,
|
||||
override suspend fun checkHasLinkedTokens(network: Network): Boolean {
|
||||
return useCasesFacade.checkHasLinkedTokensUseCase(
|
||||
network = network,
|
||||
tempAddedTokens = changedCurrenciesManager.currenciesToAdd.value,
|
||||
tempRemovedTokens = changedCurrenciesManager.currenciesToRemove.value,
|
||||
|
|
@ -269,7 +269,7 @@ internal class ManageTokensListManager @AssistedInject constructor(
|
|||
it,
|
||||
"""
|
||||
Failed to check linked tokens
|
||||
|- User wallet ID: $userWalletId
|
||||
|- Mode: $mode
|
||||
|- Network ID: ${network.id}
|
||||
""".trimIndent(),
|
||||
)
|
||||
|
|
@ -286,18 +286,16 @@ internal class ManageTokensListManager @AssistedInject constructor(
|
|||
}
|
||||
|
||||
override suspend fun checkCurrencyUnsupportedState(
|
||||
userWalletId: UserWalletId,
|
||||
sourceNetwork: ManagedCryptoCurrency.SourceNetwork,
|
||||
): CurrencyUnsupportedState? {
|
||||
return checkCurrencyUnsupportedUseCase(
|
||||
userWalletId = userWalletId,
|
||||
return useCasesFacade.checkCurrencyUnsupportedUseCase(
|
||||
sourceNetwork = sourceNetwork,
|
||||
).getOrElse {
|
||||
Timber.e(
|
||||
it,
|
||||
"""
|
||||
Failed to check currency unsupported state
|
||||
|- User wallet ID: $userWalletId
|
||||
|- Mode: $mode
|
||||
|- Source Network: $sourceNetwork
|
||||
""".trimIndent(),
|
||||
)
|
||||
|
|
@ -359,8 +357,7 @@ internal class ManageTokensListManager @AssistedInject constructor(
|
|||
if (currency !is ManagedCryptoCurrency.Token) return@launch
|
||||
|
||||
if (isSelected) {
|
||||
val userWalletId = state.value.userWalletId
|
||||
val unsupportedState = userWalletId?.let { checkCurrencyUnsupportedState(it, source) }
|
||||
val unsupportedState = checkCurrencyUnsupportedState(source)
|
||||
if (unsupportedState != null) {
|
||||
showUnsupportedWarning(unsupportedState)
|
||||
} else {
|
||||
|
|
@ -368,7 +365,7 @@ internal class ManageTokensListManager @AssistedInject constructor(
|
|||
}
|
||||
} else {
|
||||
if (checkNeedToShowRemoveNetworkWarning(currency, source.network)) {
|
||||
showRemoveNetworkWarning(
|
||||
manageTokensWarningDelegate.showRemoveNetworkWarning(
|
||||
currency = currency,
|
||||
network = source.network,
|
||||
isCoin = source is ManagedCryptoCurrency.SourceNetwork.Main,
|
||||
|
|
@ -404,67 +401,6 @@ internal class ManageTokensListManager @AssistedInject constructor(
|
|||
messageSender.send(message)
|
||||
}
|
||||
|
||||
private suspend fun showRemoveNetworkWarning(
|
||||
currency: ManagedCryptoCurrency,
|
||||
network: Network,
|
||||
isCoin: Boolean,
|
||||
onConfirm: () -> Unit,
|
||||
) {
|
||||
val userWalletId = state.value.userWalletId
|
||||
val hasLinkedTokens = if (userWalletId == null || !isCoin) {
|
||||
false
|
||||
} else {
|
||||
checkHasLinkedTokens(userWalletId, network)
|
||||
}
|
||||
val canHideWithoutConfirming = source == ManageTokensSource.ONBOARDING
|
||||
|
||||
if (hasLinkedTokens) {
|
||||
showLinkedTokensWarning(currency, network)
|
||||
} else if (canHideWithoutConfirming) {
|
||||
onConfirm()
|
||||
} else {
|
||||
showHideTokenWarning(currency, onConfirm)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showLinkedTokensWarning(currency: ManagedCryptoCurrency, network: Network) {
|
||||
val message = DialogMessage(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_title,
|
||||
formatArgs = wrappedList(currency.name),
|
||||
),
|
||||
message = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_message,
|
||||
formatArgs = wrappedList(
|
||||
currency.name,
|
||||
currency.symbol,
|
||||
network.name,
|
||||
),
|
||||
),
|
||||
)
|
||||
messageSender.send(message)
|
||||
}
|
||||
|
||||
private fun showHideTokenWarning(currency: ManagedCryptoCurrency, onConfirm: () -> Unit) {
|
||||
val message = DialogMessage(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_hide_alert_title,
|
||||
formatArgs = wrappedList(currency.name),
|
||||
),
|
||||
message = resourceReference(R.string.token_details_hide_alert_message),
|
||||
firstActionBuilder = {
|
||||
EventMessageAction(
|
||||
title = resourceReference(R.string.token_details_hide_alert_hide),
|
||||
warning = true,
|
||||
onClick = onConfirm,
|
||||
)
|
||||
},
|
||||
secondActionBuilder = { cancelAction() },
|
||||
)
|
||||
|
||||
messageSender.send(message)
|
||||
}
|
||||
|
||||
private fun Batch<Int, List<ManagedCryptoCurrency>>.currencyIndexById(id: ManagedCryptoCurrency.ID): Int {
|
||||
return data
|
||||
.indexOfFirst { it.id == id }
|
||||
|
|
@ -474,6 +410,12 @@ internal class ManageTokensListManager @AssistedInject constructor(
|
|||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(onCurrencySelect: (ManagedCryptoCurrency.Token) -> Unit = {}): ManageTokensListManager
|
||||
fun create(
|
||||
scope: CoroutineScope,
|
||||
mode: ManageTokensMode,
|
||||
source: ManageTokensSource,
|
||||
useCasesFacade: ManageTokensUseCasesFacade,
|
||||
onCurrencySelect: (ManagedCryptoCurrency.Token) -> Unit = {},
|
||||
): ManageTokensListManager
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ package com.tangem.features.managetokens.utils.list
|
|||
import com.tangem.domain.managetokens.model.ManageTokensListConfig
|
||||
import com.tangem.domain.managetokens.model.ManageTokensUpdateAction
|
||||
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.managetokens.component.ManageTokensMode
|
||||
import com.tangem.features.managetokens.entity.item.CurrencyItemUM
|
||||
import com.tangem.pagination.Batch
|
||||
import com.tangem.pagination.BatchAction
|
||||
|
|
@ -13,7 +13,7 @@ internal typealias ManageTokensBatchAction = BatchAction<Int, ManageTokensListCo
|
|||
|
||||
internal data class ManageTokensListState(
|
||||
val status: PaginationStatus<*> = PaginationStatus.None,
|
||||
val userWalletId: UserWalletId? = null,
|
||||
val mode: ManageTokensMode,
|
||||
val uiBatches: List<Batch<Int, List<CurrencyItemUM>>> = mutableListOf(),
|
||||
val currencyBatches: List<Batch<Int, List<ManagedCryptoCurrency>>> = mutableListOf(),
|
||||
val canEditItems: Boolean = true,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.tangem.features.managetokens.utils.list
|
|||
import com.tangem.domain.managetokens.model.CurrencyUnsupportedState
|
||||
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
internal interface ManageTokensUiActions {
|
||||
|
||||
|
|
@ -13,14 +12,13 @@ internal interface ManageTokensUiActions {
|
|||
|
||||
fun removeCurrency(batchKey: Int, currency: ManagedCryptoCurrency.Token, network: Network)
|
||||
|
||||
fun removeCustomCurrency(userWalletId: UserWalletId, currency: ManagedCryptoCurrency.Custom)
|
||||
fun removeCustomCurrency(currency: ManagedCryptoCurrency.Custom)
|
||||
|
||||
fun checkNeedToShowRemoveNetworkWarning(currency: ManagedCryptoCurrency.Token, network: Network): Boolean
|
||||
|
||||
suspend fun checkHasLinkedTokens(userWalletId: UserWalletId, network: Network): Boolean
|
||||
suspend fun checkHasLinkedTokens(network: Network): Boolean
|
||||
|
||||
suspend fun checkCurrencyUnsupportedState(
|
||||
userWalletId: UserWalletId,
|
||||
sourceNetwork: ManagedCryptoCurrency.SourceNetwork,
|
||||
): CurrencyUnsupportedState?
|
||||
}
|
||||
|
|
@ -1,19 +1,10 @@
|
|||
package com.tangem.features.managetokens.utils.list
|
||||
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.core.ui.message.EventMessageAction
|
||||
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.features.managetokens.component.ManageTokensSource
|
||||
import com.tangem.features.managetokens.entity.item.CurrencyItemUM
|
||||
import com.tangem.features.managetokens.impl.R
|
||||
import com.tangem.features.managetokens.utils.mapper.toUiModel
|
||||
import com.tangem.features.managetokens.utils.ui.update
|
||||
import com.tangem.pagination.Batch
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.extensions.addOrReplace
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
|
@ -29,19 +20,12 @@ import kotlinx.coroutines.launch
|
|||
@Suppress("LongParameterList")
|
||||
internal class ManageTokensUiManager(
|
||||
private val state: MutableStateFlow<ManageTokensListState>,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val scopeProvider: Provider<CoroutineScope>,
|
||||
private val sourceProvider: Provider<ManageTokensSource>,
|
||||
private val scope: CoroutineScope,
|
||||
private val actions: ManageTokensUiActions,
|
||||
private val manageTokensWarningDelegate: ManageTokensWarningDelegate,
|
||||
) {
|
||||
|
||||
private val scope: CoroutineScope
|
||||
get() = scopeProvider()
|
||||
|
||||
private val source: ManageTokensSource
|
||||
get() = sourceProvider()
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val items: Flow<ImmutableList<CurrencyItemUM>> = state
|
||||
.mapLatest { state ->
|
||||
|
|
@ -109,75 +93,11 @@ internal class ManageTokensUiManager(
|
|||
}
|
||||
|
||||
private fun removeCustomCurrency(currency: ManagedCryptoCurrency.Custom) = scope.launch(dispatchers.default) {
|
||||
showRemoveNetworkWarning(
|
||||
manageTokensWarningDelegate.showRemoveNetworkWarning(
|
||||
currency = currency,
|
||||
network = currency.network,
|
||||
isCoin = currency is ManagedCryptoCurrency.Custom.Coin,
|
||||
onConfirm = {
|
||||
val userWalletId = requireNotNull(state.value.userWalletId) { "UserWalletId is null. Can not remove" }
|
||||
actions.removeCustomCurrency(userWalletId = userWalletId, currency = currency)
|
||||
},
|
||||
onConfirm = { actions.removeCustomCurrency(currency = currency) },
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun showRemoveNetworkWarning(
|
||||
currency: ManagedCryptoCurrency,
|
||||
network: Network,
|
||||
isCoin: Boolean,
|
||||
onConfirm: () -> Unit,
|
||||
) {
|
||||
val userWalletId = state.value.userWalletId
|
||||
val hasLinkedTokens = if (userWalletId == null || !isCoin) {
|
||||
false
|
||||
} else {
|
||||
actions.checkHasLinkedTokens(userWalletId, network)
|
||||
}
|
||||
val canHideWithoutConfirming = source == ManageTokensSource.ONBOARDING
|
||||
|
||||
if (hasLinkedTokens) {
|
||||
showLinkedTokensWarning(currency, network)
|
||||
} else if (canHideWithoutConfirming) {
|
||||
onConfirm()
|
||||
} else {
|
||||
showHideTokenWarning(currency, onConfirm)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showLinkedTokensWarning(currency: ManagedCryptoCurrency, network: Network) {
|
||||
val message = DialogMessage(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_title,
|
||||
formatArgs = wrappedList(currency.name),
|
||||
),
|
||||
message = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_message,
|
||||
formatArgs = wrappedList(
|
||||
currency.name,
|
||||
currency.symbol,
|
||||
network.name,
|
||||
),
|
||||
),
|
||||
)
|
||||
messageSender.send(message)
|
||||
}
|
||||
|
||||
private fun showHideTokenWarning(currency: ManagedCryptoCurrency, onConfirm: () -> Unit) {
|
||||
val message = DialogMessage(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_hide_alert_title,
|
||||
formatArgs = wrappedList(currency.name),
|
||||
),
|
||||
message = resourceReference(R.string.token_details_hide_alert_message),
|
||||
firstActionBuilder = {
|
||||
EventMessageAction(
|
||||
title = resourceReference(R.string.token_details_hide_alert_hide),
|
||||
warning = true,
|
||||
onClick = onConfirm,
|
||||
)
|
||||
},
|
||||
secondActionBuilder = { cancelAction() },
|
||||
)
|
||||
|
||||
messageSender.send(message)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
package com.tangem.features.managetokens.utils.list
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.left
|
||||
import com.tangem.domain.managetokens.*
|
||||
import com.tangem.domain.managetokens.model.CurrencyUnsupportedState
|
||||
import com.tangem.domain.managetokens.model.ManageTokensListConfig
|
||||
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase
|
||||
import com.tangem.features.managetokens.component.ManageTokensMode
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class ManageTokensUseCasesFacade @AssistedInject constructor(
|
||||
val getManagedTokensUseCase: GetManagedTokensUseCase,
|
||||
val getDistinctManagedTokensUseCase: GetDistinctManagedCurrenciesUseCase,
|
||||
private val checkHasLinkedTokensUseCase: CheckHasLinkedTokensUseCase,
|
||||
private val removeCustomCurrencyUseCase: RemoveCustomManagedCryptoCurrencyUseCase,
|
||||
private val checkCurrencyUnsupportedUseCase: CheckCurrencyUnsupportedUseCase,
|
||||
private val hasMissedDerivationsUseCase: HasMissedDerivationsUseCase,
|
||||
private val saveManagedTokensUseCase: SaveManagedTokensUseCase,
|
||||
@Assisted private val mode: ManageTokensMode,
|
||||
) {
|
||||
|
||||
private val nonePortfolioError: IllegalStateException
|
||||
get() = IllegalStateException("Unsupported")
|
||||
|
||||
fun manageTokensListConfig(searchText: String?): ManageTokensListConfig {
|
||||
val userWalletId: UserWalletId? = when (mode) {
|
||||
is ManageTokensMode.Account -> TODO("Account")
|
||||
ManageTokensMode.None -> null
|
||||
is ManageTokensMode.Wallet -> mode.userWalletId
|
||||
}
|
||||
return ManageTokensListConfig(userWalletId, searchText)
|
||||
}
|
||||
|
||||
suspend fun removeCustomCurrencyUseCase(customCurrency: ManagedCryptoCurrency.Custom): Either<Throwable, Unit> {
|
||||
return when (mode) {
|
||||
is ManageTokensMode.Account -> TODO("Account")
|
||||
is ManageTokensMode.Wallet -> removeCustomCurrencyUseCase.invoke(
|
||||
userWalletId = mode.userWalletId,
|
||||
customCurrency = customCurrency,
|
||||
)
|
||||
ManageTokensMode.None -> nonePortfolioError.left()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun checkHasLinkedTokensUseCase(
|
||||
network: Network,
|
||||
tempAddedTokens: Map<ManagedCryptoCurrency.Token, Set<Network>>,
|
||||
tempRemovedTokens: Map<ManagedCryptoCurrency.Token, Set<Network>>,
|
||||
): Either<Throwable, Boolean> {
|
||||
return when (mode) {
|
||||
is ManageTokensMode.Account -> TODO("Account")
|
||||
is ManageTokensMode.Wallet -> checkHasLinkedTokensUseCase.invoke(
|
||||
userWalletId = mode.userWalletId,
|
||||
network = network,
|
||||
tempAddedTokens = tempAddedTokens,
|
||||
tempRemovedTokens = tempRemovedTokens,
|
||||
)
|
||||
ManageTokensMode.None -> nonePortfolioError.left()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun checkCurrencyUnsupportedUseCase(
|
||||
sourceNetwork: ManagedCryptoCurrency.SourceNetwork,
|
||||
): Either<Throwable, CurrencyUnsupportedState?> {
|
||||
return when (mode) {
|
||||
is ManageTokensMode.Account -> TODO("Account")
|
||||
is ManageTokensMode.Wallet -> checkCurrencyUnsupportedUseCase.invoke(
|
||||
userWalletId = mode.userWalletId,
|
||||
sourceNetwork = sourceNetwork,
|
||||
)
|
||||
ManageTokensMode.None -> nonePortfolioError.left()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun hasMissedDerivationsUseCase(network: Map<String, Nothing?>): Boolean = when (mode) {
|
||||
is ManageTokensMode.Account -> TODO("Account")
|
||||
is ManageTokensMode.Wallet -> hasMissedDerivationsUseCase.invoke(
|
||||
userWalletId = mode.userWalletId,
|
||||
networksWithDerivationPath = network,
|
||||
)
|
||||
ManageTokensMode.None -> false
|
||||
}
|
||||
|
||||
suspend fun saveManagedTokensUseCase(
|
||||
currenciesToAdd: Map<ManagedCryptoCurrency.Token, Set<Network>>,
|
||||
currenciesToRemove: Map<ManagedCryptoCurrency.Token, Set<Network>>,
|
||||
): Either<Throwable, Unit> = when (mode) {
|
||||
is ManageTokensMode.Account -> TODO("Account")
|
||||
is ManageTokensMode.Wallet -> saveManagedTokensUseCase.invoke(
|
||||
userWalletId = mode.userWalletId,
|
||||
currenciesToAdd = currenciesToAdd,
|
||||
currenciesToRemove = currenciesToRemove,
|
||||
)
|
||||
ManageTokensMode.None -> nonePortfolioError.left()
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(mode: ManageTokensMode): ManageTokensUseCasesFacade
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
package com.tangem.features.managetokens.utils.list
|
||||
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.core.ui.message.EventMessageAction
|
||||
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.features.managetokens.component.ManageTokensMode
|
||||
import com.tangem.features.managetokens.component.ManageTokensSource
|
||||
import com.tangem.features.managetokens.impl.R
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
internal class ManageTokensWarningDelegate @AssistedInject constructor(
|
||||
private val messageSender: UiMessageSender,
|
||||
@Assisted private val mode: ManageTokensMode,
|
||||
@Assisted private val source: ManageTokensSource,
|
||||
@Assisted private val uiActions: ManageTokensUiActions,
|
||||
) {
|
||||
|
||||
suspend fun showRemoveNetworkWarning(
|
||||
currency: ManagedCryptoCurrency,
|
||||
network: Network,
|
||||
isCoin: Boolean,
|
||||
onConfirm: () -> Unit,
|
||||
) {
|
||||
val isNonePortfolio = when (mode) {
|
||||
ManageTokensMode.None -> true
|
||||
is ManageTokensMode.Account,
|
||||
is ManageTokensMode.Wallet,
|
||||
-> false
|
||||
}
|
||||
val hasLinkedTokens = if (isNonePortfolio || !isCoin) {
|
||||
false
|
||||
} else {
|
||||
uiActions.checkHasLinkedTokens(network)
|
||||
}
|
||||
val canHideWithoutConfirming = source == ManageTokensSource.ONBOARDING
|
||||
|
||||
if (hasLinkedTokens) {
|
||||
showLinkedTokensWarning(currency, network)
|
||||
} else if (canHideWithoutConfirming) {
|
||||
onConfirm()
|
||||
} else {
|
||||
showHideTokenWarning(currency, onConfirm)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showLinkedTokensWarning(currency: ManagedCryptoCurrency, network: Network) {
|
||||
val message = DialogMessage(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_title,
|
||||
formatArgs = wrappedList(currency.name),
|
||||
),
|
||||
message = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_message,
|
||||
formatArgs = wrappedList(
|
||||
currency.name,
|
||||
currency.symbol,
|
||||
network.name,
|
||||
),
|
||||
),
|
||||
)
|
||||
messageSender.send(message)
|
||||
}
|
||||
|
||||
private fun showHideTokenWarning(currency: ManagedCryptoCurrency, onConfirm: () -> Unit) {
|
||||
val message = DialogMessage(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_hide_alert_title,
|
||||
formatArgs = wrappedList(currency.name),
|
||||
),
|
||||
message = resourceReference(R.string.token_details_hide_alert_message),
|
||||
firstActionBuilder = {
|
||||
EventMessageAction(
|
||||
title = resourceReference(R.string.token_details_hide_alert_hide),
|
||||
warning = true,
|
||||
onClick = onConfirm,
|
||||
)
|
||||
},
|
||||
secondActionBuilder = { cancelAction() },
|
||||
)
|
||||
|
||||
messageSender.send(message)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(
|
||||
mode: ManageTokensMode,
|
||||
source: ManageTokensSource,
|
||||
uiActions: ManageTokensUiActions,
|
||||
): ManageTokensWarningDelegate
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue