From adaa72f359d491ea0e7c659bdffa5178be6f8c64 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 25 Apr 2024 14:12:17 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../impl/presentation/state/SendUiState.kt | 56 +++++++++- .../impl/presentation/state/StateRouter.kt | 47 ++++++-- .../state/common/SendSyncEditConverter.kt | 26 +++++ .../state/previewdata/SendClickIntentsStub.kt | 2 +- .../send/impl/presentation/ui/SendScreen.kt | 103 +++++++++++------- .../viewmodel/SendClickIntents.kt | 2 +- 6 files changed, 184 insertions(+), 52 deletions(-) create mode 100644 features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/common/SendSyncEditConverter.kt diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendUiState.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendUiState.kt index 043f45837f..23453c4b4d 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendUiState.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendUiState.kt @@ -28,9 +28,58 @@ internal data class SendUiState( val recipientState: SendStates.RecipientState? = null, val feeState: SendStates.FeeState? = null, val sendState: SendStates.SendState? = null, + val editAmountState: SendStates.AmountState? = null, + val editRecipientState: SendStates.RecipientState? = null, + val editFeeState: SendStates.FeeState? = null, val isBalanceHidden: Boolean, val event: StateEvent, -) +) { + + fun getAmountState(isEditState: Boolean): SendStates.AmountState? { + return if (isEditState) { + editAmountState + } else { + amountState + } + } + + fun getRecipientState(isEditState: Boolean): SendStates.RecipientState? { + return if (isEditState) { + editRecipientState + } else { + recipientState + } + } + + fun getFeeState(isEditState: Boolean): SendStates.FeeState? { + return if (isEditState) { + editFeeState + } else { + feeState + } + } + + fun copyWrapped( + isEditState: Boolean, + amountState: SendStates.AmountState? = this.amountState, + feeState: SendStates.FeeState? = this.feeState, + recipientState: SendStates.RecipientState? = this.recipientState, + sendState: SendStates.SendState? = this.sendState, + ): SendUiState = if (isEditState) { + copy( + editAmountState = amountState, + editFeeState = feeState, + editRecipientState = recipientState, + ) + } else { + copy( + amountState = amountState, + feeState = feeState, + recipientState = recipientState, + sendState = sendState, + ) + } +} @Stable internal sealed class SendStates { @@ -105,6 +154,9 @@ enum class SendUiStateType { None, Recipient, Amount, - Send, Fee, + Send, + EditAmount, + EditRecipient, + EditFee, } \ 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 079dbfdb6f..5f2201052b 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 @@ -18,6 +18,9 @@ internal class StateRouter( val currentState: StateFlow get() = mutableCurrentState + val isEditState: Boolean + get() = currentState.value.isFromConfirmation + fun clear() { mutableCurrentState.update { getInitState() } } @@ -35,21 +38,29 @@ internal class StateRouter( else -> popBackStack() } else -> when (type) { - SendUiStateType.Amount -> continueToSend(::showRecipient) + SendUiStateType.Amount -> showRecipient() SendUiStateType.Fee -> showSend() - SendUiStateType.Send -> continueToSend(::showAmount) - else -> continueToSend(::popBackStack) + SendUiStateType.Send -> showAmount() + SendUiStateType.Recipient -> popBackStack() + SendUiStateType.EditAmount -> showSend() + SendUiStateType.EditRecipient -> showSend() + SendUiStateType.EditFee -> showSend() + else -> popBackStack() } } } fun onNextClick() { when (currentState.value.type) { - SendUiStateType.Recipient -> continueToSend(::showAmount) + SendUiStateType.Recipient -> showAmount() SendUiStateType.Amount, SendUiStateType.Fee, + SendUiStateType.EditAmount, + SendUiStateType.EditRecipient, + SendUiStateType.EditFee, -> showSend() SendUiStateType.Send -> onBackClick() + else -> popBackStack() } } @@ -67,17 +78,35 @@ internal class StateRouter( fun showAmount(isFromConfirmation: Boolean = false) { analyticsEventsHandler.send(SendAnalyticEvents.AmountScreenOpened) - mutableCurrentState.update { SendUiCurrentScreen(SendUiStateType.Amount, isFromConfirmation) } + mutableCurrentState.update { + if (isFromConfirmation) { + SendUiCurrentScreen(SendUiStateType.EditAmount, true) + } else { + SendUiCurrentScreen(SendUiStateType.Amount, false) + } + } } fun showRecipient(isFromConfirmation: Boolean = false) { analyticsEventsHandler.send(SendAnalyticEvents.AddressScreenOpened) - mutableCurrentState.update { SendUiCurrentScreen(SendUiStateType.Recipient, isFromConfirmation) } + mutableCurrentState.update { + if (isFromConfirmation) { + SendUiCurrentScreen(SendUiStateType.EditRecipient, true) + } else { + SendUiCurrentScreen(SendUiStateType.Recipient, false) + } + } } fun showFee(isFromConfirmation: Boolean = false) { analyticsEventsHandler.send(SendAnalyticEvents.FeeScreenOpened) - mutableCurrentState.update { SendUiCurrentScreen(SendUiStateType.Fee, isFromConfirmation) } + mutableCurrentState.update { + if (isFromConfirmation) { + SendUiCurrentScreen(SendUiStateType.EditFee, true) + } else { + SendUiCurrentScreen(SendUiStateType.Fee, false) + } + } } fun showSend() { @@ -85,10 +114,6 @@ internal class StateRouter( mutableCurrentState.update { SendUiCurrentScreen(SendUiStateType.Send, isFromConfirmation = false) } } - private fun continueToSend(show: () -> Unit) { - if (currentState.value.isFromConfirmation) showSend() else show() - } - private fun getInitState() = if (isEditingDisabled) { SendUiCurrentScreen( type = SendUiStateType.None, diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/common/SendSyncEditConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/common/SendSyncEditConverter.kt new file mode 100644 index 0000000000..f0abbba036 --- /dev/null +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/common/SendSyncEditConverter.kt @@ -0,0 +1,26 @@ +package com.tangem.features.send.impl.presentation.state.common + +import com.tangem.features.send.impl.presentation.state.SendUiState +import com.tangem.utils.Provider +import com.tangem.utils.converter.Converter + +internal class SendSyncEditConverter( + private val currentStateProvider: Provider, +) : Converter { + override fun convert(value: Boolean): SendUiState { + val state = currentStateProvider() + return if (value) { + state.copy( + amountState = state.editAmountState, + feeState = state.editFeeState, + recipientState = state.editRecipientState, + ) + } else { + state.copy( + editAmountState = state.amountState, + editRecipientState = state.recipientState, + editFeeState = state.feeState, + ) + } + } +} \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/SendClickIntentsStub.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/SendClickIntentsStub.kt index 5235588e51..0a113ea474 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/SendClickIntentsStub.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/SendClickIntentsStub.kt @@ -14,7 +14,7 @@ internal object SendClickIntentsStub : SendClickIntents { override fun onBackClick() {} - override fun onNextClick() {} + override fun onNextClick(isFromEdit: Boolean) {} override fun onPrevClick() {} diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt index ffa3bf5d06..b289867885 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt @@ -1,8 +1,11 @@ package com.tangem.features.send.impl.presentation.ui import androidx.activity.compose.BackHandler -import androidx.compose.animation.* +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.core.tween +import androidx.compose.animation.togetherWith import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.material3.SnackbarHostState @@ -23,12 +26,13 @@ import com.tangem.features.send.impl.presentation.ui.fee.SendSpeedAndFeeContent import com.tangem.features.send.impl.presentation.ui.recipient.SendRecipientContent import com.tangem.features.send.impl.presentation.ui.send.SendContent import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.withIndex @Composable internal fun SendScreen(uiState: SendUiState, currentState: SendUiCurrentScreen) { val snackbarHostState = remember { SnackbarHostState() } - val sendState = uiState.sendState ?: return BackHandler { uiState.clickIntents.onBackClick() } Column( modifier = Modifier @@ -38,38 +42,9 @@ internal fun SendScreen(uiState: SendUiState, currentState: SendUiCurrentScreen) .background(color = TangemTheme.colors.background.tertiary), horizontalAlignment = Alignment.CenterHorizontally, ) { - val titleRes = when (currentState.type) { - SendUiStateType.Amount -> resourceReference(R.string.send_amount_label) - SendUiStateType.Recipient -> resourceReference(R.string.send_recipient_label) - SendUiStateType.Fee -> resourceReference(R.string.common_fee_selector_title) - SendUiStateType.Send -> if (!sendState.isSuccess) { - resourceReference(R.string.send_summary_title, wrappedList(uiState.cryptoCurrencyName)) - } else { - null - } - else -> null - } - val isSending = currentState.type == SendUiStateType.Send && !uiState.sendState.isSuccess - val subtitleRes = if (isSending) { - uiState.amountState?.walletName - } else { - null - } - val iconRes = if (currentState.type == SendUiStateType.Recipient) { - R.drawable.ic_qrcode_scan_24 - } else { - null - } - - AppBarWithBackButtonAndIcon( - text = titleRes?.resolveReference(), - subtitle = subtitleRes, - onBackClick = uiState.clickIntents::popBackStack, - onIconClick = uiState.clickIntents::onQrCodeScanClick, - backIconRes = R.drawable.ic_close_24, - iconRes = iconRes, - backgroundColor = TangemTheme.colors.background.tertiary, - modifier = Modifier.height(TangemTheme.dimens.size56), + SendAppBar( + uiState = uiState, + currentState = currentState, ) SendScreenContent( uiState = uiState, @@ -88,6 +63,50 @@ internal fun SendScreen(uiState: SendUiState, currentState: SendUiCurrentScreen) ) } +@Composable +private fun SendAppBar(uiState: SendUiState, currentState: SendUiCurrentScreen) { + val (titleRes, subtitleRes) = when (currentState.type) { + SendUiStateType.Amount, + SendUiStateType.EditAmount, + -> resourceReference(R.string.send_amount_label) to null + SendUiStateType.Recipient, + SendUiStateType.EditRecipient, + -> resourceReference(R.string.send_recipient_label) to null + SendUiStateType.Fee, + SendUiStateType.EditFee, + -> resourceReference(R.string.common_fee_selector_title) to null + SendUiStateType.Send -> if (uiState.sendState?.isSuccess == false) { + resourceReference(R.string.send_summary_title, wrappedList(uiState.cryptoCurrencyName)) to + uiState.amountState?.walletName + } else { + null to null + } + else -> null to null + } + val iconRes = if (currentState.type == SendUiStateType.Recipient) { + R.drawable.ic_qrcode_scan_24 + } else { + null + } + val (backIcon, backClick) = when (currentState.type) { + SendUiStateType.EditAmount, + SendUiStateType.EditFee, + SendUiStateType.EditRecipient, + -> R.drawable.ic_back_24 to uiState.clickIntents::onBackClick + else -> R.drawable.ic_close_24 to uiState.clickIntents::popBackStack + } + AppBarWithBackButtonAndIcon( + text = titleRes?.resolveReference(), + subtitle = subtitleRes, + onBackClick = backClick, + onIconClick = uiState.clickIntents::onQrCodeScanClick, + backIconRes = backIcon, + iconRes = iconRes, + backgroundColor = TangemTheme.colors.background.tertiary, + modifier = Modifier.height(TangemTheme.dimens.size56), + ) +} + @OptIn(ExperimentalAnimationApi::class) @Composable private fun SendScreenContent(uiState: SendUiState, currentState: SendUiCurrentScreen, modifier: Modifier = Modifier) { @@ -135,13 +154,23 @@ private fun SendScreenContent(uiState: SendUiState, currentState: SendUiCurrentS isBalanceHiding = uiState.isBalanceHidden, clickIntents = uiState.clickIntents, ) + SendUiStateType.EditAmount -> SendAmountContent( + amountState = uiState.editAmountState, + isBalanceHiding = uiState.isBalanceHidden, + clickIntents = uiState.clickIntents, + ) SendUiStateType.Recipient -> SendRecipientContent( uiState = uiState.recipientState, clickIntents = uiState.clickIntents, isBalanceHidden = uiState.isBalanceHidden, ) - SendUiStateType.Fee -> SendSpeedAndFeeContent( - state = uiState.feeState, + SendUiStateType.EditRecipient -> SendRecipientContent( + uiState = uiState.editRecipientState, + clickIntents = uiState.clickIntents, + isBalanceHidden = uiState.isBalanceHidden, + ) + SendUiStateType.EditFee -> SendSpeedAndFeeContent( + state = uiState.editFeeState, clickIntents = uiState.clickIntents, ) SendUiStateType.Send -> SendContent(uiState) diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt index a353059047..f0715cd50a 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt @@ -14,7 +14,7 @@ internal interface SendClickIntents { fun onBackClick() - fun onNextClick() + fun onNextClick(isFromEdit: Boolean = false) fun onPrevClick()