Updated on 2026-08-14
This commit is contained in:
parent
2803ac9eef
commit
ee722c5f46
11 changed files with 327 additions and 198 deletions
|
|
@ -6,6 +6,7 @@ import androidx.fragment.app.Fragment
|
|||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.tangem.common.extensions.VoidCallback
|
||||
import com.tangem.feature.referral.ReferralFragment
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.FragmentShareTransition
|
||||
import com.tangem.tap.features.details.ui.appsettings.AppSettingsFragment
|
||||
|
|
@ -108,5 +109,6 @@ private fun fragmentFactory(screen: AppScreen): Fragment {
|
|||
AppScreen.WalletDetails -> WalletDetailsFragment()
|
||||
AppScreen.WalletConnectSessions -> WalletConnectFragment()
|
||||
AppScreen.QrScan -> QrScanFragment()
|
||||
AppScreen.ReferralProgram -> ReferralFragment()
|
||||
}
|
||||
}
|
||||
|
|
@ -22,4 +22,5 @@ enum class AppScreen(
|
|||
AddTokens, AddCustomToken,
|
||||
WalletConnectSessions,
|
||||
QrScan,
|
||||
ReferralProgram
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.utils.coroutines
|
||||
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
suspend fun <R> runCatching(dispatcher: CoroutineDispatcher, block: suspend () -> R): Result<R> {
|
||||
return runCatching {
|
||||
withContext(dispatcher) { block() }
|
||||
}
|
||||
}
|
||||
|
|
@ -34,10 +34,13 @@ android {
|
|||
|
||||
dependencies {
|
||||
/** Core modules */
|
||||
implementation(project(":core:utils"))
|
||||
implementation(project(":core:ui"))
|
||||
|
||||
/** AndroidX */
|
||||
implementation(AndroidX.appCompat)
|
||||
implementation(AndroidX.fragmentKtx)
|
||||
implementation(AndroidX.lifecycleViewModelKtx)
|
||||
|
||||
/** Compose */
|
||||
implementation(Compose.foundation)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.feature.referral
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.tangem.feature.referral.ui.ReferralScreen
|
||||
import com.tangem.feature.referral.viewmodels.ReferralViewModel
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ReferralFragment : Fragment() {
|
||||
private val viewModel by viewModels<ReferralViewModel>().apply {
|
||||
// TODO("[REDACTED_JIRA]") this.value.setOnBackClicked()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
return ComposeView(inflater.context).apply {
|
||||
setContent {
|
||||
ReferralScreen(stateHolder = viewModel.uiState)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,36 +3,39 @@ package com.tangem.feature.referral.models
|
|||
data class ReferralStateHolder(
|
||||
val headerState: HeaderState,
|
||||
val referralInfoState: ReferralInfoState,
|
||||
val effects: Effects,
|
||||
val agreementBottomSheetState: AgreementBottomSheetState
|
||||
val errorToast: ErrorToast,
|
||||
) {
|
||||
|
||||
data class HeaderState(val onBackClicked: () -> Unit)
|
||||
|
||||
sealed interface ReferralInfoContentState
|
||||
sealed interface ReferralInfoContentState {
|
||||
val award: String
|
||||
val discount: String
|
||||
val url: String
|
||||
}
|
||||
|
||||
sealed interface ReferralInfoState {
|
||||
|
||||
data class ParticipantContent(
|
||||
val award: String,
|
||||
override val award: String,
|
||||
val address: String,
|
||||
val discount: String,
|
||||
val onParticipateClicked: () -> Unit,
|
||||
override val discount: String,
|
||||
val purchasedWalletCount: Int,
|
||||
val code: String,
|
||||
override val url: String,
|
||||
) : ReferralInfoState, ReferralInfoContentState
|
||||
|
||||
data class NonParticipantContent(
|
||||
val award: String,
|
||||
val discount: String,
|
||||
val purchasedWalletCount: Int,
|
||||
val code: String,
|
||||
val onCopyClicked: () -> Unit,
|
||||
val onShareClicked: () -> Unit,
|
||||
override val award: String,
|
||||
override val discount: String,
|
||||
override val url: String,
|
||||
val onParticipateClicked: () -> Unit,
|
||||
) : ReferralInfoState, ReferralInfoContentState
|
||||
|
||||
object Loading : ReferralInfoState
|
||||
}
|
||||
|
||||
data class Effects(val showErrorToast: Boolean)
|
||||
|
||||
data class AgreementBottomSheetState(val url: String)
|
||||
data class ErrorToast(
|
||||
val visibility: Boolean,
|
||||
val changeVisibility: () -> Unit
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
package com.tangem.feature.referral.presentation
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.tangem.feature.referral.domain.ReferralInteractor
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ReferralViewModel @Inject constructor(referralInteractor: ReferralInteractor) : ViewModel() {
|
||||
|
||||
}
|
||||
|
|
@ -1,40 +1,40 @@
|
|||
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.components.PrimaryEndIconButton
|
||||
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
|
||||
|
||||
@Composable
|
||||
fun NonParticipateBottomBlock(onAgreementClicked: () -> Unit, onParticipateClicked: () -> Unit) {
|
||||
Column {
|
||||
AgreementText(
|
||||
firstPartResId = R.string.referral_tos_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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_NonParticipateBottomBlock_InLightTheme() {
|
||||
TangemTheme(isDark = false) {
|
||||
Column(Modifier.background(MaterialTheme.colors.primary)) {
|
||||
NonParticipateBottomBlock(
|
||||
purchasedWalletCount = 3,
|
||||
code = "x4JdK",
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
onAgreementClicked = {},
|
||||
)
|
||||
NonParticipateBottomBlock(onAgreementClicked = {}, onParticipateClicked = {})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -44,96 +44,7 @@ fun Preview_NonParticipateBottomBlock_InLightTheme() {
|
|||
fun Preview_NonParticipateBottomBlock_InDarkTheme() {
|
||||
TangemTheme(isDark = true) {
|
||||
Column(Modifier.background(MaterialTheme.colors.primary)) {
|
||||
NonParticipateBottomBlock(
|
||||
purchasedWalletCount = 3,
|
||||
code = "x4JdK",
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
onAgreementClicked = {},
|
||||
)
|
||||
NonParticipateBottomBlock(onAgreementClicked = {}, onParticipateClicked = {})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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_tos_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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +1,135 @@
|
|||
package com.tangem.feature.referral.ui
|
||||
|
||||
import android.content.Intent
|
||||
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.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.PrimaryEndIconButton
|
||||
import androidx.core.content.ContextCompat.startActivity
|
||||
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
|
||||
|
||||
@Composable
|
||||
fun ParticipateBottomBlock(
|
||||
purchasedWalletCount: Int,
|
||||
code: String,
|
||||
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(code = code)
|
||||
AgreementText(firstPartResId = R.string.referral_tos_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(code: String) {
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
val context = LocalContext.current
|
||||
|
||||
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 = { clipboardManager.setText(AnnotatedString(code)) },
|
||||
)
|
||||
PrimaryStartIconButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = stringResource(id = R.string.common_share),
|
||||
iconResId = R.drawable.ic_share,
|
||||
onClicked = {
|
||||
val sendIntent: Intent = Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
putExtra(Intent.EXTRA_TEXT, code)
|
||||
type = "text/plain"
|
||||
}
|
||||
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||
startActivity(context, shareIntent, null)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_ParticipateBottomBlock_InLightTheme() {
|
||||
TangemTheme(isDark = false) {
|
||||
Column(Modifier.background(MaterialTheme.colors.primary)) {
|
||||
ParticipateBottomBlock(onAgreementClicked = {}, onParticipateClicked = {})
|
||||
ParticipateBottomBlock(
|
||||
purchasedWalletCount = 3,
|
||||
code = "x4JdK",
|
||||
onAgreementClicked = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -28,23 +139,11 @@ fun Preview_ParticipateBottomBlock_InLightTheme() {
|
|||
fun Preview_ParticipateBottomBlock_InDarkTheme() {
|
||||
TangemTheme(isDark = true) {
|
||||
Column(Modifier.background(MaterialTheme.colors.primary)) {
|
||||
ParticipateBottomBlock(onAgreementClicked = {}, onParticipateClicked = {})
|
||||
ParticipateBottomBlock(
|
||||
purchasedWalletCount = 3,
|
||||
code = "x4JdK",
|
||||
onAgreementClicked = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ParticipateBottomBlock(onAgreementClicked: () -> Unit, onParticipateClicked: () -> Unit) {
|
||||
Column {
|
||||
AgreementText(
|
||||
firstPartResId = R.string.referral_tos_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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.feature.referral.ui
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
|
|
@ -26,10 +27,12 @@ import androidx.compose.material.MaterialTheme
|
|||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.rememberBottomSheetScaffoldState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
|
@ -49,6 +52,7 @@ import com.tangem.core.ui.res.buttonColor
|
|||
import com.tangem.core.ui.res.iconColor
|
||||
import com.tangem.core.ui.res.textColor
|
||||
import com.tangem.feature.referral.models.ReferralStateHolder
|
||||
import com.tangem.feature.referral.models.ReferralStateHolder.ReferralInfoContentState
|
||||
import com.tangem.feature.referral.models.ReferralStateHolder.ReferralInfoState
|
||||
import com.tangem.feature.referral.presentation.R
|
||||
import com.valentinilk.shimmer.shimmer
|
||||
|
|
@ -69,7 +73,11 @@ fun ReferralScreen(stateHolder: ReferralStateHolder) {
|
|||
|
||||
TangemTheme {
|
||||
BottomSheetScaffold(
|
||||
sheetContent = { AgreementBottomSheetContent(stateHolder.agreementBottomSheetState.url) },
|
||||
sheetContent = {
|
||||
AgreementBottomSheetContent(
|
||||
url = (stateHolder.referralInfoState as ReferralInfoContentState).url,
|
||||
)
|
||||
},
|
||||
scaffoldState = bottomSheetScaffoldState,
|
||||
sheetShape = RoundedCornerShape(
|
||||
topStart = dimensionResource(id = R.dimen.radius16),
|
||||
|
|
@ -92,6 +100,15 @@ fun ReferralScreen(stateHolder: ReferralStateHolder) {
|
|||
)
|
||||
},
|
||||
)
|
||||
|
||||
val context = LocalContext.current
|
||||
SideEffect {
|
||||
if (stateHolder.errorToast.visibility) {
|
||||
//TODO("[REDACTED_JIRA]")
|
||||
Toast.makeText(context, "", Toast.LENGTH_LONG).show()
|
||||
stateHolder.errorToast.changeVisibility()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -137,12 +154,11 @@ fun ReferralInfo(stateHolder: ReferralStateHolder, onAgreementClicked: () -> Uni
|
|||
when (val state = stateHolder.referralInfoState) {
|
||||
is ReferralInfoState.ParticipantContent -> {
|
||||
Conditions(state = state)
|
||||
VerticalSpacer(spaceResId = R.dimen.spacing44)
|
||||
ParticipantBottomBlock(state = state, onAgreementClicked = onAgreementClicked)
|
||||
}
|
||||
is ReferralInfoState.NonParticipantContent -> {
|
||||
Conditions(state = state)
|
||||
VerticalSpacer(spaceResId = R.dimen.spacing24)
|
||||
VerticalSpacer(spaceResId = R.dimen.spacing44)
|
||||
NonParticipantBottomBlock(state = state, onAgreementClicked = onAgreementClicked)
|
||||
}
|
||||
is ReferralInfoState.Loading -> {
|
||||
|
|
@ -162,14 +178,14 @@ private fun AppBar(stateHolder: ReferralStateHolder) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun Conditions(state: ReferralStateHolder.ReferralInfoContentState) {
|
||||
private fun Conditions(state: ReferralInfoContentState) {
|
||||
ConditionForYou(state = state)
|
||||
VerticalSpacer(spaceResId = R.dimen.spacing32)
|
||||
ConditionForYourFriend(state = state)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ConditionForYou(state: ReferralStateHolder.ReferralInfoContentState) {
|
||||
private fun ConditionForYou(state: ReferralInfoContentState) {
|
||||
Condition(iconResId = R.drawable.ic_tether) {
|
||||
when (state) {
|
||||
is ReferralInfoState.ParticipantContent -> InfoForYou(award = state.award, address = state.address)
|
||||
|
|
@ -179,7 +195,7 @@ private fun ConditionForYou(state: ReferralStateHolder.ReferralInfoContentState)
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun ConditionForYourFriend(state: ReferralStateHolder.ReferralInfoContentState) {
|
||||
private fun ConditionForYourFriend(state: ReferralInfoContentState) {
|
||||
Condition(iconResId = R.drawable.ic_discount) {
|
||||
when (state) {
|
||||
is ReferralInfoState.ParticipantContent -> InfoForYourFriend(discount = state.discount)
|
||||
|
|
@ -306,19 +322,17 @@ private fun ShimmerInfo() {
|
|||
@Composable
|
||||
private fun ParticipantBottomBlock(state: ReferralInfoState.ParticipantContent, onAgreementClicked: () -> Unit) {
|
||||
ParticipateBottomBlock(
|
||||
purchasedWalletCount = state.purchasedWalletCount,
|
||||
code = state.code,
|
||||
onAgreementClicked = onAgreementClicked,
|
||||
onParticipateClicked = state.onParticipateClicked,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NonParticipantBottomBlock(state: ReferralInfoState.NonParticipantContent, onAgreementClicked: () -> Unit) {
|
||||
NonParticipateBottomBlock(
|
||||
purchasedWalletCount = state.purchasedWalletCount,
|
||||
code = state.code,
|
||||
onCopyClicked = state.onCopyClicked,
|
||||
onShareClicked = state.onShareClicked,
|
||||
onAgreementClicked = onAgreementClicked,
|
||||
onParticipateClicked = state.onParticipateClicked,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -333,12 +347,11 @@ fun Preview_ReferralScreen_Participant_InLightTheme() {
|
|||
award = "10 USDT",
|
||||
address = "ma80...zk8q2",
|
||||
discount = "10%",
|
||||
onParticipateClicked = {},
|
||||
),
|
||||
effects = ReferralStateHolder.Effects(showErrorToast = false),
|
||||
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
|
||||
purchasedWalletCount = 3,
|
||||
code = "x4JdK",
|
||||
url = "",
|
||||
),
|
||||
errorToast = ReferralStateHolder.ErrorToast(visibility = false, changeVisibility = {}),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -355,13 +368,11 @@ fun Preview_ReferralScreen_Participant_InDarkTheme() {
|
|||
award = "10 USDT",
|
||||
address = "ma80...zk8q2",
|
||||
discount = "10%",
|
||||
|
||||
onParticipateClicked = {},
|
||||
),
|
||||
effects = ReferralStateHolder.Effects(showErrorToast = false),
|
||||
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
|
||||
purchasedWalletCount = 3,
|
||||
code = "x4JdK",
|
||||
url = "",
|
||||
),
|
||||
errorToast = ReferralStateHolder.ErrorToast(visibility = false, changeVisibility = {}),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -377,16 +388,10 @@ fun Preview_ReferralScreen_NonParticipant_InLightTheme() {
|
|||
referralInfoState = ReferralInfoState.NonParticipantContent(
|
||||
award = "10 USDT",
|
||||
discount = "10%",
|
||||
purchasedWalletCount = 3,
|
||||
code = "x4JdK",
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
|
||||
),
|
||||
effects = ReferralStateHolder.Effects(showErrorToast = false),
|
||||
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
|
||||
url = "",
|
||||
onParticipateClicked = {},
|
||||
),
|
||||
errorToast = ReferralStateHolder.ErrorToast(visibility = false, changeVisibility = {}),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -402,16 +407,10 @@ fun Preview_ReferralScreen_NonParticipant_InDarkTheme() {
|
|||
referralInfoState = ReferralInfoState.NonParticipantContent(
|
||||
award = "10 USDT",
|
||||
discount = "10%",
|
||||
purchasedWalletCount = 3,
|
||||
code = "x4JdK",
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
|
||||
),
|
||||
effects = ReferralStateHolder.Effects(showErrorToast = false),
|
||||
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
|
||||
url = "",
|
||||
onParticipateClicked = {},
|
||||
),
|
||||
errorToast = ReferralStateHolder.ErrorToast(visibility = false, changeVisibility = {}),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -425,10 +424,7 @@ fun Preview_ReferralScreen_Loading_InLightTheme() {
|
|||
stateHolder = ReferralStateHolder(
|
||||
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
|
||||
referralInfoState = ReferralInfoState.Loading,
|
||||
effects = ReferralStateHolder.Effects(showErrorToast = false),
|
||||
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
|
||||
url = "",
|
||||
),
|
||||
errorToast = ReferralStateHolder.ErrorToast(visibility = false, changeVisibility = {}),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -442,10 +438,7 @@ fun Preview_ReferralScreen_Loading_InDarkTheme() {
|
|||
stateHolder = ReferralStateHolder(
|
||||
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
|
||||
referralInfoState = ReferralInfoState.Loading,
|
||||
effects = ReferralStateHolder.Effects(showErrorToast = false),
|
||||
agreementBottomSheetState = ReferralStateHolder.AgreementBottomSheetState(
|
||||
url = "",
|
||||
),
|
||||
errorToast = ReferralStateHolder.ErrorToast(visibility = false, changeVisibility = {}),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
package com.tangem.feature.referral.viewmodels
|
||||
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.tangem.feature.referral.domain.ReferralInteractor
|
||||
import com.tangem.feature.referral.domain.models.DiscountType
|
||||
import com.tangem.feature.referral.domain.models.ReferralData
|
||||
import com.tangem.feature.referral.models.ReferralStateHolder
|
||||
import com.tangem.feature.referral.models.ReferralStateHolder.ReferralInfoState
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.runCatching
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ReferralViewModel @Inject constructor(
|
||||
private val referralInteractor: ReferralInteractor,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : ViewModel() {
|
||||
|
||||
var uiState by mutableStateOf(createInitiallyUiState())
|
||||
private set
|
||||
|
||||
init {
|
||||
loadReferralData()
|
||||
}
|
||||
|
||||
fun setOnBackClicked(onBackClicked: () -> Unit) {
|
||||
uiState = uiState.copy(headerState = ReferralStateHolder.HeaderState(onBackClicked = onBackClicked))
|
||||
}
|
||||
|
||||
private fun createInitiallyUiState() = ReferralStateHolder(
|
||||
headerState = ReferralStateHolder.HeaderState(onBackClicked = { }),
|
||||
referralInfoState = ReferralInfoState.Loading,
|
||||
errorToast = ReferralStateHolder.ErrorToast(visibility = false, changeVisibility = ::cancelErrorToast),
|
||||
)
|
||||
|
||||
private fun loadReferralData() {
|
||||
uiState = uiState.copy(referralInfoState = ReferralInfoState.Loading)
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
runCatching(dispatchers.io) { referralInteractor.getReferralStatus() }
|
||||
.onSuccess { uiState = uiState.copy(referralInfoState = it.convertToReferralInfoState()) }
|
||||
.onFailure { uiState = uiState.copy(errorToast = uiState.errorToast.copy(visibility = true)) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun ReferralData.convertToReferralInfoState(): ReferralInfoState = when (this) {
|
||||
is ReferralData.ParticipantData -> ReferralInfoState.ParticipantContent(
|
||||
award = getAwardValue(),
|
||||
address = referral.address,
|
||||
discount = getDiscountValue(),
|
||||
purchasedWalletCount = referral.walletsPurchased,
|
||||
code = referral.promocode,
|
||||
url = tosLink,
|
||||
)
|
||||
is ReferralData.NonParticipantData -> ReferralInfoState.NonParticipantContent(
|
||||
award = getAwardValue(),
|
||||
discount = getDiscountValue(),
|
||||
url = tosLink,
|
||||
onParticipateClicked = ::onParticipateClicked,
|
||||
)
|
||||
}
|
||||
|
||||
private fun ReferralData.getAwardValue(): String =
|
||||
"$award ${requireNotNull(tokens.firstOrNull()?.symbol) { "Token list is empty" }}"
|
||||
|
||||
private fun ReferralData.getDiscountValue(): String {
|
||||
val discountSymbol = when (discountType) {
|
||||
DiscountType.PERCENTAGE -> "%"
|
||||
DiscountType.VALUE -> throw java.lang.IllegalStateException("Value doesn't support")
|
||||
}
|
||||
return "$discount $discountSymbol"
|
||||
}
|
||||
|
||||
private fun onParticipateClicked() {
|
||||
uiState = uiState.copy(referralInfoState = ReferralInfoState.Loading)
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
runCatching(dispatchers.io) { referralInteractor.startReferral() }
|
||||
.onSuccess { uiState = uiState.copy(referralInfoState = it.convertToReferralInfoState()) }
|
||||
.onFailure { uiState = uiState.copy(errorToast = uiState.errorToast.copy(visibility = true)) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun cancelErrorToast() {
|
||||
uiState = uiState.copy(errorToast = uiState.errorToast.copy(visibility = false))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue