Updated on 2026-08-14
This commit is contained in:
parent
939dcf8405
commit
7c9e533757
10 changed files with 242 additions and 228 deletions
|
|
@ -258,7 +258,7 @@
|
|||
<string name="common_enable">Enable</string>
|
||||
<string name="common_enabled">Enabled</string>
|
||||
<string name="common_error">Error</string>
|
||||
<string name="common_estimated_fee">Network service fee</string>
|
||||
<string name="common_estimated_fee">Top-up network fee</string>
|
||||
<string name="common_exchange">Swap</string>
|
||||
<string name="common_explore">Explore</string>
|
||||
<string name="common_explore_transaction_history">Explore transaction history</string>
|
||||
|
|
@ -274,7 +274,7 @@
|
|||
<string name="common_free">Free</string>
|
||||
<string name="common_from">From</string>
|
||||
<string name="common_generate_addresses">Synchronize addresses</string>
|
||||
<string name="common_get_started">Get started</string>
|
||||
<string name="common_get_started">Learn more</string>
|
||||
<string name="common_get_token">Get token</string>
|
||||
<string name="common_go_to_provider">Go to provider</string>
|
||||
<string name="common_go_to_token">Go to token</string>
|
||||
|
|
@ -573,8 +573,8 @@
|
|||
<string name="hw_backup_hardware_upgrade_title">Upgrade current wallet</string>
|
||||
<string name="hw_backup_need_action">Go to backup</string>
|
||||
<string name="hw_backup_need_description">Please back up your wallet before creating an access code.</string>
|
||||
<string name="hw_backup_need_finish_first">Finish Backup First</string>
|
||||
<string name="hw_backup_need_title">Finalize backup first</string>
|
||||
<string name="hw_backup_need_finish_first">Finish backup first</string>
|
||||
<string name="hw_backup_no_backup">Incomplete</string>
|
||||
<string name="hw_backup_section_other_title">Other methods</string>
|
||||
<string name="hw_backup_seed_description">Physical devices that securely store your private key offline.</string>
|
||||
|
|
@ -1374,6 +1374,7 @@
|
|||
<string name="tangem_pay_status_completed">Completed</string>
|
||||
<string name="tangem_pay_status_declined">Declined</string>
|
||||
<string name="tangem_pay_status_pending">Pending</string>
|
||||
<string name="tangem_pay_terms_fees_limits">Terms, Fees & Limits</string>
|
||||
<string name="tangem_pay_transaction_declined_notification_text">The bank rejected this transaction request.</string>
|
||||
<string name="tangem_pay_transaction_fee_notification_text">This fee goes to cover the cost of handling your transfer.</string>
|
||||
<string name="tangem_pay_unfreeze_card_alert_body">Keep using your money. You can freeze anytime.</string>
|
||||
|
|
@ -1410,12 +1411,12 @@
|
|||
<string name="tangempay_kyc_in_progress_notification_button">View Status</string>
|
||||
<string name="tangempay_kyc_in_progress_notification_title">KYC in progress for Tangem Pay</string>
|
||||
<string name="tangempay_onboarding_get_card_button_text">Get card</string>
|
||||
<string name="tangempay_onboarding_pay_description">Add to your wallet and pay with your phone anywhere.</string>
|
||||
<string name="tangempay_onboarding_pay_title">Apple Pay & Google Pay</string>
|
||||
<string name="tangempay_onboarding_purchases_description">Use your USDC balance to pay for everyday purchases seamlessly.</string>
|
||||
<string name="tangempay_onboarding_purchases_title">Everyday purchases</string>
|
||||
<string name="tangempay_onboarding_security_description">Your card details are protected — full control in the app.</string>
|
||||
<string name="tangempay_onboarding_security_title">Built-in security</string>
|
||||
<string name="tangempay_onboarding_pay_description">Spend your crypto anywhere</string>
|
||||
<string name="tangempay_onboarding_pay_title">With digital card that works with Apple Pay and Google Pay</string>
|
||||
<string name="tangempay_onboarding_purchases_description">There are no additional fees for purchases</string>
|
||||
<string name="tangempay_onboarding_purchases_title">Pay exactly what you see</string>
|
||||
<string name="tangempay_onboarding_security_description">A separate payment account will be created without disclosing your addresses and assets</string>
|
||||
<string name="tangempay_onboarding_security_title">Unrivaled privacy</string>
|
||||
<string name="tangempay_onboarding_title">Get your free Crypto Card\nin minutes</string>
|
||||
<string name="tangempay_title">Tangem Pay</string>
|
||||
<string name="this_is_my_wallet_title">This is my wallet</string>
|
||||
|
|
@ -1880,7 +1881,7 @@
|
|||
<string name="yield_module_alert_description">With Yield mode active, all future deposits to this address will go to Aave. You can still manage your funds freely.</string>
|
||||
<string name="yield_module_alert_title">Your %s is supplied to Aave</string>
|
||||
<string name="yield_module_amount_not_transfered_to_aave_title">Supplying %1$s %2$s to Aave is pending</string>
|
||||
<string name="yield_module_approve_needed_notification_cta">Give Approve</string>
|
||||
<string name="yield_module_approve_needed_notification_cta">Approve</string>
|
||||
<string name="yield_module_approve_needed_notification_description">Your token’s approval has been revoked. Grant it again to resume service functionality.</string>
|
||||
<string name="yield_module_approve_needed_notification_title">Approve needed</string>
|
||||
<string name="yield_module_approve_sheet_fee_note">The fee will be taken out, and your assets will be lent again.</string>
|
||||
|
|
@ -1909,7 +1910,7 @@
|
|||
<string name="yield_module_fee_policy_sheet_max_fee_title">Maximum fee</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_note">The minimum amount is calculated based on the current network fee so that it does not exceed 4%% of the top-up amount, which makes the minimum %1$s (%2$s).</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_title">Minimum top-up</string>
|
||||
<string name="yield_module_fee_policy_sheet_title">Fee policy</string>
|
||||
<string name="yield_module_fee_policy_sheet_title">Top-up fee policy</string>
|
||||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem also takes a 15% service fee on yield earned.</string>
|
||||
<string name="yield_module_high_fee_error">Your funds will be automatically supplied to Aave once network fees are lower or your balance meets the minimum required amount.</string>
|
||||
<string name="yield_module_historical_returns">Historical returns</string>
|
||||
|
|
@ -1936,7 +1937,7 @@
|
|||
<string name="yield_module_receive_sheet_description">When you top up, your funds will be automatically sent to Aave to start earning interest. %s will be deducted to cover the transaction fee.</string>
|
||||
<string name="yield_module_start_earning">Supply assets</string>
|
||||
<string name="yield_module_start_earning_sheet_description">Your %s will be supplied to Aave, but will remain manageable.</string>
|
||||
<string name="yield_module_start_earning_sheet_fee_policy">See fee policy</string>
|
||||
<string name="yield_module_start_earning_sheet_fee_policy">See top-up fee policy</string>
|
||||
<string name="yield_module_start_earning_sheet_next_deposits">Your next top-ups will be automatically supplied to Aave.</string>
|
||||
<string name="yield_module_status_active">Active</string>
|
||||
<string name="yield_module_status_paused">Paused</string>
|
||||
|
|
@ -1950,7 +1951,7 @@
|
|||
<string name="yield_module_token_details_earn_notification_description">Interest accrues automatically.</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_subtitle">Interest accrues automatically</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Yield mode</string>
|
||||
<string name="yield_module_token_details_earn_notification_processing">Processing your deposit</string>
|
||||
<string name="yield_module_token_details_earn_notification_processing">Processing your top-up</string>
|
||||
<string name="yield_module_token_details_earn_notification_title">Yield Mode</string>
|
||||
<string name="yield_module_transfer_mode_automatic">Automatic</string>
|
||||
<string name="yield_module_unable_to_cover_fee_description">Deposit some %1$s %2$s to cover the network fee for transactions</string>
|
||||
|
|
|
|||
BIN
core/ui/src/main/res/drawable/img_tangem_pay_visa.webp
Normal file
BIN
core/ui/src/main/res/drawable/img_tangem_pay_visa.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
|
|
@ -16,6 +16,8 @@ dependencies {
|
|||
implementation(projects.core.decompose)
|
||||
implementation(projects.core.ui)
|
||||
implementation(projects.core.error)
|
||||
implementation(projects.core.navigation)
|
||||
implementation(deps.arrow.core)
|
||||
implementation(deps.arrow.core)
|
||||
|
||||
/** Common */
|
||||
|
|
|
|||
|
|
@ -6,14 +6,17 @@ import com.tangem.core.decompose.di.ModelScoped
|
|||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.domain.pay.repository.OnboardingRepository
|
||||
import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase
|
||||
import com.tangem.features.tangempay.components.TangemPayOnboardingComponent
|
||||
import com.tangem.features.tangempay.model.transformers.TangemPayOnboardingButtonLoadingTransformer
|
||||
import com.tangem.features.tangempay.ui.TangemPayOnboardingScreenState
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import com.tangem.utils.transformer.update as transformerUpdate
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
|
@ -26,6 +29,7 @@ internal class TangemPayOnboardingModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val repository: OnboardingRepository,
|
||||
private val produceInitialDataUseCase: ProduceTangemPayInitialDataUseCase,
|
||||
private val urlOpener: UrlOpener,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<TangemPayOnboardingComponent.Params>()
|
||||
|
|
@ -48,7 +52,16 @@ internal class TangemPayOnboardingModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun showOnboarding() {
|
||||
uiState.update { it.copy(fullScreenLoading = false) }
|
||||
uiState.update {
|
||||
TangemPayOnboardingScreenState.Content(
|
||||
onBack = it.onBack,
|
||||
onTermsClick = ::onTermsClick,
|
||||
buttonConfig = TangemPayOnboardingScreenState.Content.ButtonConfig(
|
||||
isLoading = false,
|
||||
onClick = ::onGetCardClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun checkCustomerInfo() {
|
||||
|
|
@ -57,8 +70,7 @@ internal class TangemPayOnboardingModel @Inject constructor(
|
|||
when {
|
||||
!customerInfo.isKycApproved -> {
|
||||
when (params) {
|
||||
is TangemPayOnboardingComponent.Params.Deeplink ->
|
||||
uiState.value = uiState.value.copy(fullScreenLoading = false)
|
||||
is TangemPayOnboardingComponent.Params.Deeplink -> showOnboarding()
|
||||
else -> openKyc()
|
||||
}
|
||||
}
|
||||
|
|
@ -68,13 +80,17 @@ internal class TangemPayOnboardingModel @Inject constructor(
|
|||
.onLeft { back() }
|
||||
}
|
||||
|
||||
private fun onTermsClick() {
|
||||
urlOpener.openUrl("https://tangem.com/docs/en/tangem-visa-tariffs.pdf")
|
||||
}
|
||||
|
||||
private fun onGetCardClick() {
|
||||
uiState.update { it.copy(buttonLoading = true) }
|
||||
uiState.transformerUpdate(TangemPayOnboardingButtonLoadingTransformer(isLoading = true))
|
||||
modelScope.launch {
|
||||
val result = produceInitialDataUseCase()
|
||||
if (result.isLeft()) {
|
||||
Timber.e("Error producing initial data: ${result.leftOrNull()?.message}")
|
||||
uiState.update { it.copy(buttonLoading = false) }
|
||||
uiState.transformerUpdate(TangemPayOnboardingButtonLoadingTransformer(isLoading = false))
|
||||
return@launch
|
||||
}
|
||||
|
||||
|
|
@ -82,7 +98,7 @@ internal class TangemPayOnboardingModel @Inject constructor(
|
|||
.fold(
|
||||
ifLeft = {
|
||||
Timber.e("Error getCustomerInfo: ${it.errorCode}")
|
||||
uiState.update { it.copy(buttonLoading = false) }
|
||||
uiState.transformerUpdate(TangemPayOnboardingButtonLoadingTransformer(isLoading = false))
|
||||
},
|
||||
ifRight = { customerInfo ->
|
||||
if (customerInfo.isKycApproved) {
|
||||
|
|
@ -104,11 +120,6 @@ internal class TangemPayOnboardingModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun getInitialState(): TangemPayOnboardingScreenState {
|
||||
return TangemPayOnboardingScreenState(
|
||||
fullScreenLoading = true,
|
||||
buttonLoading = false,
|
||||
onGetCardClick = ::onGetCardClick,
|
||||
onBackClick = ::back,
|
||||
)
|
||||
return TangemPayOnboardingScreenState.Loading(onBack = ::back)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.features.tangempay.model.transformers
|
||||
|
||||
import com.tangem.features.tangempay.ui.TangemPayOnboardingScreenState
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class TangemPayOnboardingButtonLoadingTransformer(
|
||||
private val isLoading: Boolean,
|
||||
) : Transformer<TangemPayOnboardingScreenState> {
|
||||
override fun transform(prevState: TangemPayOnboardingScreenState): TangemPayOnboardingScreenState {
|
||||
val contentState = prevState as? TangemPayOnboardingScreenState.Content ?: return prevState
|
||||
val updatedButtonConfig = contentState.buttonConfig.copy(isLoading = isLoading)
|
||||
return contentState.copy(buttonConfig = updatedButtonConfig)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,34 @@
|
|||
package com.tangem.features.tangempay.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
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.navigationButtons.NavigationButton
|
||||
import com.tangem.common.ui.navigationButtons.NavigationPrimaryButton
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.SecondaryButton
|
||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||
|
||||
|
|
@ -23,27 +39,166 @@ internal fun TandemPayOnboardingScreen(state: TangemPayOnboardingScreenState, mo
|
|||
topBar = {
|
||||
AppBarWithBackButton(
|
||||
modifier = Modifier.statusBarsPadding(),
|
||||
onBackClick = state.onBackClick,
|
||||
onBackClick = state.onBack,
|
||||
iconRes = R.drawable.ic_back_24,
|
||||
)
|
||||
},
|
||||
contentWindowInsets = WindowInsetsZero,
|
||||
content = { paddingValues ->
|
||||
TangemPayOnboardingContent(
|
||||
modifier = Modifier
|
||||
.padding(paddingValues)
|
||||
.fillMaxSize(),
|
||||
state = state,
|
||||
onButtonClick = state.onGetCardClick,
|
||||
)
|
||||
val contentModifier = Modifier
|
||||
.systemBarsPadding()
|
||||
.padding(paddingValues)
|
||||
.fillMaxSize()
|
||||
when (state) {
|
||||
is TangemPayOnboardingScreenState.Loading -> TangemPayOnboardingLoading(modifier = contentModifier)
|
||||
is TangemPayOnboardingScreenState.Content -> TangemPayOnboardingContent(
|
||||
state = state,
|
||||
modifier = contentModifier,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TangemPayOnboardingLoading(modifier: Modifier = Modifier) {
|
||||
Box(modifier = modifier, contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier,
|
||||
color = TangemTheme.colors.icon.primary1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TangemPayOnboardingContent(state: TangemPayOnboardingScreenState.Content, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier.padding(horizontal = 16.dp)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 16.dp)
|
||||
.weight(1f)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.img_tangem_pay_visa),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(width = 200.dp, height = 130.dp),
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.tangempay_onboarding_title),
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(top = 24.dp)
|
||||
.padding(horizontal = 12.dp)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
|
||||
TangemPayOnboardingBlocks(
|
||||
modifier = Modifier
|
||||
.padding(top = 24.dp)
|
||||
.padding(horizontal = 12.dp),
|
||||
)
|
||||
}
|
||||
FooterButtons(
|
||||
modifier = Modifier.padding(bottom = 16.dp),
|
||||
primaryButtonConfig = state.buttonConfig,
|
||||
onTermsClick = state.onTermsClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayOnboardingBlocks(modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
verticalArrangement = Arrangement.spacedBy(20.dp),
|
||||
) {
|
||||
TangemPayOnboardingBlock(
|
||||
painterRes = R.drawable.ic_security_check_22,
|
||||
titleRef = TextReference.Res(R.string.tangempay_onboarding_security_title),
|
||||
descriptionRef = TextReference.Res(R.string.tangempay_onboarding_security_description),
|
||||
)
|
||||
|
||||
TangemPayOnboardingBlock(
|
||||
painterRes = R.drawable.ic_shopping_basket_22,
|
||||
titleRef = TextReference.Res(R.string.tangempay_onboarding_purchases_title),
|
||||
descriptionRef = TextReference.Res(R.string.tangempay_onboarding_purchases_description),
|
||||
)
|
||||
|
||||
TangemPayOnboardingBlock(
|
||||
painterRes = R.drawable.ic_credit_card_add_22,
|
||||
titleRef = TextReference.Res(R.string.tangempay_onboarding_pay_title),
|
||||
descriptionRef = TextReference.Res(R.string.tangempay_onboarding_pay_description),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TangemPayOnboardingBlock(
|
||||
@DrawableRes painterRes: Int,
|
||||
titleRef: TextReference,
|
||||
descriptionRef: TextReference,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Row(modifier = modifier) {
|
||||
Icon(
|
||||
painter = painterResource(id = painterRes),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(width = 24.dp, height = 24.dp),
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(start = 12.dp)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
Text(
|
||||
text = titleRef.resolveReference(),
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
Text(
|
||||
text = descriptionRef.resolveReference(),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun FooterButtons(
|
||||
primaryButtonConfig: TangemPayOnboardingScreenState.Content.ButtonConfig,
|
||||
onTermsClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
SecondaryButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResourceSafe(R.string.tangem_pay_terms_fees_limits),
|
||||
onClick = onTermsClick,
|
||||
)
|
||||
NavigationPrimaryButton(
|
||||
primaryButton = NavigationButton(
|
||||
textReference = resourceReference(R.string.tangempay_onboarding_get_card_button_text),
|
||||
iconRes = R.drawable.ic_tangem_24,
|
||||
isIconVisible = true,
|
||||
shouldShowProgress = primaryButtonConfig.isLoading,
|
||||
onClick = primaryButtonConfig.onClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun PreviewDarkTheme(
|
||||
private fun TandemPayOnboardingScreenPreview(
|
||||
@PreviewParameter(TangemPayOnboardingScreenStateProvider::class)
|
||||
state: TangemPayOnboardingScreenState,
|
||||
) {
|
||||
|
|
@ -55,23 +210,16 @@ private fun PreviewDarkTheme(
|
|||
private class TangemPayOnboardingScreenStateProvider :
|
||||
CollectionPreviewParameterProvider<TangemPayOnboardingScreenState>(
|
||||
listOf(
|
||||
TangemPayOnboardingScreenState(
|
||||
fullScreenLoading = true,
|
||||
buttonLoading = false,
|
||||
onGetCardClick = {},
|
||||
onBackClick = {},
|
||||
TangemPayOnboardingScreenState.Loading(onBack = {}),
|
||||
TangemPayOnboardingScreenState.Content(
|
||||
onBack = {},
|
||||
onTermsClick = {},
|
||||
buttonConfig = TangemPayOnboardingScreenState.Content.ButtonConfig(isLoading = false, onClick = {}),
|
||||
),
|
||||
TangemPayOnboardingScreenState(
|
||||
fullScreenLoading = false,
|
||||
buttonLoading = false,
|
||||
onGetCardClick = {},
|
||||
onBackClick = {},
|
||||
),
|
||||
TangemPayOnboardingScreenState(
|
||||
fullScreenLoading = false,
|
||||
buttonLoading = true,
|
||||
onGetCardClick = {},
|
||||
onBackClick = {},
|
||||
TangemPayOnboardingScreenState.Content(
|
||||
onBack = {},
|
||||
onTermsClick = {},
|
||||
buttonConfig = TangemPayOnboardingScreenState.Content.ButtonConfig(isLoading = true, onClick = {}),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
package com.tangem.features.tangempay.ui
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayOnboardingBlock(
|
||||
@DrawableRes painterRes: Int,
|
||||
titleRef: TextReference,
|
||||
descriptionRef: TextReference,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.padding(start = 32.dp, end = 32.dp),
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = painterRes),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.width(24.dp)
|
||||
.height(24.dp),
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.padding(start = 12.dp),
|
||||
) {
|
||||
Text(
|
||||
text = titleRef.resolveReference(),
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
Text(
|
||||
text = descriptionRef.resolveReference(),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
package com.tangem.features.tangempay.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayOnboardingBLocks(modifier: Modifier = Modifier) {
|
||||
TangemPayOnboardingBlock(
|
||||
modifier = modifier,
|
||||
painterRes = R.drawable.ic_security_check_22,
|
||||
titleRef = TextReference.Res(R.string.tangempay_onboarding_security_title),
|
||||
descriptionRef = TextReference.Res(R.string.tangempay_onboarding_security_description),
|
||||
)
|
||||
|
||||
SpacerH(18.dp)
|
||||
|
||||
TangemPayOnboardingBlock(
|
||||
modifier = modifier,
|
||||
painterRes = R.drawable.ic_shopping_basket_22,
|
||||
titleRef = TextReference.Res(R.string.tangempay_onboarding_purchases_title),
|
||||
descriptionRef = TextReference.Res(R.string.tangempay_onboarding_purchases_description),
|
||||
)
|
||||
|
||||
SpacerH(18.dp)
|
||||
|
||||
TangemPayOnboardingBlock(
|
||||
modifier = modifier,
|
||||
painterRes = R.drawable.ic_credit_card_add_22,
|
||||
titleRef = TextReference.Res(R.string.tangempay_onboarding_pay_title),
|
||||
descriptionRef = TextReference.Res(R.string.tangempay_onboarding_pay_description),
|
||||
)
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
package com.tangem.features.tangempay.ui
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.navigationButtons.NavigationButton
|
||||
import com.tangem.common.ui.navigationButtons.NavigationPrimaryButton
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.tangempay.onboarding.impl.R
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayOnboardingContent(
|
||||
state: TangemPayOnboardingScreenState,
|
||||
onButtonClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
if (state.fullScreenLoading) {
|
||||
Box(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier,
|
||||
color = TangemTheme.colors.icon.primary1,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Column(
|
||||
modifier
|
||||
.fillMaxSize()
|
||||
.navigationBarsPadding(),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(top = 24.dp, bottom = 32.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.img_tangem_pay_onboarding),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.height(250.dp)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.tangempay_onboarding_title),
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
|
||||
SpacerH(32.dp)
|
||||
|
||||
TangemPayOnboardingBLocks()
|
||||
}
|
||||
|
||||
NavigationPrimaryButton(
|
||||
modifier = Modifier
|
||||
.imePadding()
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
primaryButton = NavigationButton(
|
||||
textReference = resourceReference(R.string.tangempay_onboarding_get_card_button_text),
|
||||
iconRes = R.drawable.ic_tangem_24,
|
||||
isIconVisible = true,
|
||||
shouldShowProgress = state.buttonLoading,
|
||||
onClick = onButtonClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,9 +3,15 @@ package com.tangem.features.tangempay.ui
|
|||
import javax.annotation.concurrent.Immutable
|
||||
|
||||
@Immutable
|
||||
internal data class TangemPayOnboardingScreenState(
|
||||
val fullScreenLoading: Boolean,
|
||||
val buttonLoading: Boolean,
|
||||
val onGetCardClick: () -> Unit,
|
||||
val onBackClick: () -> Unit,
|
||||
)
|
||||
internal sealed class TangemPayOnboardingScreenState {
|
||||
abstract val onBack: () -> Unit
|
||||
|
||||
data class Loading(override val onBack: () -> Unit) : TangemPayOnboardingScreenState()
|
||||
data class Content(
|
||||
override val onBack: () -> Unit,
|
||||
val onTermsClick: () -> Unit,
|
||||
val buttonConfig: ButtonConfig,
|
||||
) : TangemPayOnboardingScreenState() {
|
||||
data class ButtonConfig(val isLoading: Boolean, val onClick: () -> Unit)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue