diff --git a/core/res/src/main/res/values-zh-rTW/strings.xml b/core/res/src/main/res/values-zh-rTW/strings.xml index b198f3eee7..acd0b259b8 100644 --- a/core/res/src/main/res/values-zh-rTW/strings.xml +++ b/core/res/src/main/res/values-zh-rTW/strings.xml @@ -48,7 +48,7 @@ 生物 購買 您尚未授予相機訪問權限,請更改您的隱私設置 - 刪除 + 删除 關閉 繼續 複製 diff --git a/core/ui/src/main/res/drawable/img_staking_banner.xml b/core/ui/src/main/res/drawable/img_staking_banner.xml new file mode 100644 index 0000000000..b3dfcacad4 --- /dev/null +++ b/core/ui/src/main/res/drawable/img_staking_banner.xml @@ -0,0 +1,345 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt index edda2d6732..3036764d3d 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt @@ -18,6 +18,8 @@ object StakingClickIntentsStub : StakingClickIntents { override fun onPrevClick() {} + override fun onInitialInfoBannerClick() {} + override fun onInfoClick(infoType: InfoType) {} override fun onAmountValueChange(value: String) {} 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 a40933fac8..30711535be 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 @@ -87,8 +87,8 @@ internal class SetInitialDataStateTransformer( val yieldBalance = cryptoCurrencyStatus.value.yieldBalance return listOfNotNull( + createAnnualPercentageRateItem(), createAvailableItem(cryptoCurrencyStatus), - createApyItem(), createUnbondingPeriodItem(), createMinimumRequirementItem(cryptoCurrencyStatus), createRewardClaimingItem(), @@ -97,6 +97,15 @@ internal class SetInitialDataStateTransformer( ).toPersistentList() } + private fun createAnnualPercentageRateItem(): RoundedListWithDividersItemData { + return RoundedListWithDividersItemData( + id = R.string.staking_details_annual_percentage_rate, + startText = TextReference.Res(R.string.staking_details_annual_percentage_rate), + endText = getAprRange(), + iconClick = { clickIntents.onInfoClick(InfoType.ANNUAL_PERCENTAGE_RATE) }, + ) + } + private fun createAvailableItem(cryptoCurrencyStatus: CryptoCurrencyStatus): RoundedListWithDividersItemData { return RoundedListWithDividersItemData( id = R.string.staking_details_available, @@ -111,15 +120,6 @@ internal class SetInitialDataStateTransformer( ) } - private fun createApyItem(): RoundedListWithDividersItemData { - return RoundedListWithDividersItemData( - id = R.string.staking_details_annual_percentage_rate, - startText = TextReference.Res(R.string.staking_details_annual_percentage_rate), - endText = getAprRange(), - iconClick = { clickIntents.onInfoClick(InfoType.APY) }, - ) - } - private fun createUnbondingPeriodItem(): RoundedListWithDividersItemData { return RoundedListWithDividersItemData( id = R.string.staking_details_unbonding_period, @@ -161,7 +161,10 @@ internal class SetInitialDataStateTransformer( ) } - private fun createWarmupPeriodItem(): RoundedListWithDividersItemData { + private fun createWarmupPeriodItem(): RoundedListWithDividersItemData? { + val warmupPeriod = yield.metadata.warmupPeriod.days + if (warmupPeriod == 0) return null + return RoundedListWithDividersItemData( id = R.string.staking_details_warmup_period, startText = TextReference.Res(R.string.staking_details_warmup_period), diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/ShowInfoBottomSheetStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/ShowInfoBottomSheetStateTransformer.kt index 755ca4552d..06f89bdd94 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/ShowInfoBottomSheetStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/ShowInfoBottomSheetStateTransformer.kt @@ -18,7 +18,7 @@ internal class ShowInfoBottomSheetStateTransformer( onDismissRequest = onDismiss, isShow = true, content = when (infoType) { - InfoType.APY -> StakingInfoBottomSheetConfig( + InfoType.ANNUAL_PERCENTAGE_RATE -> StakingInfoBottomSheetConfig( title = resourceReference(R.string.staking_details_annual_percentage_rate), text = resourceReference(R.string.staking_details_annual_percentage_rate_info), ) @@ -45,7 +45,7 @@ internal class ShowInfoBottomSheetStateTransformer( } enum class InfoType { - APY, + ANNUAL_PERCENTAGE_RATE, UNBONDING_PERIOD, REWARD_CLAIMING, WARMUP_PERIOD, 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 c144d71513..51bb3380b1 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 @@ -2,14 +2,13 @@ package com.tangem.features.staking.impl.presentation.ui import android.content.res.Configuration import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.Image 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.lazy.LazyColumn -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.ripple.rememberRipple -import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.key @@ -17,8 +16,12 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.* import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider @@ -28,6 +31,7 @@ import com.tangem.core.ui.components.inputrow.InputRowDefault import com.tangem.core.ui.components.inputrow.InputRowImageInfo import com.tangem.core.ui.components.list.roundedListWithDividersItems import com.tangem.core.ui.extensions.* +import com.tangem.core.ui.res.TangemColorPalette import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.utils.BigDecimalFormatter @@ -45,9 +49,7 @@ import com.tangem.utils.StringsSigns.PLUS import com.tangem.utils.extensions.orZero import kotlinx.collections.immutable.ImmutableList -// TODO staking metrics block is temporary disabled -// private const val METRICS_BLOCK_KEY = "MetricsBlock" - +private const val BANNER_BLOCK_KEY = "BannerBlock" private const val STAKING_REWARD_BLOCK_KEY = "StakingRewardBlock" private const val ACTIVE_STAKING_BLOCK_KEY = "ActiveStakingBlock" @@ -61,16 +63,16 @@ internal fun StakingInitialInfoContent(state: StakingStates.InitialInfoState, cl .background(TangemTheme.colors.background.secondary) .padding(horizontal = TangemTheme.dimens.spacing16), ) { - // TODO staking metrics block is temporary disabled - // https://www.figma.com/design/Vs6SkVsFnUPsSCNwlnVf5U?node-id=12484-35755#876661319 - // if (state.yieldBalance == InnerYieldBalanceState.Empty) { - // item(key = METRICS_BLOCK_KEY) { - // Column(modifier = Modifier.animateItemPlacement()) { - // MetricsBlock(state) - // SpacerH12() - // } - // } - // } + if (state.yieldBalance == InnerYieldBalanceState.Empty) { + item(key = BANNER_BLOCK_KEY) { + Column( + modifier = Modifier.animateItemPlacement(), + ) { + BannerBlock(onClick = clickIntents::onInitialInfoBannerClick) + SpacerH12() + } + } + } this.roundedListWithDividersItems( rows = state.infoItems, @@ -102,66 +104,31 @@ internal fun StakingInitialInfoContent(state: StakingStates.InitialInfoState, cl } } -@Suppress("UnusedPrivateMember") @Composable -private fun MetricsBlock(state: StakingStates.InitialInfoState.Data) { - Column( - modifier = Modifier - .background( - color = TangemTheme.colors.background.primary, - shape = RoundedCornerShape(TangemTheme.dimens.radius12), - ) - .padding(TangemTheme.dimens.spacing12) - .fillMaxWidth(), +private fun BannerBlock(onClick: () -> Unit) { + Box( + modifier = Modifier.clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(), + onClick = onClick, + ), ) { - Text( - text = stringResource(id = R.string.staking_details_metrics_block_header), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, + Image( + modifier = Modifier.fillMaxSize(), + painter = painterResource(R.drawable.img_staking_banner), + contentDescription = null, ) - Spacer(modifier = Modifier.height(TangemTheme.dimens.size8)) - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - ) { - Column(modifier = Modifier.weight(1F)) { - Text( - text = stringResource(id = R.string.staking_details_apr), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) - Text( - modifier = Modifier.padding(top = TangemTheme.dimens.spacing8), - text = state.aprRange.resolveReference(), - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.accent, - ) - } - Column(modifier = Modifier.weight(1F)) { - Row { - Text( - modifier = Modifier.padding(end = TangemTheme.dimens.spacing4), - text = stringResource(id = R.string.staking_details_market_rating), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) - Icon( - modifier = Modifier - .size(TangemTheme.dimens.size16) - .align(Alignment.CenterVertically), - painter = painterResource(id = R.drawable.ic_alert_24), - contentDescription = null, - tint = TangemTheme.colors.text.tertiary, - ) + Text( + modifier = Modifier + .align(Alignment.CenterStart) + .padding(TangemTheme.dimens.spacing16), + text = buildAnnotatedString { + withStyle(SpanStyle(Brush.linearGradient(textGradientColors))) { + append(stringResource(R.string.staking_details_banner_text)) } - Text( - modifier = Modifier.padding(top = TangemTheme.dimens.spacing8), - text = "1", // TODO staking - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.accent, - ) - } - } + }, + style = TangemTheme.typography.h2, + ) } } @@ -271,6 +238,11 @@ private fun ActiveStakingBlock(groups: ImmutableList, onCli } } +private val textGradientColors = listOf( + TangemColorPalette.White, + Color(0xff8fb4df), +) + // region preview @Preview(showBackground = true, widthDp = 360) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingClickIntents.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingClickIntents.kt index b5cb61db29..3734e90f19 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingClickIntents.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingClickIntents.kt @@ -22,6 +22,8 @@ internal interface StakingClickIntents : AmountScreenClickIntents { fun onPrevClick() + fun onInitialInfoBannerClick() + fun onInfoClick(infoType: InfoType) override fun onAmountNext() = onNextClick(actionType = null) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt index cdb9cbd9ca..a5fd8c4d07 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt @@ -207,6 +207,10 @@ internal class StakingViewModel @Inject constructor( stakingStateRouter.onPrevClick() } + override fun onInitialInfoBannerClick() { + innerRouter.openUrl(WHAT_IS_STAKING_ARTICLE_URL) + } + override fun onInfoClick(infoType: InfoType) { stateController.update( ShowInfoBottomSheetStateTransformer(infoType) { @@ -401,4 +405,8 @@ internal class StakingViewModel @Inject constructor( (value.confirmationState as? StakingStates.ConfirmationState.Data)?.innerState == InnerConfirmationStakingState.ASSENT } + + companion object { + const val WHAT_IS_STAKING_ARTICLE_URL = "TODO staking" + } } \ No newline at end of file