Updated on 2026-08-14

This commit is contained in:
Tangem 2025-02-17 15:57:47 +03:00
parent a0bd40c496
commit 0b6257796a
35 changed files with 204 additions and 201 deletions

View file

@ -10,6 +10,13 @@ android {
}
dependencies {
/** Core */
implementation(projects.core.decompose)
implementation(projects.core.ui)
/** Domain models */
implementation(projects.domain.wallets.models)
implementation(projects.domain.tokens.models)
/** AndroidX */
implementation(deps.androidx.fragment.ktx)

View file

@ -0,0 +1,20 @@
package com.tangem.features.send.api
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.wallets.models.UserWalletId
interface SendComponent : ComposableContentComponent {
data class Params(
val userWalletId: UserWalletId,
val currency: CryptoCurrency,
val transactionId: String? = null,
val amount: String? = null,
val tag: String? = null,
val destinationAddress: String? = null,
)
interface Factory : ComponentFactory<Params, SendComponent>
}

View file

@ -1,8 +0,0 @@
package com.tangem.features.send.api.navigation
import androidx.fragment.app.Fragment
interface SendRouter {
fun getEntryFragment(): Fragment
}

View file

@ -50,6 +50,7 @@ dependencies {
implementation(projects.core.analytics)
implementation(projects.core.analytics.models)
implementation(projects.core.datasource)
implementation(projects.core.decompose)
/** Common */
implementation(projects.common.ui)

View file

@ -0,0 +1,35 @@
package com.tangem.features.send.impl
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.features.send.api.SendComponent
import com.tangem.features.send.impl.presentation.model.SendModel
import com.tangem.features.send.impl.presentation.ui.SendScreen
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
internal class DefaultSendComponent @AssistedInject constructor(
@Assisted appComponentContext: AppComponentContext,
@Assisted params: SendComponent.Params,
) : SendComponent, AppComponentContext by appComponentContext {
private val model: SendModel = getOrCreateModel(params)
@Composable
override fun Content(modifier: Modifier) {
val currentState = model.stateRouter.currentState.collectAsStateWithLifecycle()
val uiState by model.uiState.collectAsStateWithLifecycle()
SendScreen(uiState, currentState.value)
}
@AssistedFactory
interface Factory : SendComponent.Factory {
override fun create(context: AppComponentContext, params: SendComponent.Params): DefaultSendComponent
}
}

View file

@ -0,0 +1,38 @@
package com.tangem.features.send.impl.di
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.send.api.SendComponent
import com.tangem.features.send.impl.DefaultSendComponent
import com.tangem.features.send.impl.navigation.DefaultSendRouter
import com.tangem.features.send.impl.navigation.InnerSendRouter
import com.tangem.features.send.impl.presentation.model.SendModel
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(SingletonComponent::class)
internal interface SendModule {
@Binds
fun bindComponentFactory(factory: DefaultSendComponent.Factory): SendComponent.Factory
@Binds
@IntoMap
@ClassKey(SendModel::class)
fun bindModel(model: SendModel): Model
}
@Module
@InstallIn(DecomposeComponent::class)
internal interface SendModelModule {
@Binds
@ComponentScoped
fun bindRouter(router: DefaultSendRouter): InnerSendRouter
}

View file

@ -1,25 +0,0 @@
package com.tangem.features.send.impl.di
import com.tangem.common.routing.AppRouter
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.features.send.api.navigation.SendRouter
import com.tangem.features.send.impl.navigation.DefaultSendRouter
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.scopes.ActivityScoped
/**
* DI module provides implementation of [SendRouter]
*/
@Module
@InstallIn(ActivityComponent::class)
internal object SendRouterModule {
@Provides
@ActivityScoped
fun provideSendRouter(appRouter: AppRouter, urlOpener: UrlOpener): SendRouter {
return DefaultSendRouter(appRouter, urlOpener)
}
}

View file

@ -1,21 +1,20 @@
package com.tangem.features.send.impl.navigation
import androidx.fragment.app.Fragment
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRouter
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.domain.qrscanning.models.SourceType
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.send.impl.presentation.SendFragment
import javax.inject.Inject
internal class DefaultSendRouter(
@ComponentScoped
internal class DefaultSendRouter @Inject constructor(
private val router: AppRouter,
private val urlOpener: UrlOpener,
) : InnerSendRouter {
override fun getEntryFragment(): Fragment = SendFragment.create()
override fun openUrl(url: String) {
urlOpener.openUrl(url)
}

View file

@ -2,9 +2,8 @@ package com.tangem.features.send.impl.navigation
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.send.api.navigation.SendRouter
interface InnerSendRouter : SendRouter {
interface InnerSendRouter {
/** Open website by [url] */
fun openUrl(url: String)

View file

@ -1,78 +0,0 @@
package com.tangem.features.send.impl.presentation
import android.os.Bundle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.fragment.app.viewModels
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRouter
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.ui.UiDependencies
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.features.send.api.navigation.SendRouter
import com.tangem.features.send.impl.navigation.InnerSendRouter
import com.tangem.features.send.impl.presentation.state.StateRouter
import com.tangem.features.send.impl.presentation.ui.SendScreen
import com.tangem.features.send.impl.presentation.viewmodel.SendViewModel
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
/**
* Send fragment
*/
@AndroidEntryPoint
internal class SendFragment : ComposeFragment() {
@Inject
override lateinit var uiDependencies: UiDependencies
@Inject
lateinit var router: SendRouter
@Inject
lateinit var appRouter: AppRouter
@Inject
lateinit var analyticsEventsHandler: AnalyticsEventHandler
private val viewModel by viewModels<SendViewModel>()
private val innerSendRouter: InnerSendRouter
get() = requireNotNull(router as? InnerSendRouter) {
"innerSendRouter should be instance of InnerSendRouter"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycle.addObserver(viewModel)
val isEditingDisabled = arguments?.getString(AppRoute.Send.TRANSACTION_ID_KEY) != null
viewModel.setRouter(
innerSendRouter,
StateRouter(
appRouter = appRouter,
isEditingDisabled = isEditingDisabled,
analyticsEventsHandler = analyticsEventsHandler,
),
)
}
@Composable
override fun ScreenContent(modifier: Modifier) {
val currentState = viewModel.stateRouter.currentState.collectAsStateWithLifecycle()
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
SendScreen(uiState, currentState.value)
}
override fun onDestroy() {
lifecycle.removeObserver(viewModel)
super.onDestroy()
}
companion object {
/** Create send fragment instance */
fun create(): SendFragment = SendFragment()
}
}

View file

@ -1,4 +1,4 @@
package com.tangem.features.send.impl.presentation.viewmodel
package com.tangem.features.send.impl.presentation.model
import com.tangem.common.ui.amountScreen.AmountScreenClickIntents
import com.tangem.common.ui.notifications.NotificationUM

View file

@ -1,20 +1,21 @@
package com.tangem.features.send.impl.presentation.viewmodel
package com.tangem.features.send.impl.presentation.model
import android.os.Bundle
import android.os.SystemClock
import androidx.lifecycle.*
import androidx.compose.runtime.Stable
import arrow.core.Either
import arrow.core.getOrElse
import arrow.core.left
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.TransactionData
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.bundle.unbundle
import com.tangem.common.routing.AppRouter
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.navigation.share.ShareManager
import com.tangem.core.ui.utils.parseBigDecimal
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
@ -47,6 +48,7 @@ import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.features.send.api.SendComponent
import com.tangem.features.send.impl.navigation.InnerSendRouter
import com.tangem.features.send.impl.presentation.analytics.EnterAddressSource
import com.tangem.features.send.impl.presentation.analytics.SendAnalyticEvents
@ -63,7 +65,6 @@ import com.tangem.utils.Provider
import com.tangem.utils.coroutines.*
import com.tangem.utils.extensions.orZero
import com.tangem.utils.extensions.stripZeroPlainString
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import timber.log.Timber
@ -73,9 +74,10 @@ import javax.inject.Inject
import kotlin.properties.Delegates
@Suppress("LongParameterList", "TooManyFunctions", "LargeClass")
@HiltViewModel
internal class SendViewModel @Inject constructor(
private val dispatchers: CoroutineDispatcherProvider,
@Stable
@ComponentScoped
internal class SendModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val getUserWalletUseCase: GetUserWalletUseCase,
private val getCryptoCurrencyStatusSyncUseCase: GetCryptoCurrencyStatusSyncUseCase,
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
@ -109,31 +111,31 @@ internal class SendViewModel @Inject constructor(
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
private val shareManager: ShareManager,
@DelayedWork private val coroutineScope: CoroutineScope,
private val innerRouter: InnerSendRouter,
private val appRouter: AppRouter,
paramsContainer: ParamsContainer,
validateTransactionUseCase: ValidateTransactionUseCase,
getCurrencyCheckUseCase: GetCurrencyCheckUseCase,
isFeeApproximateUseCase: IsFeeApproximateUseCase,
getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase,
savedStateHandle: SavedStateHandle,
) : ViewModel(), DefaultLifecycleObserver, SendClickIntents {
) : Model(), SendClickIntents {
private val userWalletId: UserWalletId = savedStateHandle.get<Bundle>(AppRoute.Send.USER_WALLET_ID_KEY)
?.unbundle(UserWalletId.serializer())
?: error("This screen can't open without `UserWalletId`")
private val params = paramsContainer.require<SendComponent.Params>()
private val cryptoCurrency: CryptoCurrency = savedStateHandle.get<Bundle>(AppRoute.Send.CRYPTO_CURRENCY_KEY)
?.unbundle(CryptoCurrency.serializer())
?: error("This screen can't open without `CryptoCurrency`")
private val transactionId: String? = savedStateHandle[AppRoute.Send.TRANSACTION_ID_KEY]
private val amount: String? = savedStateHandle[AppRoute.Send.AMOUNT_KEY]
private val destinationAddress: String? = savedStateHandle[AppRoute.Send.DESTINATION_ADDRESS_KEY]
private val memo: String? = savedStateHandle[AppRoute.Send.TAG_KEY]
private val userWalletId: UserWalletId = params.userWalletId
private val cryptoCurrency: CryptoCurrency = params.currency
private val transactionId: String? = params.transactionId
private val amount: String? = params.amount
private val destinationAddress: String? = params.destinationAddress
private val memo: String? = params.tag
private val selectedAppCurrencyFlow: StateFlow<AppCurrency> = createSelectedAppCurrencyFlow()
private var innerRouter: InnerSendRouter by Delegates.notNull()
var stateRouter: StateRouter by Delegates.notNull()
private set
val stateRouter = StateRouter(
appRouter = appRouter,
isEditingDisabled = transactionId != null,
analyticsEventsHandler = analyticsEventHandler,
)
private val stateFactory = SendStateFactory(
clickIntents = this,
@ -234,33 +236,26 @@ internal class SendViewModel @Inject constructor(
subscribeOnCurrencyStatusUpdates()
subscribeOnBalanceHidden()
getTapHelpPreviewAvailability()
}
override fun onCreate(owner: LifecycleOwner) {
onStateActive()
}
override fun onCleared() {
super.onCleared()
override fun onDestroy() {
super.onDestroy()
balanceHidingJobHolder.cancel()
balanceJobHolder.cancel()
stateRouter.clear()
}
fun setRouter(router: InnerSendRouter, stateRouter: StateRouter) {
innerRouter = router
this.stateRouter = stateRouter
}
private fun subscribeOnQRScannerResult() {
listenToQrScanningUseCase(SourceType.SEND)
.getOrElse { emptyFlow() }
.onEach(::onQrCodeScanned)
.launchIn(viewModelScope)
.launchIn(modelScope)
}
private fun subscribeOnCurrencyStatusUpdates() {
viewModelScope.launch {
modelScope.launch {
getUserWalletUseCase(userWalletId).fold(
ifRight = { wallet ->
userWallet = wallet
@ -289,7 +284,7 @@ internal class SendViewModel @Inject constructor(
.onEach {
uiState.value = stateFactory.getOnHideBalanceState(isBalanceHidden = it.isBalanceHidden)
}
.launchIn(viewModelScope)
.launchIn(modelScope)
.saveIn(balanceHidingJobHolder)
}
@ -310,7 +305,7 @@ internal class SendViewModel @Inject constructor(
}
private fun getTapHelpPreviewAvailability() {
viewModelScope.launch {
modelScope.launch {
isTapHelpPreviewEnabled = isSendTapHelpEnabledUseCase().getOrElse { false }
}
}
@ -362,7 +357,7 @@ internal class SendViewModel @Inject constructor(
maybeAppCurrency.getOrElse { AppCurrency.Default }
}
.stateIn(
scope = viewModelScope,
scope = modelScope,
started = SharingStarted.Eagerly,
initialValue = AppCurrency.Default,
)
@ -395,13 +390,13 @@ internal class SendViewModel @Inject constructor(
private fun getWalletsAndRecent() {
getUserWallets()
viewModelScope.launch {
modelScope.launch {
getTxHistory()
}
}
private fun getUserWallets() {
viewModelScope.launch {
modelScope.launch {
runCatching {
waitForDelay(delay = RECENT_LOAD_DELAY) {
getWalletsUseCase.invokeSync()
@ -466,7 +461,7 @@ internal class SendViewModel @Inject constructor(
else -> Unit
}
}
.launchIn(viewModelScope)
.launchIn(modelScope)
}
private fun updateNotifications() {
@ -475,7 +470,7 @@ internal class SendViewModel @Inject constructor(
.distinctUntilChanged()
.onEach { uiState.value = stateFactory.getSendNotificationState(notifications = it) }
.flowOn(dispatchers.main)
.launchIn(viewModelScope)
.launchIn(modelScope)
.saveIn(sendNotificationsJobHolder)
}
@ -485,7 +480,7 @@ internal class SendViewModel @Inject constructor(
.distinctUntilChanged()
.onEach { uiState.value = feeStateFactory.getFeeNotificationState(notifications = it) }
.flowOn(dispatchers.main)
.launchIn(viewModelScope)
.launchIn(modelScope)
.saveIn(feeNotificationsJobHolder)
}
@ -573,7 +568,7 @@ internal class SendViewModel @Inject constructor(
val cardInfo = getCardInfoUseCase(userWallet.scanResponse).getOrNull() ?: return
viewModelScope.launch {
modelScope.launch {
sendFeedbackEmailUseCase(type = FeedbackEmailType.TransactionSendingProblem(cardInfo = cardInfo))
}
}
@ -615,7 +610,7 @@ internal class SendViewModel @Inject constructor(
}
private fun cancelFeeRequest() {
viewModelScope.launch {
modelScope.launch {
feeJobHolder.cancel()
}
}
@ -660,7 +655,7 @@ internal class SendViewModel @Inject constructor(
// region recipient state clicks
override fun onRecipientAddressValueChange(value: String, type: EnterAddressSource?) {
viewModelScope.launch {
modelScope.launch {
if (!checkIfXrpAddressValue(value)) {
uiState.value = recipientStateFactory.onRecipientAddressValueChange(value, isValuePasted = type != null)
uiState.value = recipientStateFactory.getOnRecipientAddressValidationStarted()
@ -680,7 +675,7 @@ internal class SendViewModel @Inject constructor(
}
override fun onRecipientMemoValueChange(value: String, isValuePasted: Boolean) {
viewModelScope.launch {
modelScope.launch {
if (!checkIfXrpAddressValue(value)) {
uiState.value = recipientStateFactory.getOnRecipientMemoValueChange(value, isValuePasted)
uiState.value = recipientStateFactory.getOnRecipientAddressValidationStarted()
@ -758,7 +753,7 @@ internal class SendViewModel @Inject constructor(
}
private fun loadFee() {
viewModelScope.launch {
modelScope.launch {
val isShowStatus = uiState.value.feeState?.fee == null
if (isShowStatus) {
uiState.value = feeStateFactory.onFeeOnLoadingState()
@ -911,7 +906,7 @@ internal class SendViewModel @Inject constructor(
reduceAmountBy = uiState.value.sendState?.reduceAmountBy ?: BigDecimal.ZERO,
)
viewModelScope.launch {
modelScope.launch {
createTransactionUseCase(
amount = receivingAmount.convertToSdkAmount(cryptoCurrency),
fee = fee,
@ -969,7 +964,7 @@ internal class SendViewModel @Inject constructor(
val receivingUserWallet = userWallets.firstOrNull { it.address == destinationAddress } ?: return
viewModelScope.launch {
modelScope.launch {
addCryptoCurrenciesUseCase(
userWalletId = receivingUserWallet.userWalletId,
cryptoCurrency = cryptoCurrency,
@ -1031,7 +1026,7 @@ internal class SendViewModel @Inject constructor(
val noErrorNotifications = sendState.notifications.none { it is NotificationUM.Error }
if (!isSuccess && noErrorNotifications) {
viewModelScope.launch {
modelScope.launch {
val feeUpdatedState = callFeeUseCase()?.fold(
ifRight = {
uiState.value = stateFactory.getSendingStateUpdate(isSending = false)
@ -1065,7 +1060,7 @@ internal class SendViewModel @Inject constructor(
}
private fun setNeverToShowTapHelp() {
viewModelScope.launch {
modelScope.launch {
neverShowTapHelpUseCase()
}
uiState.value = stateFactory.getHiddenTapHelpState()

View file

@ -8,7 +8,7 @@ import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState
import com.tangem.features.send.impl.presentation.state.fee.FeeStateFactory
import com.tangem.features.send.impl.presentation.state.fee.FeeType
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.Provider
import java.math.BigDecimal

View file

@ -18,7 +18,7 @@ import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState
import com.tangem.features.send.impl.presentation.state.fee.SendFeeStateConverter
import com.tangem.features.send.impl.presentation.state.fee.checkFeeCoverage
import com.tangem.features.send.impl.presentation.state.recipient.SendRecipientStateConverter
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.Provider
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf

View file

@ -10,7 +10,7 @@ import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.features.send.impl.presentation.domain.SendRecipientListContent
import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState
import com.tangem.features.send.impl.presentation.state.fields.SendTextField
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import kotlinx.collections.immutable.ImmutableList
import java.math.BigDecimal

View file

@ -12,7 +12,7 @@ internal class StateRouter(
private val analyticsEventsHandler: AnalyticsEventHandler,
private val isEditingDisabled: Boolean,
) {
private var mutableCurrentState: MutableStateFlow<SendUiCurrentScreen> = MutableStateFlow(getInitState())
private val mutableCurrentState: MutableStateFlow<SendUiCurrentScreen> = MutableStateFlow(getInitState())
val currentState: StateFlow<SendUiCurrentScreen>
get() = mutableCurrentState

View file

@ -34,7 +34,7 @@ import com.tangem.features.send.impl.presentation.state.SendUiState
import com.tangem.features.send.impl.presentation.state.SendUiStateType
import com.tangem.features.send.impl.presentation.state.StateRouter
import com.tangem.features.send.impl.presentation.state.fee.*
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.lib.crypto.BlockchainUtils
import com.tangem.lib.crypto.BlockchainUtils.isTezos
import com.tangem.utils.Provider

View file

@ -9,7 +9,7 @@ import com.tangem.features.send.impl.presentation.state.StateRouter
import com.tangem.features.send.impl.presentation.state.fee.custom.BitcoinCustomFeeConverter
import com.tangem.features.send.impl.presentation.state.fee.custom.EthereumCustomFeeConverter
import com.tangem.features.send.impl.presentation.state.fee.custom.KaspaCustomFeeConverter
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.Provider
import com.tangem.utils.converter.Converter

View file

@ -4,7 +4,7 @@ import com.tangem.common.ui.notifications.NotificationsFactory.addFeeUnreachable
import com.tangem.features.send.impl.presentation.state.SendUiState
import com.tangem.features.send.impl.presentation.state.SendUiStateType
import com.tangem.features.send.impl.presentation.state.StateRouter
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.Provider
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList

View file

@ -14,7 +14,7 @@ import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
import com.tangem.features.send.impl.presentation.state.SendStates
import com.tangem.features.send.impl.presentation.state.SendUiState
import com.tangem.features.send.impl.presentation.state.StateRouter
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.Provider
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf

View file

@ -9,7 +9,7 @@ import com.tangem.features.send.impl.presentation.state.fee.custom.BitcoinCustom
import com.tangem.features.send.impl.presentation.state.fee.custom.EthereumCustomFeeConverter
import com.tangem.features.send.impl.presentation.state.fee.custom.KaspaCustomFeeConverter
import com.tangem.features.send.impl.presentation.state.fields.SendTextField
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.Provider
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.ImmutableList

View file

@ -15,7 +15,7 @@ import com.tangem.features.send.impl.R
import com.tangem.features.send.impl.presentation.state.StateRouter
import com.tangem.features.send.impl.presentation.state.fee.checkExceedBalance
import com.tangem.features.send.impl.presentation.state.fields.SendTextField
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.lib.crypto.BlockchainUtils.isUseBitcoinFeeConverter
import com.tangem.utils.Provider
import kotlinx.collections.immutable.ImmutableList

View file

@ -14,7 +14,7 @@ import com.tangem.features.send.impl.R
import com.tangem.features.send.impl.presentation.state.StateRouter
import com.tangem.features.send.impl.presentation.state.fee.checkExceedBalance
import com.tangem.features.send.impl.presentation.state.fields.SendTextField
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.Provider
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList

View file

@ -18,7 +18,7 @@ import com.tangem.features.send.impl.presentation.state.fee.custom.EthereumCusto
import com.tangem.features.send.impl.presentation.state.fee.custom.EthereumCustomFeeConverter.Companion.GAS_DECIMALS
import com.tangem.features.send.impl.presentation.state.fee.custom.EthereumCustomFeeConverter.Companion.GIGA_DECIMALS
import com.tangem.features.send.impl.presentation.state.fields.SendTextField
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.Provider
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf

View file

@ -18,7 +18,7 @@ import com.tangem.features.send.impl.presentation.state.fee.custom.EthereumCusto
import com.tangem.features.send.impl.presentation.state.fee.custom.EthereumCustomFeeConverter.Companion.GAS_DECIMALS
import com.tangem.features.send.impl.presentation.state.fee.custom.EthereumCustomFeeConverter.Companion.GIGA_DECIMALS
import com.tangem.features.send.impl.presentation.state.fields.SendTextField
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.Provider
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf

View file

@ -13,7 +13,7 @@ import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.impl.R
import com.tangem.features.send.impl.presentation.state.fields.SendTextField
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.Provider
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf

View file

@ -4,7 +4,7 @@ import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.features.send.impl.presentation.analytics.EnterAddressSource
import com.tangem.features.send.impl.presentation.state.fee.FeeType
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import java.math.BigDecimal
@Suppress("TooManyFunctions")

View file

@ -6,7 +6,7 @@ import androidx.compose.ui.text.input.KeyboardType
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.send.impl.R
import com.tangem.features.send.impl.presentation.state.fields.SendTextField
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.converter.Converter
internal class SendRecipientAddressFieldConverter(

View file

@ -9,7 +9,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.Network
import com.tangem.features.send.impl.R
import com.tangem.features.send.impl.presentation.state.fields.SendTextField
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.Provider
import com.tangem.utils.converter.Converter

View file

@ -3,7 +3,7 @@ package com.tangem.features.send.impl.presentation.state.recipient
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.impl.presentation.state.SendStates
import com.tangem.features.send.impl.presentation.state.recipient.utils.*
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import com.tangem.utils.Provider
import com.tangem.utils.converter.Converter

View file

@ -20,7 +20,7 @@ import com.tangem.features.send.impl.presentation.state.fee.FeeType
import com.tangem.features.send.impl.presentation.state.previewdata.FeeStatePreviewData
import com.tangem.features.send.impl.presentation.state.previewdata.SendClickIntentsStub
import com.tangem.features.send.impl.presentation.ui.common.notifications
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
private const val FEE_SELECTOR_KEY = "FEE_SELECTOR_KEY"
private const val FEE_CUSTOM_KEY = "FEE_CUSTOM_KEY"

View file

@ -25,7 +25,7 @@ import com.tangem.features.send.impl.presentation.state.SendStates
import com.tangem.features.send.impl.presentation.state.fee.FeeType
import com.tangem.features.send.impl.presentation.state.previewdata.FeeStatePreviewData
import com.tangem.features.send.impl.presentation.state.previewdata.SendClickIntentsStub
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
@Suppress("LongMethod")
@Composable

View file

@ -32,7 +32,7 @@ import com.tangem.features.send.impl.presentation.state.SendStates
import com.tangem.features.send.impl.presentation.state.fields.SendTextField
import com.tangem.features.send.impl.presentation.state.previewdata.RecipientStatePreviewData
import com.tangem.features.send.impl.presentation.state.previewdata.SendClickIntentsStub
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.features.send.impl.presentation.model.SendClickIntents
import kotlinx.collections.immutable.ImmutableList
private const val ADDRESS_FIELD_KEY = "ADDRESS_FIELD_KEY"