Updated on 2026-08-14

This commit is contained in:
Tangem 2026-03-06 16:56:01 +05:00
parent a67ca6279f
commit 47db65fdbe
2 changed files with 67 additions and 11 deletions

View file

@ -1,8 +1,13 @@
package com.tangem.features.send.v2.send
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.extensions.compose.subscribeAsState
@ -21,8 +26,8 @@ import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.decompose.navigation.inner.InnerRouter
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.domain.models.account.derivationIndex
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
import com.tangem.features.send.v2.api.SendComponent
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
@ -193,12 +198,9 @@ internal class DefaultSendComponent @AssistedInject constructor(
}
private fun getConfirmComponent(factoryContext: AppComponentContext): ComposableContentComponent {
val cryptoCurrencyStatus = model.cryptoCurrencyStatusFlow.value
val feeCryptoCurrencyStatus = model.feeCryptoCurrencyStatusFlow.value
return if (cryptoCurrencyStatus.value != CryptoCurrencyStatus.Loading &&
feeCryptoCurrencyStatus.value != CryptoCurrencyStatus.Loading
) {
return if (model.isAvailableForSend) {
val cryptoCurrencyStatus = model.cryptoCurrencyStatusFlow.value
val feeCryptoCurrencyStatus = model.feeCryptoCurrencyStatusFlow.value
SendConfirmComponent(
appComponentContext = factoryContext,
params = SendConfirmComponent.Params(
@ -280,6 +282,17 @@ internal class DefaultSendComponent @AssistedInject constructor(
class StubComponent : ComposableContentComponent {
@Composable
override fun Content(modifier: Modifier) {
Box(
modifier = Modifier
.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
CircularProgressIndicator(
modifier = Modifier.padding(TangemTheme.dimens.spacing12),
color = TangemTheme.colors.icon.primary1,
strokeWidth = TangemTheme.dimens.size2,
)
}
}
}

View file

@ -138,6 +138,22 @@ internal class SendModel @Inject constructor(
),
)
val isAvailableForSend: Boolean
get() {
val cryptoCurrencyStatus = cryptoCurrencyStatusFlow.value
val feeCryptoCurrencyStatus = feeCryptoCurrencyStatusFlow.value
return cryptoCurrencyStatus.isAvailableForSend() && feeCryptoCurrencyStatus.isAvailableForSend()
}
val isUnavailableForSend: Boolean
get() {
val cryptoCurrencyStatus = cryptoCurrencyStatusFlow.value
val feeCryptoCurrencyStatus = feeCryptoCurrencyStatusFlow.value
return cryptoCurrencyStatus.isUnavailableForSend() || feeCryptoCurrencyStatus.isUnavailableForSend()
}
val accountFlow: StateFlow<Account?>
field = MutableStateFlow(null)
val isAccountModeFlow: StateFlow<Boolean>
@ -153,6 +169,9 @@ internal class SendModel @Inject constructor(
subscribeOnBalanceHidden()
subscribeOnQRScannerResult()
subscribeOnCurrencyStatusUpdates()
if (params.amount != null) {
subscribeOnStatusForDeeplinkDestination()
}
initAppCurrency()
initPredefinedValues()
}
@ -363,10 +382,6 @@ internal class SendModel @Inject constructor(
userWalletId = params.userWalletId,
cryptoCurrencyStatus = cryptoCurrencyStatus,
).getOrNull() ?: cryptoCurrencyStatus
if (params.amount != null) {
router.replaceAll(Confirm)
}
}.flowOn(dispatchers.default)
.launchIn(modelScope)
},
@ -379,6 +394,34 @@ internal class SendModel @Inject constructor(
}
}
private fun subscribeOnStatusForDeeplinkDestination() {
combine(
cryptoCurrencyStatusFlow,
feeCryptoCurrencyStatusFlow,
) { cryptoCurrencyStatus, feeCryptoCurrencyStatus ->
if (isAvailableForSend && currentRoute.value == initialRoute) {
router.replaceAll(Confirm)
} else if (isUnavailableForSend) {
showAlertError()
}
}.launchIn(modelScope)
}
private fun CryptoCurrencyStatus.hasAvailableStatus(): Boolean = this.value is CryptoCurrencyStatus.Loaded ||
this.value is CryptoCurrencyStatus.Custom ||
this.value is CryptoCurrencyStatus.NoQuote
private fun CryptoCurrencyStatus.hasUnavailableStatus(): Boolean = this.value is CryptoCurrencyStatus.Unreachable ||
this.value is CryptoCurrencyStatus.NoAmount ||
this.value is CryptoCurrencyStatus.MissedDerivation ||
this.value is CryptoCurrencyStatus.NoAccount
private fun CryptoCurrencyStatus.isAvailableForSend(): Boolean =
this.hasAvailableStatus() && this.value.sources.networkSource.isActual()
private fun CryptoCurrencyStatus.isUnavailableForSend(): Boolean =
this.hasUnavailableStatus() && this.value.sources.networkSource.isActual()
private fun subscribeOnBalanceHidden() {
getBalanceHidingSettingsUseCase()
.conflate()