Updated on 2026-08-14

This commit is contained in:
Tangem 2023-04-10 14:55:39 +03:00
parent 1c0820be32
commit a6b259ac6c
9 changed files with 141 additions and 152 deletions

View file

@ -39,6 +39,7 @@ dependencies {
/** Other libraries */
implementation(deps.compose.shimmer)
implementation(deps.kotlin.immutable.collections)
implementation(deps.kotlin.serialization)
implementation(deps.timber)

View file

@ -5,8 +5,7 @@ package com.tangem.feature.onboarding.presentation.wallet2.model
*/
data class ButtonState(
val enabled: Boolean = true,
val isClickable: Boolean = true,
val showProgress: Boolean = false,
val onClick: () -> Unit = {},
) {
val isClickable: Boolean = !showProgress
}
val onClick: () -> Unit,
)

View file

@ -1,23 +1,8 @@
package com.tangem.feature.onboarding.presentation.wallet2.model
import android.content.Context
import androidx.annotation.StringRes
data class OnboardingDescription(
@StringRes val titleRes: Int? = null,
@StringRes val subTitleRes: Int? = null,
val title: String? = null,
val subTitle: String? = null,
) {
fun hasTitle(): Boolean = title != null || titleRes != null
fun hasSubTitle(): Boolean = subTitle != null || subTitleRes != null
fun getTitle(context: Context): String = context.get(titleRes, title)
fun getSubTitle(context: Context): String = context.get(subTitleRes, subTitle)
private fun Context.get(@StringRes resId: Int?, text: String?): String {
return resId?.let { this.getString(it) } ?: text ?: ""
}
}
@StringRes val titleRes: Int,
@StringRes val subTitleRes: Int,
)

View file

@ -1,6 +1,5 @@
package com.tangem.feature.onboarding.presentation.wallet2.model
import androidx.annotation.StringRes
import androidx.compose.ui.text.input.TextFieldValue
import com.tangem.feature.onboarding.domain.SeedPhraseError
@ -8,13 +7,13 @@ import com.tangem.feature.onboarding.domain.SeedPhraseError
[REDACTED_AUTHOR]
*/
data class OnboardingSeedPhraseState(
val step: OnboardingSeedPhraseStep = OnboardingSeedPhraseStep.Intro,
val introState: IntroState = IntroState(),
val aboutState: AboutState = AboutState(),
val yourSeedPhraseState: YourSeedPhraseState = YourSeedPhraseState(),
val checkSeedPhraseState: CheckSeedPhraseState = CheckSeedPhraseState(),
val importSeedPhraseState: ImportSeedPhraseState = ImportSeedPhraseState(),
val menuButtonChat: ButtonState = ButtonState(),
val step: OnboardingSeedPhraseStep,
val introState: IntroState,
val aboutState: AboutState,
val yourSeedPhraseState: YourSeedPhraseState,
val checkSeedPhraseState: CheckSeedPhraseState,
val importSeedPhraseState: ImportSeedPhraseState,
val menuButtonChat: ButtonState,
val isOnboardingFinished: Boolean = false,
)
@ -23,43 +22,42 @@ enum class OnboardingSeedPhraseStep {
}
data class IntroState(
val buttonCreateWallet: ButtonState = ButtonState(),
val buttonOtherOptions: ButtonState = ButtonState(),
val buttonCreateWallet: ButtonState,
val buttonOtherOptions: ButtonState,
)
data class AboutState(
val buttonReadMoreAboutSeedPhrase: ButtonState = ButtonState(),
val buttonGenerateSeedPhrase: ButtonState = ButtonState(),
val buttonImportSeedPhrase: ButtonState = ButtonState(),
val buttonReadMoreAboutSeedPhrase: ButtonState,
val buttonGenerateSeedPhrase: ButtonState,
val buttonImportSeedPhrase: ButtonState,
)
data class YourSeedPhraseState(
val mnemonicComponents: List<String> = listOf(),
val buttonContinue: ButtonState = ButtonState(),
val buttonContinue: ButtonState,
)
data class CheckSeedPhraseState(
val tvSecondPhrase: TextFieldState = TextFieldState(),
val tvSeventhPhrase: TextFieldState = TextFieldState(),
val tvEleventhPhrase: TextFieldState = TextFieldState(),
val buttonCreateWallet: ButtonState = ButtonState(),
val tvSecondPhrase: TextFieldState,
val tvSeventhPhrase: TextFieldState,
val tvEleventhPhrase: TextFieldState,
val buttonCreateWallet: ButtonState,
)
data class ImportSeedPhraseState(
val tvSeedPhrase: TextFieldState = TextFieldState(),
val tvSeedPhrase: TextFieldState,
val onSuggestedPhraseClick: (Int) -> Unit,
val buttonCreateWallet: ButtonState,
val invalidWords: Set<String> = emptySet(),
val suggestionsList: List<String> = emptyList(),
val error: SeedPhraseError? = null,
val onSuggestedPhraseClick: (Int) -> Unit = {},
val buttonCreateWallet: ButtonState = ButtonState(),
)
data class TextFieldState(
val onTextFieldValueChanged: (TextFieldValue) -> Unit,
val textFieldValue: TextFieldValue = TextFieldValue(),
val label: String? = null,
@StringRes val labelRes: Int? = null,
val isError: Boolean = false,
val isFocused: Boolean = false,
val onTextFieldValueChanged: (TextFieldValue) -> Unit = {},
val onFocusChanged: (Boolean) -> Unit = {},
)

View file

@ -6,45 +6,45 @@ import androidx.compose.ui.text.input.TextFieldValue
[REDACTED_AUTHOR]
*/
data class UiActions(
val introActions: IntroUiAction = IntroUiAction(),
val aboutActions: AboutUiAction = AboutUiAction(),
val yourSeedPhraseActions: YourSeedPhraseUiAction = YourSeedPhraseUiAction(),
val checkSeedPhraseActions: CheckSeedPhraseUiAction = CheckSeedPhraseUiAction(),
val importSeedPhraseActions: ImportSeedPhraseUiAction = ImportSeedPhraseUiAction(),
val menuChatClick: () -> Unit = {},
val introActions: IntroUiAction,
val aboutActions: AboutUiAction,
val yourSeedPhraseActions: YourSeedPhraseUiAction,
val checkSeedPhraseActions: CheckSeedPhraseUiAction,
val importSeedPhraseActions: ImportSeedPhraseUiAction,
val menuChatClick: () -> Unit,
)
data class IntroUiAction(
val buttonCreateWalletClick: () -> Unit = {},
val buttonOtherOptionsClick: () -> Unit = {},
val buttonCreateWalletClick: () -> Unit,
val buttonOtherOptionsClick: () -> Unit,
)
data class AboutUiAction(
val buttonReadMoreAboutSeedPhraseClick: () -> Unit = {},
val buttonGenerateSeedPhraseClick: () -> Unit = {},
val buttonImportSeedPhraseClick: () -> Unit = {},
val buttonReadMoreAboutSeedPhraseClick: () -> Unit,
val buttonGenerateSeedPhraseClick: () -> Unit,
val buttonImportSeedPhraseClick: () -> Unit,
)
data class YourSeedPhraseUiAction(
val buttonContinueClick: () -> Unit = {},
val buttonContinueClick: () -> Unit,
)
data class CheckSeedPhraseUiAction(
val secondTextFieldAction: TextFieldUiAction = TextFieldUiAction(),
val seventhTextFieldAction: TextFieldUiAction = TextFieldUiAction(),
val eleventhTextFieldAction: TextFieldUiAction = TextFieldUiAction(),
val buttonCreateWalletClick: () -> Unit = {},
val secondTextFieldAction: TextFieldUiAction,
val seventhTextFieldAction: TextFieldUiAction,
val eleventhTextFieldAction: TextFieldUiAction,
val buttonCreateWalletClick: () -> Unit,
)
data class ImportSeedPhraseUiAction(
val phraseTextFieldAction: TextFieldUiAction = TextFieldUiAction(),
val suggestedPhraseClick: (Int) -> Unit = {},
val buttonCreateWalletClick: () -> Unit = {},
val phraseTextFieldAction: TextFieldUiAction,
val suggestedPhraseClick: (Int) -> Unit,
val buttonCreateWalletClick: () -> Unit,
)
data class TextFieldUiAction(
val onFocusChanged: (Boolean) -> Unit = { },
val onTextFieldChanged: (TextFieldValue) -> Unit = { },
val onFocusChanged: (Boolean) -> Unit,
val onTextFieldChanged: (TextFieldValue) -> Unit,
)
enum class SeedPhraseField {

View file

@ -0,0 +1,80 @@
package com.tangem.feature.onboarding.presentation.wallet2.ui
import androidx.compose.ui.text.input.TextFieldValue
import com.tangem.feature.onboarding.presentation.wallet2.model.OnboardingSeedPhraseState
import com.tangem.feature.onboarding.presentation.wallet2.model.SeedPhraseField
/**
[REDACTED_AUTHOR]
*/
class CheckSeedPhraseStateBuilder {
fun updateTextField(
uiState: OnboardingSeedPhraseState,
field: SeedPhraseField,
textFieldValue: TextFieldValue,
): OnboardingSeedPhraseState = when (field) {
SeedPhraseField.Second -> uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
tvSecondPhrase = uiState.checkSeedPhraseState.tvSecondPhrase.copy(
textFieldValue = textFieldValue,
),
),
)
SeedPhraseField.Seventh -> uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
tvSeventhPhrase = uiState.checkSeedPhraseState.tvSeventhPhrase.copy(
textFieldValue = textFieldValue,
),
),
)
SeedPhraseField.Eleventh -> uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
tvEleventhPhrase = uiState.checkSeedPhraseState.tvEleventhPhrase.copy(
textFieldValue = textFieldValue,
),
),
)
}
fun updateTextFieldError(
uiState: OnboardingSeedPhraseState,
field: SeedPhraseField,
hasError: Boolean,
): OnboardingSeedPhraseState = when (field) {
SeedPhraseField.Second -> uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
tvSecondPhrase = uiState.checkSeedPhraseState.tvSecondPhrase.copy(
isError = hasError,
),
),
)
SeedPhraseField.Seventh -> uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
tvSeventhPhrase = uiState.checkSeedPhraseState.tvSeventhPhrase.copy(
isError = hasError,
),
),
)
SeedPhraseField.Eleventh -> uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
tvEleventhPhrase = uiState.checkSeedPhraseState.tvEleventhPhrase.copy(
isError = hasError,
),
),
)
}
fun updateCreateWalletButton(
uiState: OnboardingSeedPhraseState,
enabled: Boolean,
): OnboardingSeedPhraseState {
return uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
buttonCreateWallet = uiState.checkSeedPhraseState.buttonCreateWallet.copy(
enabled = enabled,
),
),
)
}
}

View file

@ -1,6 +1,5 @@
package com.tangem.feature.onboarding.presentation.wallet2.ui
import androidx.compose.ui.text.input.TextFieldValue
import com.tangem.feature.onboarding.presentation.wallet2.model.AboutState
import com.tangem.feature.onboarding.presentation.wallet2.model.ButtonState
import com.tangem.feature.onboarding.presentation.wallet2.model.CheckSeedPhraseState
@ -8,7 +7,6 @@ import com.tangem.feature.onboarding.presentation.wallet2.model.ImportSeedPhrase
import com.tangem.feature.onboarding.presentation.wallet2.model.IntroState
import com.tangem.feature.onboarding.presentation.wallet2.model.OnboardingSeedPhraseState
import com.tangem.feature.onboarding.presentation.wallet2.model.OnboardingSeedPhraseStep
import com.tangem.feature.onboarding.presentation.wallet2.model.SeedPhraseField
import com.tangem.feature.onboarding.presentation.wallet2.model.TextFieldState
import com.tangem.feature.onboarding.presentation.wallet2.model.UiActions
import com.tangem.feature.onboarding.presentation.wallet2.model.YourSeedPhraseState
@ -136,76 +134,4 @@ class StateBuilder(
mnemonicComponents = phraseList,
),
)
}
class CheckSeedPhraseStateBuilder {
fun updateTextField(
uiState: OnboardingSeedPhraseState,
field: SeedPhraseField,
textFieldValue: TextFieldValue,
): OnboardingSeedPhraseState = when (field) {
SeedPhraseField.Second -> uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
tvSecondPhrase = uiState.checkSeedPhraseState.tvSecondPhrase.copy(
textFieldValue = textFieldValue,
),
),
)
SeedPhraseField.Seventh -> uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
tvSeventhPhrase = uiState.checkSeedPhraseState.tvSeventhPhrase.copy(
textFieldValue = textFieldValue,
),
),
)
SeedPhraseField.Eleventh -> uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
tvEleventhPhrase = uiState.checkSeedPhraseState.tvEleventhPhrase.copy(
textFieldValue = textFieldValue,
),
),
)
}
fun updateTextFieldError(
uiState: OnboardingSeedPhraseState,
field: SeedPhraseField,
hasError: Boolean,
): OnboardingSeedPhraseState = when (field) {
SeedPhraseField.Second -> uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
tvSecondPhrase = uiState.checkSeedPhraseState.tvSecondPhrase.copy(
isError = hasError,
),
),
)
SeedPhraseField.Seventh -> uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
tvSeventhPhrase = uiState.checkSeedPhraseState.tvSeventhPhrase.copy(
isError = hasError,
),
),
)
SeedPhraseField.Eleventh -> uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
tvEleventhPhrase = uiState.checkSeedPhraseState.tvEleventhPhrase.copy(
isError = hasError,
),
),
)
}
fun updateCreateWalletButton(
uiState: OnboardingSeedPhraseState,
enabled: Boolean,
): OnboardingSeedPhraseState {
return uiState.copy(
checkSeedPhraseState = uiState.checkSeedPhraseState.copy(
buttonCreateWallet = uiState.checkSeedPhraseState.buttonCreateWallet.copy(
enabled = enabled,
),
),
)
}
}

View file

@ -3,7 +3,6 @@ package com.tangem.feature.onboarding.presentation.wallet2.ui.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -18,9 +17,10 @@ fun OnboardingActionBlock(
firstActionContent: @Composable (() -> Unit)? = null,
secondActionContent: @Composable (() -> Unit)? = null,
) {
if (firstActionContent == null && secondActionContent == null) return
Box(
modifier = Modifier
.wrapContentSize()
.padding(
top = TangemTheme.dimens.size8,
bottom = TangemTheme.dimens.size32,

View file

@ -7,11 +7,13 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import com.tangem.core.ui.components.SpacerH12
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.onboarding.presentation.wallet2.model.OnboardingDescription
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
/**
* UI component witch provides single and carousel description for the onboarding process
@ -19,7 +21,7 @@ import com.tangem.feature.onboarding.presentation.wallet2.model.OnboardingDescri
@Composable
fun OnboardingDescriptionBlock(
modifier: Modifier = Modifier,
descriptionsList: List<OnboardingDescription> = emptyList(),
descriptionsList: ImmutableList<OnboardingDescription> = persistentListOf(),
) {
if (descriptionsList.isEmpty()) return
@ -29,7 +31,7 @@ fun OnboardingDescriptionBlock(
.padding(horizontal = TangemTheme.dimens.size24),
) {
if (descriptionsList.size == 1) {
SingleDescription(descriptionsList[0])
Description(descriptionsList[0])
} else {
CarouselDescription(descriptionsList)
}
@ -37,18 +39,16 @@ fun OnboardingDescriptionBlock(
}
@Composable
private fun SingleDescription(description: OnboardingDescription) {
private fun Description(description: OnboardingDescription) {
Column {
if (description.hasTitle()) {
DescriptionTitleText(text = description.getTitle(LocalContext.current))
SpacerH12()
}
DescriptionSubTitleText(text = description.getSubTitle(LocalContext.current))
DescriptionTitleText(text = stringResource(id = description.titleRes))
SpacerH12()
DescriptionSubTitleText(text = stringResource(id = description.subTitleRes))
}
}
@Composable
private fun CarouselDescription(descriptionsList: List<OnboardingDescription>) {
private fun CarouselDescription(descriptionsList: ImmutableList<OnboardingDescription>) {
//TODO: implement
}