Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-10 19:51:45 +04:00
parent bf27373667
commit fb69f0df7c
3 changed files with 224 additions and 4 deletions

View file

@ -102,6 +102,8 @@ internal class DefaultSendWithSwapComponent @AssistedInject constructor(
if (model.currentRoute.value.isEditMode) {
activeComponent.updateState(model.uiState.value)
}
// Re-sync destination from parent on Confirm entry, bypassing the edit-mode gate ([REDACTED_TASK_KEY]).
activeComponent.updateDestinationState(model.uiState.value.destinationUM)
val fromCurrency = params.currency
val content = model.uiState.value.amountUM as? SwapAmountUM.Content ?: return@launch
val toCurrency = content.secondaryCryptoCurrencyStatus?.currency ?: return@launch

View file

@ -21,6 +21,7 @@ import com.tangem.features.send.api.entity.PredefinedValues
import com.tangem.features.send.api.params.FeeSelectorParams.*
import com.tangem.features.send.api.subcomponents.destination.SendDestinationBlockComponent
import com.tangem.features.send.api.subcomponents.destination.SendDestinationComponentParams
import com.tangem.features.send.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.swap.v2.impl.amount.SwapAmountBlockComponent
import com.tangem.features.swap.v2.impl.amount.SwapAmountComponentParams
import com.tangem.features.swap.v2.impl.common.SwapUtils.SEND_WITH_SWAP_PROVIDER_TYPES
@ -40,7 +41,7 @@ import kotlinx.coroutines.flow.*
internal class SendWithSwapConfirmComponent @AssistedInject constructor(
@Assisted private val appComponentContext: AppComponentContext,
@Assisted private val params: Params,
sendDestinationBlockComponent: SendDestinationBlockComponent.Factory,
sendDestinationBlockComponentFactory: SendDestinationBlockComponent.Factory,
feeSelectorBlockComponentFactory: FeeSelectorBlockComponent.Factory,
sendNotificationsComponentFactory: SendNotificationsComponent.Factory,
) : ComposableContentComponent, AppComponentContext by appComponentContext {
@ -69,7 +70,7 @@ internal class SendWithSwapConfirmComponent @AssistedInject constructor(
onClick = model::showEditAmount,
)
private val sendDestinationBlockComponent = sendDestinationBlockComponent.create(
private val sendDestinationBlockComponent = sendDestinationBlockComponentFactory.create(
context = child("sendWithSwapConfirmDestinationBlock"),
params = SendDestinationComponentParams.DestinationBlockParams(
state = model.uiState.value.destinationUM,
@ -81,7 +82,8 @@ internal class SendWithSwapConfirmComponent @AssistedInject constructor(
predefinedValues = PredefinedValues.Empty,
isAllowSelfSend = true,
),
onResult = model::onDestinationResult,
// No feedback: the read-only block is driven one-way by the model.uiState collector ([REDACTED_TASK_KEY]).
onResult = {},
onClick = model::showEditDestination,
)
@ -151,15 +153,29 @@ internal class SendWithSwapConfirmComponent @AssistedInject constructor(
val confirmUM = state.confirmUM as? ConfirmUM.Content
blockClickEnableFlow.value = confirmUM?.isTransactionInProcess == false
}.launchIn(componentScope)
// Single source of truth: the block always mirrors the model's authoritative destinationUM.
model.uiState
.map { it.destinationUM }
.distinctUntilChanged()
.onEach(sendDestinationBlockComponent::updateState)
.launchIn(componentScope)
}
fun updateState(sendWithSwapUM: SendWithSwapUM) {
amountBlockComponent.updateState(sendWithSwapUM.amountUM)
sendDestinationBlockComponent.updateState(sendWithSwapUM.destinationUM)
feeSelectorBlockComponent.updateState(sendWithSwapUM.feeSelectorUM)
model.updateState(sendWithSwapUM)
}
// Re-sync destination from parent on Confirm entry, bypassing the edit-mode gate; Empty only occurs on
// reset (which leaves Confirm), so only Content is applied ([REDACTED_TASK_KEY]).
fun updateDestinationState(destinationUM: DestinationUM) {
if (destinationUM is DestinationUM.Content && destinationUM != model.uiState.value.destinationUM) {
model.onDestinationResult(destinationUM)
}
}
@Composable
override fun Content(modifier: Modifier) {
val sendWithSwapUM by model.uiState.collectAsStateWithLifecycle()