Updated on 2026-08-14
This commit is contained in:
commit
31be70ecf3
529 changed files with 15730 additions and 4170 deletions
|
|
@ -9,6 +9,7 @@ import com.tangem.datasource.api.common.response.getOrThrow
|
|||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.StartReferralBody
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.referral.converters.ReferralConverter
|
||||
|
|
@ -20,7 +21,6 @@ import kotlinx.coroutines.withContext
|
|||
import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class ReferralRepositoryImpl @Inject constructor(
|
||||
private val referralApi: TangemTechApi,
|
||||
private val referralConverter: ReferralConverter,
|
||||
|
|
@ -74,7 +74,11 @@ internal class ReferralRepositoryImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun getCryptoCurrency(userWalletId: UserWalletId, tokenData: TokenData): CryptoCurrency? {
|
||||
override suspend fun getCryptoCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
tokenData: TokenData,
|
||||
accountIndex: DerivationIndex?,
|
||||
): CryptoCurrency? {
|
||||
val userWallet = withContext(coroutineDispatcher.io) {
|
||||
userWalletsStore.getSyncOrNull(userWalletId) ?: error("Wallet $userWalletId not found")
|
||||
}
|
||||
|
|
@ -97,12 +101,14 @@ internal class ReferralRepositoryImpl @Inject constructor(
|
|||
blockchain = blockchain,
|
||||
extraDerivationPath = null,
|
||||
userWallet = userWallet,
|
||||
accountIndex = accountIndex,
|
||||
)
|
||||
} else {
|
||||
cryptoCurrencyFactory.createCoin(
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = null,
|
||||
userWallet = userWallet,
|
||||
accountIndex = accountIndex,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ dependencies {
|
|||
implementation(projects.libs.crypto)
|
||||
|
||||
/** Domain modules */
|
||||
implementation(projects.domain.account.status)
|
||||
implementation(projects.domain.card)
|
||||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.tokens)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.feature.referral.domain
|
||||
|
||||
import com.tangem.domain.models.PortfolioId
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.referral.domain.models.ReferralData
|
||||
|
|
@ -12,5 +13,9 @@ interface ReferralInteractor {
|
|||
|
||||
suspend fun startReferral(portfolioId: PortfolioId): ReferralData
|
||||
|
||||
suspend fun getCryptoCurrency(userWalletId: UserWalletId, tokenData: TokenData): CryptoCurrency?
|
||||
suspend fun getCryptoCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
tokenData: TokenData,
|
||||
accountIndex: DerivationIndex?,
|
||||
): CryptoCurrency?
|
||||
}
|
||||
|
|
@ -2,7 +2,11 @@ package com.tangem.feature.referral.domain
|
|||
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.domain.account.producer.SingleAccountProducer
|
||||
import com.tangem.domain.account.status.usecase.ManageCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.account.supplier.SingleAccountSupplier
|
||||
import com.tangem.domain.models.PortfolioId
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
|
||||
|
|
@ -21,6 +25,8 @@ internal class ReferralInteractorImpl(
|
|||
private val derivePublicKeysUseCase: DerivePublicKeysUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase,
|
||||
private val manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase,
|
||||
private val singleAccountSupplier: SingleAccountSupplier,
|
||||
) : ReferralInteractor {
|
||||
|
||||
private val tokensForReferral = mutableListOf<TokenData>()
|
||||
|
|
@ -42,30 +48,47 @@ internal class ReferralInteractorImpl(
|
|||
error("Failed to get user wallet $userWalletId: $it")
|
||||
}
|
||||
|
||||
val cryptoCurrency = repository.getCryptoCurrency(userWalletId = userWallet.walletId, tokenData = tokenData)
|
||||
val accountIndex = when (portfolioId) {
|
||||
is PortfolioId.Account -> {
|
||||
val account = singleAccountSupplier.getSyncOrNull(
|
||||
params = SingleAccountProducer.Params(accountId = portfolioId.accountId),
|
||||
)
|
||||
?: error("Account not found: ${portfolioId.accountId}")
|
||||
|
||||
account.derivationIndex
|
||||
}
|
||||
is PortfolioId.Wallet -> null
|
||||
}
|
||||
|
||||
val cryptoCurrency = getCryptoCurrency(
|
||||
userWalletId = portfolioId.userWalletId,
|
||||
tokenData = tokenData,
|
||||
accountIndex = accountIndex,
|
||||
)
|
||||
?: error("Failed to create crypto currency")
|
||||
|
||||
// todo account different for account?
|
||||
derivePublicKeysUseCase(userWallet.walletId, listOfNotNull(cryptoCurrency)).getOrElse {
|
||||
Timber.e("Failed to derive public keys: $it")
|
||||
throw it.mapToDomainError()
|
||||
}
|
||||
|
||||
when (portfolioId) {
|
||||
is PortfolioId.Account -> TODO("account")
|
||||
is PortfolioId.Wallet -> addCryptoCurrenciesUseCase(
|
||||
userWalletId = userWallet.walletId,
|
||||
currency = cryptoCurrency,
|
||||
)
|
||||
}
|
||||
is PortfolioId.Account -> {
|
||||
manageCryptoCurrenciesUseCase(accountId = portfolioId.accountId, add = cryptoCurrency)
|
||||
}
|
||||
is PortfolioId.Wallet -> {
|
||||
derivePublicKeysUseCase(userWallet.walletId, listOfNotNull(cryptoCurrency)).getOrElse {
|
||||
Timber.e("Failed to derive public keys: $it")
|
||||
throw it.mapToDomainError()
|
||||
}
|
||||
|
||||
val publicAddress = when (portfolioId) {
|
||||
is PortfolioId.Account -> TODO("account")
|
||||
is PortfolioId.Wallet -> userWalletManager.getWalletAddress(
|
||||
networkId = tokenData.networkId,
|
||||
derivationPath = cryptoCurrency.network.derivationPath.value,
|
||||
)
|
||||
addCryptoCurrenciesUseCase(
|
||||
userWalletId = userWallet.walletId,
|
||||
currency = cryptoCurrency,
|
||||
)
|
||||
}
|
||||
}
|
||||
.onLeft(Timber::e)
|
||||
|
||||
val publicAddress = userWalletManager.getWalletAddress(
|
||||
networkId = tokenData.networkId,
|
||||
derivationPath = cryptoCurrency.network.derivationPath.value,
|
||||
)
|
||||
|
||||
return repository.startReferral(
|
||||
walletId = userWalletManager.getWalletId(),
|
||||
|
|
@ -75,8 +98,17 @@ internal class ReferralInteractorImpl(
|
|||
)
|
||||
}
|
||||
|
||||
override suspend fun getCryptoCurrency(userWalletId: UserWalletId, tokenData: TokenData): CryptoCurrency? =
|
||||
repository.getCryptoCurrency(userWalletId = userWalletId, tokenData = tokenData)
|
||||
override suspend fun getCryptoCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
tokenData: TokenData,
|
||||
accountIndex: DerivationIndex?,
|
||||
): CryptoCurrency? {
|
||||
return repository.getCryptoCurrency(
|
||||
userWalletId = userWalletId,
|
||||
tokenData = tokenData,
|
||||
accountIndex = accountIndex,
|
||||
)
|
||||
}
|
||||
|
||||
private fun saveReferralTokens(tokens: List<TokenData>) {
|
||||
tokensForReferral.clear()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.feature.referral.domain
|
||||
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.referral.domain.models.ReferralData
|
||||
|
|
@ -16,5 +17,10 @@ interface ReferralRepository {
|
|||
/** Starts user referral program */
|
||||
suspend fun startReferral(walletId: String, networkId: String, tokenId: String, address: String): ReferralData
|
||||
|
||||
suspend fun getCryptoCurrency(userWalletId: UserWalletId, tokenData: TokenData): CryptoCurrency?
|
||||
/** Returns [CryptoCurrency] by [tokenData] for specific [userWalletId] and optional [accountIndex] */
|
||||
suspend fun getCryptoCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
tokenData: TokenData,
|
||||
accountIndex: DerivationIndex?,
|
||||
): CryptoCurrency?
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
package com.tangem.feature.referral.domain.di
|
||||
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.di.ModelComponent
|
||||
import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.domain.account.status.usecase.ManageCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.account.supplier.SingleAccountSupplier
|
||||
import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.feature.referral.domain.ReferralInteractor
|
||||
import com.tangem.feature.referral.domain.ReferralInteractorImpl
|
||||
|
|
@ -25,6 +27,8 @@ class ReferralDomainModule {
|
|||
derivePublicKeysUseCase: DerivePublicKeysUseCase,
|
||||
getUserWalletUseCase: GetUserWalletUseCase,
|
||||
addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase,
|
||||
manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase,
|
||||
singleAccountSupplier: SingleAccountSupplier,
|
||||
): ReferralInteractor {
|
||||
return ReferralInteractorImpl(
|
||||
repository = referralRepository,
|
||||
|
|
@ -32,6 +36,8 @@ class ReferralDomainModule {
|
|||
derivePublicKeysUseCase = derivePublicKeysUseCase,
|
||||
getUserWalletUseCase = getUserWalletUseCase,
|
||||
addCryptoCurrenciesUseCase = addCryptoCurrenciesUseCase,
|
||||
manageCryptoCurrenciesUseCase = manageCryptoCurrenciesUseCase,
|
||||
singleAccountSupplier = singleAccountSupplier,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ import com.tangem.features.account.PortfolioSelectorComponent
|
|||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
class DefaultReferralComponent @AssistedInject constructor(
|
||||
private val portfolioSelectorComponentFactory: PortfolioSelectorComponent.Factory,
|
||||
|
|
@ -27,7 +28,7 @@ class DefaultReferralComponent @AssistedInject constructor(
|
|||
private val model: ReferralModel = getOrCreateModel(params)
|
||||
private val bottomSheetSlot = childSlot(
|
||||
source = model.bottomSheetNavigation,
|
||||
serializer = null,
|
||||
serializer = Unit.serializer(),
|
||||
handleBackButton = false,
|
||||
childFactory = { configuration, context -> bottomSheetChild(context) },
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.feature.referral.model
|
||||
|
||||
import com.tangem.common.ui.account.PortfolioSelectUM
|
||||
import com.tangem.common.ui.account.toUM
|
||||
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedCryptoAmount
|
||||
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedFiatAmount
|
||||
|
|
@ -14,8 +15,10 @@ import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
|||
import com.tangem.feature.referral.models.ReferralStateHolder.AccountAward
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class AccountAwardConverter(
|
||||
private val isBalanceHidden: Boolean,
|
||||
private val isSingleAccount: Boolean,
|
||||
private val appCurrency: AppCurrency,
|
||||
private val awardCryptoCurrency: CryptoCurrency,
|
||||
private val accountAwardToken: CryptoCurrencyStatus?,
|
||||
|
|
@ -56,11 +59,15 @@ internal class AccountAwardConverter(
|
|||
}
|
||||
|
||||
return AccountAward(
|
||||
accountName = cryptoPortfolio.account.accountName.toUM().value,
|
||||
accountIcon = cryptoPortfolio.account.icon.toUM(),
|
||||
onAccountClick = onAccountClick,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
tokenState = tokenState,
|
||||
accountSelectUM = PortfolioSelectUM(
|
||||
icon = cryptoPortfolio.account.icon.toUM(),
|
||||
name = cryptoPortfolio.account.accountName.toUM().value,
|
||||
isAccountMode = true,
|
||||
onClick = onAccountClick,
|
||||
isMultiChoice = !isSingleAccount,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ import androidx.compose.runtime.Stable
|
|||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import arrow.core.getOrElse
|
||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.arkivanov.decompose.router.slot.dismiss
|
||||
|
|
@ -23,7 +22,6 @@ import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
|||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.account.status.usecase.GetAccountCurrencyByAddressUseCase
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||
import com.tangem.domain.models.PortfolioId
|
||||
|
|
@ -87,8 +85,8 @@ internal class ReferralModel @Inject constructor(
|
|||
private set
|
||||
|
||||
val portfolioSelectorCallback = object : PortfolioSelectorComponent.BottomSheetCallback {
|
||||
override val onDismiss: () -> Unit = { bottomSheetNavigation::dismiss }
|
||||
override val onBack: () -> Unit = { bottomSheetNavigation::dismiss }
|
||||
override val onDismiss: () -> Unit = { bottomSheetNavigation.dismiss() }
|
||||
override val onBack: () -> Unit = { bottomSheetNavigation.dismiss() }
|
||||
}
|
||||
|
||||
init {
|
||||
|
|
@ -117,39 +115,45 @@ internal class ReferralModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun combineAccountUI(referralData: ReferralData): Flow<AccountAward?> = combine(
|
||||
flow = portfolioSelectorController.selectedAccountWithData(portfolioFetcher),
|
||||
flow2 = getBalanceHidingSettingsFlow(),
|
||||
flow3 = appCurrencyFlow(),
|
||||
) { a, b, c -> Triple(a, b, c) }.mapLatest { triple ->
|
||||
val (_, selectedAccount) = triple.first ?: return@mapLatest null
|
||||
val isBalanceHidden = triple.second
|
||||
val appCurrency: AppCurrency = triple.third
|
||||
val awardCryptoCurrency = referralInteractor.getCryptoCurrency(
|
||||
userWalletId = params.userWalletId,
|
||||
tokenData = referralData.getToken(),
|
||||
) ?: return@mapLatest null
|
||||
flow = portfolioSelectorController.selectedAccountWithData(portfolioFetcher)
|
||||
.onEach { bottomSheetNavigation.dismiss() },
|
||||
flow2 = getBalanceHidingSettingsUseCase.isBalanceHidden(),
|
||||
flow3 = getSelectedAppCurrencyUseCase.invokeOrDefault(),
|
||||
flow4 = portfolioFetcher.data,
|
||||
) { pair, isBalanceHidden, appCurrency, portfolios ->
|
||||
val selectedAccount = pair?.second ?: return@combine null
|
||||
|
||||
val cryptoPortfolio = when (selectedAccount) {
|
||||
is AccountStatus.CryptoPortfolio -> selectedAccount
|
||||
}
|
||||
|
||||
val awardCryptoCurrency = referralInteractor.getCryptoCurrency(
|
||||
userWalletId = params.userWalletId,
|
||||
tokenData = referralData.getToken(),
|
||||
accountIndex = cryptoPortfolio.account.derivationIndex,
|
||||
) ?: return@combine null
|
||||
|
||||
val accountAwardToken = cryptoPortfolio.tokenList.flattenCurrencies()
|
||||
.find { it.currency.id == awardCryptoCurrency.id }
|
||||
return@mapLatest AccountAwardConverter(
|
||||
|
||||
return@combine AccountAwardConverter(
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
awardCryptoCurrency = awardCryptoCurrency,
|
||||
accountAwardToken = accountAwardToken,
|
||||
cryptoPortfolio = cryptoPortfolio,
|
||||
appCurrency = appCurrency,
|
||||
isSingleAccount = portfolios.isSingleChoice,
|
||||
onAccountClick = { bottomSheetNavigation.activate(Unit) },
|
||||
).convert(Unit)
|
||||
}
|
||||
|
||||
private fun createInitiallyUiState() = ReferralStateHolder(
|
||||
headerState = ReferralStateHolder.HeaderState(
|
||||
headerState = HeaderState(
|
||||
onBackClicked = appRouter::pop,
|
||||
),
|
||||
referralInfoState = ReferralInfoState.Loading,
|
||||
errorSnackbar = null,
|
||||
analytics = ReferralStateHolder.Analytics(
|
||||
analytics = Analytics(
|
||||
onAgreementClicked = ::onAgreementClicked,
|
||||
onCopyClicked = ::onCopyClicked,
|
||||
onShareClicked = ::onShareClicked,
|
||||
|
|
@ -277,18 +281,6 @@ internal class ReferralModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getBalanceHidingSettingsFlow(): Flow<Boolean> {
|
||||
return getBalanceHidingSettingsUseCase()
|
||||
.map { it.isBalanceHidden }
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
private fun appCurrencyFlow(): Flow<AppCurrency> {
|
||||
return getSelectedAppCurrencyUseCase()
|
||||
.map { it.getOrElse { AppCurrency.Default } }
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private fun ReferralInfo.getAddressValue(): String {
|
||||
check(address.length > 5) { "Invalid address" }
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
package com.tangem.feature.referral.models
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.tangem.common.ui.account.CryptoPortfolioIconUM
|
||||
import com.tangem.common.ui.account.PortfolioSelectUM
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.feature.referral.domain.models.ExpectedAwards
|
||||
|
||||
internal data class ReferralStateHolder(
|
||||
|
|
@ -64,8 +63,6 @@ internal data class ReferralStateHolder(
|
|||
data class AccountAward(
|
||||
val tokenState: TokenItemState,
|
||||
val isBalanceHidden: Boolean,
|
||||
val accountName: TextReference,
|
||||
val accountIcon: CryptoPortfolioIconUM,
|
||||
val onAccountClick: () -> Unit,
|
||||
val accountSelectUM: PortfolioSelectUM,
|
||||
)
|
||||
}
|
||||
|
|
@ -10,25 +10,33 @@ import androidx.compose.material3.*
|
|||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.account.AccountIcon
|
||||
import com.tangem.core.res.getStringSafe
|
||||
import com.tangem.core.ui.components.PrimaryButtonIconStart
|
||||
import com.tangem.core.ui.components.SpacerH12
|
||||
import com.tangem.core.ui.components.SpacerW12
|
||||
import com.tangem.core.ui.components.account.AccountIconSize
|
||||
import com.tangem.core.ui.components.rows.RoundableCornersRow
|
||||
import com.tangem.core.ui.extensions.pluralStringResourceSafe
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.referral.domain.models.ExpectedAward
|
||||
import com.tangem.feature.referral.domain.models.ExpectedAwards
|
||||
import com.tangem.feature.referral.models.ReferralStateHolder
|
||||
import com.tangem.feature.referral.presentation.R
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
|
@ -43,6 +51,7 @@ internal fun ParticipateBottomBlock(
|
|||
onAgreementClick: () -> Unit,
|
||||
onCopyClick: () -> Unit,
|
||||
onShareClick: (String) -> Unit,
|
||||
accountAward: ReferralStateHolder.AccountAward?,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
|
@ -53,7 +62,7 @@ internal fun ParticipateBottomBlock(
|
|||
.padding(horizontal = TangemTheme.dimens.spacing16),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
PersonalCodeCard(code = code)
|
||||
PersonalCodeCard(code = code, accountAward = accountAward)
|
||||
AdditionalButtons(
|
||||
code = code,
|
||||
shareLink = shareLink,
|
||||
|
|
@ -242,19 +251,13 @@ private fun ExtraItems(extraItems: List<ExpectedAward>, overallItemsLastIndex: I
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun PersonalCodeCard(code: String) {
|
||||
private fun PersonalCodeCard(code: String, accountAward: ReferralStateHolder.AccountAward?) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.shadow(
|
||||
elevation = TangemTheme.dimens.elevation2,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius12),
|
||||
)
|
||||
.background(
|
||||
color = TangemTheme.colors.background.secondary,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius12),
|
||||
)
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius12))
|
||||
.background(color = TangemTheme.colors.background.primary)
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = TangemTheme.dimens.spacing12),
|
||||
.padding(top = TangemTheme.dimens.spacing12),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
|
|
@ -270,6 +273,53 @@ private fun PersonalCodeCard(code: String) {
|
|||
maxLines = 1,
|
||||
style = TangemTheme.typography.h2,
|
||||
)
|
||||
|
||||
if (accountAward != null) {
|
||||
AwardAccount(accountAward)
|
||||
} else {
|
||||
SpacerH12()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AwardAccount(accountAward: ReferralStateHolder.AccountAward) {
|
||||
Column {
|
||||
HorizontalDivider(
|
||||
thickness = 0.5.dp,
|
||||
color = TangemTheme.colors.stroke.primary,
|
||||
modifier = Modifier.padding(horizontal = 12.dp),
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.padding(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = stringResourceSafe(R.string.account_for_rewards),
|
||||
style = TangemTheme.typography.body1,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
)
|
||||
SpacerW12()
|
||||
val icon = accountAward.accountSelectUM.icon
|
||||
if (icon != null) {
|
||||
AccountIcon(
|
||||
name = accountAward.accountSelectUM.name,
|
||||
icon = icon,
|
||||
size = AccountIconSize.Small,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.padding(horizontal = 4.dp),
|
||||
text = accountAward.accountSelectUM.name.resolveReference(),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -351,10 +401,11 @@ private fun ParticipateBottomBlockPreview(
|
|||
code = data.code,
|
||||
shareLink = data.shareLink,
|
||||
expectedAwards = data.expectedAwards,
|
||||
onAgreementClick = data.onAgreementClick,
|
||||
snackbarHostState = SnackbarHostState(),
|
||||
onAgreementClick = data.onAgreementClick,
|
||||
onCopyClick = data.onCopyClick,
|
||||
onShareClick = data.onShareClick,
|
||||
accountAward = data.accountAward,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -410,12 +461,18 @@ private class ParticipateBottomBlockDataProvider : CollectionPreviewParameterPro
|
|||
purchasedWalletCount = 0,
|
||||
expectedAwards = null,
|
||||
),
|
||||
ParticipateBottomBlockData(
|
||||
purchasedWalletCount = 0,
|
||||
expectedAwards = null,
|
||||
accountAward = accountReward,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
private data class ParticipateBottomBlockData(
|
||||
val purchasedWalletCount: Int,
|
||||
val expectedAwards: ExpectedAwards?,
|
||||
val accountAward: ReferralStateHolder.AccountAward? = null,
|
||||
val code: String = "x4JDK",
|
||||
val shareLink: String = "",
|
||||
val onAgreementClick: () -> Unit = {},
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import androidx.compose.runtime.remember
|
|||
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.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
|
|
@ -26,14 +27,15 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.account.AccountIcon
|
||||
import com.tangem.common.ui.account.AccountIconPreviewData
|
||||
import com.tangem.common.ui.account.PortfolioSelectRow
|
||||
import com.tangem.common.ui.account.PortfolioSelectUM
|
||||
import com.tangem.common.ui.account.toUM
|
||||
import com.tangem.core.res.getStringSafe
|
||||
import com.tangem.core.ui.components.RectangleShimmer
|
||||
import com.tangem.core.ui.components.SpacerH16
|
||||
import com.tangem.core.ui.components.SpacerH24
|
||||
import com.tangem.core.ui.components.SpacerH32
|
||||
import com.tangem.core.ui.components.account.AccountIconSize
|
||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
||||
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
||||
import com.tangem.core.ui.components.snackbar.CopiedTextSnackbar
|
||||
|
|
@ -41,13 +43,13 @@ import com.tangem.core.ui.components.snackbar.TangemSnackbar
|
|||
import com.tangem.core.ui.components.token.TokenItem
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState.FiatAmountState
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.ReferralProgramScreenTestTags
|
||||
import com.tangem.domain.models.account.AccountName
|
||||
import com.tangem.feature.referral.domain.models.ExpectedAward
|
||||
import com.tangem.feature.referral.domain.models.ExpectedAwards
|
||||
import com.tangem.feature.referral.models.DemoModeException
|
||||
|
|
@ -183,6 +185,7 @@ private fun ReferralInfo(
|
|||
code = state.code,
|
||||
shareLink = state.shareLink,
|
||||
expectedAwards = state.expectedAwards,
|
||||
accountAward = state.accountAward,
|
||||
snackbarHostState = snackbarHostState,
|
||||
onAgreementClick = onAgreementClick,
|
||||
onCopyClick = stateHolder.analytics.onCopyClicked,
|
||||
|
|
@ -390,10 +393,8 @@ private fun NonParticipateAccountAwardBlock(accountAward: AccountAward) {
|
|||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.background(
|
||||
color = TangemTheme.colors.background.primary,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.spacing16),
|
||||
),
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.spacing16))
|
||||
.background(color = TangemTheme.colors.background.primary),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(
|
||||
|
|
@ -418,44 +419,7 @@ private fun NonParticipateAccountAwardBlock(accountAward: AccountAward) {
|
|||
color = TangemTheme.colors.stroke.primary,
|
||||
modifier = Modifier.padding(horizontal = 12.dp),
|
||||
)
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(TangemTheme.dimens.spacing12),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = stringResourceSafe(R.string.account_details_title),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
AccountIcon(
|
||||
name = accountAward.accountName,
|
||||
icon = accountAward.accountIcon,
|
||||
size = AccountIconSize.Small,
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 4.dp),
|
||||
text = accountAward.accountName.resolveReference(),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
Icon(
|
||||
modifier = Modifier.size(width = 18.dp, height = 24.dp),
|
||||
painter = painterResource(id = R.drawable.ic_select_18_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
)
|
||||
}
|
||||
PortfolioSelectRow(accountAward.accountSelectUM)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -516,6 +480,7 @@ private fun Preview_ReferralScreen_Participant_With_Referrals() {
|
|||
code = "x4JdK",
|
||||
shareLink = "",
|
||||
url = "",
|
||||
accountAward = accountReward,
|
||||
expectedAwards = ExpectedAwards(
|
||||
numberOfWallets = 5,
|
||||
expectedAwards = listOf(
|
||||
|
|
@ -572,6 +537,41 @@ private fun Preview_ReferralScreen_NonParticipant() {
|
|||
}
|
||||
}
|
||||
|
||||
internal val account = PortfolioSelectUM(
|
||||
icon = AccountIconPreviewData.randomAccountIcon(),
|
||||
name = AccountName.DefaultMain.toUM().value,
|
||||
isAccountMode = true,
|
||||
isMultiChoice = true,
|
||||
onClick = {},
|
||||
)
|
||||
|
||||
internal val accountReward
|
||||
get() = AccountAward(
|
||||
accountSelectUM = account,
|
||||
isBalanceHidden = false,
|
||||
tokenState = TokenItemState.Content(
|
||||
id = UUID.randomUUID().toString(),
|
||||
iconState = CurrencyIconState.TokenIcon(
|
||||
url = null,
|
||||
topBadgeIconResId = R.drawable.img_tron_22,
|
||||
fallbackTint = TangemColorPalette.Black,
|
||||
fallbackBackground = TangemColorPalette.Meadow,
|
||||
isGrayscale = false,
|
||||
shouldShowCustomBadge = false,
|
||||
),
|
||||
titleState = TokenItemState.TitleState.Content(
|
||||
text = stringReference(value = "Tether"),
|
||||
),
|
||||
fiatAmountState = FiatAmountState.Content(
|
||||
text = "129,65 $",
|
||||
),
|
||||
subtitle2State = TokenItemState.Subtitle2State.TextContent(text = "129,65 USDT"),
|
||||
subtitleState = TokenItemState.SubtitleState.TextContent(value = stringReference("USDT")),
|
||||
onItemClick = null,
|
||||
onItemLongClick = null,
|
||||
),
|
||||
)
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Preview(widthDp = 360, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
|
|
@ -587,33 +587,7 @@ private fun Preview_ReferralScreen_NonParticipantAccount() {
|
|||
url = "",
|
||||
onParticipateClicked = {},
|
||||
participateButtonIcon = R.drawable.ic_tangem_24,
|
||||
accountAward = AccountAward(
|
||||
onAccountClick = {},
|
||||
accountIcon = AccountIconPreviewData.randomAccountIcon(),
|
||||
accountName = stringReference("Main Account"),
|
||||
isBalanceHidden = false,
|
||||
tokenState = TokenItemState.Content(
|
||||
id = UUID.randomUUID().toString(),
|
||||
iconState = CurrencyIconState.TokenIcon(
|
||||
url = null,
|
||||
topBadgeIconResId = R.drawable.img_tron_22,
|
||||
fallbackTint = TangemColorPalette.Black,
|
||||
fallbackBackground = TangemColorPalette.Meadow,
|
||||
isGrayscale = false,
|
||||
shouldShowCustomBadge = false,
|
||||
),
|
||||
titleState = TokenItemState.TitleState.Content(
|
||||
text = stringReference(value = "Tether"),
|
||||
),
|
||||
fiatAmountState = FiatAmountState.Content(
|
||||
text = "129,65 $",
|
||||
),
|
||||
subtitle2State = TokenItemState.Subtitle2State.TextContent(text = "129,65 USDT"),
|
||||
subtitleState = TokenItemState.SubtitleState.TextContent(value = stringReference("USDT")),
|
||||
onItemClick = {},
|
||||
onItemLongClick = {},
|
||||
),
|
||||
),
|
||||
accountAward = accountReward,
|
||||
),
|
||||
errorSnackbar = null,
|
||||
analytics = Analytics(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue