Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-09 09:01:19 +02:00
parent f692cd4788
commit 3e250db77c
5 changed files with 55 additions and 42 deletions

View file

@ -18,7 +18,11 @@ import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState
import com.tangem.core.ui.ds2.button.Close import com.tangem.core.ui.ds2.button.Close
import com.tangem.core.ui.ds2.button.TangemButton import com.tangem.core.ui.ds2.button.TangemButton
import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenComponent import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenComponent
import com.tangem.features.promobanners.impl.campaigns.entity.CampaignType
import com.tangem.features.promobanners.impl.campaigns.model.ActivateCampaignsModel import com.tangem.features.promobanners.impl.campaigns.model.ActivateCampaignsModel
import com.tangem.features.promobanners.impl.campaigns.ui.ActivateCampaignContent import com.tangem.features.promobanners.impl.campaigns.ui.ActivateCampaignContent
import com.tangem.features.promobanners.impl.campaigns.ui.ActivateCampaignFooter import com.tangem.features.promobanners.impl.campaigns.ui.ActivateCampaignFooter
@ -26,7 +30,8 @@ import com.tangem.features.promobanners.impl.campaigns.ui.ActivateCampaignFooter
internal class ActivateCampaignBottomSheetComponent( internal class ActivateCampaignBottomSheetComponent(
appComponentContext: AppComponentContext, appComponentContext: AppComponentContext,
chooseTokenComponentFactory: ChooseTokenComponent.Factory, chooseTokenComponentFactory: ChooseTokenComponent.Factory,
private val params: ActivateCampaignsModel.Params, private val params: Params,
val onDismiss: () -> Unit,
) : CampaignsModularComponent, AppComponentContext by appComponentContext { ) : CampaignsModularComponent, AppComponentContext by appComponentContext {
private val model: ActivateCampaignsModel = getOrCreateModel(params) private val model: ActivateCampaignsModel = getOrCreateModel(params)
@ -41,7 +46,7 @@ internal class ActivateCampaignBottomSheetComponent(
TangemTopNavigation( TangemTopNavigation(
windowInsets = WindowInsets(0), windowInsets = WindowInsets(0),
blurBackground = false, blurBackground = false,
endButton = { TangemButton.Close(onClick = params.onDismiss) }, endButton = { TangemButton.Close(onClick = onDismiss) },
) )
} }
@ -77,4 +82,14 @@ internal class ActivateCampaignBottomSheetComponent(
content = { chooseTokenComponent.Content(modifier = Modifier.fillMaxWidth()) }, content = { chooseTokenComponent.Content(modifier = Modifier.fillMaxWidth()) },
) )
} }
data class Params(
val campaignType: CampaignType,
val modelCallbacks: ActivateCampaignModelCallbacks,
)
interface ActivateCampaignModelCallbacks {
val onActivated: (CampaignType) -> Unit
val onAlreadyActivated: (CampaignType, AppCurrency, Account?, CryptoCurrencyStatus) -> Unit
}
} }

View file

@ -16,13 +16,18 @@ import com.tangem.core.ui.ds2.button.Close
import com.tangem.core.ui.ds2.button.TangemButton import com.tangem.core.ui.ds2.button.TangemButton
import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation
import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.promobanners.impl.R import com.tangem.features.promobanners.impl.R
import com.tangem.features.promobanners.impl.campaigns.entity.CampaignType
import com.tangem.features.promobanners.impl.campaigns.model.CampaignAlreadyActivatedModel import com.tangem.features.promobanners.impl.campaigns.model.CampaignAlreadyActivatedModel
import com.tangem.features.promobanners.impl.campaigns.ui.ActivateCampaignContent import com.tangem.features.promobanners.impl.campaigns.ui.ActivateCampaignContent
internal class CampaignAlreadyActivatedBottomSheetComponent( internal class CampaignAlreadyActivatedBottomSheetComponent(
appComponentContext: AppComponentContext, appComponentContext: AppComponentContext,
private val params: CampaignAlreadyActivatedModel.Params, params: Params,
val onDismiss: () -> Unit,
) : CampaignsModularComponent, AppComponentContext by appComponentContext { ) : CampaignsModularComponent, AppComponentContext by appComponentContext {
private val model: CampaignAlreadyActivatedModel = getOrCreateModel(params) private val model: CampaignAlreadyActivatedModel = getOrCreateModel(params)
@ -32,7 +37,7 @@ internal class CampaignAlreadyActivatedBottomSheetComponent(
TangemTopNavigation( TangemTopNavigation(
windowInsets = WindowInsets(0), windowInsets = WindowInsets(0),
blurBackground = false, blurBackground = false,
endButton = { TangemButton.Close(onClick = params.onDismiss) }, endButton = { TangemButton.Close(onClick = onDismiss) },
) )
} }
@ -48,7 +53,14 @@ internal class CampaignAlreadyActivatedBottomSheetComponent(
PrimaryButton( PrimaryButton(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
text = stringResourceSafe(R.string.common_close), text = stringResourceSafe(R.string.common_close),
onClick = params.onDismiss, onClick = onDismiss,
) )
} }
data class Params(
val campaignType: CampaignType,
val account: Account?,
val appCurrency: AppCurrency,
val currency: CryptoCurrencyStatus,
)
} }

View file

@ -26,11 +26,14 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState
import com.tangem.core.ui.extensions.rememberLastNonNull import com.tangem.core.ui.extensions.rememberLastNonNull
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenComponent import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenComponent
import com.tangem.features.promobanners.api.swapcashback.CampaignsComponent import com.tangem.features.promobanners.api.swapcashback.CampaignsComponent
import com.tangem.features.promobanners.impl.campaigns.component.ActivateCampaignBottomSheetComponent.ActivateCampaignModelCallbacks
import com.tangem.features.promobanners.impl.campaigns.entity.CampaignType
import com.tangem.features.promobanners.impl.campaigns.entity.CampaignsBottomSheetConfig import com.tangem.features.promobanners.impl.campaigns.entity.CampaignsBottomSheetConfig
import com.tangem.features.promobanners.impl.campaigns.model.ActivateCampaignsModel
import com.tangem.features.promobanners.impl.campaigns.model.CampaignAlreadyActivatedModel
import com.tangem.features.promobanners.impl.campaigns.model.CampaignsModel import com.tangem.features.promobanners.impl.campaigns.model.CampaignsModel
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
@ -121,28 +124,28 @@ internal class DefaultCampaignsComponent @AssistedInject constructor(
is CampaignsBottomSheetConfig.Activate -> ActivateCampaignBottomSheetComponent( is CampaignsBottomSheetConfig.Activate -> ActivateCampaignBottomSheetComponent(
appComponentContext = context, appComponentContext = context,
chooseTokenComponentFactory = chooseTokenComponentFactory, chooseTokenComponentFactory = chooseTokenComponentFactory,
params = ActivateCampaignsModel.Params( onDismiss = model::onDismiss,
params = ActivateCampaignBottomSheetComponent.Params(
campaignType = config.campaignType, campaignType = config.campaignType,
onDismiss = model::onDismiss, modelCallbacks = object : ActivateCampaignModelCallbacks {
onActivated = model::onActivated, override val onActivated: (CampaignType) -> Unit = model::onActivated
onAlreadyActivated = { campaignType, appCurrency, account, currency -> override val onAlreadyActivated: (
model.onAlreadyActivated( CampaignType,
campaignType = campaignType, AppCurrency,
appCurrency = appCurrency, Account?,
account = account, CryptoCurrencyStatus,
currency = currency, ) -> Unit = model::onAlreadyActivated
)
}, },
), ),
) )
is CampaignsBottomSheetConfig.AlreadyActivated -> CampaignAlreadyActivatedBottomSheetComponent( is CampaignsBottomSheetConfig.AlreadyActivated -> CampaignAlreadyActivatedBottomSheetComponent(
appComponentContext = context, appComponentContext = context,
params = CampaignAlreadyActivatedModel.Params( onDismiss = model::onDismiss,
params = CampaignAlreadyActivatedBottomSheetComponent.Params(
campaignType = config.campaignType, campaignType = config.campaignType,
appCurrency = config.appCurrency, appCurrency = config.appCurrency,
account = config.account, account = config.account,
currency = config.currency, currency = config.currency,
onDismiss = model::onDismiss,
), ),
) )
} }

View file

@ -19,8 +19,8 @@ import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenBridge import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenBridge
import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenResult import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenResult
import com.tangem.features.promobanners.impl.R import com.tangem.features.promobanners.impl.R
import com.tangem.features.promobanners.impl.campaigns.component.ActivateCampaignBottomSheetComponent
import com.tangem.features.promobanners.impl.campaigns.entity.ActivateCampaignUM import com.tangem.features.promobanners.impl.campaigns.entity.ActivateCampaignUM
import com.tangem.features.promobanners.impl.campaigns.entity.CampaignType
import com.tangem.features.promobanners.impl.campaigns.entity.FooterUM import com.tangem.features.promobanners.impl.campaigns.entity.FooterUM
import com.tangem.features.promobanners.impl.campaigns.entity.SelectedAccountUM import com.tangem.features.promobanners.impl.campaigns.entity.SelectedAccountUM
import com.tangem.features.promobanners.impl.campaigns.entity.TermsUM import com.tangem.features.promobanners.impl.campaigns.entity.TermsUM
@ -45,7 +45,7 @@ internal class ActivateCampaignsModel @Inject constructor(
private val urlOpener: UrlOpener, private val urlOpener: UrlOpener,
) : Model() { ) : Model() {
private val params = paramsContainer.require<Params>() private val params = paramsContainer.require<ActivateCampaignBottomSheetComponent.Params>()
private val accountIconConverter = AccountIconItemStateConverter(size = AccountIconSize.ExtraSmall) private val accountIconConverter = AccountIconItemStateConverter(size = AccountIconSize.ExtraSmall)
private var appCurrency: AppCurrency = AppCurrency.Default private var appCurrency: AppCurrency = AppCurrency.Default
private var selectedAccount: Account? = null private var selectedAccount: Account? = null
@ -92,10 +92,10 @@ internal class ActivateCampaignsModel @Inject constructor(
// Success -> the "enrolled" sheet; "already activated" error -> hand the chosen token/account // Success -> the "enrolled" sheet; "already activated" error -> hand the chosen token/account
// over to the "already activated" sheet. // over to the "already activated" sheet.
if (enrollInCampaign()) { if (enrollInCampaign()) {
params.onActivated(params.campaignType) params.modelCallbacks.onActivated(params.campaignType)
} else { } else {
selectedCurrency?.let { selectedCurrency?.let {
params.onAlreadyActivated(params.campaignType, appCurrency, selectedAccount, it) params.modelCallbacks.onAlreadyActivated(params.campaignType, appCurrency, selectedAccount, it)
} }
} }
} }
@ -179,13 +179,6 @@ internal class ActivateCampaignsModel @Inject constructor(
) )
} }
data class Params(
val campaignType: CampaignType,
val onDismiss: () -> Unit,
val onActivated: (CampaignType) -> Unit,
val onAlreadyActivated: (CampaignType, AppCurrency, Account?, CryptoCurrencyStatus) -> Unit,
)
private companion object { private companion object {
// TODO([REDACTED_TASK_KEY]): replace with the real campaign terms URL. // TODO([REDACTED_TASK_KEY]): replace with the real campaign terms URL.
const val CAMPAIGN_TERMS_URL = "https://tangem.com/en/" const val CAMPAIGN_TERMS_URL = "https://tangem.com/en/"

View file

@ -8,11 +8,9 @@ import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.ui.components.account.AccountIconSize import com.tangem.core.ui.components.account.AccountIconSize
import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.account.Account import com.tangem.domain.models.account.Account
import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.features.promobanners.impl.campaigns.component.CampaignAlreadyActivatedBottomSheetComponent
import com.tangem.features.promobanners.impl.campaigns.entity.CampaignAlreadyActivatedUM import com.tangem.features.promobanners.impl.campaigns.entity.CampaignAlreadyActivatedUM
import com.tangem.features.promobanners.impl.campaigns.entity.CampaignType
import com.tangem.features.promobanners.impl.campaigns.entity.SelectedAccountUM import com.tangem.features.promobanners.impl.campaigns.entity.SelectedAccountUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@ -34,7 +32,7 @@ internal class CampaignAlreadyActivatedModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider, override val dispatchers: CoroutineDispatcherProvider,
) : Model() { ) : Model() {
private val params = paramsContainer.require<Params>() private val params = paramsContainer.require<CampaignAlreadyActivatedBottomSheetComponent.Params>()
private val accountIconConverter = AccountIconItemStateConverter(size = AccountIconSize.ExtraSmall) private val accountIconConverter = AccountIconItemStateConverter(size = AccountIconSize.ExtraSmall)
val uiState: StateFlow<CampaignAlreadyActivatedUM> val uiState: StateFlow<CampaignAlreadyActivatedUM>
@ -62,12 +60,4 @@ internal class CampaignAlreadyActivatedModel @Inject constructor(
selectedAccount = selectedAccountUM, selectedAccount = selectedAccountUM,
) )
} }
data class Params(
val campaignType: CampaignType,
val account: Account?,
val appCurrency: AppCurrency,
val currency: CryptoCurrencyStatus,
val onDismiss: () -> Unit,
)
} }