Updated on 2026-08-14
This commit is contained in:
parent
7355e24baa
commit
d0c4d92a8c
12 changed files with 346 additions and 0 deletions
|
|
@ -17,6 +17,9 @@ import com.tangem.tap.features.onboarding.AddressInfoBottomSheetDialog
|
|||
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.features.onboarding.products.twins.ui.dialog.CreateWalletInterruptDialog
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.BackupDialog
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.dialog.NoFundsForActivationDialog
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.dialog.RegistrationErrorDialog
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.dialog.SaltPayDialog
|
||||
import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.AddMoreBackupCardsDialog
|
||||
import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.BackupInProgressDialog
|
||||
import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.ConfirmDiscardingBackupDialog
|
||||
|
|
@ -126,6 +129,8 @@ class DialogManager : StoreSubscriber<GlobalState> {
|
|||
is BackupDialog.BackupInProgress -> BackupInProgressDialog.create(context)
|
||||
is BackupDialog.UnfinishedBackupFound -> UnfinishedBackupFoundDialog.create(context)
|
||||
is BackupDialog.ConfirmDiscardingBackup -> ConfirmDiscardingBackupDialog.create(context)
|
||||
is SaltPayDialog.NoFundsForActivation -> NoFundsForActivationDialog.create(context)
|
||||
is SaltPayDialog.RegistrationError -> RegistrationErrorDialog.create(context, state.dialog)
|
||||
is WalletDialog.CurrencySelectionDialog ->
|
||||
CurrencySelectionDialog.create(state.dialog, context)
|
||||
is WalletDialog.ChooseTradeActionDialog ->
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ fun postBackground(ms: Long = 0, func: Runnable) {
|
|||
if (ms == 0L) backgroundHandler.post { func.run() } else backgroundHandler.postDelayed(func, ms)
|
||||
}
|
||||
|
||||
fun postUiDelayBg(ms: Long, func: Runnable) {
|
||||
backgroundHandler.postDelayed({ uiHandler.post(func) }, ms)
|
||||
}
|
||||
|
||||
fun post(ms: Long = 0, func: Runnable) {
|
||||
if (ms == 0L) {
|
||||
func.run()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
package com.tangem.tap.domain.moduleMessage
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
* Base interface for conversion outputs from ModuleMessageConverter
|
||||
*/
|
||||
interface ConvertedMessage {
|
||||
val message: String
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog message used to construct a android.Dialog
|
||||
*/
|
||||
interface DialogMessage : ConvertedMessage {
|
||||
val title: String
|
||||
override val message: String
|
||||
val onPositive: String?
|
||||
val onNegative: String?
|
||||
val onNeutral: String?
|
||||
}
|
||||
|
||||
data class ConvertedStringMessage(
|
||||
override val message: String,
|
||||
) : ConvertedMessage
|
||||
|
||||
data class ConvertedDialogMessage(
|
||||
override val title: String,
|
||||
override val message: String,
|
||||
override val onPositive: String? = null,
|
||||
override val onNegative: String? = null,
|
||||
override val onNeutral: String? = null,
|
||||
) : DialogMessage
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.tap.domain.moduleMessage
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.common.module.ModuleMessage
|
||||
import com.tangem.common.module.ModuleMessageConverter
|
||||
import com.tangem.domain.DomainModuleMessage
|
||||
import com.tangem.tap.domain.moduleMessage.domain.DomainMessageConverter
|
||||
import com.tangem.tap.domain.moduleMessage.saltPay.SaltPayMessageConverter
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayModuleMessage
|
||||
|
||||
class ModuleMessageConverter(
|
||||
private val context: Context,
|
||||
) : ModuleMessageConverter<ModuleMessage, ConvertedMessage> {
|
||||
|
||||
override fun convert(message: ModuleMessage): ConvertedMessage {
|
||||
val convertedMessage = when (message) {
|
||||
is DomainModuleMessage -> DomainMessageConverter(context).convert(message)
|
||||
is SaltPayModuleMessage -> SaltPayMessageConverter(context).convert(message)
|
||||
else -> null
|
||||
}
|
||||
return convertedMessage ?: convertUnknownMessage(message)
|
||||
}
|
||||
|
||||
private fun convertUnknownMessage(message: ModuleMessage): ConvertedMessage {
|
||||
return ConvertedStringMessage("Unknown message: ${message::class.java.simpleName}")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.tangem.tap.domain.moduleMessage.domain
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.common.module.ModuleMessageConverter
|
||||
import com.tangem.domain.AddCustomTokenError
|
||||
import com.tangem.domain.DomainModuleError
|
||||
import com.tangem.domain.DomainModuleMessage
|
||||
import com.tangem.tap.domain.moduleMessage.ConvertedMessage
|
||||
import com.tangem.tap.domain.moduleMessage.domain.converter.AddCustomTokenErrorConverter
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class DomainMessageConverter(
|
||||
private val context: Context,
|
||||
) : ModuleMessageConverter<DomainModuleMessage, ConvertedMessage?> {
|
||||
|
||||
override fun convert(message: DomainModuleMessage): ConvertedMessage? {
|
||||
return when (message) {
|
||||
is DomainModuleError -> DomainErrorConverter(context).convert(message)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DomainErrorConverter(
|
||||
private val context: Context,
|
||||
) : ModuleMessageConverter<DomainModuleError, ConvertedMessage?> {
|
||||
|
||||
override fun convert(message: DomainModuleError): ConvertedMessage? = when (message) {
|
||||
is AddCustomTokenError -> AddCustomTokenErrorConverter(context).convert(message)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.tangem.tap.domain.moduleMessage.domain.converter
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.common.module.ModuleMessageConverter
|
||||
import com.tangem.domain.AddCustomTokenError
|
||||
import com.tangem.domain.DomainModuleError
|
||||
import com.tangem.tap.domain.moduleMessage.ConvertedMessage
|
||||
import com.tangem.tap.domain.moduleMessage.ConvertedStringMessage
|
||||
import com.tangem.wallet.R
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class AddCustomTokenErrorConverter(
|
||||
private val context: Context,
|
||||
) : ModuleMessageConverter<DomainModuleError, ConvertedMessage?> {
|
||||
|
||||
override fun convert(message: DomainModuleError): ConvertedMessage? {
|
||||
val customTokenError = (message as? AddCustomTokenError) ?: throw UnsupportedOperationException()
|
||||
|
||||
val rawMessage = when (customTokenError) {
|
||||
AddCustomTokenError.Warning.PotentialScamToken -> R.string.custom_token_validation_error_not_found
|
||||
AddCustomTokenError.Warning.TokenAlreadyAdded -> R.string.custom_token_validation_error_already_added
|
||||
AddCustomTokenError.Warning.UnsupportedSolanaToken -> R.string.alert_manage_tokens_unsupported_message
|
||||
AddCustomTokenError.InvalidContractAddress -> R.string.custom_token_creation_error_invalid_contract_address
|
||||
AddCustomTokenError.NetworkIsNotSelected -> R.string.custom_token_creation_error_network_not_selected
|
||||
AddCustomTokenError.InvalidDerivationPath -> R.string.custom_token_creation_error_invalid_derivation_path
|
||||
AddCustomTokenError.InvalidDecimalsCount -> {
|
||||
context.getString(R.string.custom_token_creation_error_wrong_decimals, 30)
|
||||
}
|
||||
AddCustomTokenError.FieldIsEmpty -> R.string.custom_token_creation_error_required_field
|
||||
else -> null
|
||||
}
|
||||
|
||||
return when (rawMessage) {
|
||||
is Int -> ConvertedStringMessage(context.getString(rawMessage))
|
||||
is String -> ConvertedStringMessage(rawMessage)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.tangem.tap.domain.moduleMessage.saltPay
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.common.module.ModuleMessageConverter
|
||||
import com.tangem.tap.domain.moduleMessage.ConvertedMessage
|
||||
import com.tangem.tap.domain.moduleMessage.saltPay.converter.SaltPayRegistrationErrorConverter
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayModuleError
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayModuleMessage
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayRegistrationError
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class SaltPayMessageConverter(
|
||||
private val context: Context,
|
||||
) : ModuleMessageConverter<SaltPayModuleMessage, ConvertedMessage?> {
|
||||
|
||||
override fun convert(message: SaltPayModuleMessage): ConvertedMessage? {
|
||||
return when (message) {
|
||||
is SaltPayModuleError -> SaltPayErrorConverter(context).convert(message)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SaltPayErrorConverter(
|
||||
private val context: Context,
|
||||
) : ModuleMessageConverter<SaltPayModuleError, ConvertedMessage?> {
|
||||
|
||||
override fun convert(message: SaltPayModuleError): ConvertedMessage? = when (message) {
|
||||
is SaltPayRegistrationError -> SaltPayRegistrationErrorConverter(context).convert(message)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.tangem.tap.domain.moduleMessage.saltPay.converter
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.common.module.ModuleMessageConverter
|
||||
import com.tangem.tap.domain.moduleMessage.ConvertedDialogMessage
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayRegistrationError
|
||||
import com.tangem.wallet.R
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class SaltPayRegistrationErrorConverter(
|
||||
private val context: Context,
|
||||
) : ModuleMessageConverter<SaltPayRegistrationError, ConvertedDialogMessage?> {
|
||||
|
||||
override fun convert(message: SaltPayRegistrationError): ConvertedDialogMessage? {
|
||||
val saltPayError = (message as? SaltPayRegistrationError) ?: throw UnsupportedOperationException()
|
||||
|
||||
val dialogMessage = when (saltPayError) {
|
||||
SaltPayRegistrationError.NoGas -> {
|
||||
ConvertedDialogMessage(
|
||||
title = context.getString(R.string.saltpay_error_no_gas_title),
|
||||
message = context.getString(R.string.saltpay_error_no_gas_message),
|
||||
)
|
||||
}
|
||||
SaltPayRegistrationError.EmptyBackupCardScanned -> {
|
||||
ConvertedDialogMessage(
|
||||
title = context.getString(R.string.saltpay_error_empty_backup_title),
|
||||
message = context.getString(R.string.saltpay_error_empty_backup_message),
|
||||
)
|
||||
}
|
||||
SaltPayRegistrationError.WeakPin -> {
|
||||
ConvertedDialogMessage(
|
||||
title = context.getString(R.string.saltpay_error_pin_weak_title),
|
||||
message = context.getString(R.string.saltpay_error_pin_weak_message),
|
||||
)
|
||||
}
|
||||
else -> ConvertedDialogMessage(
|
||||
title = context.getString(R.string.common_error),
|
||||
message = saltPayError::class.java.simpleName,
|
||||
)
|
||||
}
|
||||
|
||||
return dialogMessage
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.saltPay.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.tangem.tap.common.feedback.SupportInfo
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class NoFundsForActivationDialog {
|
||||
companion object {
|
||||
fun create(context: Context): Dialog {
|
||||
return AlertDialog.Builder(context).apply {
|
||||
setTitle(R.string.saltpay_error_no_gas_title)
|
||||
setMessage(R.string.saltpay_error_no_gas_message)
|
||||
//TODO: SaltPay: change onboarding_supplement_button_kyc_waiting -> to appropriate string
|
||||
setPositiveButton(R.string.onboarding_supplement_button_kyc_waiting) { _, _ ->
|
||||
store.dispatch(GlobalAction.OpenChat(SupportInfo()))
|
||||
}
|
||||
setNegativeButton(R.string.common_cancel) { _, _ ->
|
||||
}
|
||||
setOnDismissListener {
|
||||
store.dispatch(GlobalAction.HideDialog)
|
||||
}
|
||||
setCancelable(false)
|
||||
}.create()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.saltPay.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.domain.moduleMessage.ConvertedDialogMessage
|
||||
import com.tangem.tap.domain.moduleMessage.saltPay.SaltPayErrorConverter
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class RegistrationErrorDialog {
|
||||
companion object {
|
||||
fun create(context: Context, dialog: SaltPayDialog.RegistrationError): Dialog {
|
||||
val convertedMessage = SaltPayErrorConverter(context).convert(dialog.error) as ConvertedDialogMessage
|
||||
|
||||
return AlertDialog.Builder(context).apply {
|
||||
setTitle(convertedMessage.title)
|
||||
setMessage(convertedMessage.message)
|
||||
setPositiveButton(R.string.common_ok) { _, _ ->
|
||||
store.dispatch(GlobalAction.HideDialog)
|
||||
}
|
||||
setOnDismissListener {
|
||||
store.dispatch(GlobalAction.HideDialog)
|
||||
}
|
||||
setCancelable(false)
|
||||
}.create()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.saltPay.dialog
|
||||
|
||||
import com.tangem.tap.common.redux.StateDialog
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayRegistrationError
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
sealed class SaltPayDialog : StateDialog {
|
||||
object NoFundsForActivation : SaltPayDialog()
|
||||
data class RegistrationError(val error: SaltPayRegistrationError) : SaltPayDialog()
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.saltPay.message
|
||||
|
||||
import com.tangem.common.module.ModuleError
|
||||
import com.tangem.common.module.ModuleErrorCode
|
||||
import com.tangem.common.module.ModuleMessage
|
||||
|
||||
sealed interface SaltPayModuleMessage : ModuleMessage
|
||||
|
||||
sealed class SaltPayModuleError(
|
||||
subCode: Int,
|
||||
override val message: String,
|
||||
override val data: Any? = null,
|
||||
) : SaltPayModuleMessage, ModuleError() {
|
||||
override val code: Int = ModuleErrorCode.SALT_PAY + subCode
|
||||
|
||||
companion object {
|
||||
// base code used for all errors in the module
|
||||
internal const val ERROR_CODE_REGISTRATION = 100
|
||||
// const val CODE_ANY_OTHER = 200..299, 300..399 etc
|
||||
}
|
||||
}
|
||||
|
||||
sealed class SaltPayRegistrationError(
|
||||
subCode: Int,
|
||||
message: String? = null,
|
||||
override val data: Any? = null,
|
||||
) : SaltPayModuleError(
|
||||
subCode = ERROR_CODE_REGISTRATION + subCode,
|
||||
message = message ?: this::class.java.simpleName,
|
||||
) {
|
||||
object Unknown : SaltPayRegistrationError(4)
|
||||
object Empty : SaltPayRegistrationError(4)
|
||||
object FailedToMakeTxData : SaltPayRegistrationError(1)
|
||||
object FailedToSendTx : SaltPayRegistrationError(2)
|
||||
object NeedPin : SaltPayRegistrationError(3)
|
||||
object NoGas : SaltPayRegistrationError(5)
|
||||
object EmptyResponse : SaltPayRegistrationError(6)
|
||||
object Card : SaltPayRegistrationError(7)
|
||||
object CardNotFound : SaltPayRegistrationError(8)
|
||||
object CardDisabled : SaltPayRegistrationError(9)
|
||||
object CardNotPassed : SaltPayRegistrationError(10)
|
||||
object EmptyDynamicAttestResponse : SaltPayRegistrationError(11)
|
||||
object EmptyBackupCardScanned : SaltPayRegistrationError(12)
|
||||
object WeakPin : SaltPayRegistrationError(13)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue