Updated on 2026-08-14
This commit is contained in:
parent
bcfca80f54
commit
66f7ab98e9
30 changed files with 412 additions and 442 deletions
|
|
@ -11,6 +11,7 @@ import com.tangem.tap.features.onboarding.products.otherCards.redux.OnboardingOt
|
|||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletReducer
|
||||
import com.tangem.tap.features.send.redux.reducers.SendScreenReducer
|
||||
import com.tangem.tap.features.tokens.redux.TokensReducer
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsReducer
|
||||
import com.tangem.tap.features.wallet.redux.reducers.WalletReducer
|
||||
import org.rekotlin.Action
|
||||
|
||||
|
|
@ -26,6 +27,7 @@ fun appReducer(action: Action, state: AppState?): AppState {
|
|||
onboardingWalletState = OnboardingWalletReducer.reduce(action, state),
|
||||
onboardingOtherCardsState = OnboardingOtherCardsReducer.reduce(action, state),
|
||||
walletState = WalletReducer.reduce(action, state),
|
||||
twinCardsState = TwinCardsReducer.reduce(action, state),
|
||||
sendState = SendScreenReducer.reduce(action, state.sendState),
|
||||
detailsState = DetailsReducer.reduce(action, state),
|
||||
disclaimerState = DisclaimerReducer.reduce(action, state),
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ import com.tangem.tap.features.send.redux.middlewares.SendMiddleware
|
|||
import com.tangem.tap.features.send.redux.states.SendState
|
||||
import com.tangem.tap.features.tokens.redux.TokensMiddleware
|
||||
import com.tangem.tap.features.tokens.redux.TokensState
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletMiddleware
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsMiddleware
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsState
|
||||
import com.tangem.tap.features.wallet.redux.WalletState
|
||||
import com.tangem.tap.features.wallet.redux.middlewares.WalletMiddleware
|
||||
import org.rekotlin.Middleware
|
||||
|
|
@ -36,6 +37,7 @@ data class AppState(
|
|||
val onboardingWalletState: OnboardingWalletState = OnboardingWalletState(),
|
||||
val onboardingOtherCardsState: OnboardingOtherCardsState = OnboardingOtherCardsState(),
|
||||
val walletState: WalletState = WalletState(),
|
||||
val twinCardsState: TwinCardsState = TwinCardsState(),
|
||||
val sendState: SendState = SendState(),
|
||||
val detailsState: DetailsState = DetailsState(),
|
||||
val disclaimerState: DisclaimerState = DisclaimerState(),
|
||||
|
|
@ -53,7 +55,7 @@ data class AppState(
|
|||
OnboardingWalletMiddleware.handler,
|
||||
OnboardingOtherCardsMiddleware.handler,
|
||||
WalletMiddleware().walletMiddleware,
|
||||
CreateTwinWalletMiddleware.handler,
|
||||
TwinCardsMiddleware.handler,
|
||||
SendMiddleware().sendMiddleware,
|
||||
DetailsMiddleware().detailsMiddleware,
|
||||
DisclaimerMiddleware().disclaimerMiddleware,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import com.tangem.tap.domain.tokens.CardCurrencies
|
|||
import com.tangem.tap.domain.twins.getTwinCardNumber
|
||||
import com.tangem.tap.domain.twins.isTangemTwin
|
||||
import com.tangem.tap.features.tokens.redux.TokensAction
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.features.wallet.redux.Currency
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.network.NetworkConnectivity
|
||||
|
|
@ -82,7 +83,8 @@ class TapWalletManager {
|
|||
FirebaseAnalyticsHandler.triggerEvent(AnalyticsEvent.CARD_IS_SCANNED, data.card, data.walletData?.blockchain)
|
||||
}
|
||||
store.state.globalState.feedbackManager?.infoHolder?.setCardInfo(data.card)
|
||||
updateConfigManager(data)
|
||||
val configManager = store.state.globalState.configManager
|
||||
updateConfigManager(configManager, data)
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
store.dispatch(WalletAction.ResetState)
|
||||
|
|
@ -91,7 +93,8 @@ class TapWalletManager {
|
|||
store.dispatch(WalletAction.MultiWallet.SetIsMultiwalletAllowed(data.card.isMultiwalletAllowed))
|
||||
if (data.card.isTangemTwin()) {
|
||||
data.card.getTwinCardNumber()?.let {
|
||||
store.dispatch(WalletAction.TwinsAction.SetTwinCard(null, it, true))
|
||||
val isCreatingTwinsAllowed = configManager?.config?.isCreatingTwinCardsAllowed ?: false
|
||||
store.dispatch(TwinCardsAction.SetTwinCard(it, null, isCreatingTwinsAllowed))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,8 +107,7 @@ class TapWalletManager {
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateConfigManager(data: ScanResponse) {
|
||||
val configManager = store.state.globalState.configManager
|
||||
private fun updateConfigManager(configManager: ConfigManager?, data: ScanResponse) {
|
||||
val blockchain = data.getBlockchain()
|
||||
if (data.card.isStart2Coin) {
|
||||
configManager?.turnOff(ConfigManager.isSendingToPayIdEnabled)
|
||||
|
|
@ -122,53 +124,42 @@ class TapWalletManager {
|
|||
|
||||
suspend fun loadData(data: ScanResponse) {
|
||||
withContext(Dispatchers.Main) {
|
||||
|
||||
store.dispatch(WalletAction.LoadCardInfo(data.card))
|
||||
getActionIfUnknownBlockchainOrEmptyWallet(data)?.let {
|
||||
store.dispatch(it)
|
||||
return@withContext
|
||||
}
|
||||
|
||||
when {
|
||||
data.card.isTangemTwin() && data.secondTwinPublicKey == null -> {
|
||||
store.dispatch(WalletAction.EmptyWallet)
|
||||
val config = store.state.globalState.configManager?.config ?: return@withContext
|
||||
val blockchain = data.getBlockchain()
|
||||
val primaryWalletManager = walletManagerFactory.makePrimaryWalletManager(data)
|
||||
|
||||
if (blockchain != Blockchain.Unknown && primaryWalletManager != null) {
|
||||
val primaryToken = data.getPrimaryToken()
|
||||
|
||||
store.dispatch(WalletAction.MultiWallet.SetPrimaryBlockchain(blockchain))
|
||||
if (primaryToken != null) {
|
||||
primaryWalletManager.addToken(primaryToken)
|
||||
store.dispatch(WalletAction.MultiWallet.SetPrimaryToken(primaryToken))
|
||||
}
|
||||
data.getBlockchain() == Blockchain.Unknown && !data.card.isMultiwalletAllowed -> {
|
||||
store.dispatch(WalletAction.LoadData.Failure(TapError.UnknownBlockchain))
|
||||
if (data.card.isMultiwalletAllowed) {
|
||||
loadMultiWalletData(data.card, blockchain, primaryWalletManager)
|
||||
} else {
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(primaryWalletManager))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchains(listOf(blockchain)))
|
||||
}
|
||||
data.card.wallets.isEmpty() -> {
|
||||
store.dispatch(WalletAction.EmptyWallet)
|
||||
}
|
||||
else -> {
|
||||
val config = store.state.globalState.configManager?.config ?: return@withContext
|
||||
|
||||
val blockchain = data.getBlockchain()
|
||||
val primaryWalletManager = walletManagerFactory.makePrimaryWalletManager(data)
|
||||
|
||||
if (blockchain != Blockchain.Unknown && primaryWalletManager != null) {
|
||||
val primaryToken = data.getPrimaryToken()
|
||||
|
||||
store.dispatch(WalletAction.MultiWallet.SetPrimaryBlockchain(blockchain))
|
||||
if (primaryToken != null) {
|
||||
primaryWalletManager.addToken(primaryToken)
|
||||
store.dispatch(WalletAction.MultiWallet.SetPrimaryToken(primaryToken))
|
||||
}
|
||||
if (data.card.isMultiwalletAllowed) {
|
||||
loadMultiWalletData(data.card, blockchain, primaryWalletManager)
|
||||
} else {
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(primaryWalletManager))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchains(listOf(blockchain)))
|
||||
}
|
||||
|
||||
} else {
|
||||
if (data.card.isMultiwalletAllowed) {
|
||||
loadMultiWalletData(data.card, blockchain, null)
|
||||
}
|
||||
}
|
||||
val moonPayUserStatus = store.state.globalState.moonPayUserStatus
|
||||
store.dispatch(WalletAction.LoadWallet(
|
||||
allowToBuy = config.isTopUpEnabled && moonPayUserStatus?.isBuyAllowed == true,
|
||||
allowToSell = config.isTopUpEnabled && moonPayUserStatus?.isSellAllowed == true,
|
||||
))
|
||||
store.dispatch(WalletAction.LoadFiatRate())
|
||||
} else {
|
||||
if (data.card.isMultiwalletAllowed) {
|
||||
loadMultiWalletData(data.card, blockchain, null)
|
||||
}
|
||||
}
|
||||
val moonPayUserStatus = store.state.globalState.moonPayUserStatus
|
||||
store.dispatch(WalletAction.LoadWallet(
|
||||
allowToBuy = config.isTopUpEnabled && moonPayUserStatus?.isBuyAllowed == true,
|
||||
allowToSell = config.isTopUpEnabled && moonPayUserStatus?.isSellAllowed == true,
|
||||
))
|
||||
store.dispatch(WalletAction.LoadFiatRate())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -220,28 +211,38 @@ class TapWalletManager {
|
|||
|
||||
suspend fun reloadData(data: ScanResponse) {
|
||||
withContext(Dispatchers.Main) {
|
||||
when {
|
||||
data.getBlockchain() == Blockchain.Unknown && !data.card.isMultiwalletAllowed -> {
|
||||
store.dispatch(WalletAction.LoadData.Failure(TapError.UnknownBlockchain))
|
||||
}
|
||||
data.card.wallets.isEmpty() ||
|
||||
(data.card.isTangemTwin() && data.secondTwinPublicKey == null) -> {
|
||||
store.dispatch(WalletAction.EmptyWallet)
|
||||
}
|
||||
else -> {
|
||||
if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) {
|
||||
store.dispatch(WalletAction.LoadData.Failure(TapError.NoInternetConnection))
|
||||
return@withContext
|
||||
}
|
||||
val config = store.state.globalState.configManager?.config ?: return@withContext
|
||||
val moonpayUserStatus = store.state.globalState.moonPayUserStatus
|
||||
store.dispatch(WalletAction.LoadWallet(
|
||||
allowToBuy = config.isTopUpEnabled && moonpayUserStatus?.isBuyAllowed == true,
|
||||
allowToSell = config.isTopUpEnabled && moonpayUserStatus?.isSellAllowed == true,
|
||||
))
|
||||
store.dispatch(WalletAction.LoadFiatRate())
|
||||
}
|
||||
getActionIfUnknownBlockchainOrEmptyWallet(data)?.let {
|
||||
store.dispatch(it)
|
||||
return@withContext
|
||||
}
|
||||
if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) {
|
||||
store.dispatch(WalletAction.LoadData.Failure(TapError.NoInternetConnection))
|
||||
return@withContext
|
||||
}
|
||||
|
||||
val config = store.state.globalState.configManager?.config ?: return@withContext
|
||||
val moonpayUserStatus = store.state.globalState.moonPayUserStatus
|
||||
store.dispatch(WalletAction.LoadWallet(
|
||||
allowToBuy = config.isTopUpEnabled && moonpayUserStatus?.isBuyAllowed == true,
|
||||
allowToSell = config.isTopUpEnabled && moonpayUserStatus?.isSellAllowed == true,
|
||||
))
|
||||
store.dispatch(WalletAction.LoadFiatRate())
|
||||
}
|
||||
}
|
||||
|
||||
private fun getActionIfUnknownBlockchainOrEmptyWallet(data: ScanResponse): WalletAction? {
|
||||
return when {
|
||||
// check order is important
|
||||
data.card.isTangemTwin() && !data.twinsIsTwinned() -> {
|
||||
WalletAction.EmptyWallet
|
||||
}
|
||||
data.getBlockchain() == Blockchain.Unknown && !data.card.isMultiwalletAllowed -> {
|
||||
WalletAction.LoadData.Failure(TapError.UnknownBlockchain)
|
||||
}
|
||||
data.card.wallets.isEmpty() -> {
|
||||
WalletAction.EmptyWallet
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,10 +28,13 @@ object TapWorkarounds {
|
|||
return excludedBatch || excludedIssuerName
|
||||
}
|
||||
|
||||
fun Card.isTangemNote(): Boolean = tangemNoteBatches.contains(batchId)
|
||||
fun Card.isTangemWallet(): Boolean = tangemWalletBatches.contains(batchId)
|
||||
@Deprecated("Use ScanResponse.isTangemNote")
|
||||
fun isTangemNote(card: Card): Boolean = tangemNoteBatches.contains(card.batchId)
|
||||
|
||||
fun Card.getTangemNoteBlockchain(): Blockchain? = tangemNoteBatches[batchId]
|
||||
@Deprecated("Use ScanResponse.isTangemWallet")
|
||||
fun isTangemWallet(card: Card): Boolean = tangemWalletBatches.contains(card.batchId)
|
||||
|
||||
fun getTangemNoteBlockchain(card: Card): Blockchain? = tangemNoteBatches[card.batchId]
|
||||
|
||||
private const val START_2_COIN_ISSUER = "start2coin"
|
||||
private const val TEST_CARD_BATCH = "99FF"
|
||||
|
|
@ -64,7 +67,7 @@ val DELAY_SDK_DIALOG_CLOSE = 1400L
|
|||
|
||||
val Card.isMultiwalletAllowed: Boolean
|
||||
get() {
|
||||
return !isTangemTwin() && !isStart2Coin && !isTangemNote()
|
||||
return !isTangemTwin() && !isStart2Coin && !isTangemNote(this)
|
||||
&& (firmwareVersion >= FirmwareVersion.MultiWalletAvailable ||
|
||||
getSingleWallet()?.curve == EllipticCurve.Secp256k1)
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable<ScanResponse> {
|
|||
|
||||
if (card.isTangemTwin()) {
|
||||
dealWithTwinCard(card, session, callback)
|
||||
} else if (!card.isTangemNote() && card.firmwareVersion >= FirmwareVersion.MultiWalletAvailable) {
|
||||
} else if (!isTangemNote(card) && card.firmwareVersion >= FirmwareVersion.MultiWalletAvailable) {
|
||||
createMissingWalletsIfNeeded(card, session, callback)
|
||||
} else {
|
||||
callback(CompletionResult.Success(
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ private class CreateWalletTangemNote : ProductCommandProcessor<CreateWalletRespo
|
|||
return
|
||||
}
|
||||
|
||||
val curvesSupportedByBlockchain = card.getTangemNoteBlockchain()?.getSupportedCurves()
|
||||
val curvesSupportedByBlockchain = getTangemNoteBlockchain(card)?.getSupportedCurves()
|
||||
if (curvesSupportedByBlockchain == null || curvesSupportedByBlockchain.isEmpty()) {
|
||||
callback(CompletionResult.Failure(TangemSdkError.CardError()))
|
||||
return
|
||||
|
|
|
|||
|
|
@ -19,10 +19,9 @@ import com.tangem.operations.ScanTask
|
|||
import com.tangem.operations.issuerAndUserData.ReadIssuerDataCommand
|
||||
import com.tangem.tap.domain.ProductType
|
||||
import com.tangem.tap.domain.TapSdkError
|
||||
import com.tangem.tap.domain.TapWorkarounds
|
||||
import com.tangem.tap.domain.TapWorkarounds.getTangemNoteBlockchain
|
||||
import com.tangem.tap.domain.TapWorkarounds.isExcluded
|
||||
import com.tangem.tap.domain.TapWorkarounds.isTangemNote
|
||||
import com.tangem.tap.domain.TapWorkarounds.isTangemWallet
|
||||
import com.tangem.tap.domain.extensions.getSingleWallet
|
||||
import com.tangem.tap.domain.twins.TwinsHelper
|
||||
import com.tangem.tap.domain.twins.isTangemTwin
|
||||
|
|
@ -35,7 +34,7 @@ data class ScanResponse(
|
|||
) : CommandResponse {
|
||||
|
||||
fun getBlockchain(): Blockchain {
|
||||
if (productType == ProductType.Note) return card.getTangemNoteBlockchain() ?: return Blockchain.Unknown
|
||||
if (productType == ProductType.Note) return getTangemNoteBlockchain(card) ?: return Blockchain.Unknown
|
||||
val blockchainName: String = walletData?.blockchain ?: return Blockchain.Unknown
|
||||
return Blockchain.fromId(blockchainName)
|
||||
}
|
||||
|
|
@ -51,11 +50,20 @@ data class ScanResponse(
|
|||
)
|
||||
}
|
||||
|
||||
fun isTangemNote(): Boolean = productType == ProductType.Note
|
||||
fun isTangemWallet(): Boolean = productType == ProductType.Wallet
|
||||
fun isTangemTwins(): Boolean = productType == ProductType.Twins
|
||||
fun isTangemOtherCards(): Boolean = productType == ProductType.Other
|
||||
|
||||
fun twinsIsTwinned(): Boolean {
|
||||
return walletData != null && secondTwinPublicKey != null
|
||||
return card.isTangemTwin() && walletData != null && secondTwinPublicKey != null
|
||||
}
|
||||
}
|
||||
|
||||
private fun Card.isTangemTwin(): Boolean {
|
||||
return TwinsHelper.getTwinCardNumber(cardId) != null
|
||||
}
|
||||
|
||||
class ScanProductTask(val card: Card? = null) : CardSessionRunnable<ScanResponse> {
|
||||
|
||||
override fun run(
|
||||
|
|
@ -74,9 +82,9 @@ class ScanProductTask(val card: Card? = null) : CardSessionRunnable<ScanResponse
|
|||
}
|
||||
|
||||
val commandProcessor = when {
|
||||
card.isTangemNote() -> ScanNoteProcessor()
|
||||
card.isTangemTwin() -> ScanTwinProcessor()
|
||||
card.isTangemWallet() -> ScanWalletProcessor()
|
||||
TapWorkarounds.isTangemNote(card) -> ScanNoteProcessor()
|
||||
TwinsHelper.getTwinCardNumber(card.cardId) != null -> ScanTwinProcessor()
|
||||
TapWorkarounds.isTangemWallet(card) -> ScanWalletProcessor()
|
||||
else -> ScanOtherCardsProcessor()
|
||||
}
|
||||
commandProcessor.proceed(card, session, callback)
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ enum class TwinCardNumber(val number: Int) {
|
|||
}
|
||||
}
|
||||
|
||||
@Deprecated("Use ScanResponse.isTangemTwin")
|
||||
fun Card.isTangemTwin(): Boolean {
|
||||
return TwinsHelper.getTwinCardNumber(cardId) != null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.tap.features.details.redux
|
||||
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.operations.pins.CheckUserCodesResponse
|
||||
import com.tangem.tap.common.redux.NotificationAction
|
||||
import com.tangem.tap.common.redux.global.FiatCurrencyName
|
||||
|
|
@ -14,10 +13,8 @@ import org.rekotlin.Action
|
|||
sealed class DetailsAction : Action {
|
||||
|
||||
data class PrepareScreen(
|
||||
val card: Card,
|
||||
val scanResponse: ScanResponse,
|
||||
val wallets: List<Wallet>,
|
||||
val isCreatingTwinWalletAllowed: Boolean?,
|
||||
val cardTou: CardTou,
|
||||
val fiatCurrencyName: FiatCurrencyName,
|
||||
val fiatCurrencies: List<FiatCurrencyName>? = null,
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@ import com.tangem.tap.domain.TapWorkarounds.isStart2Coin
|
|||
import com.tangem.tap.domain.extensions.isWalletDataSupported
|
||||
import com.tangem.tap.domain.extensions.signedHashesCount
|
||||
import com.tangem.tap.domain.extensions.toSendableAmounts
|
||||
import com.tangem.tap.domain.twins.getTwinCardNumber
|
||||
import com.tangem.tap.domain.twins.isTangemTwin
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletState
|
||||
import com.tangem.tap.features.wallet.models.hasPendingTransactions
|
||||
import org.rekotlin.Action
|
||||
import java.util.*
|
||||
|
|
@ -42,26 +39,12 @@ private fun internalReduce(action: Action, state: AppState): DetailsState {
|
|||
}
|
||||
|
||||
private fun handlePrepareScreen(action: DetailsAction.PrepareScreen, state: DetailsState): DetailsState {
|
||||
val twinsState = if (action.card.isTangemTwin()) {
|
||||
CreateTwinWalletState(
|
||||
scanResponse = action.scanResponse,
|
||||
twinCardNumber = action.card.getTwinCardNumber(),
|
||||
createTwinWallet = null,
|
||||
showAlert = false,
|
||||
allowRecreatingWallet = action.isCreatingTwinWalletAllowed
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
return DetailsState(
|
||||
card = action.card, wallets = action.wallets,
|
||||
cardInfo = action.card.toCardInfo(),
|
||||
appCurrencyState = AppCurrencyState(
|
||||
action.fiatCurrencyName
|
||||
),
|
||||
createTwinWalletState = twinsState,
|
||||
cardTermsOfUseUrl = action.cardTou.getUrl(action.card)
|
||||
card = action.scanResponse.card,
|
||||
wallets = action.wallets,
|
||||
cardInfo = action.scanResponse.card.toCardInfo(),
|
||||
appCurrencyState = AppCurrencyState(action.fiatCurrencyName),
|
||||
cardTermsOfUseUrl = action.cardTou.getUrl(action.scanResponse.card)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ import com.tangem.common.card.Card
|
|||
import com.tangem.tap.common.entities.Button
|
||||
import com.tangem.tap.common.entities.TapCurrency.Companion.DEFAULT_FIAT_CURRENCY
|
||||
import com.tangem.tap.common.redux.global.FiatCurrencyName
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletState
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsState
|
||||
import com.tangem.tap.network.coinmarketcap.FiatCurrency
|
||||
import com.tangem.tap.store
|
||||
import org.rekotlin.StateType
|
||||
import java.util.*
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
|
||||
data class DetailsState(
|
||||
val card: Card? = null,
|
||||
|
|
@ -19,9 +21,18 @@ data class DetailsState(
|
|||
val eraseWalletState: EraseWalletState? = null,
|
||||
val confirmScreenState: ConfirmScreenState? = null,
|
||||
val securityScreenState: SecurityScreenState? = null,
|
||||
val createTwinWalletState: CreateTwinWalletState? = null,
|
||||
val cardTermsOfUseUrl: Uri? = null,
|
||||
) : StateType
|
||||
) : StateType {
|
||||
|
||||
// if you do not delegate - the application crashes on startup,
|
||||
// because twinCardsState has not been created yet
|
||||
val twinCardsState: TwinCardsState by ReadOnlyProperty<Any, TwinCardsState> { thisRef, property ->
|
||||
store.state.twinCardsState
|
||||
}
|
||||
|
||||
val isTangemTwins: Boolean
|
||||
get() = store.state.globalState.scanResponse?.isTangemTwins() == true
|
||||
}
|
||||
|
||||
data class CardInfo(
|
||||
val cardId: String,
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ import com.tangem.tap.features.details.redux.DetailsAction
|
|||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.features.details.redux.SecurityOption
|
||||
import com.tangem.tap.features.feedback.FeedbackEmail
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWallet
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletAction
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletMode
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fragment_details.*
|
||||
|
|
@ -91,12 +91,15 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber<Det
|
|||
startActivity(intent)
|
||||
}
|
||||
|
||||
if (state.createTwinWalletState != null) {
|
||||
if (state.createTwinWalletState.allowRecreatingWallet == true) {
|
||||
if (state.isTangemTwins) {
|
||||
if (state.twinCardsState.isCreatingTwinCardsAllowed) {
|
||||
tv_erase_wallet.show()
|
||||
tv_erase_wallet.text = getText(R.string.details_row_title_twins_recreate)
|
||||
tv_erase_wallet.setOnClickListener {
|
||||
store.dispatch(CreateTwinWalletAction.ShowWarning(null, CreateTwinWallet.RecreateWallet))
|
||||
store.dispatch(TwinCardsAction.CreateWallet.Create(
|
||||
state.twinCardsState.cardNumber!!,
|
||||
CreateTwinWalletMode.RecreateWallet
|
||||
))
|
||||
}
|
||||
} else {
|
||||
tv_erase_wallet.hide()
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ import com.tangem.tap.common.extensions.withMainContext
|
|||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.twins.TwinsHelper
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.features.wallet.redux.Artwork
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -37,9 +37,9 @@ class OnboardingTwinsFragment : Fragment(R.layout.fragment_twin_cards_welcome) {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
store.dispatch(WalletAction.TwinsAction.SetOnboardingShown)
|
||||
store.dispatch(TwinCardsAction.SetOnboardingShown)
|
||||
|
||||
val secondCardId = store.state.walletState.twinCardsState?.secondCardId ?: ""
|
||||
val secondCardId = store.state.twinCardsState.secondCardId ?: ""
|
||||
val secondTwinCardId = TwinsHelper.getTwinCardIdForUser(secondCardId)
|
||||
val text = getString(R.string.twins_onboarding_description_format, secondTwinCardId)
|
||||
tv_twin_cards_description_1.text = text
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
package com.tangem.tap.features.twins.redux
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.Message
|
||||
import com.tangem.tap.common.redux.NotificationAction
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.domain.twins.TwinCardNumber
|
||||
import com.tangem.wallet.R
|
||||
import org.rekotlin.Action
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
sealed class CreateTwinWalletAction : Action {
|
||||
data class ShowWarning(
|
||||
val twinCardNumber: TwinCardNumber?,
|
||||
val createTwinWallet: CreateTwinWallet = CreateTwinWallet.RecreateWallet
|
||||
) : CreateTwinWalletAction()
|
||||
|
||||
object NotEmpty : CreateTwinWalletAction(), NotificationAction {
|
||||
override val messageResource = R.string.details_notification_erase_wallet_not_possible
|
||||
}
|
||||
|
||||
object ShowAlert : CreateTwinWalletAction()
|
||||
object HideAlert : CreateTwinWalletAction()
|
||||
object Proceed : CreateTwinWalletAction()
|
||||
|
||||
object Cancel : CreateTwinWalletAction() {
|
||||
object Confirm : CreateTwinWalletAction()
|
||||
}
|
||||
|
||||
data class LaunchFirstStep(
|
||||
val message: Message, val context: Context
|
||||
) : CreateTwinWalletAction() {
|
||||
object Success : CreateTwinWalletAction()
|
||||
object Failure : CreateTwinWalletAction()
|
||||
}
|
||||
|
||||
data class LaunchSecondStep(
|
||||
val initialMessage: Message,
|
||||
val preparingMessage: Message,
|
||||
val creatingWalletMessage: Message,
|
||||
) : CreateTwinWalletAction() {
|
||||
object Success : CreateTwinWalletAction()
|
||||
object Failure : CreateTwinWalletAction()
|
||||
}
|
||||
|
||||
data class LaunchThirdStep(val message: Message) : CreateTwinWalletAction() {
|
||||
data class Success(val scanResponse: ScanResponse) : CreateTwinWalletAction()
|
||||
object Failure : CreateTwinWalletAction()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
package com.tangem.tap.features.twins.redux
|
||||
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
|
||||
class CreateTwinWalletReducer {
|
||||
companion object {
|
||||
fun handle(
|
||||
action: CreateTwinWalletAction, state: DetailsState
|
||||
): DetailsState {
|
||||
return when (action) {
|
||||
is CreateTwinWalletAction.ShowWarning -> {
|
||||
state.copy(createTwinWalletState = CreateTwinWalletState(
|
||||
scanResponse = null,
|
||||
twinCardNumber = action.twinCardNumber
|
||||
?: state.createTwinWalletState?.twinCardNumber,
|
||||
createTwinWallet = action.createTwinWallet,
|
||||
showAlert = false,
|
||||
allowRecreatingWallet = state.createTwinWalletState?.allowRecreatingWallet
|
||||
))
|
||||
}
|
||||
CreateTwinWalletAction.NotEmpty -> state
|
||||
CreateTwinWalletAction.ShowAlert -> {
|
||||
state.copy(createTwinWalletState = state.createTwinWalletState?.copy(
|
||||
showAlert = true
|
||||
))
|
||||
}
|
||||
CreateTwinWalletAction.HideAlert -> {
|
||||
state.copy(createTwinWalletState = state.createTwinWalletState?.copy(
|
||||
showAlert = false
|
||||
))
|
||||
}
|
||||
is CreateTwinWalletAction.Proceed -> {
|
||||
state
|
||||
}
|
||||
CreateTwinWalletAction.Cancel -> state
|
||||
CreateTwinWalletAction.Cancel.Confirm -> state
|
||||
is CreateTwinWalletAction.LaunchFirstStep -> state
|
||||
|
||||
CreateTwinWalletAction.LaunchFirstStep.Success -> {
|
||||
state.copy(createTwinWalletState = state.createTwinWalletState?.copy(
|
||||
step = CreateTwinWalletStep.SecondStep
|
||||
))
|
||||
}
|
||||
CreateTwinWalletAction.LaunchFirstStep.Failure -> state
|
||||
|
||||
is CreateTwinWalletAction.LaunchSecondStep -> state
|
||||
CreateTwinWalletAction.LaunchSecondStep.Success ->
|
||||
state.copy(createTwinWalletState = state.createTwinWalletState?.copy(
|
||||
step = CreateTwinWalletStep.ThirdStep
|
||||
))
|
||||
CreateTwinWalletAction.LaunchSecondStep.Failure -> {
|
||||
state
|
||||
}
|
||||
is CreateTwinWalletAction.LaunchThirdStep -> {
|
||||
state
|
||||
}
|
||||
is CreateTwinWalletAction.LaunchThirdStep.Success -> {
|
||||
state
|
||||
}
|
||||
CreateTwinWalletAction.LaunchThirdStep.Failure -> {
|
||||
state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
package com.tangem.tap.features.twins.redux
|
||||
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.domain.twins.TwinCardNumber
|
||||
|
||||
data class CreateTwinWalletState(
|
||||
val scanResponse: ScanResponse?,
|
||||
val step: CreateTwinWalletStep = CreateTwinWalletStep.FirstStep,
|
||||
val twinCardNumber: TwinCardNumber?,
|
||||
val createTwinWallet: CreateTwinWallet?,
|
||||
val showAlert: Boolean,
|
||||
val allowRecreatingWallet: Boolean? = null
|
||||
)
|
||||
|
||||
enum class CreateTwinWalletStep { FirstStep, SecondStep, ThirdStep }
|
||||
|
||||
enum class CreateTwinWallet { CreateWallet, RecreateWallet }
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package com.tangem.tap.features.twins.redux
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.Message
|
||||
import com.tangem.tap.common.redux.NotificationAction
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.domain.twins.TwinCardNumber
|
||||
import com.tangem.wallet.R
|
||||
import org.rekotlin.Action
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
sealed class TwinCardsAction : Action {
|
||||
object ShowOnboarding : TwinCardsAction()
|
||||
object SetOnboardingShown : TwinCardsAction()
|
||||
data class SetTwinCard(
|
||||
val number: TwinCardNumber,
|
||||
val secondCardId: String?,
|
||||
val isCreatingTwinCardsAllowed: Boolean,
|
||||
) : TwinCardsAction()
|
||||
|
||||
sealed class CreateWallet : TwinCardsAction() {
|
||||
data class Create(
|
||||
val number: TwinCardNumber,
|
||||
val createTwinWalletMode: CreateTwinWalletMode
|
||||
) : CreateWallet()
|
||||
|
||||
object NotEmpty : CreateWallet(), NotificationAction {
|
||||
override val messageResource = R.string.details_notification_erase_wallet_not_possible
|
||||
}
|
||||
|
||||
object ShowAlert : CreateWallet()
|
||||
object HideAlert : CreateWallet()
|
||||
object Proceed : CreateWallet()
|
||||
|
||||
object Cancel : CreateWallet() {
|
||||
object Confirm : CreateWallet()
|
||||
}
|
||||
|
||||
data class LaunchFirstStep(
|
||||
val message: Message, val context: Context
|
||||
) : CreateWallet() {
|
||||
object Success : CreateWallet()
|
||||
object Failure : CreateWallet()
|
||||
}
|
||||
|
||||
data class LaunchSecondStep(
|
||||
val initialMessage: Message,
|
||||
val preparingMessage: Message,
|
||||
val creatingWalletMessage: Message,
|
||||
) : CreateWallet() {
|
||||
object Success : CreateWallet()
|
||||
object Failure : CreateWallet()
|
||||
}
|
||||
|
||||
data class LaunchThirdStep(val message: Message) : CreateWallet() {
|
||||
data class Success(val scanResponse: ScanResponse) : CreateWallet()
|
||||
object Failure : CreateWallet()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import com.tangem.tap.common.redux.navigation.AppScreen
|
|||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.extensions.toSendableAmounts
|
||||
import com.tangem.tap.domain.twins.TwinCardsManager
|
||||
import com.tangem.tap.preferencesStorage
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -16,7 +17,7 @@ import org.rekotlin.Action
|
|||
import org.rekotlin.DispatchFunction
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
class CreateTwinWalletMiddleware {
|
||||
class TwinCardsMiddleware {
|
||||
companion object {
|
||||
val handler = twinsWalletMiddleware
|
||||
}
|
||||
|
|
@ -34,40 +35,47 @@ private val twinsWalletMiddleware: Middleware<AppState> = { dispatch, state ->
|
|||
private var twinsManager: TwinCardsManager? = null
|
||||
|
||||
private fun handle(action: Action, dispatch: DispatchFunction) {
|
||||
val action = action as? CreateTwinWalletAction ?: return
|
||||
val action = action as? TwinCardsAction ?: return
|
||||
|
||||
val twinCardsState = store.state.twinCardsState
|
||||
when (action) {
|
||||
is CreateTwinWalletAction.ShowWarning -> {
|
||||
val wallet = store.state.detailsState.wallets.firstOrNull()
|
||||
is TwinCardsAction.SetTwinCard -> {
|
||||
val showOnboarding = !preferencesStorage.wasTwinsOnboardingShown()
|
||||
if (showOnboarding) store.dispatch(TwinCardsAction.ShowOnboarding)
|
||||
}
|
||||
TwinCardsAction.SetOnboardingShown -> {
|
||||
preferencesStorage.saveTwinsOnboardingShown()
|
||||
}
|
||||
is TwinCardsAction.CreateWallet.Create -> {
|
||||
val wallet = store.state.walletState.walletManagers.map { it.wallet }.firstOrNull()
|
||||
if (wallet == null) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWalletWarning))
|
||||
return
|
||||
}
|
||||
val notEmpty = wallet.recentTransactions.isNotEmpty() || wallet.amounts.toSendableAmounts().isNotEmpty()
|
||||
if (notEmpty) {
|
||||
store.dispatch(CreateTwinWalletAction.NotEmpty)
|
||||
store.dispatch(TwinCardsAction.CreateWallet.NotEmpty)
|
||||
} else {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWalletWarning))
|
||||
}
|
||||
}
|
||||
is CreateTwinWalletAction.Proceed ->
|
||||
is TwinCardsAction.CreateWallet.Proceed -> {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWallet))
|
||||
is CreateTwinWalletAction.Cancel -> {
|
||||
|
||||
val step = store.state.detailsState.createTwinWalletState?.step
|
||||
if (step != null && step != CreateTwinWalletStep.FirstStep
|
||||
) {
|
||||
store.dispatch(CreateTwinWalletAction.ShowAlert)
|
||||
}
|
||||
is TwinCardsAction.CreateWallet.Cancel -> {
|
||||
val step = twinCardsState.createWalletState?.step
|
||||
if (step != null && step != CreateTwinWalletStep.FirstStep) {
|
||||
store.dispatch(TwinCardsAction.CreateWallet.ShowAlert)
|
||||
} else {
|
||||
twinsManager = null
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
}
|
||||
}
|
||||
is CreateTwinWalletAction.Cancel.Confirm -> {
|
||||
is TwinCardsAction.CreateWallet.Cancel.Confirm -> {
|
||||
twinsManager = null
|
||||
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
|
||||
}
|
||||
is CreateTwinWalletAction.LaunchFirstStep -> {
|
||||
is TwinCardsAction.CreateWallet.LaunchFirstStep -> {
|
||||
store.state.globalState.scanResponse?.let {
|
||||
twinsManager = TwinCardsManager(it, action.context)
|
||||
}
|
||||
|
|
@ -76,62 +84,59 @@ private fun handle(action: Action, dispatch: DispatchFunction) {
|
|||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
SimpleResult.Success ->
|
||||
store.dispatch(CreateTwinWalletAction.LaunchFirstStep.Success)
|
||||
store.dispatch(TwinCardsAction.CreateWallet.LaunchFirstStep.Success)
|
||||
is SimpleResult.Failure ->
|
||||
store.dispatch(CreateTwinWalletAction.LaunchFirstStep.Failure)
|
||||
store.dispatch(TwinCardsAction.CreateWallet.LaunchFirstStep.Failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CreateTwinWalletAction.LaunchFirstStep.Success -> {
|
||||
TwinCardsAction.CreateWallet.LaunchFirstStep.Success -> {
|
||||
|
||||
}
|
||||
CreateTwinWalletAction.LaunchFirstStep.Failure -> {
|
||||
TwinCardsAction.CreateWallet.LaunchFirstStep.Failure -> {
|
||||
|
||||
}
|
||||
is CreateTwinWalletAction.LaunchSecondStep ->
|
||||
is TwinCardsAction.CreateWallet.LaunchSecondStep ->
|
||||
scope.launch {
|
||||
val result = twinsManager?.createSecondWallet(action.initialMessage,
|
||||
action.preparingMessage, action.creatingWalletMessage)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
SimpleResult.Success ->
|
||||
store.dispatch(CreateTwinWalletAction.LaunchSecondStep.Success)
|
||||
store.dispatch(TwinCardsAction.CreateWallet.LaunchSecondStep.Success)
|
||||
is SimpleResult.Failure ->
|
||||
store.dispatch(CreateTwinWalletAction.LaunchSecondStep.Failure)
|
||||
store.dispatch(TwinCardsAction.CreateWallet.LaunchSecondStep.Failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
CreateTwinWalletAction.LaunchSecondStep.Success -> {
|
||||
TwinCardsAction.CreateWallet.LaunchSecondStep.Success -> {
|
||||
|
||||
}
|
||||
CreateTwinWalletAction.LaunchSecondStep.Failure -> {
|
||||
TwinCardsAction.CreateWallet.LaunchSecondStep.Failure -> {
|
||||
|
||||
}
|
||||
is CreateTwinWalletAction.LaunchThirdStep -> {
|
||||
is TwinCardsAction.CreateWallet.LaunchThirdStep -> {
|
||||
scope.launch {
|
||||
val result = twinsManager?.complete(action.message)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
is Result.Success ->
|
||||
store.dispatch(
|
||||
CreateTwinWalletAction
|
||||
.LaunchThirdStep.Success(result.data)
|
||||
)
|
||||
store.dispatch(TwinCardsAction.CreateWallet.LaunchThirdStep.Success(result.data))
|
||||
is Result.Failure ->
|
||||
store.dispatch(CreateTwinWalletAction.LaunchThirdStep.Failure)
|
||||
store.dispatch(TwinCardsAction.CreateWallet.LaunchThirdStep.Failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is CreateTwinWalletAction.LaunchThirdStep.Success -> {
|
||||
is TwinCardsAction.CreateWallet.LaunchThirdStep.Success -> {
|
||||
scope.launch {
|
||||
store.state.globalState.tapWalletManager.onCardScanned(action.scanResponse)
|
||||
}
|
||||
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
CreateTwinWalletAction.LaunchThirdStep.Failure -> {
|
||||
TwinCardsAction.CreateWallet.LaunchThirdStep.Failure -> {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package com.tangem.tap.features.twins.redux
|
||||
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import org.rekotlin.Action
|
||||
|
||||
class TwinCardsReducer {
|
||||
companion object {
|
||||
fun reduce(action: Action, state: AppState): TwinCardsState = internalReduce(action, state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun internalReduce(action: Action, state: AppState): TwinCardsState {
|
||||
if (action !is TwinCardsAction) return state.twinCardsState
|
||||
|
||||
val twinCardsState = state.twinCardsState
|
||||
return when (action) {
|
||||
is TwinCardsAction.SetTwinCard -> {
|
||||
twinCardsState.copy(
|
||||
cardNumber = action.number,
|
||||
secondCardId = action.secondCardId,
|
||||
showTwinOnboarding = state.twinCardsState.showTwinOnboarding,
|
||||
isCreatingTwinCardsAllowed = action.isCreatingTwinCardsAllowed,
|
||||
)
|
||||
}
|
||||
is TwinCardsAction.ShowOnboarding -> {
|
||||
state.twinCardsState.copy(showTwinOnboarding = true)
|
||||
}
|
||||
is TwinCardsAction.SetOnboardingShown -> {
|
||||
twinCardsState.copy(showTwinOnboarding = false)
|
||||
}
|
||||
is TwinCardsAction.CreateWallet.Create -> {
|
||||
val prevState = twinCardsState.createWalletState
|
||||
twinCardsState.copy(createWalletState = CreateTwinWalletState(
|
||||
prevState?.scanResponse,
|
||||
prevState?.number ?: action.number,
|
||||
prevState?.mode ?: action.createTwinWalletMode,
|
||||
))
|
||||
}
|
||||
TwinCardsAction.CreateWallet.LaunchFirstStep.Success -> {
|
||||
twinCardsState.copy(createWalletState = twinCardsState.createWalletState?.copy(
|
||||
step = CreateTwinWalletStep.SecondStep
|
||||
))
|
||||
}
|
||||
TwinCardsAction.CreateWallet.LaunchSecondStep.Success ->
|
||||
twinCardsState.copy(createWalletState = twinCardsState.createWalletState?.copy(
|
||||
step = CreateTwinWalletStep.ThirdStep
|
||||
))
|
||||
TwinCardsAction.CreateWallet.ShowAlert -> twinCardsState
|
||||
TwinCardsAction.CreateWallet.HideAlert -> twinCardsState
|
||||
is TwinCardsAction.CreateWallet.Proceed -> twinCardsState
|
||||
TwinCardsAction.CreateWallet.NotEmpty -> twinCardsState
|
||||
TwinCardsAction.CreateWallet.Cancel -> twinCardsState
|
||||
TwinCardsAction.CreateWallet.Cancel.Confirm -> twinCardsState
|
||||
is TwinCardsAction.CreateWallet.LaunchFirstStep -> twinCardsState
|
||||
TwinCardsAction.CreateWallet.LaunchFirstStep.Failure -> twinCardsState
|
||||
is TwinCardsAction.CreateWallet.LaunchSecondStep -> twinCardsState
|
||||
TwinCardsAction.CreateWallet.LaunchSecondStep.Failure -> twinCardsState
|
||||
is TwinCardsAction.CreateWallet.LaunchThirdStep -> twinCardsState
|
||||
is TwinCardsAction.CreateWallet.LaunchThirdStep.Success -> twinCardsState
|
||||
TwinCardsAction.CreateWallet.LaunchThirdStep.Failure -> twinCardsState
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.tangem.tap.features.twins.redux
|
||||
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.domain.twins.TwinCardNumber
|
||||
import org.rekotlin.StateType
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
data class TwinCardsState(
|
||||
// if cardNumber is not set -> the scanned card is not Twin
|
||||
val cardNumber: TwinCardNumber? = null,
|
||||
val secondCardId: String? = null,
|
||||
val showTwinOnboarding: Boolean = false,
|
||||
val isCreatingTwinCardsAllowed: Boolean = false,
|
||||
val createWalletState: CreateTwinWalletState? = null
|
||||
) : StateType {
|
||||
val isReadyToUse: Boolean
|
||||
get() = cardNumber != null
|
||||
}
|
||||
|
||||
data class CreateTwinWalletState(
|
||||
val scanResponse: ScanResponse?,
|
||||
val number: TwinCardNumber = TwinCardNumber.First,
|
||||
val mode: CreateTwinWalletMode = CreateTwinWalletMode.CreateWallet,
|
||||
val step: CreateTwinWalletStep = CreateTwinWalletStep.FirstStep,
|
||||
) {
|
||||
val showAlert: Boolean
|
||||
get() = mode != CreateTwinWalletMode.RecreateWallet
|
||||
}
|
||||
|
||||
enum class CreateTwinWalletStep { FirstStep, SecondStep, ThirdStep }
|
||||
|
||||
enum class CreateTwinWalletMode { CreateWallet, RecreateWallet }
|
||||
|
|
@ -11,10 +11,10 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|||
import com.squareup.picasso.Picasso
|
||||
import com.tangem.Message
|
||||
import com.tangem.tap.domain.twins.TwinCardNumber
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWallet
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletAction
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletMode
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletStep
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsState
|
||||
import com.tangem.tap.features.wallet.redux.Artwork
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -22,7 +22,7 @@ import kotlinx.android.synthetic.main.fragment_twin_cards_create.*
|
|||
import org.rekotlin.StoreSubscriber
|
||||
|
||||
class CreateTwinWalletFragment : Fragment(R.layout.fragment_twin_cards_create),
|
||||
StoreSubscriber<DetailsState> {
|
||||
StoreSubscriber<TwinCardsState> {
|
||||
|
||||
private var dialog: Dialog? = null
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_twin_cards_create),
|
|||
super.onCreate(savedInstanceState)
|
||||
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
store.dispatch(CreateTwinWalletAction.Cancel)
|
||||
store.dispatch(TwinCardsAction.CreateWallet.Cancel)
|
||||
}
|
||||
})
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
|
|
@ -42,8 +42,8 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_twin_cards_create),
|
|||
super.onStart()
|
||||
store.subscribe(this) { state ->
|
||||
state.skipRepeats { oldState, newState ->
|
||||
oldState.detailsState == newState.detailsState
|
||||
}.select { it.detailsState }
|
||||
oldState.twinCardsState == newState.twinCardsState
|
||||
}.select { it.twinCardsState }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_twin_cards_create),
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
toolbar.setNavigationOnClickListener {
|
||||
store.dispatch(CreateTwinWalletAction.Cancel)
|
||||
store.dispatch(TwinCardsAction.CreateWallet.Cancel)
|
||||
}
|
||||
|
||||
Picasso.get()
|
||||
|
|
@ -73,21 +73,21 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_twin_cards_create),
|
|||
}
|
||||
|
||||
|
||||
override fun newState(state: DetailsState) {
|
||||
override fun newState(state: TwinCardsState) {
|
||||
if (activity == null) return
|
||||
|
||||
toolbar.title = when (state.createTwinWalletState?.createTwinWallet) {
|
||||
CreateTwinWallet.CreateWallet -> getText(R.string.wallet_button_create_wallet)
|
||||
CreateTwinWallet.RecreateWallet, null -> getText(R.string.details_twins_recreate_toolbar)
|
||||
toolbar.title = when (state.createWalletState?.mode) {
|
||||
CreateTwinWalletMode.CreateWallet -> getText(R.string.wallet_button_create_wallet)
|
||||
CreateTwinWalletMode.RecreateWallet, null -> getText(R.string.details_twins_recreate_toolbar)
|
||||
|
||||
}
|
||||
|
||||
val selectedColor = getColor(requireContext(), R.color.colorSecondary)
|
||||
val defaultColor = getColor(requireContext(), R.color.blue_pale)
|
||||
|
||||
val twinCardNumber = state.createTwinWalletState?.twinCardNumber ?: TwinCardNumber.First
|
||||
val twinCardNumber = state.createWalletState?.number ?: TwinCardNumber.First
|
||||
|
||||
val cardNumber = when (state.createTwinWalletState?.step) {
|
||||
val cardNumber = when (state.createWalletState?.step) {
|
||||
CreateTwinWalletStep.FirstStep -> {
|
||||
val twinCardNumberString = twinCardNumber.number.toString()
|
||||
tv_step_number.text =
|
||||
|
|
@ -96,7 +96,7 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_twin_cards_create),
|
|||
v_step_2.setBackgroundColor(defaultColor)
|
||||
v_step_3.setBackgroundColor(defaultColor)
|
||||
btn_tap.setOnClickListener {
|
||||
store.dispatch(CreateTwinWalletAction.LaunchFirstStep(
|
||||
store.dispatch(TwinCardsAction.CreateWallet.LaunchFirstStep(
|
||||
Message(getString(
|
||||
R.string.details_twins_recreate_title_format,
|
||||
twinCardNumberString
|
||||
|
|
@ -117,7 +117,7 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_twin_cards_create),
|
|||
v_step_2.setBackgroundColor(selectedColor)
|
||||
v_step_3.setBackgroundColor(defaultColor)
|
||||
btn_tap.setOnClickListener {
|
||||
store.dispatch(CreateTwinWalletAction.LaunchSecondStep(
|
||||
store.dispatch(TwinCardsAction.CreateWallet.LaunchSecondStep(
|
||||
Message(getString(R.string.details_twins_recreate_title_format, twinCardNumberString)),
|
||||
Message(getString(R.string.details_twins_recreate_title_preparing)),
|
||||
Message(getString(R.string.details_twins_recreate_title_creating_wallet)),
|
||||
|
|
@ -135,7 +135,7 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_twin_cards_create),
|
|||
v_step_2.setBackgroundColor(selectedColor)
|
||||
v_step_3.setBackgroundColor(selectedColor)
|
||||
btn_tap.setOnClickListener {
|
||||
store.dispatch(CreateTwinWalletAction.LaunchThirdStep(
|
||||
store.dispatch(TwinCardsAction.CreateWallet.LaunchThirdStep(
|
||||
Message(getString(
|
||||
R.string.details_twins_recreate_title_format, twinCardNumberString)
|
||||
)
|
||||
|
|
@ -149,18 +149,18 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_twin_cards_create),
|
|||
btn_tap.text = getString(R.string.details_twins_recreate_button_format, cardNumber)
|
||||
tv_twin_title.text = getString(R.string.details_twins_recreate_title_format, cardNumber)
|
||||
|
||||
if (state.createTwinWalletState?.showAlert == true) {
|
||||
if (state.createWalletState?.showAlert == true) {
|
||||
if (dialog == null) {
|
||||
dialog = MaterialAlertDialogBuilder(requireContext())
|
||||
.setMessage(R.string.details_twins_recreate_alert)
|
||||
.setPositiveButton(R.string.common_ok) { _, _ ->
|
||||
store.dispatch(CreateTwinWalletAction.Cancel.Confirm)
|
||||
store.dispatch(TwinCardsAction.CreateWallet.Cancel.Confirm)
|
||||
}
|
||||
.setNegativeButton(R.string.common_cancel) { _, _ ->
|
||||
dialog?.cancel()
|
||||
}
|
||||
.setOnCancelListener {
|
||||
store.dispatch(CreateTwinWalletAction.HideAlert)
|
||||
store.dispatch(TwinCardsAction.CreateWallet.HideAlert)
|
||||
}
|
||||
.create()
|
||||
dialog?.show()
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import androidx.fragment.app.Fragment
|
|||
import androidx.transition.TransitionInflater
|
||||
import com.squareup.picasso.Picasso
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWallet
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletAction
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletMode
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.features.wallet.redux.Artwork
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -31,15 +31,15 @@ class TwinWalletWarningFragment : Fragment(R.layout.fragment_twin_cards_warning)
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val createTwinWallet = store.state.detailsState.createTwinWalletState?.createTwinWallet
|
||||
if (createTwinWallet == CreateTwinWallet.CreateWallet) {
|
||||
val createTwinWallet = store.state.twinCardsState.createWalletState?.mode
|
||||
if (createTwinWallet == CreateTwinWalletMode.CreateWallet) {
|
||||
tv_twin_cards_description.text = getText(R.string.details_twins_recreate_subtitle)
|
||||
} else if (createTwinWallet == CreateTwinWallet.RecreateWallet) {
|
||||
} else if (createTwinWallet == CreateTwinWalletMode.RecreateWallet) {
|
||||
tv_twin_cards_description.text = getText(R.string.details_twins_recreate_warning)
|
||||
}
|
||||
|
||||
btn_cancel.setOnClickListener { store.dispatch(NavigationAction.PopBackTo()) }
|
||||
btn_start.setOnClickListener { store.dispatch(CreateTwinWalletAction.Proceed) }
|
||||
btn_start.setOnClickListener { store.dispatch(TwinCardsAction.CreateWallet.Proceed) }
|
||||
Picasso.get()
|
||||
.load(Artwork.TWIN_CARD_1)
|
||||
.placeholder(R.drawable.card_placeholder)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import com.tangem.tap.common.redux.NotificationAction
|
|||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
|
||||
import com.tangem.tap.domain.tokens.CardCurrencies
|
||||
import com.tangem.tap.domain.twins.TwinCardNumber
|
||||
import com.tangem.wallet.R
|
||||
import org.rekotlin.Action
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -147,12 +146,4 @@ 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,
|
||||
val isCreatingTwinCardsAllowed: Boolean,
|
||||
) : TwinsAction()
|
||||
}
|
||||
}
|
||||
|
|
@ -12,39 +12,49 @@ import com.tangem.tap.common.toggleWidget.WidgetState
|
|||
import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
|
||||
import com.tangem.tap.domain.extensions.toSendableAmounts
|
||||
import com.tangem.tap.domain.topup.TradeCryptoHelper
|
||||
import com.tangem.tap.domain.twins.TwinCardNumber
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsState
|
||||
import com.tangem.tap.features.wallet.models.PendingTransaction
|
||||
import com.tangem.tap.features.wallet.models.toPendingTransactions
|
||||
import com.tangem.tap.features.wallet.models.toPendingTransactionsForToken
|
||||
import com.tangem.tap.features.wallet.ui.BalanceStatus
|
||||
import com.tangem.tap.features.wallet.ui.BalanceWidgetData
|
||||
import com.tangem.tap.store
|
||||
import org.rekotlin.StateType
|
||||
import java.math.BigDecimal
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
|
||||
data class WalletState(
|
||||
val state: ProgressState = ProgressState.Done,
|
||||
val error: ErrorType? = null,
|
||||
val cardImage: Artwork? = null,
|
||||
val hashesCountVerified: Boolean? = null,
|
||||
val walletDialog: StateDialog? = null,
|
||||
val twinCardsState: TwinCardsState? = null,
|
||||
val mainWarningsList: List<WarningMessage> = mutableListOf(),
|
||||
val wallets: List<WalletData> = emptyList(),
|
||||
val walletManagers: List<WalletManager> = emptyList(),
|
||||
val isMultiwalletAllowed: Boolean = false,
|
||||
val cardCurrency: CryptoCurrencyName? = null,
|
||||
val selectedWallet: Currency? = null,
|
||||
val primaryBlockchain: Blockchain? = null,
|
||||
val primaryToken: Token? = null,
|
||||
val isTestnet: Boolean = false,
|
||||
val tradeCryptoAllowed: TradeCryptoAvailability = TradeCryptoAvailability()
|
||||
val state: ProgressState = ProgressState.Done,
|
||||
val error: ErrorType? = null,
|
||||
val cardImage: Artwork? = null,
|
||||
val hashesCountVerified: Boolean? = null,
|
||||
val walletDialog: StateDialog? = null,
|
||||
val mainWarningsList: List<WarningMessage> = mutableListOf(),
|
||||
val wallets: List<WalletData> = emptyList(),
|
||||
val walletManagers: List<WalletManager> = emptyList(),
|
||||
val isMultiwalletAllowed: Boolean = false,
|
||||
val cardCurrency: CryptoCurrencyName? = null,
|
||||
val selectedWallet: Currency? = null,
|
||||
val primaryBlockchain: Blockchain? = null,
|
||||
val primaryToken: Token? = null,
|
||||
val isTestnet: Boolean = false,
|
||||
val tradeCryptoAllowed: TradeCryptoAvailability = TradeCryptoAvailability()
|
||||
) : StateType {
|
||||
|
||||
// if you do not delegate - the application crashes on startup,
|
||||
// because twinCardsState has not been created yet
|
||||
val twinCardsState: TwinCardsState by ReadOnlyProperty<Any, TwinCardsState> { thisRef, property ->
|
||||
store.state.twinCardsState
|
||||
}
|
||||
|
||||
val isTangemTwins: Boolean
|
||||
get() = store.state.globalState.scanResponse?.isTangemTwins() == true
|
||||
|
||||
val primaryWallet = if (wallets.isNotEmpty()) wallets[0] else null
|
||||
|
||||
val shouldShowDetails: Boolean =
|
||||
primaryWallet?.currencyData?.status != com.tangem.tap.features.wallet.ui.BalanceStatus.EmptyCard &&
|
||||
primaryWallet?.currencyData?.status != com.tangem.tap.features.wallet.ui.BalanceStatus.UnknownBlockchain
|
||||
primaryWallet?.currencyData?.status != BalanceStatus.EmptyCard &&
|
||||
primaryWallet?.currencyData?.status != BalanceStatus.UnknownBlockchain
|
||||
|
||||
val blockchains: List<Blockchain>
|
||||
get() = walletManagers.map { it.wallet.blockchain }
|
||||
|
|
@ -57,16 +67,16 @@ data class WalletState(
|
|||
return walletManagers.find { it.wallet.blockchain == token.blockchain }
|
||||
}
|
||||
|
||||
fun getWalletManager(currency: Currency?) : WalletManager? {
|
||||
fun getWalletManager(currency: Currency?): WalletManager? {
|
||||
if (currency?.blockchain == null) return null
|
||||
return walletManagers.find { it.wallet.blockchain == currency.blockchain }
|
||||
}
|
||||
|
||||
fun getWalletManager(blockchain: Blockchain) : WalletManager? {
|
||||
fun getWalletManager(blockchain: Blockchain): WalletManager? {
|
||||
return walletManagers.find { it.wallet.blockchain == blockchain }
|
||||
}
|
||||
|
||||
fun getWalletData(currency: Currency?) : WalletData? {
|
||||
fun getWalletData(currency: Currency?): WalletData? {
|
||||
if (currency == null) return null
|
||||
return wallets.find { it.currency == currency }
|
||||
}
|
||||
|
|
@ -93,7 +103,7 @@ data class WalletState(
|
|||
?: return true
|
||||
|
||||
if (walletData.currency is Currency.Blockchain &&
|
||||
walletManager.cardTokens.isNotEmpty()
|
||||
walletManager.cardTokens.isNotEmpty()
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
|
@ -105,9 +115,9 @@ data class WalletState(
|
|||
wallet.amounts.toSendableAmounts().isEmpty()
|
||||
} else if (walletData.currency is Currency.Token) (
|
||||
return wallet.recentTransactions.toPendingTransactionsForToken(
|
||||
walletData.currency.token, wallet.address).isEmpty()
|
||||
walletData.currency.token, wallet.address).isEmpty()
|
||||
&& wallet.amounts[AmountType.Token(token = walletData.currency.token)]
|
||||
?.isAboveZero() != true
|
||||
?.isAboveZero() != true
|
||||
)
|
||||
}
|
||||
return false
|
||||
|
|
@ -137,9 +147,9 @@ data class WalletState(
|
|||
}
|
||||
}
|
||||
|
||||
sealed class WalletDialog: StateDialog {
|
||||
sealed class WalletDialog : StateDialog {
|
||||
data class QrDialog(
|
||||
val qrCode: Bitmap?, val shareUrl: String?, val currencyName: CryptoCurrencyName?
|
||||
val qrCode: Bitmap?, val shareUrl: String?, val currencyName: CryptoCurrencyName?
|
||||
) : WalletDialog()
|
||||
|
||||
data class SelectAmountToSendDialog(val amounts: List<Amount>?) : WalletDialog()
|
||||
|
|
@ -147,7 +157,7 @@ sealed class WalletDialog: StateDialog {
|
|||
object ChooseTradeActionDialog : WalletDialog()
|
||||
}
|
||||
|
||||
enum class ProgressState: WidgetState { Loading, Done, Error }
|
||||
enum class ProgressState : WidgetState { Loading, Done, Error }
|
||||
|
||||
enum class ErrorType { NoInternetConnection }
|
||||
|
||||
|
|
@ -157,22 +167,22 @@ sealed class WalletMainButton(enabled: Boolean) : Button(enabled) {
|
|||
}
|
||||
|
||||
data class WalletAddresses(
|
||||
val selectedAddress: AddressData,
|
||||
val list: List<AddressData>
|
||||
val selectedAddress: AddressData,
|
||||
val list: List<AddressData>
|
||||
)
|
||||
|
||||
data class AddressData(
|
||||
val address: String,
|
||||
val type: AddressType,
|
||||
val shareUrl: String,
|
||||
val exploreUrl: String,
|
||||
val address: String,
|
||||
val type: AddressType,
|
||||
val shareUrl: String,
|
||||
val exploreUrl: String,
|
||||
) {
|
||||
val qrCode: Bitmap by lazy { shareUrl.toQrCode() }
|
||||
}
|
||||
|
||||
data class Artwork(
|
||||
val artworkId: String,
|
||||
val artwork: Bitmap? = null
|
||||
val artworkId: String,
|
||||
val artwork: Bitmap? = null
|
||||
) {
|
||||
companion object {
|
||||
const val DEFAULT_IMG_URL = "https://app.tangem.com/cards/card_default.png"
|
||||
|
|
@ -198,13 +208,6 @@ data class TradeCryptoAvailability(
|
|||
val availableToSell: Set<String> = TradeCryptoHelper.AVAILABLE_TO_SELL,
|
||||
)
|
||||
|
||||
data class TwinCardsState(
|
||||
val secondCardId: String?,
|
||||
val cardNumber: TwinCardNumber?,
|
||||
val showTwinOnboarding: Boolean,
|
||||
val isCreatingTwinCardsAllowed: Boolean
|
||||
)
|
||||
|
||||
data class WalletData(
|
||||
val pendingTransactions: List<PendingTransaction> = emptyList(),
|
||||
val hashesCountVerified: Boolean? = null,
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
package com.tangem.tap.features.wallet.redux.middlewares
|
||||
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.preferencesStorage
|
||||
import com.tangem.tap.store
|
||||
|
||||
class TwinsMiddleware {
|
||||
fun handle(action: WalletAction.TwinsAction) {
|
||||
when (action) {
|
||||
is WalletAction.TwinsAction.SetTwinCard -> {
|
||||
val showOnboarding = !preferencesStorage.wasTwinsOnboardingShown()
|
||||
if (showOnboarding) store.dispatch(WalletAction.TwinsAction.ShowOnboarding)
|
||||
}
|
||||
WalletAction.TwinsAction.SetOnboardingShown -> {
|
||||
preferencesStorage.saveTwinsOnboardingShown()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,11 +17,10 @@ import com.tangem.tap.common.redux.global.GlobalAction
|
|||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.extensions.toSendableAmounts
|
||||
import com.tangem.tap.domain.twins.TwinsHelper
|
||||
import com.tangem.tap.features.home.redux.HomeAction
|
||||
import com.tangem.tap.features.send.redux.PrepareSendScreen
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWallet
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletAction
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletMode
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.features.wallet.redux.*
|
||||
import com.tangem.tap.network.NetworkStateChanged
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -31,7 +30,6 @@ import org.rekotlin.Middleware
|
|||
|
||||
class WalletMiddleware {
|
||||
private val tradeCryptoMiddleware = TradeCryptoMiddleware()
|
||||
private val twinsMiddleware = TwinsMiddleware()
|
||||
private val warningsMiddleware = WarningsMiddleware()
|
||||
private val multiWalletMiddleware = MultiWalletMiddleware()
|
||||
|
||||
|
|
@ -50,7 +48,6 @@ class WalletMiddleware {
|
|||
|
||||
when (action) {
|
||||
is WalletAction.TradeCryptoAction -> tradeCryptoMiddleware.handle(action)
|
||||
is WalletAction.TwinsAction -> twinsMiddleware.handle(action)
|
||||
is WalletAction.Warnings -> warningsMiddleware.handle(action, globalState)
|
||||
is WalletAction.MultiWallet -> multiWalletMiddleware.handle(action, walletState, globalState)
|
||||
is WalletAction.LoadWallet -> {
|
||||
|
|
@ -99,12 +96,11 @@ class WalletMiddleware {
|
|||
}
|
||||
}
|
||||
is WalletAction.CreateWallet -> {
|
||||
if (walletState.twinCardsState != null) {
|
||||
val cardId = globalState.scanResponse?.card?.cardId
|
||||
val twinCardNumber = cardId?.let { TwinsHelper.getTwinCardNumber(it) }
|
||||
store.dispatch(
|
||||
CreateTwinWalletAction.ShowWarning(twinCardNumber, CreateTwinWallet.CreateWallet)
|
||||
)
|
||||
if (walletState.isTangemTwins) {
|
||||
store.dispatch(TwinCardsAction.CreateWallet.Create(
|
||||
walletState.twinCardsState.cardNumber!!,
|
||||
CreateTwinWalletMode.CreateWallet
|
||||
))
|
||||
} else {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.createWallet(
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
package com.tangem.tap.features.wallet.redux.reducers
|
||||
|
||||
import com.tangem.tap.features.wallet.redux.TwinCardsState
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletState
|
||||
|
||||
class TwinsReducer {
|
||||
fun reduce(action: WalletAction.TwinsAction, state: WalletState): WalletState {
|
||||
return when (action) {
|
||||
is WalletAction.TwinsAction.SetTwinCard -> {
|
||||
state.copy(
|
||||
twinCardsState = TwinCardsState(
|
||||
secondCardId = action.secondCardId,
|
||||
cardNumber = action.number,
|
||||
showTwinOnboarding = state.twinCardsState?.showTwinOnboarding
|
||||
?: false,
|
||||
isCreatingTwinCardsAllowed = action.isCreatingTwinCardsAllowed
|
||||
)
|
||||
)
|
||||
}
|
||||
is WalletAction.TwinsAction.ShowOnboarding -> {
|
||||
state.copy(
|
||||
twinCardsState = state.twinCardsState?.copy(showTwinOnboarding = true)
|
||||
?: TwinCardsState(null, null,
|
||||
showTwinOnboarding = true,
|
||||
isCreatingTwinCardsAllowed = false)
|
||||
)
|
||||
}
|
||||
is WalletAction.TwinsAction.SetOnboardingShown -> {
|
||||
state.copy(
|
||||
twinCardsState = state.twinCardsState?.copy(showTwinOnboarding = false)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,6 @@ class WalletReducer {
|
|||
private fun internalReduce(action: Action, state: AppState): WalletState {
|
||||
|
||||
val multiWalletReducer = MultiWalletReducer()
|
||||
val twinsReducer = TwinsReducer()
|
||||
val onWalletLoadedReducer = OnWalletLoadedReducer()
|
||||
|
||||
if (action !is WalletAction) return state.walletState
|
||||
|
|
@ -34,15 +33,12 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
|
||||
when (action) {
|
||||
is WalletAction.Warnings -> newState = handleCheckSignedHashesActions(action, newState)
|
||||
is WalletAction.TwinsAction -> newState = twinsReducer.reduce(action, newState)
|
||||
is WalletAction.MultiWallet -> newState = multiWalletReducer.reduce(action, newState)
|
||||
|
||||
is WalletAction.ResetState -> newState = WalletState()
|
||||
is WalletAction.SetIfTestnetCard -> newState = newState.copy(isTestnet = action.isTestnet)
|
||||
is WalletAction.EmptyWallet -> {
|
||||
val creatingWalletAllowed = !(newState.twinCardsState != null &&
|
||||
newState.twinCardsState?.isCreatingTwinCardsAllowed != true)
|
||||
|
||||
val creatingWalletAllowed = state.twinCardsState.isCreatingTwinCardsAllowed
|
||||
newState = newState.copy(
|
||||
state = ProgressState.Done,
|
||||
wallets = listOf(
|
||||
|
|
@ -215,7 +211,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
newState = setNewFiatRate(action.fiatRate, state.globalState.appCurrency, newState)
|
||||
is WalletAction.LoadArtwork -> {
|
||||
val artworkUrl = action.card.getArtworkUrl(action.artworkId)
|
||||
?: when (newState.twinCardsState?.cardNumber) {
|
||||
?: when (state.twinCardsState.cardNumber) {
|
||||
TwinCardNumber.First -> Artwork.TWIN_CARD_1
|
||||
TwinCardNumber.Second -> Artwork.TWIN_CARD_2
|
||||
else -> Artwork.DEFAULT_IMG_URL
|
||||
|
|
|
|||
|
|
@ -135,8 +135,8 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
if (state.error == ErrorType.NoInternetConnection) {
|
||||
srl_wallet_details?.isRefreshing = false
|
||||
(activity as? MainActivity)?.showSnackbar(
|
||||
text = R.string.wallet_notification_no_internet,
|
||||
buttonTitle = R.string.common_retry
|
||||
text = R.string.wallet_notification_no_internet,
|
||||
buttonTitle = R.string.common_retry
|
||||
) { store.dispatch(WalletAction.LoadData) }
|
||||
}
|
||||
} else {
|
||||
|
|
@ -158,11 +158,10 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
store.dispatch(GlobalAction.UpdateFeedbackInfo(store.state.walletState.walletManagers))
|
||||
store.state.globalState.scanResponse?.let { scanNoteResponse ->
|
||||
store.dispatch(DetailsAction.PrepareScreen(
|
||||
scanNoteResponse.card, scanNoteResponse,
|
||||
store.state.walletState.walletManagers.map { it.wallet },
|
||||
store.state.globalState.configManager?.config?.isCreatingTwinCardsAllowed,
|
||||
CardTou(),
|
||||
store.state.globalState.appCurrency
|
||||
scanNoteResponse,
|
||||
store.state.walletState.walletManagers.map { it.wallet },
|
||||
CardTou(),
|
||||
store.state.globalState.appCurrency
|
||||
))
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Details))
|
||||
true
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.tap.common.redux.StateDialog
|
|||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.twins.TwinCardNumber
|
||||
import com.tangem.tap.features.twins.redux.TwinCardsState
|
||||
import com.tangem.tap.features.wallet.models.PendingTransaction
|
||||
import com.tangem.tap.features.wallet.redux.*
|
||||
import com.tangem.tap.features.wallet.ui.BalanceWidget
|
||||
|
|
@ -71,7 +72,7 @@ class SingleWalletView : WalletView {
|
|||
state.primaryWallet ?: return
|
||||
|
||||
setupTwinCards(state.twinCardsState, fragment)
|
||||
setupButtons(state.primaryWallet, state.twinCardsState != null, fragment)
|
||||
setupButtons(state.primaryWallet, state.isTangemTwins, fragment)
|
||||
setupAddressCard(state.primaryWallet, fragment)
|
||||
showPendingTransactionsIfPresent(state.primaryWallet.pendingTransactions)
|
||||
setupBalance(state, state.primaryWallet)
|
||||
|
|
@ -87,7 +88,7 @@ class SingleWalletView : WalletView {
|
|||
private fun setupBalance(state: WalletState, primaryWallet: WalletData) {
|
||||
fragment?.apply {
|
||||
this.l_balance.show()
|
||||
BalanceWidget(this, primaryWallet.currencyData, state.twinCardsState != null).setup()
|
||||
BalanceWidget(this, primaryWallet.currencyData, state.isTangemTwins).setup()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue