diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt b/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt index e9e49c5c71..65b331e15c 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt @@ -101,6 +101,7 @@ fun Preview_PrimaryEndIconButton_Disabled_InDarkTheme() { /** * Primary button with an icon at the beginning of the layout * + * @param modifier button modifier * @param text button text * @param iconResId button icon res id * @param enabled controls the enabled state of the button @@ -110,8 +111,14 @@ fun Preview_PrimaryEndIconButton_Disabled_InDarkTheme() { * >Figma component */ @Composable -fun PrimaryStartIconButton(text: String, @DrawableRes iconResId: Int, enabled: Boolean = true, onClicked: () -> Unit) { - PrimaryButtonRow(enabled = enabled, onClicked = onClicked) { +fun PrimaryStartIconButton( + modifier: Modifier = Modifier, + text: String, + @DrawableRes iconResId: Int, + enabled: Boolean = true, + onClicked: () -> Unit, +) { + PrimaryButtonRow(modifier = modifier, enabled = enabled, onClicked = onClicked) { Icon( painter = painterResource(id = iconResId), contentDescription = null, @@ -124,6 +131,7 @@ fun PrimaryStartIconButton(text: String, @DrawableRes iconResId: Int, enabled: B /** * Primary button with an icon at the end of the layout * + * @param modifier button modifier * @param text button text * @param iconResId button icon res id * @param enabled controls the enabled state of the button @@ -133,8 +141,14 @@ fun PrimaryStartIconButton(text: String, @DrawableRes iconResId: Int, enabled: B * >Figma component */ @Composable -fun PrimaryEndIconButton(text: String, @DrawableRes iconResId: Int, enabled: Boolean = true, onClicked: () -> Unit) { - PrimaryButtonRow(enabled = enabled, onClicked = onClicked) { +fun PrimaryEndIconButton( + modifier: Modifier = Modifier, + text: String, + @DrawableRes iconResId: Int, + enabled: Boolean = true, + onClicked: () -> Unit, +) { + PrimaryButtonRow(modifier = modifier, enabled = enabled, onClicked = onClicked) { Text(text = text) Spacer(modifier = Modifier.width(dimensionResource(R.dimen.spacing8))) Icon( @@ -145,10 +159,15 @@ fun PrimaryEndIconButton(text: String, @DrawableRes iconResId: Int, enabled: Boo } @Composable -private fun PrimaryButtonRow(enabled: Boolean, onClicked: () -> Unit, content: @Composable (RowScope.() -> Unit)) { +private fun PrimaryButtonRow( + modifier: Modifier, + enabled: Boolean, + onClicked: () -> Unit, + content: @Composable (RowScope.() -> Unit), +) { Button( onClick = onClicked, - modifier = Modifier + modifier = modifier .fillMaxWidth() .height(dimensionResource(R.dimen.size48)), enabled = enabled, diff --git a/core/ui/src/main/res/drawable/ic_copy.xml b/core/ui/src/main/res/drawable/ic_copy.xml new file mode 100644 index 0000000000..d01cdf9823 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_copy.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/ui/src/main/res/drawable/ic_share.xml b/core/ui/src/main/res/drawable/ic_share.xml new file mode 100644 index 0000000000..e35c52d223 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_share.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/ui/src/main/res/values-ru/string_common.xml b/core/ui/src/main/res/values-ru/string_common.xml new file mode 100644 index 0000000000..ebb5d6b913 --- /dev/null +++ b/core/ui/src/main/res/values-ru/string_common.xml @@ -0,0 +1,5 @@ + + + Поделиться + Копировать + \ No newline at end of file diff --git a/core/ui/src/main/res/values/string_common.xml b/core/ui/src/main/res/values/string_common.xml new file mode 100644 index 0000000000..ad2cf0d79f --- /dev/null +++ b/core/ui/src/main/res/values/string_common.xml @@ -0,0 +1,5 @@ + + + Share + Copy + \ No newline at end of file diff --git a/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/AgreementText.kt b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/AgreementText.kt new file mode 100644 index 0000000000..133b6b374e --- /dev/null +++ b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/AgreementText.kt @@ -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)}") + } + } +} \ No newline at end of file diff --git a/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/NonParticipateBottomBlock.kt b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/NonParticipateBottomBlock.kt new file mode 100644 index 0000000000..59b7ab8148 --- /dev/null +++ b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/NonParticipateBottomBlock.kt @@ -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, + ) + } +} \ No newline at end of file diff --git a/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ParticipateBottomBlock.kt b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ParticipateBottomBlock.kt new file mode 100644 index 0000000000..7294cbd3f7 --- /dev/null +++ b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ParticipateBottomBlock.kt @@ -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, + ) + } +} \ No newline at end of file diff --git a/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ReferralScreen.kt b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ReferralScreen.kt index c7894c0bea..46de8b45c4 100644 --- a/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ReferralScreen.kt +++ b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ReferralScreen.kt @@ -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, + ) +} +