Updated on 2026-08-14

This commit is contained in:
Tangem 2022-11-19 17:02:42 +03:00
parent 8002513bf8
commit ed03d8530e
18 changed files with 542 additions and 145 deletions

View file

@ -4,6 +4,7 @@ data class ReferralStateHolder(
val headerState: HeaderState,
val referralInfoState: ReferralInfoState,
val effects: Effects,
val agreementBottomSheetState: AgreementBottomSheetState
) {
data class HeaderState(val onBackClicked: () -> Unit)
@ -16,7 +17,6 @@ data class ReferralStateHolder(
val award: String,
val address: String,
val discount: String,
val onAgreementClicked: () -> Unit,
val onParticipateClicked: () -> Unit,
) : ReferralInfoState, ReferralInfoContentState
@ -27,11 +27,12 @@ data class ReferralStateHolder(
val code: String,
val onCopyClicked: () -> Unit,
val onShareClicked: () -> Unit,
val onAgreementClicked: () -> Unit,
) : ReferralInfoState, ReferralInfoContentState
object Loading : ReferralInfoState
}
data class Effects(val showErrorToast: Boolean)
data class AgreementBottomSheetState(val url: String)
}

View file

@ -0,0 +1,80 @@
package com.tangem.feature.referral.ui
import android.view.ViewGroup.LayoutParams
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.tangem.core.ui.components.appbar.AppBarWithAdditionalButtons
import com.tangem.core.ui.components.atoms.BottomSheetIndicator
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.referral.presentation.R
/**
* Bottom sheet content with referral program terms of use
*
* @param url link to the html page
*/
@Composable
fun AgreementBottomSheetContent(url: String) {
Column(
modifier = Modifier
.background(color = MaterialTheme.colors.secondary)
.fillMaxWidth()
.height(LocalConfiguration.current.screenHeightDp.dp - dimensionResource(id = R.dimen.spacing16)),
) {
BottomSheetIndicator()
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
AppBarWithAdditionalButtons(text = stringResource(id = R.string.details_referral_title))
AgreementHtmlView(url = url)
}
}
}
@Composable
private fun AgreementHtmlView(url: String) {
AndroidView(
modifier = Modifier.background(MaterialTheme.colors.secondary),
factory = {
WebView(it).apply {
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
webViewClient = WebViewClient()
settings.apply {
javaScriptEnabled = false
allowFileAccess = false
}
loadUrl(url)
}
},
update = { it.loadUrl(url) },
)
}
@Preview
@Composable
fun Preview_AgreementBottomSheet_InLightTheme() {
TangemTheme(isDarkTheme = false) {
AgreementBottomSheetContent(url = "https://tangem.com/en/")
}
}
@Preview
@Composable
fun Preview_AgreementBottomSheet_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
AgreementBottomSheetContent(url = "https://tangem.com/en/")
}
}

View file

@ -17,10 +17,16 @@ 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.BottomSheetScaffold
import androidx.compose.material.BottomSheetState
import androidx.compose.material.BottomSheetValue
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.rememberBottomSheetScaffoldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -32,8 +38,8 @@ 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.components.AppBarWithBackButton
import com.tangem.core.ui.components.VerticalSpacer
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.res.ButtonColorType
import com.tangem.core.ui.res.IconColorType
import com.tangem.core.ui.res.TangemTheme
@ -46,126 +52,51 @@ import com.tangem.feature.referral.models.ReferralStateHolder
import com.tangem.feature.referral.models.ReferralStateHolder.ReferralInfoState
import com.tangem.feature.referral.presentation.R
import com.valentinilk.shimmer.shimmer
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Participant_InLightTheme() {
TangemTheme(isDarkTheme = false) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.ParticipantContent(
award = "10 USDT",
address = "ma80...zk8q2",
discount = "10%",
onAgreementClicked = {},
onParticipateClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Participant_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.ParticipantContent(
award = "10 USDT",
address = "ma80...zk8q2",
discount = "10%",
onAgreementClicked = {},
onParticipateClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_NonParticipant_InLightTheme() {
TangemTheme(isDarkTheme = false) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.NonParticipantContent(
award = "10 USDT",
discount = "10%",
purchasedWalletCount = 3,
code = "x4JdK",
onCopyClicked = {},
onShareClicked = {},
onAgreementClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_NonParticipant_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.NonParticipantContent(
award = "10 USDT",
discount = "10%",
purchasedWalletCount = 3,
code = "x4JdK",
onCopyClicked = {},
onShareClicked = {},
onAgreementClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Loading_InLightTheme() {
TangemTheme(isDarkTheme = false) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.Loading,
effects = ReferralStateHolder.Effects(showErrorToast = false),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Loading_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.Loading,
effects = ReferralStateHolder.Effects(showErrorToast = false),
),
)
}
}
import kotlinx.coroutines.launch
/**
* Referral program screen for participant and non-participant
*
* @param stateHolder state holder
*/
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun ReferralScreen(stateHolder: ReferralStateHolder) {
val coroutineScope = rememberCoroutineScope()
val bottomSheetScaffoldState = rememberBottomSheetScaffoldState(
bottomSheetState = BottomSheetState(BottomSheetValue.Collapsed),
)
TangemTheme {
BottomSheetScaffold(
sheetContent = { AgreementBottomSheetContent(stateHolder.agreementBottomSheetState.url) },
scaffoldState = bottomSheetScaffoldState,
sheetShape = RoundedCornerShape(
topStart = dimensionResource(id = R.dimen.radius16),
topEnd = dimensionResource(id = R.dimen.radius16),
),
sheetElevation = dimensionResource(id = R.dimen.elevation24),
sheetPeekHeight = dimensionResource(id = R.dimen.size0),
content = {
ReferralContent(
stateHolder = stateHolder,
onAgreementClicked = {
coroutineScope.launch {
if (bottomSheetScaffoldState.bottomSheetState.isCollapsed) {
bottomSheetScaffoldState.bottomSheetState.expand()
} else {
bottomSheetScaffoldState.bottomSheetState.collapse()
}
}
},
)
},
)
}
}
@Composable
fun ReferralContent(stateHolder: ReferralStateHolder, onAgreementClicked: () -> Unit) {
Column(
modifier = Modifier
.background(color = MaterialTheme.colors.primary)
@ -175,7 +106,7 @@ fun ReferralScreen(stateHolder: ReferralStateHolder) {
) {
Header(stateHolder = stateHolder)
VerticalSpacer(spaceResId = R.dimen.spacing16)
ReferralInfo(stateHolder = stateHolder)
ReferralInfo(stateHolder = stateHolder, onAgreementClicked = onAgreementClicked)
}
}
@ -202,17 +133,17 @@ private fun ColumnScope.Header(stateHolder: ReferralStateHolder) {
}
@Composable
fun ReferralInfo(stateHolder: ReferralStateHolder) {
fun ReferralInfo(stateHolder: ReferralStateHolder, onAgreementClicked: () -> Unit) {
when (val state = stateHolder.referralInfoState) {
is ReferralInfoState.ParticipantContent -> {
Conditions(state = state)
VerticalSpacer(spaceResId = R.dimen.spacing44)
ParticipantBottomBlock(state = state)
ParticipantBottomBlock(state = state, onAgreementClicked = onAgreementClicked)
}
is ReferralInfoState.NonParticipantContent -> {
Conditions(state = state)
VerticalSpacer(spaceResId = R.dimen.spacing24)
NonParticipantBottomBlock(state = state)
NonParticipantBottomBlock(state = state, onAgreementClicked = onAgreementClicked)
}
is ReferralInfoState.Loading -> {
LoadingCondition(iconResId = R.drawable.ic_tether)
@ -373,21 +304,150 @@ private fun ShimmerInfo() {
}
@Composable
private fun ParticipantBottomBlock(state: ReferralInfoState.ParticipantContent) {
private fun ParticipantBottomBlock(state: ReferralInfoState.ParticipantContent, onAgreementClicked: () -> Unit) {
ParticipateBottomBlock(
onAgreementClicked = state.onAgreementClicked,
onAgreementClicked = onAgreementClicked,
onParticipateClicked = state.onParticipateClicked,
)
}
@Composable
private fun NonParticipantBottomBlock(state: ReferralInfoState.NonParticipantContent) {
private fun NonParticipantBottomBlock(state: ReferralInfoState.NonParticipantContent, onAgreementClicked: () -> Unit) {
NonParticipateBottomBlock(
purchasedWalletCount = state.purchasedWalletCount,
code = state.code,
onCopyClicked = state.onCopyClicked,
onShareClicked = state.onShareClicked,
onAgreementClicked = state.onAgreementClicked,
onAgreementClicked = onAgreementClicked,
)
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Participant_InLightTheme() {
TangemTheme(isDarkTheme = false) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.ParticipantContent(
award = "10 USDT",
address = "ma80...zk8q2",
discount = "10%",
onParticipateClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
url = "",
),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Participant_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.ParticipantContent(
award = "10 USDT",
address = "ma80...zk8q2",
discount = "10%",
onParticipateClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
url = "",
),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_NonParticipant_InLightTheme() {
TangemTheme(isDarkTheme = false) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.NonParticipantContent(
award = "10 USDT",
discount = "10%",
purchasedWalletCount = 3,
code = "x4JdK",
onCopyClicked = {},
onShareClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
url = "",
),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_NonParticipant_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.NonParticipantContent(
award = "10 USDT",
discount = "10%",
purchasedWalletCount = 3,
code = "x4JdK",
onCopyClicked = {},
onShareClicked = {},
),
effects = ReferralStateHolder.Effects(showErrorToast = false),
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
url = "",
),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Loading_InLightTheme() {
TangemTheme(isDarkTheme = false) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.Loading,
effects = ReferralStateHolder.Effects(showErrorToast = false),
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
url = "",
),
),
)
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
fun Preview_ReferralScreen_Loading_InDarkTheme() {
TangemTheme(isDarkTheme = true) {
ReferralScreen(
stateHolder = ReferralStateHolder(
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
referralInfoState = ReferralInfoState.Loading,
effects = ReferralStateHolder.Effects(showErrorToast = false),
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
url = "",
),
),
)
}
}

View file

@ -4,10 +4,10 @@
<string name="referral_title">Приведи друга в Tangem</string>
<string name="referral_point_currencies_title">Вы</string>
<string name="referral_point_currencies_description_prefix">Получите</string>
<string name="referral_point_currencies_description_suffix">за каждый кошелек, который купит ваш друг на ваш адрес в сети Tron %@</string>
<string name="referral_point_currencies_description_suffix">за каждый кошелек, который купит ваш друг на ваш адрес в сети Tron %s</string>
<string name="referral_point_discount_title">Ваш друг</string>
<string name="referral_point_discount_description_prefix">Получит</string>
<string name="referral_point_discount_description_value">%@ скидку</string>
<string name="referral_point_discount_description_value">%s скидку</string>
<string name="referral_point_discount_description_suffix">при покупке карточки на сайте tangem.com</string>
<string name="referral_tou_not_enroled_prefix">Нажимая на эту кнопку вы принимаете</string>
<string name="common_terms_and_conditions">условия участия</string>