diff --git a/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenHub.kt b/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenHub.kt index 00728ab1e2..7cfd1ec542 100644 --- a/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenHub.kt +++ b/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenHub.kt @@ -20,7 +20,11 @@ import com.tangem.domain.common.form.* import com.tangem.domain.features.addCustomToken.* import com.tangem.domain.features.addCustomToken.CustomTokenFieldId.* import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenAction.* -import com.tangem.domain.redux.* +import com.tangem.domain.redux.BaseStoreHub +import com.tangem.domain.redux.DomainState +import com.tangem.domain.redux.ReStoreReducer +import com.tangem.domain.redux.domainStore +import com.tangem.domain.redux.extensions.dispatchOnMain import com.tangem.domain.redux.global.DomainGlobalAction import com.tangem.domain.redux.global.DomainGlobalState import com.tangem.network.api.tangemTech.CoinsResponse @@ -105,14 +109,14 @@ internal class AddCustomTokenHub : BaseStoreHub("AddCustomT null -> { // valid contract address ContractAddress.removeError() - changeBlockchainNetworkList() + reassembleBlockchainNetworkList() findTokenAndUpdateFields(contractAddress) } AddCustomTokenError.InvalidContractAddress -> { // invalid contract address ContractAddress.addError(error) updateTokenDetailFields(hubState.tokensAnyFieldsIsFilled()) - changeBlockchainNetworkList() + reassembleBlockchainNetworkList() checkAndUpdateAddButton() } AddCustomTokenError.FieldIsEmpty -> { @@ -120,7 +124,7 @@ internal class AddCustomTokenHub : BaseStoreHub("AddCustomT ContractAddress.removeError() clearTokenDetailsFields() updateTokenDetailFields(false) - changeBlockchainNetworkList() + reassembleBlockchainNetworkList() checkAndUpdateAddButton() } } @@ -129,21 +133,22 @@ internal class AddCustomTokenHub : BaseStoreHub("AddCustomT null -> { // valid contract address ContractAddress.removeError() - changeBlockchainNetworkList() + reassembleBlockchainNetworkList() findTokenAndUpdateFields(contractAddress) } else -> { ContractAddress.removeError() clearTokenDetailsFields() updateTokenDetailFields(false) - changeBlockchainNetworkList() + reassembleBlockchainNetworkList() checkAndUpdateAddButton() } } } + updateDerivationPath(Network.getFieldValue()) } - private suspend fun changeBlockchainNetworkList() { + private suspend fun reassembleBlockchainNetworkList() { val state = hubState val networkBlockchainList = Network.getField().itemList val card = requireNotNull(globalState.scanResponse?.card) @@ -159,13 +164,12 @@ internal class AddCustomTokenHub : BaseStoreHub("AddCustomT val listSameSize = networkBlockchainList.size == newNetworkBlockchainList.size val newListLessThanOld = networkBlockchainList.size > newNetworkBlockchainList.size if (listSameSize || newListLessThanOld) { -// check selected blockchain + // check selected blockchain val selectedBlockchain = Network.getFieldValue() val defaultSelection = Blockchain.Unknown if (!newNetworkBlockchainList.contains(selectedBlockchain) - && newNetworkBlockchainList.contains(defaultSelection) - ) { -// selectedBlockchain not present in the new list. Change selection to default + && newNetworkBlockchainList.contains(defaultSelection)) { + // selectedBlockchain not present in the new list. Change selection to default newNetworkField.data = Field.Data(defaultSelection, false) } } @@ -175,6 +179,31 @@ internal class AddCustomTokenHub : BaseStoreHub("AddCustomT dispatchOnMain(UpdateForm(hubState)) } + private suspend fun updateDerivationPath(blockchainNetwork: Blockchain) { + val state = hubState + val derivationIsSupportedByNetwork = blockchainNetwork.isEvm() || blockchainNetwork == Blockchain.Unknown + + if (DerivationPath.isFilled() && !derivationIsSupportedByNetwork) { + // reset to default + val derivationField = DerivationPath.getField() + derivationField.data = derivationField.data.copy( + value = Blockchain.Unknown, + isUserInput = false + ) + state.setField(derivationField) + dispatchOnMain(UpdateForm(hubState)) + } + + if (state.screenState.derivationPath.isEnabled != derivationIsSupportedByNetwork) { + val action = Screen.UpdateTokenFields(listOf( + DerivationPath to state.screenState.derivationPath.copy( + isEnabled = derivationIsSupportedByNetwork, + ), + )) + dispatchOnMain(action) + } + } + private suspend fun requestInfoAboutToken( contractAddress: String, ): List { @@ -382,6 +411,58 @@ internal class AddCustomTokenHub : BaseStoreHub("AddCustomT derivationStyle = hubState.cardDerivationStyle ) + private suspend fun fillTokenFields( + token: CoinsResponse.Coin, + coinNetwork: CoinsResponse.Coin.Network, + ) { + val blockchain = Blockchain.fromNetworkId(coinNetwork.networkId) ?: Blockchain.Unknown + Network.setFieldValue(Field.Data(blockchain, false)) + Name.setFieldValue(Field.Data(token.name, false)) + Symbol.setFieldValue(Field.Data(token.symbol, false)) + Decimals.setFieldValue(Field.Data(coinNetwork.decimalCount.toString(), false)) + dispatchOnMain(UpdateForm(hubState)) + } + + private suspend fun clearTokenDetailsFields() { + Name.setFieldValue(Field.Data("", false)) + Symbol.setFieldValue(Field.Data("", false)) + Decimals.setFieldValue(Field.Data("", false)) + dispatchOnMain(UpdateForm(hubState)) + } + + private suspend fun updateTokenDetailFields(isEnabled: Boolean = true) { + val state = hubState + val action = Screen.UpdateTokenFields(listOf( + Name to state.screenState.name.copy(isEnabled = isEnabled), + Symbol to state.screenState.symbol.copy(isEnabled = isEnabled), + Decimals to state.screenState.decimals.copy(isEnabled = isEnabled), + )) + dispatchOnMain(action) + } + + private suspend fun updateBlockchainNetworkField(isEnabled: Boolean) { + val action = Screen.UpdateTokenFields(listOf( + Name to hubState.screenState.name.copy(isEnabled = isEnabled), + )) + dispatchOnMain(action) + } + + private suspend fun updateAddButton(isEnabled: Boolean) { + dispatchOnMain(Screen.UpdateAddButton(ViewStates.AddButton(isEnabled))) + } + + private fun canHandleToken(blockchain: Blockchain): Boolean { + val card = globalState.scanResponse?.card ?: return false + return card.canHandleToken(blockchain) + } + + @Throws + private fun throwUnAppropriateInitialization(objName: String) { + throw AddCustomTokenException.UnAppropriateInitializationException( + "AddCustomTokenHub", "$objName must be not NULL" + ) + } + private suspend fun CustomTokenFieldId.addError(error: AddCustomTokenError) { dispatchOnMain(FieldError.Add(this, error)) } @@ -469,46 +550,6 @@ internal class AddCustomTokenHub : BaseStoreHub("AddCustomT return error } - private suspend fun fillTokenFields( - token: CoinsResponse.Coin, - coinNetwork: CoinsResponse.Coin.Network, - ) { - val blockchain = Blockchain.fromNetworkId(coinNetwork.networkId) ?: Blockchain.Unknown - Network.setFieldValue(Field.Data(blockchain, false)) - Name.setFieldValue(Field.Data(token.name, false)) - Symbol.setFieldValue(Field.Data(token.symbol, false)) - Decimals.setFieldValue(Field.Data(coinNetwork.decimalCount.toString(), false)) - dispatchOnMain(UpdateForm(hubState)) - } - - private suspend fun clearTokenDetailsFields() { - Name.setFieldValue(Field.Data("", false)) - Symbol.setFieldValue(Field.Data("", false)) - Decimals.setFieldValue(Field.Data("", false)) - dispatchOnMain(UpdateForm(hubState)) - } - - private suspend fun updateTokenDetailFields(isEnabled: Boolean = true) { - val state = hubState - val action = Screen.UpdateTokenFields(listOf( - Name to state.screenState.name.copy(isEnabled = isEnabled), - Symbol to state.screenState.symbol.copy(isEnabled = isEnabled), - Decimals to state.screenState.decimals.copy(isEnabled = isEnabled), - )) - dispatchOnMain(action) - } - - private suspend fun updateBlockchainNetworkField(isEnabled: Boolean) { - val action = Screen.UpdateTokenFields(listOf( - Name to hubState.screenState.name.copy(isEnabled = isEnabled), - )) - dispatchOnMain(action) - } - - private suspend fun updateAddButton(isEnabled: Boolean) { - dispatchOnMain(Screen.UpdateAddButton(ViewStates.AddButton(isEnabled))) - } - private suspend fun AddCustomTokenError.Warning.add() { dispatchOnMain(Warning.Add(setOf(this))) } @@ -520,18 +561,6 @@ internal class AddCustomTokenHub : BaseStoreHub("AddCustomT private suspend fun AddCustomTokenError.Warning.replaceBy(to: AddCustomTokenError.Warning) { dispatchOnMain(Warning.Replace(setOf(this), setOf(to))) } - - private fun canHandleToken(blockchain: Blockchain): Boolean { - val card = globalState.scanResponse?.card ?: return false - return card.canHandleToken(blockchain) - } - - @Throws - private fun throwUnAppropriateInitialization(objName: String) { - throw AddCustomTokenException.UnAppropriateInitializationException( - "AddCustomTokenHub", "$objName must be not NULL" - ) - } } private class AddCustomTokenReducer( @@ -671,6 +700,13 @@ private class AddCustomTokenReducer( newScreenState.copy(decimals = it.second) } } + DerivationPath -> { + if (state.screenState.derivationPath == it.second) { + newScreenState + } else { + newScreenState.copy(derivationPath = it.second) + } + } else -> newScreenState } } diff --git a/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt b/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt index 46b4541494..af7bed54ea 100644 --- a/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt +++ b/domain/src/main/java/com/tangem/domain/features/addCustomToken/redux/AddCustomTokenState.kt @@ -206,7 +206,7 @@ data class AddCustomTokenState( private fun getSupportedDerivations(card: Card): List { val evmBlockchains = Blockchain.values().filter { - card.isTestCard == it.isTestnet() && it.getChainId() != null + card.isTestCard == it.isTestnet() && it.isEvm() } return listOf(Blockchain.Unknown) + evmBlockchains } diff --git a/domain/src/main/java/com/tangem/domain/redux/ReStoreHub.kt b/domain/src/main/java/com/tangem/domain/redux/ReStoreHub.kt index 06775baafd..a869c18177 100644 --- a/domain/src/main/java/com/tangem/domain/redux/ReStoreHub.kt +++ b/domain/src/main/java/com/tangem/domain/redux/ReStoreHub.kt @@ -2,8 +2,6 @@ package com.tangem.domain.redux import android.webkit.ValueCallback import com.tangem.domain.common.FeatureCoroutineExceptionHandler -import com.tangem.domain.common.extensions.withIOContext -import com.tangem.domain.common.extensions.withMainContext import com.tangem.domain.redux.global.DomainGlobalState import kotlinx.coroutines.* import org.rekotlin.Action @@ -105,13 +103,4 @@ internal abstract class BaseStoreHub( protected abstract fun getHubState(storeState: DomainState): State protected abstract fun updateStoreState(storeState: DomainState, newHubState: State): DomainState - -} - -internal suspend inline fun ReStoreHub<*, *>.dispatchOnMain(vararg actions: Action) { - withMainContext { actions.forEach { domainStore.dispatch(it) } } -} - -internal suspend inline fun ReStoreHub<*, *>.dispatchOnIO(vararg actions: Action) { - withIOContext { actions.forEach { domainStore.dispatch(it) } } -} +} \ No newline at end of file diff --git a/domain/src/main/java/com/tangem/domain/redux/extensions/Dispatch.kt b/domain/src/main/java/com/tangem/domain/redux/extensions/Dispatch.kt new file mode 100644 index 0000000000..7bf82849e0 --- /dev/null +++ b/domain/src/main/java/com/tangem/domain/redux/extensions/Dispatch.kt @@ -0,0 +1,17 @@ +package com.tangem.domain.redux.extensions + +import com.tangem.domain.common.extensions.withIOContext +import com.tangem.domain.common.extensions.withMainContext +import com.tangem.domain.redux.domainStore +import org.rekotlin.Action + +/** +[REDACTED_AUTHOR] + */ +internal suspend inline fun dispatchOnMain(vararg actions: Action) { + withMainContext { actions.forEach { domainStore.dispatch(it) } } +} + +internal suspend inline fun dispatchOnIO(vararg actions: Action) { + withIOContext { actions.forEach { domainStore.dispatch(it) } } +} \ No newline at end of file