Updated on 2026-08-14
This commit is contained in:
parent
59b4045b71
commit
7cf2836cfc
3 changed files with 73 additions and 150 deletions
|
|
@ -26,7 +26,7 @@ class StringIsNotEmptyValidator : CustomTokenValidator<String>() {
|
|||
|
||||
class TokenContractAddressValidator : CustomTokenValidator<String>() {
|
||||
override fun validate(data: String?): AddCustomTokenError? {
|
||||
if (data == null || data.isEmpty()) return AddCustomTokenError.FieldIsEmpty
|
||||
if (data == null || data.isEmpty()) return null
|
||||
|
||||
return if (EthereumAddressService().validate(data)) {
|
||||
null
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ package com.tangem.domain.features.addCustomToken.redux
|
|||
|
||||
import android.webkit.ValueCallback
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.DerivationStyle
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.DomainDialog
|
||||
import com.tangem.domain.DomainException
|
||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.domain.common.form.*
|
||||
|
|
@ -39,17 +41,6 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
return storeState.copy(addCustomTokensState = newHubState)
|
||||
}
|
||||
|
||||
private val contractAddressValidator: TokenContractAddressValidator
|
||||
get() = hubState.getValidator(ContractAddress)
|
||||
private val nameValidator: TokenNameValidator
|
||||
get() = hubState.getValidator(Name)
|
||||
private val symbolValidator: TokenSymbolValidator
|
||||
get() = hubState.getValidator(Symbol)
|
||||
private val decimalsValidator: TokenDecimalsValidator
|
||||
get() = hubState.getValidator(Decimals)
|
||||
val networkValidator: TokenNetworkValidator
|
||||
get() = hubState.getValidator(Network)
|
||||
|
||||
override suspend fun handleAction(
|
||||
action: Action,
|
||||
storeState: DomainState,
|
||||
|
|
@ -61,70 +52,76 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
is Init.SetAddedCurrencies -> {}
|
||||
is Init.SetOnAddTokenCallback -> {}
|
||||
is OnCreate -> {
|
||||
// hubState.addedCurrencies.guard {
|
||||
// return throwUnAppropriateInitialization("addedTokens")
|
||||
// }
|
||||
hubState.addedCurrencies.guard {
|
||||
return throwUnAppropriateInitialization("addedTokens")
|
||||
}
|
||||
}
|
||||
is OnDestroy -> hubScope.cancel()
|
||||
is OnTokenContractAddressChanged -> {
|
||||
val address = action.contractAddress.value
|
||||
when (val error = ContractAddress.validate(address)) {
|
||||
null -> {
|
||||
ContractAddress.removeError()
|
||||
dispatchOnMain(unlockTokenFieldsAction())
|
||||
}
|
||||
AddCustomTokenError.FieldIsEmpty -> {
|
||||
ContractAddress.removeError()
|
||||
dispatchOnMain(lockTokenFieldsAction())
|
||||
return
|
||||
}
|
||||
AddCustomTokenError.InvalidContractAddress -> {
|
||||
ContractAddress.addError(error)
|
||||
dispatchOnMain(unlockTokenFieldsAction())
|
||||
return
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
dispatchOnMain(
|
||||
Screen.UpdateAddButton(
|
||||
ViewStates.AddButton(!hubState.allFieldsIsEmpty())
|
||||
)
|
||||
)
|
||||
val contractAddress = action.contractAddress.value
|
||||
val validator: TokenContractAddressValidator = hubState.getValidator(ContractAddress)
|
||||
val error = validator.validate(contractAddress)
|
||||
addOrRemoveError(ContractAddress, error)
|
||||
|
||||
if (error != null || contractAddress.isEmpty()) {
|
||||
dispatchOnMain(unlockTokenFields())
|
||||
return
|
||||
}
|
||||
if (!action.contractAddress.isUserInput) return
|
||||
|
||||
manageTokenChanges(requestInfoAboutContractAddress(address))
|
||||
manageTokenChanges(requestInfoAboutContractAddress(contractAddress))
|
||||
}
|
||||
is OnTokenNetworkChanged -> {
|
||||
if (!action.blockchainNetwork.isUserInput) return
|
||||
|
||||
val contractAddress = ContractAddress.getFieldValue<String>()
|
||||
val error = ContractAddress.validate(contractAddress)
|
||||
if (error == null) {
|
||||
manageTokenChanges(requestInfoAboutContractAddress(contractAddress))
|
||||
} else {
|
||||
|
||||
}
|
||||
val contractAddress = hubState.getField<TokenField>(ContractAddress).data.value
|
||||
manageTokenChanges(requestInfoAboutContractAddress(contractAddress))
|
||||
}
|
||||
is OnTokenNameChanged -> {
|
||||
Name.addOrRemoveError(Name.validate(action.tokenName.value))
|
||||
val validator: TokenNameValidator = hubState.getValidator(Name)
|
||||
addOrRemoveError(Name, validator.validate(action.tokenName.value))
|
||||
}
|
||||
is OnTokenSymbolChanged -> {
|
||||
Symbol.addOrRemoveError(Symbol.validate(action.tokenSymbol.value))
|
||||
val validator: TokenSymbolValidator = hubState.getValidator(Symbol)
|
||||
addOrRemoveError(Symbol, validator.validate(action.tokenSymbol.value))
|
||||
}
|
||||
is OnTokenDecimalsChanged -> {
|
||||
Decimals.addOrRemoveError(Decimals.validate(action.tokenDecimals.value))
|
||||
val validator: TokenDecimalsValidator = hubState.getValidator(Decimals)
|
||||
addOrRemoveError(Decimals, validator.validate(action.tokenDecimals.value))
|
||||
}
|
||||
// is OnTokenDerivationPathChanged -> {
|
||||
// val validator: TokenDerivationPathValidator = getValidator(DerivationPath, hubState)
|
||||
// addOrRemoveError(DerivationPath, validator.validate(action.value.value))
|
||||
// }
|
||||
is ClearTokenFields -> {
|
||||
Name.setFieldValue(Field.Data("", false))
|
||||
Symbol.setFieldValue(Field.Data("", false))
|
||||
Decimals.setFieldValue(Field.Data("", false))
|
||||
val nameField = hubState.getField<TokenField>(Name)
|
||||
val symbolField = hubState.getField<TokenField>(Symbol)
|
||||
val decimalsField = hubState.getField<TokenField>(Decimals)
|
||||
|
||||
nameField.data = Field.Data("", false)
|
||||
symbolField.data = Field.Data("", false)
|
||||
decimalsField.data = Field.Data("", false)
|
||||
|
||||
dispatchOnMain(UpdateForm(hubState))
|
||||
}
|
||||
is FillTokenFields -> {
|
||||
val networkField = hubState.getField<TokenBlockchainField>(Network)
|
||||
val nameField = hubState.getField<TokenField>(Name)
|
||||
val symbolField = hubState.getField<TokenField>(Symbol)
|
||||
val decimalsField = hubState.getField<TokenField>(Decimals)
|
||||
|
||||
val token = action.token
|
||||
val contract = action.contract
|
||||
val blockchain = Blockchain.fromNetworkId(contract.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(contract.decimalCount.toString(), false))
|
||||
networkField.data = Field.Data(blockchain, false)
|
||||
nameField.data = Field.Data(token.name, false)
|
||||
symbolField.data = Field.Data(token.symbol, false)
|
||||
decimalsField.data = Field.Data(contract.decimalCount.toString(), false)
|
||||
|
||||
dispatchOnMain(UpdateForm(hubState))
|
||||
}
|
||||
|
|
@ -132,7 +129,7 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
// if (hubState.allFieldsIsEmpty()) {
|
||||
dispatchOnMain(
|
||||
DomainGlobalAction.ShowDialog(DomainDialog.DialogError(
|
||||
AddCustomTokenError.InvalidDerivationPath
|
||||
AddCustomTokenError.FieldIsEmpty
|
||||
)))
|
||||
return
|
||||
// }
|
||||
|
|
@ -188,7 +185,7 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
toAddWarnings.add(AddCustomTokenWarning.PotentialScamToken)
|
||||
toRemoveWarnings.add(AddCustomTokenWarning.TokenAlreadyAdded)
|
||||
dispatchOnMain(ClearTokenFields)
|
||||
dispatchOnMain(unlockTokenFieldsAction())
|
||||
dispatchOnMain(unlockTokenFields())
|
||||
}
|
||||
else -> {
|
||||
val token = foundTokens[0]
|
||||
|
|
@ -207,7 +204,7 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
toRemoveWarnings.add(AddCustomTokenWarning.PotentialScamToken)
|
||||
|
||||
dispatchOnMain(Screen.UpdateAddButton(ViewStates.AddButton(false)))
|
||||
dispatchOnMain(lockTokenFieldsAction())
|
||||
dispatchOnMain(lockTokenFields())
|
||||
} else {
|
||||
toRemoveWarnings.add(AddCustomTokenWarning.TokenAlreadyAdded)
|
||||
dispatchOnMain(Screen.UpdateAddButton(ViewStates.AddButton(true)))
|
||||
|
|
@ -217,11 +214,11 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
if (tokenContract.active && isStandardDerivation) {
|
||||
toRemoveWarnings.add(AddCustomTokenWarning.PotentialScamToken)
|
||||
dispatchOnMain(FillTokenFields(token, contract))
|
||||
dispatchOnMain(lockTokenFieldsAction())
|
||||
dispatchOnMain(lockTokenFields())
|
||||
} else {
|
||||
toAddWarnings.add(AddCustomTokenWarning.PotentialScamToken)
|
||||
dispatchOnMain(ClearTokenFields)
|
||||
dispatchOnMain(unlockTokenFieldsAction())
|
||||
dispatchOnMain(unlockTokenFields())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -239,7 +236,7 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
hubScope.launch {
|
||||
// find how to connect to the upper coroutineContext and dispatch through them
|
||||
dispatchOnMain(FillTokenFields(token, selectedContract))
|
||||
dispatchOnMain(lockTokenFieldsAction())
|
||||
dispatchOnMain(lockTokenFields())
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
@ -259,69 +256,15 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
contract: Coins.CheckAddressResponse.Token.Contract
|
||||
): Boolean = false
|
||||
|
||||
private suspend fun CustomTokenFieldId.addError(error: AddCustomTokenError) {
|
||||
dispatchOnMain(FieldError.Add(this, error))
|
||||
}
|
||||
|
||||
private suspend fun CustomTokenFieldId.removeError() {
|
||||
dispatchOnMain(FieldError.Remove(this))
|
||||
}
|
||||
|
||||
private suspend fun CustomTokenFieldId.addOrRemoveError(error: AddCustomTokenError?) {
|
||||
when (error) {
|
||||
null -> removeError()
|
||||
else -> addError(error)
|
||||
private suspend fun addOrRemoveError(id: CustomTokenFieldId, error: AddCustomTokenError?) {
|
||||
if (error == null) {
|
||||
dispatchOnMain(FieldError.Remove(id))
|
||||
} else {
|
||||
dispatchOnMain(FieldError.Add(id, error))
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <reified T> CustomTokenFieldId.getField(): T {
|
||||
val state = hubState
|
||||
val value = when (this) {
|
||||
ContractAddress -> state.getField<TokenField>(this)
|
||||
Network -> state.getField<TokenBlockchainField>(this)
|
||||
Name -> state.getField<TokenField>(this)
|
||||
Symbol -> state.getField<TokenField>(this)
|
||||
Decimals -> state.getField<TokenField>(this)
|
||||
DerivationPath -> state.getField<TokenDerivationPathField>(this)
|
||||
}
|
||||
return value as T
|
||||
}
|
||||
|
||||
private inline fun <reified T> CustomTokenFieldId.getFieldValue(): T {
|
||||
val value = when (this) {
|
||||
ContractAddress -> getField<TokenField>().data.value
|
||||
Network -> getField<TokenBlockchainField>().data.value
|
||||
Name -> getField<TokenField>().data.value
|
||||
Symbol -> getField<TokenField>().data.value
|
||||
Decimals -> getField<TokenField>().data.value
|
||||
DerivationPath -> getField<TokenDerivationPathField>().data.value
|
||||
}
|
||||
return value as T
|
||||
}
|
||||
|
||||
private fun CustomTokenFieldId.setFieldValue(fieldData: Field.Data<*>) {
|
||||
when (this) {
|
||||
ContractAddress -> getField<TokenField>().data = fieldData as Field.Data<String>
|
||||
Network -> getField<TokenBlockchainField>().data = fieldData as Field.Data<Blockchain>
|
||||
Name -> getField<TokenField>().data = fieldData as Field.Data<String>
|
||||
Symbol -> getField<TokenField>().data = fieldData as Field.Data<String>
|
||||
Decimals -> getField<TokenField>().data = fieldData as Field.Data<String>
|
||||
DerivationPath -> getField<TokenDerivationPathField>().data = fieldData as Field.Data<Blockchain>
|
||||
}
|
||||
}
|
||||
|
||||
private fun CustomTokenFieldId.validate(value: Any): AddCustomTokenError? {
|
||||
return when (this) {
|
||||
ContractAddress -> contractAddressValidator.validate(value as String)
|
||||
Network -> networkValidator.validate(value as Blockchain)
|
||||
Name -> nameValidator.validate(value as String)
|
||||
Symbol -> symbolValidator.validate(value as String)
|
||||
Decimals -> decimalsValidator.validate(value as String)
|
||||
DerivationPath -> networkValidator.validate(value as Blockchain)
|
||||
}
|
||||
}
|
||||
|
||||
private fun lockTokenFieldsAction(): Action {
|
||||
private fun lockTokenFields(): Action {
|
||||
val state = hubState
|
||||
return Screen.UpdateTokenFields(listOf(
|
||||
Network to state.screenState.network.copy(isEnabled = false),
|
||||
|
|
@ -331,7 +274,7 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
))
|
||||
}
|
||||
|
||||
private fun unlockTokenFieldsAction(): Action {
|
||||
private fun unlockTokenFields(): Action {
|
||||
val state = hubState
|
||||
return Screen.UpdateTokenFields(listOf(
|
||||
Network to state.screenState.network.copy(isEnabled = true),
|
||||
|
|
@ -341,19 +284,6 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
))
|
||||
}
|
||||
|
||||
private suspend fun toggleAddButtonAction(enable: Boolean) = when (enable) {
|
||||
true -> unlockAddButtonAction()
|
||||
else -> lockAddButtonAction()
|
||||
}
|
||||
|
||||
private suspend fun lockAddButtonAction() {
|
||||
dispatchOnMain(Screen.UpdateAddButton(ViewStates.AddButton(false)))
|
||||
}
|
||||
|
||||
private suspend fun unlockAddButtonAction() {
|
||||
dispatchOnMain(Screen.UpdateAddButton(ViewStates.AddButton(true)))
|
||||
}
|
||||
|
||||
override fun reduceAction(action: Action, state: AddCustomTokenState): AddCustomTokenState {
|
||||
return when (action) {
|
||||
is Init.SetAddedCurrencies -> {
|
||||
|
|
@ -363,12 +293,11 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
state.copy(onTokenAddCallback = action.callback)
|
||||
}
|
||||
is OnCreate -> {
|
||||
// val card = requireNotNull(globalState.scanResponse?.card)
|
||||
val card = requireNotNull(globalState.scanResponse?.card)
|
||||
val tangemTechServiceManager = TangemTechServiceManager(TangemTechService())
|
||||
// tangemTechServiceManager.attachAuthKey(card.cardPublicKey.toHexString())
|
||||
tangemTechServiceManager.attachAuthKey(card.cardPublicKey.toHexString())
|
||||
state.copy(
|
||||
// derivationStyle = card.derivationStyle,
|
||||
derivationStyle = DerivationStyle.LEGACY,
|
||||
derivationStyle = card.derivationStyle,
|
||||
tangemTechServiceManager = tangemTechServiceManager
|
||||
)
|
||||
}
|
||||
|
|
@ -506,8 +435,4 @@ internal class AddCustomTokenHub : BaseStoreHub<AddCustomTokenState>("AddCustomT
|
|||
"AddCustomTokenHub", "$objName must be not NULL"
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -73,14 +73,12 @@ data class AddCustomTokenState(
|
|||
// val errors = mutableMapOf<>()
|
||||
fieldsToCheck.forEach { field ->
|
||||
val error = validator.validate(field.data.value?.toString())
|
||||
if (error != null) return false
|
||||
if (error != null) return true
|
||||
}
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
fun allFieldsIsEmpty(): Boolean {
|
||||
return networkIsEmpty() && customTokensFieldsIsEmpty()
|
||||
}
|
||||
fun allFieldsIsEmpty(): Boolean = networkIsEmpty() && customTokensFieldsIsEmpty()
|
||||
|
||||
private fun getToken(): CompleteData.CustomToken {
|
||||
return CompleteData.CustomToken.Converter(tokenId)
|
||||
|
|
@ -140,11 +138,11 @@ data class AddCustomTokenState(
|
|||
return ScreenState(
|
||||
contractAddressField = ViewStates.TokenField(),
|
||||
network = ViewStates.TokenField(),
|
||||
name = ViewStates.TokenField(isEnabled = false),
|
||||
symbol = ViewStates.TokenField(isEnabled = false),
|
||||
decimals = ViewStates.TokenField(isEnabled = false),
|
||||
name = ViewStates.TokenField(),
|
||||
symbol = ViewStates.TokenField(),
|
||||
decimals = ViewStates.TokenField(),
|
||||
derivationPath = ViewStates.TokenField(),
|
||||
addButton = ViewStates.AddButton(isEnabled = false)
|
||||
addButton = ViewStates.AddButton()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue