diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 2629c88c99..ea038372cd 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -453,8 +453,6 @@ Приготовьте свою карту Уже содержится в введенном адресе Сумма - Вычесть из суммы отправки - Сумма к получению %s Транзакция не выполнена Причина: %1$s\nКод: %2$s Недостаточно средств для покрытия комиссии сети. Вычесть комиссию из отправляемой сумму? diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index a4fd2f577a..cada81a5ff 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -455,8 +455,6 @@ Get your card ready! Already included in the entered address Amount - Subtract from send amount - The recipient will receive %s The transaction is not completed Reason: %1$s\nCode: %2$s Not enough funds to cover the network commission. Subtract the commission from the amount sent? diff --git a/core/utils/src/main/java/com/tangem/utils/coroutines/JobHolder.kt b/core/utils/src/main/java/com/tangem/utils/coroutines/JobHolder.kt index 3c0ca6bd8d..42c4c7b296 100644 --- a/core/utils/src/main/java/com/tangem/utils/coroutines/JobHolder.kt +++ b/core/utils/src/main/java/com/tangem/utils/coroutines/JobHolder.kt @@ -16,6 +16,11 @@ class JobHolder { this.job?.cancel() this.job = job } + + /** Cancel current [job] */ + fun cancel() { + job?.cancel() + } } fun Job.saveIn(jobHolder: JobHolder) = jobHolder.update(job = this) \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/StateRouter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/StateRouter.kt index fea5777945..bf7b83183b 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/StateRouter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/StateRouter.kt @@ -14,23 +14,15 @@ internal class StateRouter( private val analyticsEventsHandler: AnalyticsEventHandler, private val isEditingDisabled: Boolean, ) { - private var mutableCurrentState: MutableStateFlow = MutableStateFlow( - if (isEditingDisabled) { - SendUiCurrentScreen( - type = SendUiStateType.None, - isFromConfirmation = false, - ) - } else { - SendUiCurrentScreen( - type = SendUiStateType.Recipient, - isFromConfirmation = false, - ) - }, - ) + private var mutableCurrentState: MutableStateFlow = MutableStateFlow(getInitState()) val currentState: StateFlow get() = mutableCurrentState + fun clear() { + mutableCurrentState.update { getInitState() } + } + fun popBackStack() { fragmentManager.get()?.popBackStack() } @@ -128,4 +120,16 @@ internal class StateRouter( private fun continueToSend(show: () -> Unit) { if (currentState.value.isFromConfirmation) showSend() else show() } + + private fun getInitState() = if (isEditingDisabled) { + SendUiCurrentScreen( + type = SendUiStateType.None, + isFromConfirmation = false, + ) + } else { + SendUiCurrentScreen( + type = SendUiStateType.Recipient, + isFromConfirmation = false, + ) + } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt index 1b2a4d56f6..cd6254be4f 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt @@ -34,9 +34,10 @@ internal class SendAmountFieldChangeConverter( val checkValue = if (amountTextField.isFiatValue) fiatValue else cryptoValue val isExceedBalance = checkValue.checkExceedBalance(amountTextField) + val isZero = if (amountTextField.isFiatValue) decimalFiatValue.isZero() else decimalCryptoValue.isZero() return state.copy( amountState = amountState.copy( - isPrimaryButtonEnabled = !isExceedBalance, + isPrimaryButtonEnabled = !isExceedBalance && !isZero, amountTextField = amountTextField.copy( value = cryptoValue, fiatValue = fiatValue, @@ -93,9 +94,9 @@ internal class SendAmountFieldChangeConverter( val fiatDecimal = parseToBigDecimal(amountTextField.fiatAmount.decimals) val cryptoDecimal = parseToBigDecimal(amountTextField.cryptoAmount.decimals) return if (amountTextField.isFiatValue) { - fiatDecimal > currencyFiatAmount || fiatDecimal.isZero() + fiatDecimal > currencyFiatAmount } else { - cryptoDecimal > currencyCryptoAmount || cryptoDecimal.isZero() + cryptoDecimal > currencyCryptoAmount } } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSubtract.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSubtract.kt deleted file mode 100644 index 5fa7355bce..0000000000 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSubtract.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.tangem.features.send.impl.presentation.ui.fee - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.stringResource -import com.tangem.core.ui.components.TangemSwitch -import com.tangem.core.ui.res.TangemTheme -import com.tangem.features.send.impl.R -import com.tangem.features.send.impl.presentation.ui.common.FooterContainer - -@Composable -internal fun SendSpeedSubtract( - receivingAmount: String, - isSubtract: Boolean, - onSelectClick: (Boolean) -> Unit, - modifier: Modifier = Modifier, -) { - val footerText = if (isSubtract) { - stringResource(R.string.send_amount_substract_footer, receivingAmount) - } else { - null - } - - FooterContainer( - footer = footerText, - modifier = modifier, - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier - .fillMaxWidth() - .clip(TangemTheme.shapes.roundedCornersXMedium) - .background(TangemTheme.colors.background.action) - .padding( - vertical = TangemTheme.dimens.spacing16, - horizontal = TangemTheme.dimens.spacing20, - ), - ) { - Text( - text = stringResource(R.string.send_amount_substract), - style = TangemTheme.typography.subtitle1, - color = TangemTheme.colors.text.primary1, - modifier = Modifier - .padding(end = TangemTheme.dimens.spacing12), - ) - TangemSwitch( - checked = isSubtract, - onCheckedChange = onSelectClick, - ) - } - } -} \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt index 8267ee3c2a..4cbe0159d8 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt @@ -171,6 +171,7 @@ internal class SendViewModel @Inject constructor( private var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull() private var balanceJobHolder = JobHolder() + private var balanceHidingJobHolder = JobHolder() private var recipientsJobHolder = JobHolder() private var feeJobHolder = JobHolder() private var addressValidationJobHolder = JobHolder() @@ -180,25 +181,35 @@ internal class SendViewModel @Inject constructor( private var sendIdleTimer = 0L + init { + subscribeOnCurrencyStatusUpdates() + subscribeOnBalanceHidden() + } + override fun onCreate(owner: LifecycleOwner) { - subscribeOnCurrencyStatusUpdates(owner) onStateActive() - subscribeOnBalanceHidden(owner) analyticsEventHandler.send(SendAnalyticEvents.SendOpened) } + override fun onCleared() { + super.onCleared() + balanceHidingJobHolder.cancel() + balanceJobHolder.cancel() + stateRouter.clear() + } + fun setRouter(router: InnerSendRouter, stateRouter: StateRouter) { innerRouter = router this.stateRouter = stateRouter } - private fun subscribeOnCurrencyStatusUpdates(owner: LifecycleOwner) { + private fun subscribeOnCurrencyStatusUpdates() { viewModelScope.launch(dispatchers.main) { getUserWalletUseCase(userWalletId).fold( ifRight = { wallet -> userWallet = wallet checkIfSubtractAvailable() - getCurrenciesStatusUpdates(owner, wallet) + getCurrenciesStatusUpdates(wallet) }, ifLeft = { uiState = eventStateFactory.getGenericErrorState( @@ -210,23 +221,22 @@ internal class SendViewModel @Inject constructor( } } - private fun subscribeOnBalanceHidden(owner: LifecycleOwner) { + private fun subscribeOnBalanceHidden() { getBalanceHidingSettingsUseCase() - .flowWithLifecycle(owner.lifecycle) .conflate() .distinctUntilChanged() .onEach { uiState = stateFactory.getOnHideBalanceState(isBalanceHidden = it.isBalanceHidden) } .launchIn(viewModelScope) + .saveIn(balanceHidingJobHolder) } - private fun getCurrenciesStatusUpdates(owner: LifecycleOwner, wallet: UserWallet) { + private fun getCurrenciesStatusUpdates(wallet: UserWallet) { val isSingleWallet = wallet.scanResponse.walletData?.token != null && !wallet.isMultiCurrency if (cryptoCurrency is CryptoCurrency.Coin) { getCurrencyStatusUpdates(isSingleWallet = isSingleWallet) - .flowWithLifecycle(owner.lifecycle) .onEach { currencyStatus -> currencyStatus.onRight { onDataLoaded( @@ -249,7 +259,7 @@ internal class SendViewModel @Inject constructor( coinCurrencyStatus = coinStatus.getOrElse { error("Coin status is unreachable") }, ) } - }.flowWithLifecycle(owner.lifecycle) + } .flowOn(dispatchers.main) .launchIn(viewModelScope) .saveIn(balanceJobHolder) @@ -703,11 +713,10 @@ internal class SendViewModel @Inject constructor( } private fun onCheckFeeUpdate() { - val isSending = uiState.sendState.isSending val isSuccess = uiState.sendState.isSuccess val noErrorNotifications = uiState.sendState.notifications.none { it is SendNotification.Error } - if (!isSending && !isSuccess && noErrorNotifications) { + if (!isSuccess && noErrorNotifications) { viewModelScope.launch(dispatchers.main) { val feeUpdatedState = callFeeUseCase()?.fold( ifRight = {