diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/models/request/Address.kt b/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/models/request/Address.kt index 03921fa39c..4e93f0353a 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/models/request/Address.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/models/request/Address.kt @@ -21,6 +21,7 @@ data class Address( val binanceBeaconAddress: String? = null, // solana-specific + @Deprecated("Legacy in StakeKit, isn't used in Solana") @Json(name = "stakeAccounts") val stakeAccounts: List? = null, @Json(name = "lidoStakeAccounts") diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/list/RoundedListWithDividers.kt b/core/ui/src/main/java/com/tangem/core/ui/components/list/RoundedListWithDividers.kt new file mode 100644 index 0000000000..8161f2ff69 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/list/RoundedListWithDividers.kt @@ -0,0 +1,123 @@ +package com.tangem.core.ui.components.list + +import android.content.res.Configuration +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.tangem.core.ui.R +import com.tangem.core.ui.components.rows.CornersToRound +import com.tangem.core.ui.components.rows.RoundableCornersRow +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview +import kotlinx.collections.immutable.persistentListOf + +@Composable +fun RoundedListWithDividers(rows: List, modifier: Modifier = Modifier) { + LazyColumn(modifier = modifier) { + itemsIndexed( + items = rows, + key = { _, item -> item.id }, + ) { index, row -> + InitialInfoContentRow( + startText = row.startText.resolveReference(), + endText = row.endText.resolveReference(), + cornersToRound = getCornersToRound(index, rows.size), + iconClick = row.iconClick, + ) + if (index < rows.lastIndex) { + RoundedListDivider() + } + } + } +} + +@Composable +private fun InitialInfoContentRow( + startText: String, + endText: String, + cornersToRound: CornersToRound, + iconClick: (() -> Unit)? = null, +) { + RoundableCornersRow( + startText = startText, + startTextColor = TangemTheme.colors.text.primary1, + startTextStyle = TangemTheme.typography.body2, + endText = endText, + endTextColor = TangemTheme.colors.text.tertiary, + endTextStyle = TangemTheme.typography.body2, + cornersToRound = cornersToRound, + iconResId = R.drawable.ic_information_24, + iconClick = iconClick, + ) +} + +@Composable +fun RoundedListDivider() { + Row( + modifier = Modifier + .fillMaxWidth() + .height(TangemTheme.dimens.size0_5), + ) { + Box( + modifier = Modifier + .width(TangemTheme.dimens.size16) + .height(TangemTheme.dimens.size0_5) + .background(TangemTheme.colors.background.primary), + ) + Box( + modifier = Modifier + .weight(1f) + .height(TangemTheme.dimens.size0_5) + .background(TangemTheme.colors.background.tertiary), + ) + } +} + +private fun getCornersToRound(currentIndex: Int, listSize: Int): CornersToRound { + return when (currentIndex) { + 0 -> CornersToRound.TOP_2 + listSize - 1 -> CornersToRound.BOTTOM_2 + else -> CornersToRound.ZERO + } +} + +data class RoundedListWithDividersItemData( + val id: Int, + val startText: TextReference, + val endText: TextReference, + val iconClick: (() -> Unit)? = null, +) + +@Composable +@Preview(showBackground = true) +@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +private fun Preview_StakingInfoBottomSheet() { + TangemThemePreview { + RoundedListWithDividers( + rows = persistentListOf( + RoundedListWithDividersItemData( + id = 1, + startText = TextReference.Str("Key 1"), + endText = TextReference.Str("Value 1"), + ), + RoundedListWithDividersItemData( + id = 2, + startText = TextReference.Str("Key 2"), + endText = TextReference.Str("Value 2"), + ), + RoundedListWithDividersItemData( + id = 3, + startText = TextReference.Str("Key 3"), + endText = TextReference.Str("Value 3"), + iconClick = {}, + ), + ), + ) + } +} \ No newline at end of file diff --git a/core/ui/src/main/res/drawable/ic_staking_24.xml b/core/ui/src/main/res/drawable/ic_staking_24.xml new file mode 100644 index 0000000000..9a74909897 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_staking_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt index ddb05b9851..bc015d17b5 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt @@ -124,9 +124,9 @@ internal class DefaultStakingRepository( } } - override suspend fun getEntryInfo(integrationId: String): StakingEntryInfo { + override suspend fun getEntryInfo(cryptoCurrencyId: CryptoCurrency.ID, symbol: String): StakingEntryInfo { return withContext(dispatchers.io) { - val yield = stakeKitApi.getSingleYield(integrationId).getOrThrow() + val yield = getYield(cryptoCurrencyId, symbol) StakingEntryInfo( interestRate = yield.apy, diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/GetStakingEntryInfoUseCase.kt b/domain/staking/src/main/java/com/tangem/domain/staking/GetStakingEntryInfoUseCase.kt index 6192e9d92a..ffa3cbb0a3 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/GetStakingEntryInfoUseCase.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/GetStakingEntryInfoUseCase.kt @@ -5,6 +5,7 @@ import com.tangem.domain.staking.model.StakingEntryInfo import com.tangem.domain.staking.model.stakekit.StakingError import com.tangem.domain.staking.repositories.StakingErrorResolver import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.tokens.model.CryptoCurrency /** * Use case for getting entry info about staking on token screen. @@ -14,9 +15,17 @@ class GetStakingEntryInfoUseCase( private val stakingErrorResolver: StakingErrorResolver, ) { - suspend operator fun invoke(integrationId: String): Either { + suspend operator fun invoke( + cryptoCurrencyId: CryptoCurrency.ID, + symbol: String, + ): Either { return Either - .catch { stakingRepository.getEntryInfo(integrationId) } + .catch { + stakingRepository.getEntryInfo( + cryptoCurrencyId = cryptoCurrencyId, + symbol = symbol, + ) + } .mapLeft { stakingErrorResolver.resolve(it) } } } \ No newline at end of file diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt b/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt index 356dc7aac9..a9ff51285e 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt @@ -21,7 +21,7 @@ interface StakingRepository { suspend fun fetchEnabledYields(refresh: Boolean) - suspend fun getEntryInfo(integrationId: String): StakingEntryInfo + suspend fun getEntryInfo(cryptoCurrencyId: CryptoCurrency.ID, symbol: String): StakingEntryInfo suspend fun getYield(cryptoCurrencyId: CryptoCurrency.ID, symbol: String): Yield diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt index 6116e0afda..ad8a88a0fd 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt @@ -25,11 +25,12 @@ class MockStakingRepository : StakingRepository { /* no-op */ } - override suspend fun getEntryInfo(integrationId: String): StakingEntryInfo = StakingEntryInfo( - interestRate = 1.toBigDecimal(), - periodInDays = 2, - tokenSymbol = "SOL", - ) + override suspend fun getEntryInfo(cryptoCurrencyId: CryptoCurrency.ID, symbol: String): StakingEntryInfo = + StakingEntryInfo( + interestRate = 1.toBigDecimal(), + periodInDays = 2, + tokenSymbol = "SOL", + ) override suspend fun getYield(cryptoCurrencyId: CryptoCurrency.ID, symbol: String): Yield = Yield( id = "1", diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingUiState.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingUiState.kt index 085a7fcd94..2ad72821a5 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingUiState.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingUiState.kt @@ -3,6 +3,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.components.bottomsheets.TangemBottomSheetConfig +import com.tangem.core.ui.components.list.RoundedListWithDividersItemData import com.tangem.core.ui.event.StateEvent import com.tangem.core.ui.extensions.TextReference import com.tangem.domain.staking.model.stakekit.PendingAction @@ -47,6 +48,14 @@ internal sealed class StakingStates { sealed class InitialInfoState : StakingStates() { data class Data( override val isPrimaryButtonEnabled: Boolean, + val infoItems: ImmutableList, + val aprRange: TextReference, + val onInfoClick: (InfoType) -> Unit, + val yieldBalance: InnerYieldBalanceState, + val isStakeMoreAvailable: Boolean, + ) : InitialInfoState() + + data class InitialInfoItems( val available: String, val onStake: String, val aprRange: TextReference, @@ -55,10 +64,7 @@ internal sealed class StakingStates { val rewardClaiming: String, val warmupPeriod: String, val rewardSchedule: String, - val onInfoClick: (InfoType) -> Unit, - val yieldBalance: InnerYieldBalanceState, - val isStakeMoreAvailable: Boolean, - ) : InitialInfoState() + ) data class Empty( override val isPrimaryButtonEnabled: Boolean = false, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt index ac561e7608..2255ba2015 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt @@ -1,21 +1,59 @@ package com.tangem.features.staking.impl.presentation.state.previewdata +import com.tangem.core.ui.components.list.RoundedListWithDividersItemData +import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.stringReference import com.tangem.domain.staking.model.stakekit.Yield +import com.tangem.features.staking.impl.R import com.tangem.features.staking.impl.presentation.state.* import kotlinx.collections.immutable.persistentListOf internal object InitialStakingStatePreview { val defaultState = StakingStates.InitialInfoState.Data( isPrimaryButtonEnabled = true, - available = "15 SOL", - onStake = "0 SOL", aprRange = stringReference("2.54-5.12%"), - unbondingPeriod = "3d", - minimumRequirement = "12 SOL", - rewardClaiming = "Auto", - warmupPeriod = "Days", - rewardSchedule = "Block", + infoItems = persistentListOf( + RoundedListWithDividersItemData( + id = R.string.staking_details_available, + startText = TextReference.Res(R.string.staking_details_available), + endText = TextReference.Str("15 SOL"), + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_apy, + startText = TextReference.Res(R.string.staking_details_apy), + endText = TextReference.Str("2.54-5.12%"), + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_on_stake, + startText = TextReference.Res(R.string.staking_details_on_stake), + endText = TextReference.Str("0 SOL"), + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_unbonding_period, + startText = TextReference.Res(R.string.staking_details_unbonding_period), + endText = TextReference.Str("3d"), + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_minimum_requirement, + startText = TextReference.Res(R.string.staking_details_minimum_requirement), + endText = TextReference.Str("12 SOL"), + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_reward_claiming, + startText = TextReference.Res(R.string.staking_details_reward_claiming), + endText = TextReference.Str("Auto"), + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_warmup_period, + startText = TextReference.Res(R.string.staking_details_warmup_period), + endText = TextReference.Str("Days"), + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_reward_schedule, + startText = TextReference.Res(R.string.staking_details_reward_schedule), + endText = TextReference.Str("Block"), + ), + ), onInfoClick = {}, yieldBalance = InnerYieldBalanceState.Empty, isStakeMoreAvailable = true, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateAssentTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateAssentTransformer.kt index 90e5434e09..f2dc22698e 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateAssentTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateAssentTransformer.kt @@ -14,7 +14,6 @@ import com.tangem.utils.Provider import com.tangem.utils.transformer.Transformer import kotlinx.collections.immutable.ImmutableList -@Suppress("UnusedPrivateMember") internal class SetConfirmationStateAssentTransformer( private val appCurrencyProvider: Provider, private val cryptoCurrencyStatusProvider: Provider, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt index e6ba83a11d..b9bd36aff7 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt @@ -5,7 +5,6 @@ import com.tangem.features.staking.impl.presentation.state.* import com.tangem.utils.transformer.Transformer import kotlinx.collections.immutable.persistentListOf -@Suppress("UnusedPrivateMember") internal class SetConfirmationStateLoadingTransformer( private val yield: Yield, ) : Transformer { diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt index c361dcf147..7e45dc8557 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt @@ -4,6 +4,7 @@ import com.tangem.common.extensions.remove import com.tangem.common.ui.amountScreen.converters.AmountStateConverter import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter +import com.tangem.core.ui.components.list.RoundedListWithDividersItemData import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference @@ -26,6 +27,8 @@ import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickInten import com.tangem.utils.Provider import com.tangem.utils.extensions.orZero import com.tangem.utils.transformer.Transformer +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf import java.math.BigDecimal internal class SetInitialDataStateTransformer( @@ -70,33 +73,87 @@ internal class SetInitialDataStateTransformer( } private fun createInitialInfoState(): StakingStates.InitialInfoState.Data { - val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() - val yieldBalance = cryptoCurrencyStatus.value.yieldBalance - return StakingStates.InitialInfoState.Data( isPrimaryButtonEnabled = true, - available = BigDecimalFormatter.formatCryptoAmount( - cryptoAmount = cryptoCurrencyStatus.value.amount, - cryptoCurrency = cryptoCurrencyStatus.currency.symbol, - decimals = cryptoCurrencyStatus.currency.decimals, - ), - onStake = BigDecimalFormatter.formatCryptoAmount( - cryptoAmount = (yieldBalance as? YieldBalance.Data)?.getTotalStakingBalance().orZero(), - cryptoCurrency = cryptoCurrencyStatus.currency.symbol, - decimals = cryptoCurrencyStatus.currency.decimals, - ), aprRange = getAprRange(), - unbondingPeriod = yield.metadata.cooldownPeriod.days.toString(), - minimumRequirement = yield.metadata.minimumStake.toString(), - rewardClaiming = yield.metadata.rewardClaiming, - warmupPeriod = yield.metadata.warmupPeriod.days.toString(), - rewardSchedule = yield.metadata.rewardSchedule, + infoItems = getInfoItems(), onInfoClick = clickIntents::onInfoClick, yieldBalance = yieldBalancesConverter.convert(Unit), isStakeMoreAvailable = isStakeMoreAvailable, ) } + private fun getInfoItems(): PersistentList { + val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() + val yieldBalance = cryptoCurrencyStatus.value.yieldBalance + + return persistentListOf( + RoundedListWithDividersItemData( + id = R.string.staking_details_available, + startText = TextReference.Res(R.string.staking_details_available), + endText = TextReference.Str( + value = BigDecimalFormatter.formatCryptoAmount( + cryptoAmount = cryptoCurrencyStatus.value.amount, + cryptoCurrency = cryptoCurrencyStatus.currency.symbol, + decimals = cryptoCurrencyStatus.currency.decimals, + ), + ), + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_apy, + startText = TextReference.Res(R.string.staking_details_apy), + endText = getAprRange(), + iconClick = { clickIntents.onInfoClick(InfoType.APY) }, + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_on_stake, + startText = TextReference.Res(R.string.staking_details_on_stake), + endText = TextReference.Str( + value = BigDecimalFormatter.formatCryptoAmount( + cryptoAmount = (yieldBalance as? YieldBalance.Data)?.getTotalStakingBalance().orZero(), + cryptoCurrency = cryptoCurrencyStatus.currency.symbol, + decimals = cryptoCurrencyStatus.currency.decimals, + ), + ), + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_unbonding_period, + startText = TextReference.Res(R.string.staking_details_unbonding_period), + endText = TextReference.Str(yield.metadata.cooldownPeriod.days.toString()), + iconClick = { clickIntents.onInfoClick(InfoType.UNBOUNDING_PERIOD) }, + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_minimum_requirement, + startText = TextReference.Res(R.string.staking_details_minimum_requirement), + endText = TextReference.Str( + value = BigDecimalFormatter.formatCryptoAmount( + cryptoAmount = yield.args.enter.args[KEY_AMOUNT]?.minimum?.toBigDecimal(), + cryptoCurrency = cryptoCurrencyStatus.currency.symbol, + decimals = cryptoCurrencyStatus.currency.decimals, + ), + ), + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_reward_claiming, + startText = TextReference.Res(R.string.staking_details_reward_claiming), + endText = TextReference.Str(yield.metadata.rewardClaiming), + iconClick = { clickIntents.onInfoClick(InfoType.REWARD_CLAIMING) }, + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_warmup_period, + startText = TextReference.Res(R.string.staking_details_warmup_period), + endText = TextReference.Str(yield.metadata.warmupPeriod.days.toString()), + iconClick = { clickIntents.onInfoClick(InfoType.WARMUP_PERIOD) }, + ), + RoundedListWithDividersItemData( + id = R.string.staking_details_reward_schedule, + startText = TextReference.Res(R.string.staking_details_reward_schedule), + endText = TextReference.Str(yield.metadata.rewardSchedule), + iconClick = { clickIntents.onInfoClick(InfoType.REWARD_SCHEDULE) }, + ), + ) + } + private fun createInitialAmountState(): AmountState { return amountStateConverter.convert("") } @@ -134,5 +191,6 @@ internal class SetInitialDataStateTransformer( companion object { private val EQUALITY_THRESHOLD = BigDecimal(1E-10) + private const val KEY_AMOUNT = "amount" } } \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt index 4eb8244ef3..859bc837c1 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt @@ -7,9 +7,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.Icon import androidx.compose.material3.Text @@ -27,8 +25,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import com.tangem.core.ui.components.containers.FooterContainer import com.tangem.core.ui.components.inputrow.InputRowDefault import com.tangem.core.ui.components.inputrow.InputRowImageInfo -import com.tangem.core.ui.components.rows.CornersToRound -import com.tangem.core.ui.components.rows.RoundableCornersRow +import com.tangem.core.ui.components.list.RoundedListWithDividers import com.tangem.core.ui.extensions.* import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview @@ -37,7 +34,6 @@ import com.tangem.features.staking.impl.R import com.tangem.features.staking.impl.presentation.state.* import com.tangem.features.staking.impl.presentation.state.previewdata.InitialStakingStatePreview import com.tangem.features.staking.impl.presentation.state.stub.StakingClickIntentsStub -import com.tangem.features.staking.impl.presentation.state.transformers.InfoType import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickIntents import com.tangem.utils.StringsSigns.DOT import com.tangem.utils.StringsSigns.PLUS @@ -55,13 +51,12 @@ internal fun StakingInitialInfoContent(state: StakingStates.InitialInfoState, cl start = TangemTheme.dimens.spacing16, end = TangemTheme.dimens.spacing16, bottom = TangemTheme.dimens.spacing16, - ) - .verticalScroll(rememberScrollState()), + ), ) { AnimatedVisibility(state.yieldBalance == InnerYieldBalanceState.Empty) { MetricsBlock(state) } - StakingDetailsRows(state) + RoundedListWithDividers(state.infoItems) AnimatedContent(targetState = state.yieldBalance, label = "Rewards block visibility animation") { if (it is InnerYieldBalanceState.Data) { StakingRewardBlock( @@ -142,57 +137,6 @@ private fun MetricsBlock(state: StakingStates.InitialInfoState.Data) { } } -@Composable -internal fun StakingDetailsRows(state: StakingStates.InitialInfoState.Data) { - Column { - InitialInfoContentRow( - startText = stringResource(id = R.string.staking_details_available), - endText = state.available, - cornersToRound = CornersToRound.TOP_2, - ) - InitialInfoContentRow( - startText = stringResource(id = R.string.staking_details_on_stake), - endText = state.onStake, - cornersToRound = CornersToRound.ZERO, - ) - InitialInfoContentRow( - startText = stringResource(id = R.string.staking_details_apy), - endText = state.aprRange.resolveReference(), - cornersToRound = CornersToRound.ZERO, - iconClick = { state.onInfoClick(InfoType.APY) }, - ) - InitialInfoContentRow( - startText = stringResource(id = R.string.staking_details_unbonding_period), - endText = state.unbondingPeriod, - cornersToRound = CornersToRound.ZERO, - iconClick = { state.onInfoClick(InfoType.UNBOUNDING_PERIOD) }, - ) - InitialInfoContentRow( - startText = stringResource(id = R.string.staking_details_minimum_requirement), - endText = state.minimumRequirement, - cornersToRound = CornersToRound.ZERO, - ) - InitialInfoContentRow( - startText = stringResource(id = R.string.staking_details_reward_claiming), - endText = state.rewardClaiming, - cornersToRound = CornersToRound.ZERO, - iconClick = { state.onInfoClick(InfoType.REWARD_CLAIMING) }, - ) - InitialInfoContentRow( - startText = stringResource(id = R.string.staking_details_warmup_period), - endText = state.warmupPeriod, - cornersToRound = CornersToRound.ZERO, - iconClick = { state.onInfoClick(InfoType.WARMUP_PERIOD) }, - ) - InitialInfoContentRow( - startText = stringResource(id = R.string.staking_details_reward_schedule), - endText = state.rewardSchedule, - cornersToRound = CornersToRound.BOTTOM_2, - iconClick = { state.onInfoClick(InfoType.REWARD_SCHEDULE) }, - ) - } -} - @Composable private fun StakingRewardBlock( rewardCrypto: String, @@ -295,25 +239,7 @@ private fun ActiveStakingBlock(groups: List, onClick: (Bala } } -@Composable -private fun InitialInfoContentRow( - startText: String, - endText: String, - cornersToRound: CornersToRound, - iconClick: (() -> Unit)? = null, -) { - RoundableCornersRow( - startText = startText, - startTextColor = TangemTheme.colors.text.primary1, - startTextStyle = TangemTheme.typography.body2, - endText = endText, - endTextColor = TangemTheme.colors.text.tertiary, - endTextStyle = TangemTheme.typography.body2, - cornersToRound = cornersToRound, - iconResId = R.drawable.ic_information_24, - iconClick = iconClick, - ) -} +// region preview @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index 9fb83bd2a5..18679abdb6 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -1866,7 +1866,6 @@ internal class SwapInteractorImpl @Inject constructor( } companion object { - @Suppress("UnusedPrivateMember") private const val INCREASE_GAS_LIMIT_BY = 112 // 12% private const val INCREASE_GAS_LIMIT_FOR_SEND = 105 // 5% private const val INFINITY_SYMBOL = "∞" diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt index 51497e7f98..f02139cb42 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt @@ -847,7 +847,6 @@ internal class SwapViewModel @Inject constructor( onAmountChanged(newAmount.formatToUIRepresentation()) } - @Suppress("UnusedPrivateMember") private fun onAmountSelected(selected: Boolean) { if (selected) { analyticsEventHandler.send(SwapEvents.SendTokenBalanceClicked) diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsActionButton.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsActionButton.kt index d1ef7792c8..f3104d8636 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsActionButton.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsActionButton.kt @@ -101,7 +101,7 @@ internal sealed class TokenDetailsActionButton(val config: ActionButtonConfig) { 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 + iconResId = R.drawable.ic_staking_24, onClick = onClick, dimContent = dimContent, ), diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt index 6bdc2a3375..b885be8766 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt @@ -393,7 +393,10 @@ internal class TokenDetailsViewModel @Inject constructor( internalUiState.value = stateFactory.getStateWithUpdatedStakingAvailability(stakingAvailability) if (stakingAvailability is StakingAvailability.Available) { - val stakingInfo = getStakingEntryInfoUseCase(stakingAvailability.integrationId) + val stakingInfo = getStakingEntryInfoUseCase( + cryptoCurrencyId = cryptoCurrency.id, + symbol = cryptoCurrency.symbol, + ) internalUiState.value = stateFactory.getStateWithStaking(stakingInfo) } } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletManageButton.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletManageButton.kt index 19da0ca6a5..4c811a13ef 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletManageButton.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletManageButton.kt @@ -96,7 +96,7 @@ internal sealed class WalletManageButton(val config: ActionButtonConfig) { ) : WalletManageButton( config = ActionButtonConfig( text = TextReference.Res(id = R.string.common_stake), - iconResId = R.drawable.ic_arrow_down_24, // TODO staking + iconResId = R.drawable.ic_staking_24, onClick = onClick, dimContent = dimContent, ), diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt index 417ff93ede..d924dabe10 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt @@ -61,7 +61,7 @@ internal class MultiWalletCurrencyActionsConverter( } is TokenActionsState.ActionState.Stake -> { title = resourceReference(R.string.common_stake) - icon = R.drawable.ic_arrow_down_24 // TODO staking replace icon + icon = R.drawable.ic_staking_24 action = { clickIntents.onStakeClick(cryptoCurrencyStatus) } } is TokenActionsState.ActionState.Sell -> {