Updated on 2026-08-14
This commit is contained in:
parent
27a864a0a9
commit
0e29df4ce9
45 changed files with 731 additions and 137 deletions
|
|
@ -260,7 +260,7 @@ internal object TokenDetailsPreviewData {
|
|||
bottomSheetConfig = null,
|
||||
isBalanceHidden = false,
|
||||
isMarketPriceAvailable = false,
|
||||
isStakingAvailable = false,
|
||||
isStakingBlockShown = false,
|
||||
event = consumedEvent(),
|
||||
)
|
||||
|
||||
|
|
@ -296,7 +296,7 @@ internal object TokenDetailsPreviewData {
|
|||
bottomSheetConfig = null,
|
||||
isBalanceHidden = false,
|
||||
isMarketPriceAvailable = true,
|
||||
isStakingAvailable = true,
|
||||
isStakingBlockShown = true,
|
||||
event = consumedEvent(),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,6 @@ internal data class TokenDetailsState(
|
|||
val bottomSheetConfig: TangemBottomSheetConfig?,
|
||||
val isBalanceHidden: Boolean,
|
||||
val isMarketPriceAvailable: Boolean,
|
||||
val isStakingAvailable: Boolean,
|
||||
val isStakingBlockShown: Boolean,
|
||||
val event: StateEvent<TextReference>,
|
||||
)
|
||||
|
|
@ -91,4 +91,19 @@ internal sealed class TokenDetailsActionButton(val config: ActionButtonConfig) {
|
|||
dimContent = dimContent,
|
||||
),
|
||||
)
|
||||
|
||||
/**
|
||||
* Staking
|
||||
*
|
||||
* @property dimContent determines whether the button content will be dimmed
|
||||
* @property onClick lambda be invoked when Swap button is clicked
|
||||
*/
|
||||
data class Stake(val dimContent: Boolean, override val onClick: () -> Unit) : TokenDetailsActionButton(
|
||||
config = ActionButtonConfig(
|
||||
text = TextReference.Res(id = R.string.common_stake),
|
||||
iconResId = R.drawable.ic_arrow_down_24, // TODO staking
|
||||
onClick = onClick,
|
||||
dimContent = dimContent,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -38,6 +38,12 @@ internal class TokenDetailsActionButtonsConverter(
|
|||
onLongClick = clickIntents::onCopyAddress,
|
||||
)
|
||||
}
|
||||
is TokenActionsState.ActionState.Stake -> {
|
||||
TokenDetailsActionButton.Stake(
|
||||
dimContent = action.unavailabilityReason != ScenarioUnavailabilityReason.None,
|
||||
onClick = { clickIntents.onStakeClick(action.unavailabilityReason) },
|
||||
)
|
||||
}
|
||||
is TokenActionsState.ActionState.Sell -> {
|
||||
TokenDetailsActionButton.Sell(
|
||||
dimContent = action.unavailabilityReason != ScenarioUnavailabilityReason.None,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import com.tangem.core.ui.extensions.TextReference
|
|||
import com.tangem.core.ui.extensions.networkIconResId
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.domain.staking.model.StakingAvailability
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.*
|
||||
|
|
@ -17,7 +16,6 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.Toke
|
|||
import com.tangem.features.tokendetails.featuretoggles.TokenDetailsFeatureToggles
|
||||
import com.tangem.features.tokendetails.impl.R
|
||||
import com.tangem.lib.crypto.BlockchainUtils.isBitcoin
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -27,7 +25,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
internal class TokenDetailsSkeletonStateConverter(
|
||||
private val clickIntents: TokenDetailsClickIntents,
|
||||
private val featureToggles: TokenDetailsFeatureToggles,
|
||||
private val stakingAvailabilityProvider: Provider<StakingAvailability>,
|
||||
) : Converter<CryptoCurrency, TokenDetailsState> {
|
||||
|
||||
private val iconStateConverter by lazy { TokenDetailsIconStateConverter() }
|
||||
|
|
@ -67,7 +64,7 @@ internal class TokenDetailsSkeletonStateConverter(
|
|||
bottomSheetConfig = null,
|
||||
isBalanceHidden = true,
|
||||
isMarketPriceAvailable = value.id.rawCurrencyId != null,
|
||||
isStakingAvailable = stakingAvailabilityProvider.invoke() is StakingAvailability.Available,
|
||||
isStakingBlockShown = false,
|
||||
event = consumedEvent(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
internal class TokenDetailsStateFactory(
|
||||
private val currentStateProvider: Provider<TokenDetailsState>,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val stakingAvailabilityProvider: Provider<StakingAvailability>,
|
||||
private val clickIntents: TokenDetailsClickIntents,
|
||||
private val featureToggles: TokenDetailsFeatureToggles,
|
||||
symbol: String,
|
||||
|
|
@ -55,7 +54,6 @@ internal class TokenDetailsStateFactory(
|
|||
TokenDetailsSkeletonStateConverter(
|
||||
clickIntents = clickIntents,
|
||||
featureToggles = featureToggles,
|
||||
stakingAvailabilityProvider = stakingAvailabilityProvider,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -211,6 +209,12 @@ internal class TokenDetailsStateFactory(
|
|||
)
|
||||
}
|
||||
|
||||
fun getStateWithUpdatedStakingAvailability(stakingAvailability: StakingAvailability): TokenDetailsState {
|
||||
return currentStateProvider().copy(
|
||||
isStakingBlockShown = stakingAvailability != StakingAvailability.Unavailable,
|
||||
)
|
||||
}
|
||||
|
||||
fun getStateWithStaking(stakingEither: Either<Throwable, StakingEntryInfo>): TokenDetailsState {
|
||||
return currentStateProvider().copy(
|
||||
stakingBlockState = stakingStateConverter.convert(stakingEither),
|
||||
|
|
@ -369,6 +373,12 @@ internal class TokenDetailsStateFactory(
|
|||
|
||||
private fun getUnavailabilityReasonText(unavailabilityReason: ScenarioUnavailabilityReason): TextReference {
|
||||
return when (unavailabilityReason) {
|
||||
is ScenarioUnavailabilityReason.StakingUnavailable -> {
|
||||
resourceReference(
|
||||
id = R.string.token_button_unavailability_reason_staking_unavailable,
|
||||
formatArgs = wrappedList(unavailabilityReason.cryptoCurrencyName),
|
||||
)
|
||||
}
|
||||
is ScenarioUnavailabilityReason.PendingTransaction -> {
|
||||
when (unavailabilityReason.withdrawalScenario) {
|
||||
ScenarioUnavailabilityReason.WithdrawalScenario.SEND -> resourceReference(
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ internal fun TokenDetailsScreen(state: TokenDetailsState) {
|
|||
)
|
||||
}
|
||||
|
||||
if (state.isStakingAvailable) {
|
||||
if (state.isStakingBlockShown) {
|
||||
item(
|
||||
key = StakingBlockState::class.java,
|
||||
contentType = StakingBlockState::class.java,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ interface TokenDetailsClickIntents {
|
|||
|
||||
fun onReceiveClick(unavailabilityReason: ScenarioUnavailabilityReason)
|
||||
|
||||
fun onStakeClick(unavailabilityReason: ScenarioUnavailabilityReason)
|
||||
|
||||
fun onSendClick(unavailabilityReason: ScenarioUnavailabilityReason)
|
||||
|
||||
fun onSwapClick(unavailabilityReason: ScenarioUnavailabilityReason)
|
||||
|
|
|
|||
|
|
@ -142,9 +142,6 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
private val stateFactory = TokenDetailsStateFactory(
|
||||
currentStateProvider = Provider { uiState },
|
||||
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
|
||||
stakingAvailabilityProvider = Provider {
|
||||
getStakingAvailabilityUseCase.invoke(cryptoCurrency.network.id.value)
|
||||
},
|
||||
clickIntents = this,
|
||||
symbol = cryptoCurrency.symbol,
|
||||
decimals = cryptoCurrency.decimals,
|
||||
|
|
@ -369,7 +366,11 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
|
||||
private fun updateStakingInfo() {
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
val stakingAvailability = getStakingAvailabilityUseCase(cryptoCurrency.network.id.value)
|
||||
val stakingAvailability = getStakingAvailabilityUseCase(
|
||||
cryptoCurrencyId = cryptoCurrency.id,
|
||||
symbol = cryptoCurrency.symbol,
|
||||
)
|
||||
uiState = stateFactory.getStateWithUpdatedStakingAvailability(stakingAvailability)
|
||||
if (stakingAvailability is StakingAvailability.Available) {
|
||||
val stakingInfo = getStakingEntryInfoUseCase(stakingAvailability.integrationId)
|
||||
uiState = stateFactory.getStateWithStaking(stakingInfo)
|
||||
|
|
@ -524,6 +525,10 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onStakeClick(unavailabilityReason: ScenarioUnavailabilityReason) {
|
||||
Timber.e("Not implemented yet")
|
||||
}
|
||||
|
||||
override fun onGenerateExtendedKey() {
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
val extendedKey = getExtendedPublicKeyForCurrencyUseCase(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue