Updated on 2026-08-14
This commit is contained in:
parent
e8a2b10e6f
commit
c1900053f7
27 changed files with 270 additions and 107 deletions
|
|
@ -9,11 +9,11 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import com.tangem.common.ui.amountScreen.ui.amountField
|
||||
import com.tangem.common.ui.amountScreen.ui.buttons
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.amountScreen.preview.AmountScreenClickIntentsStub
|
||||
import com.tangem.common.ui.amountScreen.preview.AmountStatePreviewData
|
||||
import com.tangem.common.ui.amountScreen.ui.amountField
|
||||
import com.tangem.common.ui.amountScreen.ui.buttons
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
||||
|
|
@ -25,6 +25,8 @@ import com.tangem.core.ui.res.TangemThemePreview
|
|||
*/
|
||||
@Composable
|
||||
fun AmountScreenContent(amountState: AmountState, isBalanceHiding: Boolean, clickIntents: AmountScreenClickIntents) {
|
||||
if (amountState !is AmountState.Data) return
|
||||
|
||||
// Do not put fillMaxSize() in here
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
|
|
|
|||
|
|
@ -5,21 +5,24 @@ import androidx.compose.ui.text.input.ImeAction
|
|||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.isNullOrZero
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
/**
|
||||
* Selected currency change from crypto currency to app currency and vice versa
|
||||
*
|
||||
* @property cryptoCurrencyStatusProvider current cryptocurrency status provider
|
||||
* @property cryptoCurrencyStatus current cryptocurrency status
|
||||
* @property value is crypto currency or app currency
|
||||
*/
|
||||
class AmountCurrencyTransformer(
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
) : Transformer<AmountState, Boolean> {
|
||||
override fun transform(prevState: AmountState, value: Boolean): AmountState {
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val value: Boolean,
|
||||
) : Transformer<AmountState> {
|
||||
|
||||
override fun transform(prevState: AmountState): AmountState {
|
||||
if (prevState !is AmountState.Data) return prevState
|
||||
|
||||
val amountTextField = prevState.amountTextField
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
|
||||
val isValidFiatRate = cryptoCurrencyStatus.value.fiatRate.isNullOrZero()
|
||||
val isDoneActionEnabled = prevState.isPrimaryButtonEnabled
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ import com.tangem.utils.transformer.Transformer
|
|||
/**
|
||||
* Dismisses indication on pasted value
|
||||
*/
|
||||
class AmountPastedTriggerDismissTransformer : Transformer<AmountState, Boolean> {
|
||||
override fun transform(prevState: AmountState, value: Boolean): AmountState {
|
||||
class AmountPastedTriggerDismissTransformer : Transformer<AmountState> {
|
||||
override fun transform(prevState: AmountState): AmountState {
|
||||
if (prevState !is AmountState.Data) return prevState
|
||||
|
||||
return prevState.copy(
|
||||
amountTextField = prevState.amountTextField.copy(
|
||||
isValuePasted = false,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.tangem.common.ui.amountScreen.utils.getFiatValue
|
|||
import com.tangem.common.ui.amountScreen.utils.getKeyboardAction
|
||||
import com.tangem.core.ui.utils.parseBigDecimal
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.isNullOrZero
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -16,13 +15,16 @@ import java.math.BigDecimal
|
|||
/**
|
||||
* Reduces amount by specific value
|
||||
*
|
||||
* @property cryptoCurrencyStatusProvider current cryptocurrency status provider
|
||||
* @property cryptoCurrencyStatus current cryptocurrency status
|
||||
* @property value reduced by value
|
||||
*/
|
||||
class AmountReduceByTransformer(
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
) : Transformer<AmountState, AmountReduceByTransformer.ReduceByData> {
|
||||
override fun transform(prevState: AmountState, value: ReduceByData): AmountState {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val value: ReduceByData,
|
||||
) : Transformer<AmountState> {
|
||||
override fun transform(prevState: AmountState): AmountState {
|
||||
if (prevState !is AmountState.Data) return prevState
|
||||
|
||||
val amountTextField = prevState.amountTextField
|
||||
val cryptoDecimals = amountTextField.cryptoAmount.decimals
|
||||
val fiatDecimals = amountTextField.fiatAmount.decimals
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.tangem.common.ui.amountScreen.utils.getFiatValue
|
|||
import com.tangem.common.ui.amountScreen.utils.getKeyboardAction
|
||||
import com.tangem.core.ui.utils.parseBigDecimal
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.isNullOrZero
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -16,13 +15,16 @@ import java.math.BigDecimal
|
|||
/**
|
||||
* Reduces amount to specific value
|
||||
*
|
||||
* @property cryptoCurrencyStatusProvider current cryptocurrency status provider
|
||||
* @property cryptoCurrencyStatus current cryptocurrency status
|
||||
* @property value reduced to value
|
||||
*/
|
||||
class AmountReduceToTransformer(
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
) : Transformer<AmountState, BigDecimal> {
|
||||
override fun transform(prevState: AmountState, value: BigDecimal): AmountState {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val value: BigDecimal,
|
||||
) : Transformer<AmountState> {
|
||||
override fun transform(prevState: AmountState): AmountState {
|
||||
if (prevState !is AmountState.Data) return prevState
|
||||
|
||||
val amountTextField = prevState.amountTextField
|
||||
val cryptoDecimals = amountTextField.cryptoAmount.decimals
|
||||
val fiatDecimals = amountTextField.fiatAmount.decimals
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class AmountStateConverter(
|
|||
val crypto = formatCryptoAmount(status.value.amount, status.currency.symbol, status.currency.decimals)
|
||||
val noFeeRate = status.value.fiatRate.isNullOrZero()
|
||||
|
||||
return AmountState(
|
||||
return AmountState.Data(
|
||||
walletName = userWallet.name,
|
||||
walletBalance = resourceReference(R.string.send_wallet_balance_format, wrappedList(crypto, fiat)),
|
||||
tokenIconState = iconStateConverter.convert(status),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import com.tangem.common.ui.amountScreen.utils.getFiatValue
|
|||
import com.tangem.common.ui.amountScreen.utils.getKeyboardAction
|
||||
import com.tangem.core.ui.utils.parseToBigDecimal
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.isNullOrZero
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -17,14 +16,17 @@ import java.math.BigDecimal
|
|||
/**
|
||||
* Amount value change
|
||||
*
|
||||
* @property cryptoCurrencyStatusProvider current cryptocurrency status provider
|
||||
* @property cryptoCurrencyStatus current cryptocurrency status
|
||||
* @property value amount value
|
||||
*/
|
||||
class AmountFieldChangeTransformer(
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
) : Transformer<AmountState, String> {
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val value: String,
|
||||
) : Transformer<AmountState> {
|
||||
|
||||
override fun transform(prevState: AmountState): AmountState {
|
||||
if (prevState !is AmountState.Data) return prevState
|
||||
|
||||
override fun transform(prevState: AmountState, value: String): AmountState {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val amountTextField = prevState.amountTextField
|
||||
|
||||
if (value.isEmpty()) return prevState.emptyState()
|
||||
|
|
@ -67,7 +69,7 @@ class AmountFieldChangeTransformer(
|
|||
)
|
||||
}
|
||||
|
||||
private fun AmountState.emptyState(): AmountState {
|
||||
private fun AmountState.Data.emptyState(): AmountState.Data {
|
||||
return copy(
|
||||
isPrimaryButtonEnabled = false,
|
||||
amountTextField = amountTextField.copy(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import androidx.compose.ui.text.input.KeyboardType
|
|||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.core.ui.utils.parseBigDecimal
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.isNullOrZero
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import java.math.RoundingMode
|
||||
|
|
@ -14,14 +13,15 @@ import java.math.RoundingMode
|
|||
/**
|
||||
* Selects maximum amount value
|
||||
*
|
||||
* @property cryptoCurrencyStatusProvider current cryptocurrency status provider
|
||||
* @property cryptoCurrencyStatus current cryptocurrency status
|
||||
*/
|
||||
class AmountFieldMaxAmountTransformer(
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
) : Transformer<AmountState, Unit> {
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
) : Transformer<AmountState> {
|
||||
|
||||
override fun transform(prevState: AmountState): AmountState {
|
||||
if (prevState !is AmountState.Data) return prevState
|
||||
|
||||
override fun transform(prevState: AmountState, value: Unit): AmountState {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val amountTextField = prevState.amountTextField
|
||||
|
||||
val cryptoDecimals = amountTextField.cryptoAmount.decimals
|
||||
|
|
|
|||
|
|
@ -5,28 +5,36 @@ import com.tangem.core.ui.components.currency.tokenicon.TokenIconState
|
|||
import com.tangem.core.ui.extensions.TextReference
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
|
||||
/**
|
||||
* Model for amount state
|
||||
*
|
||||
* @param isPrimaryButtonEnabled indicates if next state button enabled
|
||||
* @param walletName user wallet name
|
||||
* @param walletBalance user crypto currency balance in wallet
|
||||
* @param tokenIconState crypto currency icon state
|
||||
* @param segmentedButtonConfig currency switcher config
|
||||
* @param selectedButton selected currency index
|
||||
* @param isSegmentedButtonsEnabled indicates if currency switches is enabled
|
||||
* @param amountTextField amount field state
|
||||
* @param appCurrencyCode app currency code
|
||||
*/
|
||||
/** Model for amount state */
|
||||
@Stable
|
||||
data class AmountState(
|
||||
val isPrimaryButtonEnabled: Boolean,
|
||||
val walletName: String,
|
||||
val walletBalance: TextReference,
|
||||
val tokenIconState: TokenIconState,
|
||||
val segmentedButtonConfig: PersistentList<AmountSegmentedButtonsConfig>,
|
||||
val selectedButton: Int,
|
||||
val isSegmentedButtonsEnabled: Boolean,
|
||||
val amountTextField: AmountFieldModel,
|
||||
val appCurrencyCode: String,
|
||||
)
|
||||
sealed class AmountState {
|
||||
|
||||
abstract val isPrimaryButtonEnabled: Boolean
|
||||
|
||||
/**
|
||||
* @param isPrimaryButtonEnabled indicates if next state button enabled
|
||||
* @param walletName user wallet name
|
||||
* @param walletBalance user crypto currency balance in wallet
|
||||
* @param tokenIconState crypto currency icon state
|
||||
* @param segmentedButtonConfig currency switcher config
|
||||
* @param selectedButton selected currency index
|
||||
* @param isSegmentedButtonsEnabled indicates if currency switches is enabled
|
||||
* @param amountTextField amount field state
|
||||
* @param appCurrencyCode app currency code
|
||||
*/
|
||||
data class Data(
|
||||
override val isPrimaryButtonEnabled: Boolean,
|
||||
val walletName: String,
|
||||
val walletBalance: TextReference,
|
||||
val tokenIconState: TokenIconState,
|
||||
val segmentedButtonConfig: PersistentList<AmountSegmentedButtonsConfig>,
|
||||
val selectedButton: Int,
|
||||
val isSegmentedButtonsEnabled: Boolean,
|
||||
val amountTextField: AmountFieldModel,
|
||||
val appCurrencyCode: String,
|
||||
) : AmountState()
|
||||
|
||||
data class Empty(
|
||||
override val isPrimaryButtonEnabled: Boolean = false,
|
||||
) : AmountState()
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ import java.math.BigDecimal
|
|||
|
||||
object AmountStatePreviewData {
|
||||
|
||||
val amountState = AmountState(
|
||||
val amountState = AmountState.Data(
|
||||
isPrimaryButtonEnabled = false,
|
||||
walletName = "Family Wallet",
|
||||
walletBalance = stringReference("2 130,88 USDT (2 129,92 \$)"),
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import com.tangem.utils.Strings.STARS
|
|||
private const val AMOUNT_FIELD_KEY = "amountFieldKey"
|
||||
|
||||
internal fun LazyListScope.amountField(
|
||||
amountState: AmountState,
|
||||
amountState: AmountState.Data,
|
||||
isBalanceHiding: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
package com.tangem.utils.transformer
|
||||
|
||||
interface Transformer<S, V> {
|
||||
fun transform(prevState: S, value: V): S
|
||||
/**
|
||||
* Transforms state to updated state.
|
||||
*/
|
||||
interface Transformer<S> {
|
||||
fun transform(prevState: S): S
|
||||
}
|
||||
|
|
@ -56,9 +56,13 @@ dependencies {
|
|||
implementation(projects.domain.staking)
|
||||
implementation(projects.domain.balanceHiding)
|
||||
implementation(projects.domain.balanceHiding.models)
|
||||
implementation(projects.domain.appCurrency)
|
||||
implementation(projects.domain.appCurrency.models)
|
||||
implementation(projects.domain.legacy)
|
||||
implementation(projects.domain.models)
|
||||
|
||||
/** Common */
|
||||
implementation(projects.common)
|
||||
implementation(projects.common.ui)
|
||||
|
||||
/** Libs */
|
||||
implementation(projects.libs.crypto)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
package com.tangem.features.staking.impl.presentation.state
|
||||
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.core.ui.event.consumedEvent
|
||||
import com.tangem.features.staking.impl.presentation.state.stub.StakingClickIntentsStub
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.StakingScreenStateTransformer
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
|
@ -23,7 +24,7 @@ internal class StakingStateController @Inject constructor() {
|
|||
mutableUiState.update(function = function)
|
||||
}
|
||||
|
||||
fun update(transformer: StakingScreenStateTransformer) {
|
||||
fun update(transformer: Transformer<StakingUiState>) {
|
||||
mutableUiState.update(function = transformer::transform)
|
||||
}
|
||||
|
||||
|
|
@ -37,7 +38,7 @@ internal class StakingStateController @Inject constructor() {
|
|||
cryptoCurrencyName = "",
|
||||
currentStep = StakingStep.InitialInfo,
|
||||
initialInfoState = StakingStates.InitialInfoState.Empty(),
|
||||
amountState = StakingStates.AmountState.Empty(),
|
||||
amountState = AmountState.Empty(),
|
||||
validatorState = StakingStates.ValidatorState.Empty(),
|
||||
confirmStakingState = StakingStates.ConfirmStakingState.Empty(),
|
||||
isBalanceHidden = false,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.staking.impl.presentation.state
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.core.ui.event.StateEvent
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickIntents
|
||||
|
|
@ -14,7 +15,7 @@ internal data class StakingUiState(
|
|||
val cryptoCurrencyName: String,
|
||||
val currentStep: StakingStep,
|
||||
val initialInfoState: StakingStates.InitialInfoState,
|
||||
val amountState: StakingStates.AmountState,
|
||||
val amountState: AmountState,
|
||||
val validatorState: StakingStates.ValidatorState,
|
||||
val confirmStakingState: StakingStates.ConfirmStakingState,
|
||||
val isBalanceHidden: Boolean,
|
||||
|
|
@ -23,7 +24,7 @@ internal data class StakingUiState(
|
|||
|
||||
fun copyWrapped(
|
||||
initialInfoState: StakingStates.InitialInfoState = this.initialInfoState,
|
||||
amountState: StakingStates.AmountState = this.amountState,
|
||||
amountState: AmountState = this.amountState,
|
||||
validatorState: StakingStates.ValidatorState = this.validatorState,
|
||||
confirmStakingState: StakingStates.ConfirmStakingState = this.confirmStakingState,
|
||||
): StakingUiState = copy(
|
||||
|
|
@ -57,17 +58,6 @@ internal sealed class StakingStates {
|
|||
) : InitialInfoState()
|
||||
}
|
||||
|
||||
/** Amount state */
|
||||
sealed class AmountState : StakingStates() {
|
||||
data class Data(
|
||||
override val isPrimaryButtonEnabled: Boolean,
|
||||
) : AmountState()
|
||||
|
||||
data class Empty(
|
||||
override val isPrimaryButtonEnabled: Boolean = false,
|
||||
) : AmountState()
|
||||
}
|
||||
|
||||
/** Validator state */
|
||||
sealed class ValidatorState : StakingStates() {
|
||||
data class Data(
|
||||
|
|
|
|||
|
|
@ -9,4 +9,14 @@ object StakingClickIntentsStub : StakingClickIntents {
|
|||
override fun onNextClick() {}
|
||||
|
||||
override fun onPrevClick() {}
|
||||
|
||||
override fun onAmountValueChange(value: String) {}
|
||||
|
||||
override fun onAmountPasteTriggerDismiss() {}
|
||||
|
||||
override fun onMaxValueClick() {}
|
||||
|
||||
override fun onCurrencyChangeClick(isFiat: Boolean) {}
|
||||
|
||||
override fun onAmountNext() {}
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers
|
||||
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class HideBalanceStateTransformer(
|
||||
private val isBalanceHidden: Boolean,
|
||||
) : StakingScreenStateTransformer {
|
||||
) : Transformer<StakingUiState> {
|
||||
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
return prevState.copy(isBalanceHidden = isBalanceHidden)
|
||||
|
|
|
|||
|
|
@ -1,31 +1,52 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers
|
||||
|
||||
import com.tangem.common.ui.amountScreen.converters.AmountStateConverter
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.core.ui.components.currency.tokenicon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.staking.model.Yield
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.features.staking.impl.R
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStep
|
||||
import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickIntents
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import java.math.BigDecimal
|
||||
|
||||
internal class SetInitialDataStateTransformer(
|
||||
private val clickIntents: StakingClickIntents,
|
||||
private val yield: Yield,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
) : StakingScreenStateTransformer {
|
||||
private val userWalletProvider: Provider<UserWallet>,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
) : Transformer<StakingUiState> {
|
||||
|
||||
private val iconStateConverter by lazy(::CryptoCurrencyToIconStateConverter)
|
||||
|
||||
private val amountStateConverter by lazy(LazyThreadSafetyMode.NONE) {
|
||||
AmountStateConverter(
|
||||
clickIntents = clickIntents,
|
||||
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
|
||||
appCurrencyProvider = appCurrencyProvider,
|
||||
userWalletProvider = userWalletProvider,
|
||||
iconStateConverter = iconStateConverter,
|
||||
)
|
||||
}
|
||||
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
return prevState.copy(
|
||||
clickIntents = clickIntents,
|
||||
currentStep = StakingStep.InitialInfo,
|
||||
initialInfoState = createInitialInfoState(),
|
||||
amountState = createInitialAmountState(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -50,6 +71,10 @@ internal class SetInitialDataStateTransformer(
|
|||
)
|
||||
}
|
||||
|
||||
private fun createInitialAmountState(): AmountState {
|
||||
return amountStateConverter.convert("")
|
||||
}
|
||||
|
||||
private fun getAprRange(): TextReference {
|
||||
val aprValues = yield.validators.mapNotNull { it.apr }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers
|
||||
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
|
||||
internal interface StakingScreenStateTransformer {
|
||||
|
||||
fun transform(prevState: StakingUiState): StakingUiState
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers.amount
|
||||
|
||||
import com.tangem.common.ui.amountScreen.converters.field.AmountFieldChangeTransformer
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class AmountChangeStateTransformer(
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val value: String,
|
||||
) : Transformer<StakingUiState> {
|
||||
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
return prevState.copy(
|
||||
amountState = AmountFieldChangeTransformer(cryptoCurrencyStatus, value).transform(prevState.amountState),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers.amount
|
||||
|
||||
import com.tangem.common.ui.amountScreen.converters.AmountCurrencyTransformer
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class AmountCurrencyChangeStateTransformer(
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val value: Boolean,
|
||||
) : Transformer<StakingUiState> {
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
return prevState.copy(
|
||||
amountState = AmountCurrencyTransformer(cryptoCurrencyStatus, value).transform(prevState.amountState),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers.amount
|
||||
|
||||
import com.tangem.common.ui.amountScreen.converters.field.AmountFieldMaxAmountTransformer
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class AmountMaxValueStateTransformer(
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
) : Transformer<StakingUiState> {
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
return prevState.copy(
|
||||
amountState = AmountFieldMaxAmountTransformer(cryptoCurrencyStatus).transform(prevState.amountState),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers.amount
|
||||
|
||||
import com.tangem.common.ui.amountScreen.converters.AmountPastedTriggerDismissTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class AmountPasteDismissStateTransformer : Transformer<StakingUiState> {
|
||||
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
return prevState.copy(
|
||||
amountState = AmountPastedTriggerDismissTransformer().transform(prevState.amountState),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package com.tangem.features.staking.impl.presentation.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
|
||||
@Composable
|
||||
internal fun StakingAmountContent(state: StakingStates.AmountState) {
|
||||
if (state !is StakingStates.AmountState.Data) return
|
||||
|
||||
// TODO staking
|
||||
}
|
||||
|
|
@ -12,11 +12,12 @@ import androidx.compose.runtime.*
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.tangem.common.ui.amountScreen.AmountScreenContent
|
||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButtonAndIcon
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.staking.impl.R
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStep
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
|
@ -121,8 +122,10 @@ private fun StakingScreenContent(uiState: StakingUiState, modifier: Modifier = M
|
|||
StakingStep.InitialInfo -> StakingInitialInfoContent(
|
||||
state = uiState.initialInfoState,
|
||||
)
|
||||
StakingStep.Amount -> StakingAmountContent(
|
||||
state = uiState.amountState,
|
||||
StakingStep.Amount -> AmountScreenContent(
|
||||
amountState = uiState.amountState,
|
||||
isBalanceHiding = uiState.isBalanceHidden,
|
||||
clickIntents = uiState.clickIntents,
|
||||
)
|
||||
StakingStep.ValidatorAndFee -> StakingValidatorAndFeeContent(
|
||||
state = uiState.validatorState,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
package com.tangem.features.staking.impl.presentation.viewmodel
|
||||
|
||||
internal interface StakingClickIntents {
|
||||
import com.tangem.common.ui.amountScreen.AmountScreenClickIntents
|
||||
|
||||
internal interface StakingClickIntents : AmountScreenClickIntents {
|
||||
|
||||
fun onBackClick()
|
||||
|
||||
fun onNextClick()
|
||||
|
||||
fun onPrevClick()
|
||||
|
||||
override fun onAmountNext() = onNextClick()
|
||||
}
|
||||
|
|
@ -4,19 +4,28 @@ import androidx.lifecycle.DefaultLifecycleObserver
|
|||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.staking.model.Yield
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyStatusSyncUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.features.staking.api.navigation.StakingRouter
|
||||
import com.tangem.features.staking.impl.navigation.InnerStakingRouter
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStateController
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStateRouter
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.HideBalanceStateTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.SetInitialDataStateTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.amount.AmountChangeStateTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.amount.AmountCurrencyChangeStateTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.amount.AmountMaxValueStateTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.amount.AmountPasteDismissStateTransformer
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
|
|
@ -25,12 +34,15 @@ import kotlinx.coroutines.launch
|
|||
import javax.inject.Inject
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@HiltViewModel
|
||||
internal class StakingViewModel @Inject constructor(
|
||||
private val stateController: StakingStateController,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val getCryptoCurrencyStatusSyncUseCase: GetCryptoCurrencyStatusSyncUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
savedStateHandle: SavedStateHandle,
|
||||
) : ViewModel(), DefaultLifecycleObserver, StakingClickIntents {
|
||||
|
||||
|
|
@ -53,6 +65,8 @@ internal class StakingViewModel @Inject constructor(
|
|||
private var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
|
||||
|
||||
private var innerRouter: InnerStakingRouter by Delegates.notNull()
|
||||
private var userWallet: UserWallet by Delegates.notNull()
|
||||
private val selectedAppCurrencyFlow: StateFlow<AppCurrency> = createSelectedAppCurrencyFlow()
|
||||
|
||||
init {
|
||||
subscribeOnBalanceHiding()
|
||||
|
|
@ -71,6 +85,22 @@ internal class StakingViewModel @Inject constructor(
|
|||
stakingStateRouter.onBackClick()
|
||||
}
|
||||
|
||||
override fun onAmountValueChange(value: String) {
|
||||
stateController.update(AmountChangeStateTransformer(cryptoCurrencyStatus, value))
|
||||
}
|
||||
|
||||
override fun onAmountPasteTriggerDismiss() {
|
||||
stateController.update(AmountPasteDismissStateTransformer())
|
||||
}
|
||||
|
||||
override fun onMaxValueClick() {
|
||||
stateController.update(AmountMaxValueStateTransformer(cryptoCurrencyStatus))
|
||||
}
|
||||
|
||||
override fun onCurrencyChangeClick(isFiat: Boolean) {
|
||||
stateController.update(AmountCurrencyChangeStateTransformer(cryptoCurrencyStatus, isFiat))
|
||||
}
|
||||
|
||||
fun setRouter(router: InnerStakingRouter, stateRouter: StakingStateRouter) {
|
||||
innerRouter = router
|
||||
this.stakingStateRouter = stateRouter
|
||||
|
|
@ -78,6 +108,14 @@ internal class StakingViewModel @Inject constructor(
|
|||
|
||||
private fun subscribeOnCurrencyStatusUpdates() {
|
||||
viewModelScope.launch {
|
||||
getUserWalletUseCase(userWalletId).fold(
|
||||
ifRight = { wallet ->
|
||||
userWallet = wallet
|
||||
},
|
||||
ifLeft = {
|
||||
// TODO staking error
|
||||
},
|
||||
)
|
||||
getCryptoCurrencyStatusSyncUseCase(userWalletId, cryptoCurrencyId).fold(
|
||||
ifRight = {
|
||||
cryptoCurrencyStatus = it
|
||||
|
|
@ -86,6 +124,8 @@ internal class StakingViewModel @Inject constructor(
|
|||
clickIntents = this@StakingViewModel,
|
||||
yield = yield,
|
||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
userWalletProvider = Provider { userWallet },
|
||||
appCurrencyProvider = Provider { selectedAppCurrencyFlow.value },
|
||||
),
|
||||
)
|
||||
},
|
||||
|
|
@ -106,4 +146,19 @@ internal class StakingViewModel @Inject constructor(
|
|||
.flowOn(dispatchers.main)
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
private fun createSelectedAppCurrencyFlow(): StateFlow<AppCurrency> {
|
||||
return getSelectedAppCurrencyUseCase()
|
||||
.conflate()
|
||||
.distinctUntilChanged()
|
||||
.map { maybeAppCurrency ->
|
||||
maybeAppCurrency.getOrElse { AppCurrency.Default }
|
||||
}
|
||||
.flowOn(dispatchers.main)
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.Eagerly,
|
||||
initialValue = AppCurrency.Default,
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue