diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MnemonicRepository.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MnemonicRepository.kt index 6b6ae2b138..63f732c4de 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MnemonicRepository.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MnemonicRepository.kt @@ -9,7 +9,7 @@ import com.tangem.sdk.extensions.getWordlist import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject -class MnemonicRepository @Inject constructor( +internal class MnemonicRepository @Inject constructor( @ApplicationContext private val context: Context, ) { private val wordlist = Wordlist.getWordlist(context) diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt index cf3cf6d141..93bc3e193c 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt @@ -50,8 +50,8 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( private val params = paramsContainer.require() private val multiWalletState get() = params.multiWalletState - private val state = MutableStateFlow(SeedPhraseState()) - private val _uiState = MutableStateFlow(getStartState()) + private val state = MutableStateFlow(getInitialSeedPhraseState()) + private val _uiState = MutableStateFlow(getInitialUIState()) private val generateSeedPhraseUiStateBuilder = GenerateSeedPhraseUiStateBuilder( updateUiState = { block -> updateUiStateSpecific(block) }, @@ -60,7 +60,9 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( // ============================================= // | DON'T FIXME !!! MODIFY WITH CAUTION !!! | // ============================================= - changeWords24Option = { state.update { it.copy(words24Option = it.words24Option) } }, + changeGeneratedWordsType = { newType -> + state.update { st -> st.copy(generatedWordsType = newType) } + }, // ============================================= ) @@ -75,10 +77,9 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( // ============================================= importWallet = importWallet@{ importWallet( - mnemonic = if (state.value.words24Option) { - state.value.generatedWords24 ?: return@importWallet - } else { - state.value.generatedWords12 ?: return@importWallet + mnemonic = when (state.value.generatedWordsType) { + GeneratedWordsType.Words12 -> state.value.generatedWords12 ?: return@importWallet + GeneratedWordsType.Words24 -> state.value.generatedWords24 ?: return@importWallet }, passphrase = null, generatedSeedPhrase = true, @@ -91,6 +92,7 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( modelScope = modelScope, mnemonicRepository = mnemonicRepository, updateUiState = { block -> updateUiStateSpecific(block) }, + readyToImport = { ready -> state.update { it.copy(readyToImport = ready) } }, importWallet = { mnemonic, passphrase -> importWallet( mnemonic = mnemonic, @@ -112,8 +114,8 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( is MultiWalletSeedPhraseUM.Import, is MultiWalletSeedPhraseUM.GenerateSeedPhrase, -> { - _uiState.value = getStartState() - state.value = SeedPhraseState() + _uiState.value = getInitialUIState() + state.value = getInitialSeedPhraseState() } is MultiWalletSeedPhraseUM.GeneratedWordsCheck -> { openGeneratedSeedPhrase() @@ -121,7 +123,16 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( } } - private fun getStartState(): MultiWalletSeedPhraseUM { + private fun getInitialSeedPhraseState(): SeedPhraseState { + return SeedPhraseState( + generatedWords12 = null, + generatedWords24 = null, + generatedWordsType = GeneratedWordsType.Words12, + readyToImport = false, + ) + } + + private fun getInitialUIState(): MultiWalletSeedPhraseUM { return MultiWalletSeedPhraseUM.Start( onImportSeedPhraseClicked = { openImportSeedPhrase() @@ -143,6 +154,7 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( _uiState.value = generateSeedPhraseUiStateBuilder.getState( generatedWords12 = words12, generatedWords24 = words24, + option = state.value.generatedWordsType, ) } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/SeedPhraseState.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/SeedPhraseState.kt index 796cd1599a..94750fc959 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/SeedPhraseState.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/SeedPhraseState.kt @@ -2,9 +2,14 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.mode import com.tangem.crypto.bip39.Mnemonic -data class SeedPhraseState( - val generatedWords12: Mnemonic? = null, - val generatedWords24: Mnemonic? = null, - val words24Option: Boolean = false, - val readyToImport: Boolean = false, -) \ No newline at end of file +internal data class SeedPhraseState( + val generatedWords12: Mnemonic?, + val generatedWords24: Mnemonic?, + val generatedWordsType: GeneratedWordsType, + val readyToImport: Boolean, +) + +internal enum class GeneratedWordsType(val length: Int) { + Words12(12), + Words24(24), +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/GenerateSeedPhraseUiStateBuilder.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/GenerateSeedPhraseUiStateBuilder.kt index cda23ca2df..e7c4efd3b2 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/GenerateSeedPhraseUiStateBuilder.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/GenerateSeedPhraseUiStateBuilder.kt @@ -1,19 +1,24 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.builder import com.tangem.crypto.bip39.Mnemonic +import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.GeneratedWordsType import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui.state.MultiWalletSeedPhraseUM import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList internal class GenerateSeedPhraseUiStateBuilder( - private val changeWords24Option: (Boolean) -> Unit, + private val changeGeneratedWordsType: (GeneratedWordsType) -> Unit, private val updateUiState: ( (MultiWalletSeedPhraseUM.GenerateSeedPhrase) -> MultiWalletSeedPhraseUM.GenerateSeedPhrase, ) -> Unit, private val onContinue: () -> Unit, ) { - fun getState(generatedWords12: Mnemonic, generatedWords24: Mnemonic): MultiWalletSeedPhraseUM.GenerateSeedPhrase { + fun getState( + generatedWords12: Mnemonic, + generatedWords24: Mnemonic, + option: GeneratedWordsType, + ): MultiWalletSeedPhraseUM.GenerateSeedPhrase { val words12 = generatedWords12.mnemonicComponents.mapIndexed { index, s -> MultiWalletSeedPhraseUM.GenerateSeedPhrase.MnemonicGridItem(index + 1, s) }.toImmutableList() @@ -22,26 +27,35 @@ internal class GenerateSeedPhraseUiStateBuilder( }.toImmutableList() return MultiWalletSeedPhraseUM.GenerateSeedPhrase( - words24OptionSelected = false, - words = words12, - onWords24OptionSwitch = { switchType(words12, words24) }, + option = option, + words = when (option) { + GeneratedWordsType.Words12 -> words12 + GeneratedWordsType.Words24 -> words24 + }, + onOptionChange = { + switchType( + newType = it, + generatedWords12 = words12, + generatedWords24 = words24, + ) + }, onContinueClick = onContinue, ) } private fun switchType( + newType: GeneratedWordsType, generatedWords12: ImmutableList, generatedWords24: ImmutableList, ) { updateUiState { uiSt -> - changeWords24Option(uiSt.words24OptionSelected.not()) + changeGeneratedWordsType(newType) uiSt.copy( - words24OptionSelected = uiSt.words24OptionSelected.not(), - words = if (uiSt.words24OptionSelected) { - generatedWords12 - } else { - generatedWords24 + option = newType, + words = when (newType) { + GeneratedWordsType.Words12 -> generatedWords12 + GeneratedWordsType.Words24 -> generatedWords24 }, ) } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/ImportSeedPhraseUiStateBuilder.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/ImportSeedPhraseUiStateBuilder.kt index bc73e0a862..fc500a55f4 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/ImportSeedPhraseUiStateBuilder.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/ImportSeedPhraseUiStateBuilder.kt @@ -20,6 +20,7 @@ import kotlinx.coroutines.launch internal class ImportSeedPhraseUiStateBuilder( private val modelScope: CoroutineScope, private val mnemonicRepository: MnemonicRepository, + private val readyToImport: (Boolean) -> Unit, private val updateUiState: ((MultiWalletSeedPhraseUM.Import) -> MultiWalletSeedPhraseUM.Import) -> Unit, private val importWallet: (mnemonic: Mnemonic, passphrase: String?) -> Unit, ) { @@ -100,6 +101,8 @@ internal class ImportSeedPhraseUiStateBuilder( } private fun interceptWords(wordsField: TextFieldValue) { + readyToImport(false) + updateUiState { it.copy( createWalletEnabled = false, @@ -133,7 +136,9 @@ internal class ImportSeedPhraseUiStateBuilder( createWalletEnabled = true, ) } + readyToImport(true) } catch (ex: TangemSdkError.MnemonicException) { + readyToImport(false) val error = ex.mnemonicResult if (error is MnemonicErrorResult.InvalidChecksum) { updateUiState { diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/SeedPhraseCheckUiStateBuilder.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/SeedPhraseCheckUiStateBuilder.kt index 6f7dd45195..8d55524540 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/SeedPhraseCheckUiStateBuilder.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/builder/SeedPhraseCheckUiStateBuilder.kt @@ -1,6 +1,7 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.builder import androidx.compose.ui.text.input.TextFieldValue +import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.GeneratedWordsType import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.SeedPhraseState import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui.state.MultiWalletSeedPhraseUM import kotlinx.collections.immutable.toImmutableList @@ -93,10 +94,9 @@ internal class SeedPhraseCheckUiStateBuilder( currentState.generatedWords12 ?: return false currentState.generatedWords24 ?: return false - val wordList = if (currentState.words24Option) { - currentState.generatedWords24 - } else { - currentState.generatedWords12 + val wordList = when (currentState.generatedWordsType) { + GeneratedWordsType.Words12 -> currentState.generatedWords12 + GeneratedWordsType.Words24 -> currentState.generatedWords24 }.mnemonicComponents return wordList[shownIndex - 1] == word diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/ui/MultiWalletSeedPhraseWords.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/ui/MultiWalletSeedPhraseWords.kt index 1c9b8abf0f..f5ac73fd97 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/ui/MultiWalletSeedPhraseWords.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/ui/MultiWalletSeedPhraseWords.kt @@ -19,6 +19,7 @@ import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.features.onboarding.v2.impl.R +import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.GeneratedWordsType import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui.state.MultiWalletSeedPhraseUM import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui.state.MultiWalletSeedPhraseUM.GenerateSeedPhrase.MnemonicGridItem import kotlinx.collections.immutable.ImmutableList @@ -67,19 +68,24 @@ internal fun MultiWalletSeedPhraseWords( private fun SegmentSeedBlock(state: MultiWalletSeedPhraseUM.GenerateSeedPhrase, modifier: Modifier = Modifier) { SegmentedButtons( modifier = modifier.padding(horizontal = TangemTheme.dimens.spacing76), - config = persistentListOf(0, 1), - initialSelectedItem = if (state.words24OptionSelected.not()) 0 else 1, + config = persistentListOf(GeneratedWordsType.Words12, GeneratedWordsType.Words24), + initialSelectedItem = state.option, onClick = { - if (state.words24OptionSelected && it == 0 || state.words24OptionSelected.not() && it == 1) { - state.onWords24OptionSwitch() + when { + state.option == GeneratedWordsType.Words12 && it == GeneratedWordsType.Words24 -> { + state.onOptionChange(it) + } + state.option == GeneratedWordsType.Words24 && it == GeneratedWordsType.Words12 -> { + state.onOptionChange(it) + } } }, ) { Text( text = pluralStringResourceSafe( id = R.plurals.onboarding_seed_generate_words_count, - count = if (it == 0) 12 else 24, - if (it == 0) 12 else 24, + count = state.option.length, + state.option.length, ), modifier = Modifier .padding(vertical = TangemTheme.dimens.spacing10) @@ -110,8 +116,8 @@ private fun TitleBlock(state: MultiWalletSeedPhraseUM.GenerateSeedPhrase, modifi Text( text = pluralStringResourceSafe( id = R.plurals.onboarding_seed_generate_message_words_count, - count = if (state.words24OptionSelected.not()) 12 else 24, - if (state.words24OptionSelected.not()) 12 else 24, + count = state.option.length, + state.option.length, ), style = TangemTheme.typography.body1, color = TangemTheme.colors.text.secondary, diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/ui/state/MultiWalletSeedPhraseUM.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/ui/state/MultiWalletSeedPhraseUM.kt index f13a24e712..f6dd64808c 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/ui/state/MultiWalletSeedPhraseUM.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/ui/state/MultiWalletSeedPhraseUM.kt @@ -4,6 +4,7 @@ import androidx.compose.runtime.Immutable import androidx.compose.ui.text.input.TextFieldValue import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig import com.tangem.core.ui.extensions.TextReference +import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.GeneratedWordsType import com.tangem.features.onboarding.v2.multiwallet.impl.common.ui.OnboardingDialogUM import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -20,9 +21,9 @@ internal sealed class MultiWalletSeedPhraseUM( ) : MultiWalletSeedPhraseUM(order = 0) data class GenerateSeedPhrase( - val words24OptionSelected: Boolean = false, + val option: GeneratedWordsType = GeneratedWordsType.Words12, val words: ImmutableList = persistentListOf(), - val onWords24OptionSwitch: () -> Unit = {}, + val onOptionChange: (GeneratedWordsType) -> Unit = {}, val onContinueClick: () -> Unit = {}, ) : MultiWalletSeedPhraseUM(order = 1) { data class MnemonicGridItem(