Updated on 2026-08-14

This commit is contained in:
Tangem 2023-11-21 01:02:10 +04:00
parent c28d80cb18
commit 688b5da7bd
9 changed files with 222 additions and 44 deletions

View file

@ -5,18 +5,13 @@ import android.content.Context
import com.tangem.core.navigation.StateDialog
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.common.redux.global.GlobalState
import com.tangem.tap.common.ui.SimpleAlertDialog
import com.tangem.tap.common.ui.SimpleCancelableAlertDialog
import com.tangem.tap.common.ui.*
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectDialog
import com.tangem.tap.features.details.ui.walletconnect.dialogs.*
import com.tangem.tap.features.onboarding.AddressInfoBottomSheetDialog
import com.tangem.tap.features.onboarding.OnboardingDialog
import com.tangem.tap.features.onboarding.products.twins.ui.dialog.TwinningProcessNotCompletedDialog
import com.tangem.tap.features.onboarding.products.wallet.redux.BackupDialog
import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.*
import com.tangem.tap.features.wallet.redux.models.WalletDialog
import com.tangem.tap.features.wallet.ui.dialogs.*
import com.tangem.tap.features.wallet.ui.wallet.CurrencySelectionDialog
import com.tangem.tap.store
import com.tangem.wallet.R
import org.rekotlin.StoreSubscriber
@ -50,13 +45,14 @@ class DialogManager : StoreSubscriber<GlobalState> {
if (dialog != null) return
dialog = when (state.dialog) {
is AppDialog.SimpleOkDialog -> SimpleOkDialog.create(state.dialog, context)
is AppDialog.SimpleOkDialogRes -> SimpleOkDialog.create(state.dialog, context)
is AppDialog.SimpleOkErrorDialog -> SimpleOkDialog.create(state.dialog, context)
is AppDialog.SimpleOkWarningDialog -> SimpleOkDialog.create(state.dialog, context)
is StateDialog.ScanFailsDialog -> ScanFailsDialog.create(context)
is AppDialog.AddressInfoDialog -> AddressInfoBottomSheetDialog(state.dialog, context)
is AppDialog.TestActionsDialog -> TestActionsBottomSheetDialog(state.dialog, context)
is AppDialog.RussianCardholdersWarningDialog -> RussianCardholdersWarningBottomSheetDialog(
context,
state.dialog.data,
)
is OnboardingDialog.TwinningProcessNotCompleted -> TwinningProcessNotCompletedDialog.create(context)
is OnboardingDialog.InterruptOnboarding -> InterruptOnboardingDialog.create(context, state.dialog)
is WalletConnectDialog.UnsupportedCard ->
@ -132,11 +128,7 @@ class DialogManager : StoreSubscriber<GlobalState> {
context = context,
cardId = state.dialog.cardId,
)
is WalletDialog.CurrencySelectionDialog -> CurrencySelectionDialog.create(state.dialog, context)
is WalletDialog.ChooseTradeActionDialog -> ChooseTradeActionBottomSheetDialog(context, state.dialog)
is WalletDialog.SelectAmountToSendDialog -> AmountToSendBottomSheetDialog(context, state.dialog)
is WalletDialog.SignedHashesMultiWalletDialog -> SignedHashesWarningDialog.create(context)
is WalletDialog.TokensAreLinkedDialog -> SimpleAlertDialog.create(
is AppDialog.TokensAreLinkedDialog -> SimpleAlertDialog.create(
title = context.getString(state.dialog.titleRes, state.dialog.currencySymbol),
message = context.getString(
state.dialog.messageRes,
@ -145,15 +137,13 @@ class DialogManager : StoreSubscriber<GlobalState> {
),
context = context,
)
is WalletDialog.RemoveWalletDialog -> SimpleCancelableAlertDialog.create(
is AppDialog.RemoveWalletDialog -> SimpleCancelableAlertDialog.create(
title = context.getString(state.dialog.titleRes, state.dialog.currencyTitle),
messageRes = state.dialog.messageRes,
context = context,
primaryButtonRes = state.dialog.primaryButtonRes,
primaryButtonAction = state.dialog.onOk,
)
is WalletDialog.RussianCardholdersWarningDialog ->
RussianCardholdersWarningBottomSheetDialog(context, state.dialog.data)
else -> null
}
dialog?.show()

View file

@ -5,14 +5,12 @@ import com.tangem.core.navigation.StateDialog
import com.tangem.tap.common.TestAction
import com.tangem.tap.domain.model.WalletDataModel
import com.tangem.tap.features.wallet.models.Currency
import com.tangem.wallet.R
/**
[REDACTED_AUTHOR]
*/
sealed class AppDialog : StateDialog {
data class SimpleOkDialog(val header: String, val message: String, val onOk: VoidCallback? = null) : AppDialog()
data class SimpleOkErrorDialog(val message: String, val onOk: VoidCallback? = null) : AppDialog()
data class SimpleOkWarningDialog(val message: String, val onOk: VoidCallback? = null) : AppDialog()
data class SimpleOkDialogRes(
val headerId: Int,
val messageId: Int,
@ -20,19 +18,7 @@ sealed class AppDialog : StateDialog {
val onOk: VoidCallback? = null,
) : AppDialog()
data class OkCancelDialogRes(
val headerId: Int,
val messageId: Int,
val okButton: DialogButton,
val cancelButton: DialogButton,
) : AppDialog()
data class DialogButton(
val title: Int,
val action: VoidCallback? = null,
)
data class AddressInfoDialog(
internal data class AddressInfoDialog(
val currency: Currency,
val addressData: WalletDataModel.AddressData,
) : AppDialog()
@ -40,4 +26,25 @@ sealed class AppDialog : StateDialog {
data class TestActionsDialog(
val actionsList: List<TestAction>,
) : AppDialog()
data class RussianCardholdersWarningDialog(val data: Data?) : AppDialog() {
data class Data(val topUpUrl: String)
}
data class RemoveWalletDialog(
val currencyTitle: String,
val onOk: () -> Unit,
) : AppDialog() {
val messageRes: Int = R.string.token_details_hide_alert_message
val titleRes: Int = R.string.token_details_hide_alert_title
val primaryButtonRes: Int = R.string.token_details_hide_alert_hide
}
data class TokensAreLinkedDialog(
val currencyTitle: String,
val currencySymbol: String,
) : AppDialog() {
val messageRes: Int = R.string.token_details_unable_hide_alert_message
val titleRes: Int = R.string.token_details_unable_hide_alert_title
}
}

View file

@ -0,0 +1,68 @@
package com.tangem.tap.common.ui
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.tangem.core.analytics.Analytics
import com.tangem.tap.common.analytics.events.Token
import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.domain.model.WalletDataModel
import com.tangem.tap.store
import com.tangem.wallet.R
import com.tangem.wallet.databinding.DialogOnboardingAddressInfoBinding
/**
[REDACTED_AUTHOR]
*/
internal class AddressInfoBottomSheetDialog(
private val stateDialog: AppDialog.AddressInfoDialog,
context: Context,
) : BottomSheetDialog(context) {
var binding: DialogOnboardingAddressInfoBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DialogOnboardingAddressInfoBinding
.inflate(LayoutInflater.from(context))
setContentView(binding!!.root)
behavior.state = BottomSheetBehavior.STATE_EXPANDED
setOnCancelListener {
store.dispatchDialogHide()
binding = null
}
}
override fun show() {
super.show()
Analytics.send(Token.Receive.ScreenOpened())
showData(data = stateDialog.addressData)
}
private fun showData(data: WalletDataModel.AddressData) = with(binding!!) {
pseudoToolbar.imvClose.setOnClickListener {
dismissWithAnimation = true
cancel()
}
imvQrCode.setImageBitmap(data.shareUrl.toQrCode())
tvAddress.text = data.address
btnFlCopyAddress.setOnClickListener {
Analytics.send(Token.Receive.ButtonCopyAddress())
context.copyToClipboard(data.address)
}
btnFlShare.setOnClickListener {
Analytics.send(Token.Receive.ButtonShareAddress())
store.dispatchShare(data.shareUrl)
}
val blockchain = stateDialog.currency.blockchain
tvReceiveMessage.text = tvReceiveMessage.getString(
id = R.string.address_qr_code_message_format,
blockchain.fullName,
blockchain.currency,
blockchain.fullName,
)
}
}

View file

@ -0,0 +1,57 @@
package com.tangem.tap.common.ui
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.tangem.core.analytics.Analytics
import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.tokens.legacy.TradeCryptoAction
import com.tangem.tap.common.analytics.events.Token
import com.tangem.tap.common.extensions.dispatchDialogHide
import com.tangem.tap.common.extensions.dispatchOpenUrl
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.store
import com.tangem.wallet.databinding.DialogRussiansCardholdersWarningBinding
class RussianCardholdersWarningBottomSheetDialog(
context: Context,
private val dialogData: AppDialog.RussianCardholdersWarningDialog.Data?,
) : BottomSheetDialog(context) {
private var binding: DialogRussiansCardholdersWarningBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Analytics.send(Token.Topup.P2PScreenOpened())
binding = DialogRussiansCardholdersWarningBinding
.inflate(LayoutInflater.from(context))
.also { setContentView(it.root) }
}
override fun show() {
super.show()
setOnDismissListener {
binding = null
store.dispatchDialogHide()
}
binding?.btnYes?.setOnClickListener {
if (dialogData != null) {
store.dispatchOpenUrl(dialogData.topUpUrl)
Analytics.send(Token.Topup.ScreenOpened())
} else {
store.dispatch(TradeCryptoAction.Buy(checkUserLocation = false))
}
dismiss()
}
binding?.btnNo?.setOnClickListener {
store.dispatch(NavigationAction.OpenUrl(INSTRUCTION_URL))
dismiss()
}
}
companion object {
private const val INSTRUCTION_URL = "https://tangem.com/howtobuy.html"
}
}

View file

@ -0,0 +1,30 @@
package com.tangem.tap.common.ui
import android.content.Context
import androidx.appcompat.app.AlertDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.tangem.core.analytics.Analytics
import com.tangem.tap.common.analytics.events.IntroductionProcess
import com.tangem.tap.common.extensions.dispatchDialogHide
import com.tangem.tap.common.feedback.ScanFailsEmail
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.store
import com.tangem.wallet.R
/**
[REDACTED_AUTHOR]
*/
object ScanFailsDialog {
fun create(context: Context): AlertDialog {
return MaterialAlertDialogBuilder(context, R.style.CustomMaterialDialog).apply {
setTitle(context.getString(R.string.common_warning))
setMessage(R.string.alert_troubleshooting_scan_card_title)
setPositiveButton(R.string.alert_button_request_support) { _, _ ->
Analytics.send(IntroductionProcess.ButtonRequestSupport())
store.dispatch(GlobalAction.SendEmail(ScanFailsEmail()))
}
setNeutralButton(R.string.common_cancel) { _, _ -> }
setOnDismissListener { store.dispatchDialogHide() }
}.create()
}
}

View file

@ -0,0 +1,31 @@
package com.tangem.tap.common.ui
import android.content.Context
import androidx.appcompat.app.AlertDialog
import com.tangem.tap.common.extensions.dispatchDialogHide
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.store
import com.tangem.wallet.R
/**
[REDACTED_AUTHOR]
*/
object SimpleOkDialog {
fun create(dialog: AppDialog.SimpleOkDialogRes, context: Context): AlertDialog {
val message = if (dialog.args.isEmpty()) {
context.getString(dialog.messageId)
} else {
context.getString(dialog.messageId, *dialog.args.toTypedArray())
}
return AlertDialog.Builder(context).apply {
setTitle(context.getString(dialog.headerId))
setMessage(message)
setPositiveButton(R.string.common_ok) { _, _ -> }
setOnDismissListener {
store.dispatchDialogHide()
dialog.onOk?.invoke()
}
}.create()
}
}

View file

@ -20,8 +20,6 @@ import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
import com.tangem.tap.features.onboarding.OnboardingDialog
import com.tangem.tap.features.onboarding.OnboardingHelper
import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.features.wallet.redux.models.WalletDialog
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
@ -178,8 +176,8 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch
Analytics.send(Onboarding.Topup.ButtonBuyCrypto(currencyType))
if (globalState.userCountryCode == RUSSIA_COUNTRY_CODE) {
val dialogData = WalletDialog.RussianCardholdersWarningDialog.Data(topUpUrl)
store.dispatchOnMain(WalletAction.DialogAction.RussianCardholdersWarningDialog(dialogData))
val dialogData = AppDialog.RussianCardholdersWarningDialog.Data(topUpUrl)
store.dispatchDialogShow(AppDialog.RussianCardholdersWarningDialog(dialogData))
} else {
store.dispatchOpenUrl(topUpUrl)
}

View file

@ -26,8 +26,6 @@ import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
import com.tangem.tap.features.onboarding.OnboardingDialog
import com.tangem.tap.features.onboarding.OnboardingHelper
import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.features.wallet.redux.models.WalletDialog
import com.tangem.tap.preferencesStorage
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.scope
@ -285,8 +283,8 @@ private fun handle(action: Action, dispatch: DispatchFunction) {
Analytics.send(Onboarding.Topup.ButtonBuyCrypto(currencyType))
if (globalState.userCountryCode == RUSSIA_COUNTRY_CODE) {
val dialogData = WalletDialog.RussianCardholdersWarningDialog.Data(topUpUrl)
store.dispatchOnMain(WalletAction.DialogAction.RussianCardholdersWarningDialog(dialogData))
val dialogData = AppDialog.RussianCardholdersWarningDialog.Data(topUpUrl)
store.dispatchDialogShow(AppDialog.RussianCardholdersWarningDialog(dialogData))
} else {
store.dispatchOpenUrl(topUpUrl)
}

View file

@ -6,7 +6,6 @@ import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.common.extensions.dispatchDialogShow
import com.tangem.tap.common.extensions.dispatchNotification
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.features.wallet.redux.models.WalletDialog
import com.tangem.tap.store
import com.tangem.wallet.R
@ -32,13 +31,13 @@ internal class DefaultTokensListRouter : TokensListRouter {
override fun openUnableHideMainTokenAlert(tokenName: String, tokenSymbol: String) {
store.dispatchDialogShow(
dialog = WalletDialog.TokensAreLinkedDialog(currencyTitle = tokenName, currencySymbol = tokenSymbol),
dialog = AppDialog.TokensAreLinkedDialog(currencyTitle = tokenName, currencySymbol = tokenSymbol),
)
}
override fun openRemoveWalletAlert(tokenName: String, onOkClick: () -> Unit) {
store.dispatchDialogShow(
dialog = WalletDialog.RemoveWalletDialog(currencyTitle = tokenName, onOk = onOkClick),
dialog = AppDialog.RemoveWalletDialog(currencyTitle = tokenName, onOk = onOkClick),
)
}