Updated on 2026-08-14
This commit is contained in:
parent
323d0e4a87
commit
47089f0606
9 changed files with 362 additions and 18 deletions
|
|
@ -0,0 +1,77 @@
|
|||
package com.tangem.feature.referral.ui
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.text.ClickableText
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TextColorType
|
||||
import com.tangem.core.ui.res.textColor
|
||||
import com.tangem.feature.referral.presentation.R
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_AgreementText_InLightTheme() {
|
||||
TangemTheme(isDarkTheme = false) {
|
||||
Box(modifier = Modifier.background(MaterialTheme.colors.primary)) {
|
||||
AgreementText(firstPartResId = R.string.referral_tou_not_enroled_prefix, onClicked = {})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_AgreementText_InDarkTheme() {
|
||||
TangemTheme(isDarkTheme = true) {
|
||||
Box(modifier = Modifier.background(MaterialTheme.colors.primary)) {
|
||||
AgreementText(firstPartResId = R.string.referral_tou_not_enroled_prefix, onClicked = {})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AgreementText(@StringRes firstPartResId: Int, onClicked: () -> Unit) {
|
||||
val agreementText = annotatedAgreementString(firstPart = stringResource(firstPartResId))
|
||||
ClickableText(
|
||||
text = agreementText,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = dimensionResource(id = R.dimen.spacing54)),
|
||||
style = MaterialTheme.typography.caption.copy(textAlign = TextAlign.Center),
|
||||
maxLines = 2,
|
||||
onClick = {
|
||||
val clickableSpanStyle = requireNotNull(agreementText.spanStyles.getOrNull(1))
|
||||
if (it in clickableSpanStyle.start..clickableSpanStyle.end) {
|
||||
onClicked()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun annotatedAgreementString(firstPart: String): AnnotatedString {
|
||||
return buildAnnotatedString {
|
||||
withStyle(SpanStyle(color = MaterialTheme.colors.textColor(type = TextColorType.TERTIARY))) {
|
||||
append("$firstPart ")
|
||||
}
|
||||
withStyle(SpanStyle(color = MaterialTheme.colors.textColor(type = TextColorType.ACCENT))) {
|
||||
append(stringResource(id = R.string.common_terms_and_conditions))
|
||||
}
|
||||
withStyle(SpanStyle(color = MaterialTheme.colors.textColor(type = TextColorType.TERTIARY))) {
|
||||
append(" ${stringResource(id = R.string.referral_tou_suffix)}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
package com.tangem.feature.referral.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.PrimaryStartIconButton
|
||||
import com.tangem.core.ui.components.SmallInfoCard
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TextColorType
|
||||
import com.tangem.core.ui.res.textColor
|
||||
import com.tangem.feature.referral.presentation.R
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_NonParticipateBottomBlock_InLightTheme() {
|
||||
TangemTheme(isDarkTheme = false) {
|
||||
Column(Modifier.background(MaterialTheme.colors.primary)) {
|
||||
NonParticipateBottomBlock(
|
||||
purchasedWalletCount = 3,
|
||||
code = "x4JdK",
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
onAgreementClicked = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_NonParticipateBottomBlock_InDarkTheme() {
|
||||
TangemTheme(isDarkTheme = true) {
|
||||
Column(Modifier.background(MaterialTheme.colors.primary)) {
|
||||
NonParticipateBottomBlock(
|
||||
purchasedWalletCount = 3,
|
||||
code = "x4JdK",
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
onAgreementClicked = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NonParticipateBottomBlock(
|
||||
purchasedWalletCount: Int,
|
||||
code: String,
|
||||
onCopyClicked: () -> Unit,
|
||||
onShareClicked: () -> Unit,
|
||||
onAgreementClicked: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
top = dimensionResource(id = R.dimen.spacing24),
|
||||
bottom = dimensionResource(id = R.dimen.spacing16),
|
||||
)
|
||||
.padding(horizontal = dimensionResource(id = R.dimen.spacing16)),
|
||||
verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing16)),
|
||||
) {
|
||||
SmallInfoCard(
|
||||
startText = stringResource(id = R.string.referral_friends_bought_title),
|
||||
endText = String.format(
|
||||
stringResource(id = R.string.referral_wallets_purchased_count),
|
||||
purchasedWalletCount,
|
||||
),
|
||||
)
|
||||
PersonalCodeCard(code = code)
|
||||
AdditionalButtons(onCopyClicked = onCopyClicked, onShareClicked = onShareClicked)
|
||||
AgreementText(firstPartResId = R.string.referral_tou_enroled_prefix, onClicked = onAgreementClicked)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PersonalCodeCard(code: String) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.shadow(
|
||||
elevation = dimensionResource(id = R.dimen.elevation2),
|
||||
shape = RoundedCornerShape(dimensionResource(id = R.dimen.radius12)),
|
||||
)
|
||||
.background(
|
||||
color = MaterialTheme.colors.secondary,
|
||||
shape = RoundedCornerShape(dimensionResource(id = R.dimen.radius12)),
|
||||
)
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = dimensionResource(id = R.dimen.spacing12)),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing4)),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.referral_promo_code_title),
|
||||
color = MaterialTheme.colors.textColor(type = TextColorType.TERTIARY),
|
||||
maxLines = 1,
|
||||
style = MaterialTheme.typography.subtitle2,
|
||||
)
|
||||
Text(
|
||||
text = code,
|
||||
color = MaterialTheme.colors.textColor(type = TextColorType.PRIMARY1),
|
||||
maxLines = 1,
|
||||
style = MaterialTheme.typography.h2,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AdditionalButtons(onCopyClicked: () -> Unit, onShareClicked: () -> Unit) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing16)),
|
||||
) {
|
||||
PrimaryStartIconButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = stringResource(id = R.string.common_copy),
|
||||
iconResId = R.drawable.ic_copy,
|
||||
onClicked = onCopyClicked,
|
||||
)
|
||||
PrimaryStartIconButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = stringResource(id = R.string.common_share),
|
||||
iconResId = R.drawable.ic_share,
|
||||
onClicked = onShareClicked,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.tangem.feature.referral.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.PrimaryEndIconButton
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.referral.presentation.R
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_ParticipateBottomBlock_InLightTheme() {
|
||||
TangemTheme(isDarkTheme = false) {
|
||||
Column(Modifier.background(MaterialTheme.colors.primary)) {
|
||||
ParticipateBottomBlock(onAgreementClicked = {}, onParticipateClicked = {})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_ParticipateBottomBlock_InDarkTheme() {
|
||||
TangemTheme(isDarkTheme = true) {
|
||||
Column(Modifier.background(MaterialTheme.colors.primary)) {
|
||||
ParticipateBottomBlock(onAgreementClicked = {}, onParticipateClicked = {})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ParticipateBottomBlock(onAgreementClicked: () -> Unit, onParticipateClicked: () -> Unit) {
|
||||
Column {
|
||||
AgreementText(
|
||||
firstPartResId = R.string.referral_tou_not_enroled_prefix,
|
||||
onClicked = onAgreementClicked,
|
||||
)
|
||||
PrimaryEndIconButton(
|
||||
modifier = Modifier.padding(all = dimensionResource(id = R.dimen.spacing16)),
|
||||
text = stringResource(id = R.string.referral_button_participate),
|
||||
iconResId = R.drawable.ic_tangem,
|
||||
onClicked = onParticipateClicked,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,9 @@ import androidx.compose.foundation.layout.height
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
|
|
@ -167,7 +169,8 @@ fun ReferralScreen(stateHolder: ReferralStateHolder) {
|
|||
Column(
|
||||
modifier = Modifier
|
||||
.background(color = MaterialTheme.colors.primary)
|
||||
.fillMaxSize(),
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Header(stateHolder = stateHolder)
|
||||
|
|
@ -201,18 +204,20 @@ private fun ColumnScope.Header(stateHolder: ReferralStateHolder) {
|
|||
@Composable
|
||||
fun ReferralInfo(stateHolder: ReferralStateHolder) {
|
||||
when (val state = stateHolder.referralInfoState) {
|
||||
is ReferralInfoState.ParticipantContent,
|
||||
is ReferralInfoState.ParticipantContent -> {
|
||||
Conditions(state = state)
|
||||
VerticalSpacer(spaceResId = R.dimen.spacing44)
|
||||
ParticipantBottomBlock(state = state)
|
||||
}
|
||||
is ReferralInfoState.NonParticipantContent -> {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing32))) {
|
||||
ConditionForYou(state = state as ReferralStateHolder.ReferralInfoContentState)
|
||||
ConditionForYourFriend(state = state)
|
||||
}
|
||||
Conditions(state = state)
|
||||
VerticalSpacer(spaceResId = R.dimen.spacing24)
|
||||
NonParticipantBottomBlock(state = state)
|
||||
}
|
||||
is ReferralInfoState.Loading -> {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing32))) {
|
||||
LoadingCondition(iconResId = R.drawable.ic_tether)
|
||||
LoadingCondition(iconResId = R.drawable.ic_discount)
|
||||
}
|
||||
LoadingCondition(iconResId = R.drawable.ic_tether)
|
||||
VerticalSpacer(spaceResId = R.dimen.spacing32)
|
||||
LoadingCondition(iconResId = R.drawable.ic_discount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -225,6 +230,13 @@ private fun AppBar(stateHolder: ReferralStateHolder) {
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Conditions(state: ReferralStateHolder.ReferralInfoContentState) {
|
||||
ConditionForYou(state = state)
|
||||
VerticalSpacer(spaceResId = R.dimen.spacing32)
|
||||
ConditionForYourFriend(state = state)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ConditionForYou(state: ReferralStateHolder.ReferralInfoContentState) {
|
||||
Condition(iconResId = R.drawable.ic_tether) {
|
||||
|
|
@ -248,7 +260,7 @@ private fun ConditionForYourFriend(state: ReferralStateHolder.ReferralInfoConten
|
|||
@Composable
|
||||
private fun LoadingCondition(@DrawableRes iconResId: Int) {
|
||||
Condition(iconResId = iconResId) {
|
||||
ShimmerCondition()
|
||||
ShimmerInfo()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -335,7 +347,7 @@ private fun ConditionInfo(title: String, subtitleContent: @Composable () -> Unit
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun ShimmerCondition() {
|
||||
private fun ShimmerInfo() {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
@ -360,3 +372,22 @@ private fun ShimmerCondition() {
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ParticipantBottomBlock(state: ReferralInfoState.ParticipantContent) {
|
||||
ParticipateBottomBlock(
|
||||
onAgreementClicked = state.onAgreementClicked,
|
||||
onParticipateClicked = state.onParticipateClicked,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NonParticipantBottomBlock(state: ReferralInfoState.NonParticipantContent) {
|
||||
NonParticipateBottomBlock(
|
||||
purchasedWalletCount = state.purchasedWalletCount,
|
||||
code = state.code,
|
||||
onCopyClicked = state.onCopyClicked,
|
||||
onShareClicked = state.onShareClicked,
|
||||
onAgreementClicked = state.onAgreementClicked,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue