Updated on 2026-08-14
This commit is contained in:
parent
a0bd40c496
commit
0b6257796a
35 changed files with 204 additions and 201 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
package com.tangem.features.send.api.navigation
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
interface SendRouter {
|
||||
|
||||
fun getEntryFragment(): Fragment
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue