Updated on 2026-08-14
This commit is contained in:
parent
0382c454f5
commit
78e1021a76
16 changed files with 221 additions and 62 deletions
|
|
@ -14,7 +14,16 @@ class DisclaimerMiddleware {
|
|||
when (action) {
|
||||
is DisclaimerAction.AcceptDisclaimer -> {
|
||||
preferencesStorage.saveDisclaimerAccepted()
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
if (store.state.walletState.twinCardsState != null) {
|
||||
val showOnboarding = !preferencesStorage.wasTwinsOnboardingShown()
|
||||
if (showOnboarding) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.TwinsOnboarding))
|
||||
} else {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
} else {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
}
|
||||
}
|
||||
next(action)
|
||||
|
|
|
|||
|
|
@ -54,11 +54,18 @@ class HomeMiddleware {
|
|||
}
|
||||
|
||||
private fun showDisclaimerOrNavigateToWallet() {
|
||||
if (preferencesStorage.wasDisclaimerAccepted()) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
} else {
|
||||
if (!preferencesStorage.wasDisclaimerAccepted()) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Disclaimer))
|
||||
return
|
||||
}
|
||||
if (store.state.walletState.twinCardsState != null) {
|
||||
val showOnboarding = !preferencesStorage.wasTwinsOnboardingShown()
|
||||
if (showOnboarding) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.TwinsOnboarding))
|
||||
return
|
||||
}
|
||||
}
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
|
|||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.blockchain.extensions.Signer
|
||||
import com.tangem.commands.Card
|
||||
import com.tangem.commands.common.card.Card
|
||||
import com.tangem.tap.common.analytics.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
|
||||
import com.tangem.tap.common.extensions.stripZeroPlainString
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@ import android.content.Context
|
|||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.blockchain.common.address.AddressType
|
||||
import com.tangem.commands.Card
|
||||
import com.tangem.commands.common.card.Card
|
||||
import com.tangem.tap.common.redux.ErrorAction
|
||||
import com.tangem.tap.common.redux.NotificationAction
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.domain.TwinCardNumber
|
||||
import com.tangem.wallet.R
|
||||
import org.rekotlin.Action
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -94,4 +95,10 @@ sealed class WalletAction : Action {
|
|||
}
|
||||
|
||||
data class ChangeSelectedAddress(val type: AddressType): WalletAction()
|
||||
|
||||
sealed class TwinsAction : WalletAction() {
|
||||
object ShowOnboarding : TwinsAction()
|
||||
object SetOnboardingShown : TwinsAction()
|
||||
data class SetTwinCard(val secondCardId: String, val number: TwinCardNumber) : TwinsAction()
|
||||
}
|
||||
}
|
||||
|
|
@ -6,10 +6,10 @@ import androidx.browser.customtabs.CustomTabsIntent
|
|||
import androidx.core.content.ContextCompat
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.commands.Card
|
||||
import com.tangem.commands.common.card.Card
|
||||
import com.tangem.commands.common.card.CardType
|
||||
import com.tangem.commands.common.network.Result
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.extensions.CardType
|
||||
import com.tangem.common.extensions.getType
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
|
||||
|
|
@ -20,7 +20,10 @@ import com.tangem.tap.common.redux.navigation.NavigationAction
|
|||
import com.tangem.tap.domain.PayIdManager
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.domain.TopUpHelper
|
||||
import com.tangem.tap.domain.TwinsHelper
|
||||
import com.tangem.tap.domain.extensions.toSendableAmounts
|
||||
import com.tangem.tap.features.details.redux.DetailsAction
|
||||
import com.tangem.tap.features.details.redux.twins.CreateTwinWallet
|
||||
import com.tangem.tap.features.send.redux.PrepareSendScreen
|
||||
import com.tangem.tap.features.wallet.models.toPendingTransactions
|
||||
import com.tangem.tap.network.NetworkConnectivity
|
||||
|
|
@ -60,15 +63,25 @@ class WalletMiddleware {
|
|||
}
|
||||
}
|
||||
is WalletAction.CreateWallet -> {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.createWallet(
|
||||
store.state.globalState.scanNoteResponse?.card?.cardId
|
||||
)
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
store.state.globalState.tapWalletManager.onCardScanned(result.data)
|
||||
}
|
||||
if (store.state.walletState.twinCardsState != null) {
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.Proceed(
|
||||
store.state.globalState.scanNoteResponse?.card?.cardId?.let {
|
||||
TwinsHelper.getTwinCardNumber(it)
|
||||
},
|
||||
CreateTwinWallet.CreateWallet
|
||||
))
|
||||
} else {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.createWallet(
|
||||
store.state.globalState.scanNoteResponse?.card?.cardId
|
||||
)
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
store.state.globalState.tapWalletManager
|
||||
.onCardScanned(result.data)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -164,6 +177,13 @@ class WalletMiddleware {
|
|||
val cardId = store.state.globalState.scanNoteResponse?.card?.cardId
|
||||
cardId?.let { preferencesStorage.saveScannedCardId(it) }
|
||||
}
|
||||
is WalletAction.TwinsAction.SetTwinCard -> {
|
||||
val showOnboarding = !preferencesStorage.wasTwinsOnboardingShown()
|
||||
if (showOnboarding) store.dispatch(WalletAction.TwinsAction.ShowOnboarding)
|
||||
}
|
||||
is WalletAction.TwinsAction.SetOnboardingShown -> {
|
||||
preferencesStorage.saveTwinsOnboardingShown()
|
||||
}
|
||||
}
|
||||
next(action)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,10 +214,30 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
}
|
||||
is WalletAction.ChangeSelectedAddress -> {
|
||||
val walletAddresses = newState.walletAddresses ?: return newState
|
||||
val address = walletAddresses.list.firstOrNull { it.type == action.type } ?: return newState
|
||||
val address = walletAddresses.list.firstOrNull { it.type == action.type }
|
||||
?: return newState
|
||||
|
||||
newState = newState.copy(walletAddresses = WalletAddresses(address, walletAddresses.list))
|
||||
}
|
||||
is WalletAction.TwinsAction.SetTwinCard -> {
|
||||
newState = newState.copy(
|
||||
twinCardsState = TwinCardsState(
|
||||
secondCardId = action.secondCardId,
|
||||
cardNumber = action.number,
|
||||
newState.twinCardsState?.showTwinOnboarding ?: false)
|
||||
)
|
||||
}
|
||||
is WalletAction.TwinsAction.ShowOnboarding -> {
|
||||
newState = newState.copy(
|
||||
twinCardsState = newState.twinCardsState?.copy(showTwinOnboarding = true)
|
||||
?: TwinCardsState(null, null, true)
|
||||
)
|
||||
}
|
||||
is WalletAction.TwinsAction.SetOnboardingShown -> {
|
||||
newState = newState.copy(
|
||||
twinCardsState = newState.twinCardsState?.copy(showTwinOnboarding = false)
|
||||
)
|
||||
}
|
||||
}
|
||||
return newState
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.tangem.blockchain.common.Wallet
|
|||
import com.tangem.blockchain.common.address.AddressType
|
||||
import com.tangem.tap.common.entities.Button
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.tap.domain.TwinCardNumber
|
||||
import com.tangem.tap.features.wallet.models.PendingTransaction
|
||||
import com.tangem.tap.features.wallet.ui.BalanceWidgetData
|
||||
import org.rekotlin.StateType
|
||||
|
|
@ -24,7 +25,8 @@ data class WalletState(
|
|||
val walletDialog: WalletDialog? = null,
|
||||
val updatingWallet: Boolean = false,
|
||||
val mainButton: WalletMainButton = WalletMainButton.SendButton(false),
|
||||
val topUpState: TopUpState = TopUpState()
|
||||
val topUpState: TopUpState = TopUpState(),
|
||||
val twinCardsState: TwinCardsState? = null,
|
||||
) : StateType {
|
||||
val showDetails: Boolean =
|
||||
currencyData.status != com.tangem.tap.features.wallet.ui.BalanceStatus.EmptyCard &&
|
||||
|
|
@ -45,6 +47,7 @@ sealed class WalletDialog {
|
|||
data class CreatePayIdDialog(val creatingPayIdState: CreatingPayIdState?) : WalletDialog()
|
||||
data class SelectAmountToSendDialog(val amounts: List<Amount>?) : WalletDialog()
|
||||
data class WarningDialog(val type: WarningType) : WalletDialog()
|
||||
data class TwinsOnboardingFragment(val secondCardId: String): WalletDialog()
|
||||
}
|
||||
|
||||
enum class WarningType { CardSignedHashesBefore, DevCard }
|
||||
|
|
@ -97,4 +100,10 @@ data class TopUpState(
|
|||
val allowed: Boolean = true,
|
||||
val url: String? = null,
|
||||
val redirectUrl: String? = null
|
||||
)
|
||||
|
||||
data class TwinCardsState(
|
||||
val secondCardId: String?,
|
||||
val cardNumber: TwinCardNumber?,
|
||||
val showTwinOnboarding: Boolean
|
||||
)
|
||||
|
|
@ -18,6 +18,7 @@ import com.tangem.tap.common.extensions.hide
|
|||
import com.tangem.tap.common.extensions.show
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.TwinCardNumber
|
||||
import com.tangem.tap.features.details.redux.DetailsAction
|
||||
import com.tangem.tap.features.wallet.redux.*
|
||||
import com.tangem.tap.features.wallet.ui.dialogs.AmountToSendDialog
|
||||
|
|
@ -91,6 +92,20 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
override fun newState(state: WalletState) {
|
||||
if (activity == null) return
|
||||
|
||||
state.twinCardsState?.cardNumber?.let { cardNumber ->
|
||||
tv_twin_card_number.show()
|
||||
iv_twin_card.show()
|
||||
val number = when (cardNumber) {
|
||||
TwinCardNumber.First -> "1"
|
||||
TwinCardNumber.Second -> "2"
|
||||
}
|
||||
tv_twin_card_number.text = getString(R.string.wallet_twins_chip_format, number)
|
||||
}
|
||||
if (state.twinCardsState?.cardNumber == null){
|
||||
tv_twin_card_number.hide()
|
||||
iv_twin_card.hide()
|
||||
}
|
||||
|
||||
if (!state.showDetails) {
|
||||
toolbar.menu.removeItem(R.id.details_menu)
|
||||
} else if (toolbar.menu.findItem(R.id.details_menu) == null) {
|
||||
|
|
@ -289,9 +304,10 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.details_menu -> {
|
||||
store.state.globalState.scanNoteResponse?.card?.let { card ->
|
||||
store.state.globalState.scanNoteResponse?.let { scanNoteResponse ->
|
||||
store.dispatch(DetailsAction.PrepareScreen(
|
||||
card, store.state.walletState.wallet,
|
||||
scanNoteResponse.card, scanNoteResponse,
|
||||
store.state.walletState.wallet,
|
||||
store.state.globalState.appCurrency
|
||||
))
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Details))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
package com.tangem.tap.features.wallet.ui.dialogs
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fragment_twin_cards.*
|
||||
|
||||
class TwinsOnboardingFragment : Fragment(R.layout.fragment_twin_cards) {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
|
||||
}
|
||||
})
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
enterTransition = inflater.inflateTransition(R.transition.slide_right)
|
||||
exitTransition = inflater.inflateTransition(R.transition.fade)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
store.dispatch(WalletAction.TwinsAction.SetOnboardingShown)
|
||||
|
||||
val secondCardId = store.state.walletState.twinCardsState?.secondCardId
|
||||
val text = getString(R.string.twins_onboarding_description_format, secondCardId)
|
||||
tv_twin_cards_description_1.text = text
|
||||
|
||||
setOnClickListeners()
|
||||
}
|
||||
|
||||
private fun setOnClickListeners() {
|
||||
btn_continue.setOnClickListener {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue