Updated on 2026-08-14

This commit is contained in:
Tangem 2025-02-27 17:02:13 +03:00
parent d8527a5f3f
commit 6d7ae39ba2
6 changed files with 108 additions and 31 deletions

View file

@ -81,6 +81,8 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
backups = model.backups,
)
val backButtonClickFlow = MutableSharedFlow<Unit>()
private val childStack: Value<ChildStack<OnboardingMultiWalletState.Step, ComposableContentComponent>> =
childStack(
key = "innerStack",
@ -96,8 +98,6 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
},
)
val backButtonClickFlow = MutableSharedFlow<Unit>()
override val innerNavigation: InnerNavigation = object : InnerNavigation {
override val state = innerNavigationStateFlow
@ -117,7 +117,7 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
source = bottomSheetNavigation,
serializer = null,
handleBackButton = false,
childFactory = { configuration, componentContext ->
childFactory = { _, componentContext ->
MultiWalletAccessCodeComponent(
context = childByContext(componentContext),
params = childParams,

View file

@ -0,0 +1,29 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.chooseoption.ui
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.onboarding.v2.impl.R
internal val CarouselItems = listOf(
CarouselItem(
title = resourceReference(R.string.onboarding_wallet_info_title_first),
subtitle = resourceReference(R.string.onboarding_wallet_info_subtitle_first),
),
CarouselItem(
title = resourceReference(R.string.onboarding_wallet_info_title_second),
subtitle = resourceReference(R.string.onboarding_wallet_info_subtitle_second),
),
CarouselItem(
title = resourceReference(R.string.onboarding_wallet_info_title_third),
subtitle = resourceReference(R.string.onboarding_wallet_info_subtitle_third),
),
CarouselItem(
title = resourceReference(R.string.onboarding_wallet_info_title_fourth),
subtitle = resourceReference(R.string.onboarding_wallet_info_subtitle_fourth),
),
)
internal data class CarouselItem(
val title: TextReference,
val subtitle: TextReference,
)

View file

@ -1,10 +1,15 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.chooseoption.ui
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
@ -12,6 +17,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.SecondaryButton
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
@ -30,30 +36,44 @@ fun Wallet1ChooseOption(
.navigationBarsPadding(),
verticalArrangement = Arrangement.Bottom,
) {
// val pagerState = rememberPagerState(pageCount = { 10 }) // TODO [REDACTED_TASK_KEY]
Column(
Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
.padding(start = 32.dp, end = 32.dp, bottom = 16.dp)
.weight(1f),
.weight(1f)
.padding(top = 32.dp, bottom = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = stringResourceSafe(R.string.onboarding_wallet_info_title_first),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
modifier = Modifier.padding(top = 16.dp),
)
val pagerState = rememberPagerState { CarouselItems.size }
Text(
text = stringResourceSafe(R.string.onboarding_wallet_info_subtitle_first),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.secondary,
textAlign = TextAlign.Center,
modifier = Modifier.padding(top = 12.dp),
HorizontalPager(pagerState) { selectedIndex ->
Column(
modifier = Modifier
.padding(start = 32.dp, end = 32.dp, bottom = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
val item = CarouselItems[selectedIndex]
Text(
text = item.title.resolveReference(),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
modifier = Modifier.padding(top = 16.dp),
)
Text(
text = item.subtitle.resolveReference(),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.secondary,
textAlign = TextAlign.Center,
modifier = Modifier.padding(top = 12.dp),
)
}
}
Dots(
modifier = Modifier.align(Alignment.CenterHorizontally),
count = CarouselItems.size,
selectedIndex = pagerState.currentPage,
)
}
@ -77,6 +97,28 @@ fun Wallet1ChooseOption(
}
}
@Composable
private fun Dots(count: Int, selectedIndex: Int, modifier: Modifier = Modifier) {
val generalColor = TangemTheme.colors.icon.informative
val selectedColor = TangemTheme.colors.icon.primary1
Row(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
repeat(count) { index ->
val color by animateColorAsState(if (index == selectedIndex) selectedColor else generalColor)
Canvas(Modifier.size(7.dp)) {
drawCircle(
color = color,
radius = size.width / 2f,
)
}
}
}
}
@Preview(showBackground = true)
@Composable
private fun Preview() {

View file

@ -8,6 +8,7 @@ import com.tangem.core.decompose.navigation.Router
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.wallets.usecase.GetCardImageUseCase
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.analytics.OnboardingEvent
@ -116,8 +117,13 @@ internal class OnboardingMultiWalletModel @Inject constructor(
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup &&
scanResponse.primaryCard == null -> OnboardingMultiWalletState.Step.ScanPrimary
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup ->
OnboardingMultiWalletState.Step.AddBackupDevice
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup -> {
if (scanResponse.productType == ProductType.Wallet) {
OnboardingMultiWalletState.Step.ChooseBackupOption
} else {
OnboardingMultiWalletState.Step.AddBackupDevice
}
}
card.wallets.isNotEmpty() && card.backupStatus?.isActive == true ->
OnboardingMultiWalletState.Step.Finalize
else ->

View file

@ -5,13 +5,13 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.onboarding.v2.impl.R
fun screenTitleByStep(step: OnboardingMultiWalletState.Step): TextReference = when (step) {
OnboardingMultiWalletState.Step.CreateWallet ->
resourceReference(R.string.onboarding_create_wallet_header)
OnboardingMultiWalletState.Step.SeedPhrase,
OnboardingMultiWalletState.Step.CreateWallet,
-> resourceReference(R.string.onboarding_create_wallet_header)
OnboardingMultiWalletState.Step.ScanPrimary,
OnboardingMultiWalletState.Step.AddBackupDevice,
->
resourceReference(R.string.onboarding_navbar_title_creating_backup)
OnboardingMultiWalletState.Step.Finalize ->
resourceReference(R.string.onboarding_button_finalize_backup)
else -> error("No title for the step")
-> resourceReference(R.string.onboarding_navbar_title_creating_backup)
OnboardingMultiWalletState.Step.ChooseBackupOption -> resourceReference(R.string.onboarding_getting_started)
OnboardingMultiWalletState.Step.Finalize -> resourceReference(R.string.onboarding_button_finalize_backup)
OnboardingMultiWalletState.Step.Done -> resourceReference(R.string.common_done)
}

View file

@ -51,13 +51,13 @@ internal fun OnboardingMultiWallet(
modifier = Modifier
.padding(horizontal = 34.dp)
.padding(top = 20.dp)
.weight(.4f)
.weight(.48f)
.fillMaxWidth(),
state = artworksState,
)
Box(
modifier = Modifier.weight(.44f),
modifier = Modifier.weight(.52f),
contentAlignment = Alignment.BottomStart,
) {
childContent(Modifier)