Updated on 2026-08-14

This commit is contained in:
Tangem 2022-11-18 13:00:15 +03:00
parent 323d0e4a87
commit 47089f0606
9 changed files with 362 additions and 18 deletions

View file

@ -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)}")
}
}
}

View file

@ -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,
)
}
}

View file

@ -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,
)
}
}

View file

@ -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,
)
}