Updated on 2026-08-14
This commit is contained in:
parent
5ec60f0cce
commit
7379f3555a
23 changed files with 429 additions and 402 deletions
|
|
@ -10,26 +10,26 @@ import com.tangem.tap.common.redux.navigation.FragmentShareTransition
|
|||
import com.tangem.tap.features.details.ui.DetailsConfirmFragment
|
||||
import com.tangem.tap.features.details.ui.DetailsFragment
|
||||
import com.tangem.tap.features.details.ui.DetailsSecurityFragment
|
||||
import com.tangem.tap.features.details.ui.twins.CreateTwinWalletFragment
|
||||
import com.tangem.tap.features.details.ui.twins.TwinWalletWarningFragment
|
||||
import com.tangem.tap.features.details.ui.walletconnect.QrScanFragment
|
||||
import com.tangem.tap.features.details.ui.walletconnect.WalletConnectSessionsFragment
|
||||
import com.tangem.tap.features.disclaimer.ui.DisclaimerFragment
|
||||
import com.tangem.tap.features.home.HomeFragment
|
||||
import com.tangem.tap.features.onboarding.products.note.OnboardingNoteFragment
|
||||
import com.tangem.tap.features.onboarding.products.otherCards.OnboardingOtherCardsFragment
|
||||
import com.tangem.tap.features.onboarding.products.twins.OnboardingTwinsFragment
|
||||
import com.tangem.tap.features.onboarding.products.wallet.OnboardingWalletFragment
|
||||
import com.tangem.tap.features.send.ui.SendFragment
|
||||
import com.tangem.tap.features.tokens.ui.AddTokensFragment
|
||||
import com.tangem.tap.features.wallet.ui.OnboardingTwinsFragment
|
||||
import com.tangem.tap.features.twins.ui.CreateTwinWalletFragment
|
||||
import com.tangem.tap.features.twins.ui.TwinWalletWarningFragment
|
||||
import com.tangem.tap.features.wallet.ui.WalletDetailsFragment
|
||||
import com.tangem.tap.features.wallet.ui.WalletFragment
|
||||
import com.tangem.wallet.R
|
||||
|
||||
fun FragmentActivity.openFragment(
|
||||
screen: AppScreen,
|
||||
addToBackstack: Boolean,
|
||||
fgShareTransition: FragmentShareTransition? = null
|
||||
screen: AppScreen,
|
||||
addToBackstack: Boolean,
|
||||
fgShareTransition: FragmentShareTransition? = null
|
||||
) {
|
||||
val transaction = this.supportFragmentManager.beginTransaction()
|
||||
val fragment = fragmentFactory(screen)
|
||||
|
|
@ -60,8 +60,8 @@ fun FragmentActivity.getPreviousScreen(): AppScreen? {
|
|||
}
|
||||
|
||||
fun FragmentActivity.addOnBackPressedDispatcher(
|
||||
isEnabled: Boolean = true,
|
||||
onBackPressed: VoidCallback
|
||||
isEnabled: Boolean = true,
|
||||
onBackPressed: VoidCallback
|
||||
): OnBackPressedCallback = (object : OnBackPressedCallback(isEnabled) {
|
||||
override fun handleOnBackPressed() {
|
||||
onBackPressed()
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ 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.wallet.redux.WalletState
|
||||
import com.tangem.tap.features.wallet.redux.middlewares.WalletMiddleware
|
||||
import org.rekotlin.Middleware
|
||||
|
|
@ -45,18 +46,19 @@ data class AppState(
|
|||
companion object {
|
||||
fun getMiddleware(): List<Middleware<AppState>> {
|
||||
return listOf(
|
||||
logMiddleware, navigationMiddleware, notificationsMiddleware,
|
||||
GlobalMiddleware.handler,
|
||||
HomeMiddleware.handler,
|
||||
OnboardingNoteMiddleware.handler,
|
||||
OnboardingWalletMiddleware.handler,
|
||||
OnboardingOtherCardsMiddleware.handler,
|
||||
WalletMiddleware().walletMiddleware,
|
||||
SendMiddleware().sendMiddleware,
|
||||
DetailsMiddleware().detailsMiddleware,
|
||||
DisclaimerMiddleware().disclaimerMiddleware,
|
||||
TokensMiddleware().tokensMiddleware,
|
||||
WalletConnectMiddleware().walletConnectMiddleware
|
||||
logMiddleware, navigationMiddleware, notificationsMiddleware,
|
||||
GlobalMiddleware.handler,
|
||||
HomeMiddleware.handler,
|
||||
OnboardingNoteMiddleware.handler,
|
||||
OnboardingWalletMiddleware.handler,
|
||||
OnboardingOtherCardsMiddleware.handler,
|
||||
WalletMiddleware().walletMiddleware,
|
||||
CreateTwinWalletMiddleware.handler,
|
||||
SendMiddleware().sendMiddleware,
|
||||
DetailsMiddleware().detailsMiddleware,
|
||||
DisclaimerMiddleware().disclaimerMiddleware,
|
||||
TokensMiddleware().tokensMiddleware,
|
||||
WalletConnectMiddleware().walletConnectMiddleware
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,8 +59,8 @@ class TapWalletManager {
|
|||
suspend fun loadFiatRate(fiatCurrency: FiatCurrencyName, wallet: Wallet) {
|
||||
Timber.d(wallet.getTokens().toString())
|
||||
val currencies = wallet.getTokens()
|
||||
.map { Currency.Token(it) }
|
||||
.plus(Currency.Blockchain(wallet.blockchain))
|
||||
.map { Currency.Token(it) }
|
||||
.plus(Currency.Blockchain(wallet.blockchain))
|
||||
loadFiatRate(fiatCurrency, currencies)
|
||||
}
|
||||
|
||||
|
|
@ -126,11 +126,13 @@ class TapWalletManager {
|
|||
store.dispatch(WalletAction.LoadCardInfo(data.card))
|
||||
|
||||
when {
|
||||
data.card.isTangemTwin() && data.secondTwinPublicKey == null -> {
|
||||
store.dispatch(WalletAction.EmptyWallet)
|
||||
}
|
||||
data.getBlockchain() == Blockchain.Unknown && !data.card.isMultiwalletAllowed -> {
|
||||
store.dispatch(WalletAction.LoadData.Failure(TapError.UnknownBlockchain))
|
||||
}
|
||||
data.card.wallets.isEmpty() ||
|
||||
(data.card.isTangemTwin() && data.secondTwinPublicKey == null) -> {
|
||||
data.card.wallets.isEmpty() -> {
|
||||
store.dispatch(WalletAction.EmptyWallet)
|
||||
}
|
||||
else -> {
|
||||
|
|
@ -171,7 +173,7 @@ class TapWalletManager {
|
|||
}
|
||||
|
||||
private fun loadMultiWalletData(
|
||||
card: Card, primaryBlockchain: Blockchain?, primaryWalletManager: WalletManager?
|
||||
card: Card, primaryBlockchain: Blockchain?, primaryWalletManager: WalletManager?
|
||||
) {
|
||||
val primaryTokens = primaryWalletManager?.cardTokens ?: emptySet()
|
||||
val savedCurrencies = currenciesRepository.loadCardCurrencies(card.cardId)
|
||||
|
|
@ -179,9 +181,9 @@ class TapWalletManager {
|
|||
if (savedCurrencies == null) {
|
||||
if (primaryBlockchain != null && primaryWalletManager != null) {
|
||||
store.dispatch(WalletAction.MultiWallet.SaveCurrencies(
|
||||
CardCurrencies(
|
||||
blockchains = setOf(primaryBlockchain), tokens = primaryTokens
|
||||
)))
|
||||
CardCurrencies(
|
||||
blockchains = setOf(primaryBlockchain), tokens = primaryTokens
|
||||
)))
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(primaryWalletManager))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchains(listOf(primaryBlockchain)))
|
||||
store.dispatch(WalletAction.MultiWallet.AddTokens(primaryTokens.toList()))
|
||||
|
|
@ -191,7 +193,7 @@ class TapWalletManager {
|
|||
CardCurrencies(blockchains = blockchains, tokens = emptySet())
|
||||
))
|
||||
val walletManagers =
|
||||
walletManagerFactory.makeWalletManagersForApp(card, blockchains.toList())
|
||||
walletManagerFactory.makeWalletManagersForApp(card, blockchains.toList())
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(walletManagers))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchains(blockchains.toList()))
|
||||
}
|
||||
|
|
@ -200,12 +202,12 @@ class TapWalletManager {
|
|||
} else {
|
||||
val blockchains = savedCurrencies.blockchains.toList()
|
||||
val walletManagers = if (
|
||||
primaryTokens.isNotEmpty() &&
|
||||
primaryWalletManager != null && primaryBlockchain != null
|
||||
primaryTokens.isNotEmpty() &&
|
||||
primaryWalletManager != null && primaryBlockchain != null
|
||||
) {
|
||||
val blockchainsWithoutPrimary = blockchains.filterNot { it == primaryBlockchain }
|
||||
walletManagerFactory.makeWalletManagersForApp(card, blockchainsWithoutPrimary)
|
||||
.plus(primaryWalletManager)
|
||||
.plus(primaryWalletManager)
|
||||
} else {
|
||||
walletManagerFactory.makeWalletManagersForApp(card, blockchains)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package com.tangem.tap.features.details.redux
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.Message
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.operations.pins.CheckUserCodesResponse
|
||||
|
|
@ -9,8 +7,6 @@ import com.tangem.tap.common.redux.NotificationAction
|
|||
import com.tangem.tap.common.redux.global.FiatCurrencyName
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.domain.termsOfUse.CardTou
|
||||
import com.tangem.tap.domain.twins.TwinCardNumber
|
||||
import com.tangem.tap.features.details.redux.twins.CreateTwinWallet
|
||||
import com.tangem.tap.network.coinmarketcap.FiatCurrency
|
||||
import com.tangem.wallet.R
|
||||
import org.rekotlin.Action
|
||||
|
|
@ -48,44 +44,6 @@ sealed class DetailsAction : Action {
|
|||
object Success : EraseWallet()
|
||||
}
|
||||
|
||||
sealed class CreateTwinWalletAction : DetailsAction() {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
sealed class AppCurrencyAction : DetailsAction() {
|
||||
data class SetCurrencies(val currencies: List<FiatCurrency>) : AppCurrencyAction()
|
||||
object ChooseAppCurrency : AppCurrencyAction()
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import com.tangem.tap.common.redux.AppState
|
|||
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.features.details.redux.twins.CreateTwinWalletMiddleware
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.network.coinmarketcap.CoinMarketCapService
|
||||
|
|
@ -26,7 +25,6 @@ class DetailsMiddleware {
|
|||
private val eraseWalletMiddleware = EraseWalletMiddleware()
|
||||
private val appCurrencyMiddleware = AppCurrencyMiddleware()
|
||||
private val manageSecurityMiddleware = ManageSecurityMiddleware()
|
||||
private val twinWalletMiddleware = CreateTwinWalletMiddleware()
|
||||
val detailsMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
|
|
@ -35,7 +33,6 @@ class DetailsMiddleware {
|
|||
is DetailsAction.EraseWallet -> eraseWalletMiddleware.handle(action)
|
||||
is DetailsAction.AppCurrencyAction -> appCurrencyMiddleware.handle(action)
|
||||
is DetailsAction.ManageSecurity -> manageSecurityMiddleware.handle(action)
|
||||
is DetailsAction.CreateTwinWalletAction -> twinWalletMiddleware.handle(action)
|
||||
is DetailsAction.ShowDisclaimer -> {
|
||||
store.dispatch(DisclaimerAction.ShowAcceptedDisclaimer)
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Disclaimer))
|
||||
|
|
@ -84,7 +81,7 @@ class DetailsMiddleware {
|
|||
store.dispatch(NavigationAction.PopBackTo())
|
||||
}
|
||||
is DetailsAction.EraseWallet.Confirm -> {
|
||||
val card = store.state.detailsState.card ?: return
|
||||
val card = store.state.detailsState.card ?: return
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.eraseWallet(card)
|
||||
withContext(Dispatchers.Main) {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ 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.details.redux.twins.CreateTwinWalletReducer
|
||||
import com.tangem.tap.features.details.redux.twins.CreateTwinWalletState
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletState
|
||||
import com.tangem.tap.features.wallet.models.hasPendingTransactions
|
||||
import org.rekotlin.Action
|
||||
import java.util.*
|
||||
|
|
@ -38,9 +37,6 @@ private fun internalReduce(action: Action, state: AppState): DetailsState {
|
|||
is DetailsAction.ManageSecurity -> {
|
||||
handleSecurityAction(action, detailsState)
|
||||
}
|
||||
is DetailsAction.CreateTwinWalletAction -> {
|
||||
CreateTwinWalletReducer.handle(action, detailsState)
|
||||
}
|
||||
else -> detailsState
|
||||
}
|
||||
}
|
||||
|
|
@ -48,24 +44,24 @@ 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
|
||||
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.card, wallets = action.wallets,
|
||||
cardInfo = action.card.toCardInfo(),
|
||||
appCurrencyState = AppCurrencyState(
|
||||
action.fiatCurrencyName
|
||||
),
|
||||
createTwinWalletState = twinsState,
|
||||
cardTermsOfUseUrl = action.cardTou.getUrl(action.card)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +95,7 @@ private fun handleEraseWallet(action: DetailsAction.EraseWallet, state: DetailsS
|
|||
}
|
||||
|
||||
private fun handleAppCurrencyAction(
|
||||
action: DetailsAction.AppCurrencyAction, state: DetailsState
|
||||
action: DetailsAction.AppCurrencyAction, state: DetailsState
|
||||
): DetailsState {
|
||||
return when (action) {
|
||||
is DetailsAction.AppCurrencyAction.SetCurrencies -> {
|
||||
|
|
@ -113,9 +109,9 @@ private fun handleAppCurrencyAction(
|
|||
}
|
||||
is DetailsAction.AppCurrencyAction.SelectAppCurrency -> {
|
||||
state.copy(
|
||||
appCurrencyState = state.appCurrencyState.copy(
|
||||
fiatCurrencyName = action.fiatCurrencyName, showAppCurrencyDialog = false
|
||||
)
|
||||
appCurrencyState = state.appCurrencyState.copy(
|
||||
fiatCurrencyName = action.fiatCurrencyName, showAppCurrencyDialog = false
|
||||
)
|
||||
)
|
||||
}
|
||||
else -> state
|
||||
|
|
@ -123,7 +119,7 @@ private fun handleAppCurrencyAction(
|
|||
}
|
||||
|
||||
private fun handleSecurityAction(
|
||||
action: DetailsAction.ManageSecurity, state: DetailsState
|
||||
action: DetailsAction.ManageSecurity, state: DetailsState
|
||||
): DetailsState {
|
||||
return when (action) {
|
||||
is DetailsAction.ManageSecurity.SetCurrentOption -> {
|
||||
|
|
@ -143,8 +139,8 @@ private fun handleSecurityAction(
|
|||
is DetailsAction.ManageSecurity.OpenSecurity -> {
|
||||
if (state.card?.isStart2Coin == true) {
|
||||
return state.copy(securityScreenState = state.securityScreenState?.copy(
|
||||
allowedOptions = EnumSet.of(SecurityOption.LongTap),
|
||||
selectedOption = state.securityScreenState.currentOption
|
||||
allowedOptions = EnumSet.of(SecurityOption.LongTap),
|
||||
selectedOption = state.securityScreenState.currentOption
|
||||
))
|
||||
}
|
||||
|
||||
|
|
@ -152,13 +148,13 @@ private fun handleSecurityAction(
|
|||
state.card, state.securityScreenState?.currentOption
|
||||
)
|
||||
state.copy(securityScreenState = state.securityScreenState?.copy(
|
||||
allowedOptions = allowedSecurityOptions,
|
||||
selectedOption = state.securityScreenState.currentOption
|
||||
allowedOptions = allowedSecurityOptions,
|
||||
selectedOption = state.securityScreenState.currentOption
|
||||
))
|
||||
}
|
||||
is DetailsAction.ManageSecurity.SelectOption -> {
|
||||
state.copy(securityScreenState = state.securityScreenState?.copy(
|
||||
selectedOption = action.option
|
||||
selectedOption = action.option
|
||||
))
|
||||
}
|
||||
is DetailsAction.ManageSecurity.ConfirmSelection -> {
|
||||
|
|
@ -172,10 +168,10 @@ private fun handleSecurityAction(
|
|||
is DetailsAction.ManageSecurity.SaveChanges.Success -> {
|
||||
// Setting options to show only LongTap from now on
|
||||
state.copy(
|
||||
securityScreenState = state.securityScreenState?.copy(
|
||||
currentOption = state.securityScreenState.selectedOption,
|
||||
allowedOptions = EnumSet.of(SecurityOption.LongTap)
|
||||
))
|
||||
securityScreenState = state.securityScreenState?.copy(
|
||||
currentOption = state.securityScreenState.selectedOption,
|
||||
allowedOptions = EnumSet.of(SecurityOption.LongTap)
|
||||
))
|
||||
}
|
||||
|
||||
else -> state
|
||||
|
|
@ -205,4 +201,5 @@ private fun Card.toCardInfo(): CardInfo? {
|
|||
val cardId = this.cardId.chunked(4).joinToString(separator = " ")
|
||||
val issuer = this.issuer.name
|
||||
val signedHashes = this.signedHashesCount()
|
||||
return CardInfo(cardId, issuer, signedHashes)}
|
||||
return CardInfo(cardId, issuer, signedHashes)
|
||||
}
|
||||
|
|
@ -6,41 +6,41 @@ 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.details.redux.twins.CreateTwinWalletState
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletState
|
||||
import com.tangem.tap.network.coinmarketcap.FiatCurrency
|
||||
import org.rekotlin.StateType
|
||||
import java.util.*
|
||||
|
||||
data class DetailsState(
|
||||
val card: Card? = null,
|
||||
val wallets: List<Wallet> = emptyList(),
|
||||
val cardInfo: CardInfo? = null,
|
||||
val appCurrencyState: AppCurrencyState = AppCurrencyState(),
|
||||
val eraseWalletState: EraseWalletState? = null,
|
||||
val confirmScreenState: ConfirmScreenState? = null,
|
||||
val securityScreenState: SecurityScreenState? = null,
|
||||
val createTwinWalletState: CreateTwinWalletState? = null,
|
||||
val cardTermsOfUseUrl: Uri? = null,
|
||||
val card: Card? = null,
|
||||
val wallets: List<Wallet> = emptyList(),
|
||||
val cardInfo: CardInfo? = null,
|
||||
val appCurrencyState: AppCurrencyState = AppCurrencyState(),
|
||||
val eraseWalletState: EraseWalletState? = null,
|
||||
val confirmScreenState: ConfirmScreenState? = null,
|
||||
val securityScreenState: SecurityScreenState? = null,
|
||||
val createTwinWalletState: CreateTwinWalletState? = null,
|
||||
val cardTermsOfUseUrl: Uri? = null,
|
||||
) : StateType
|
||||
|
||||
data class CardInfo(
|
||||
val cardId: String,
|
||||
val issuer: String,
|
||||
val signedHashes: Int,
|
||||
val cardId: String,
|
||||
val issuer: String,
|
||||
val signedHashes: Int,
|
||||
)
|
||||
|
||||
enum class EraseWalletState { Allowed, NotAllowedByCard, NotEmpty }
|
||||
enum class ConfirmScreenState { EraseWallet, LongTap, AccessCode, PassCode }
|
||||
data class SecurityScreenState(
|
||||
val currentOption: SecurityOption = SecurityOption.LongTap,
|
||||
val selectedOption: SecurityOption = currentOption,
|
||||
val allowedOptions: EnumSet<SecurityOption> = EnumSet.allOf(SecurityOption::class.java),
|
||||
val buttonProceed: Button = Button(true),
|
||||
val currentOption: SecurityOption = SecurityOption.LongTap,
|
||||
val selectedOption: SecurityOption = currentOption,
|
||||
val allowedOptions: EnumSet<SecurityOption> = EnumSet.allOf(SecurityOption::class.java),
|
||||
val buttonProceed: Button = Button(true),
|
||||
)
|
||||
|
||||
enum class SecurityOption { LongTap, PassCode, AccessCode }
|
||||
data class AppCurrencyState(
|
||||
val fiatCurrencyName: FiatCurrencyName = DEFAULT_FIAT_CURRENCY,
|
||||
val showAppCurrencyDialog: Boolean = false,
|
||||
val fiatCurrencies: List<FiatCurrency>? = null,
|
||||
val fiatCurrencyName: FiatCurrencyName = DEFAULT_FIAT_CURRENCY,
|
||||
val showAppCurrencyDialog: Boolean = false,
|
||||
val fiatCurrencies: List<FiatCurrency>? = null,
|
||||
)
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
package com.tangem.tap.features.details.redux.twins
|
||||
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
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.features.details.redux.DetailsAction
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class CreateTwinWalletMiddleware {
|
||||
var twinsManager: TwinCardsManager? = null
|
||||
fun handle(action: DetailsAction.CreateTwinWalletAction) {
|
||||
when (action) {
|
||||
is DetailsAction.CreateTwinWalletAction.ShowWarning -> {
|
||||
val wallet = store.state.detailsState.wallets.firstOrNull()
|
||||
if (wallet == null) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWalletWarning))
|
||||
return
|
||||
}
|
||||
val notEmpty = wallet.recentTransactions.isNotEmpty() || wallet.amounts.toSendableAmounts().isNotEmpty()
|
||||
if (notEmpty) {
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.NotEmpty)
|
||||
} else {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWalletWarning))
|
||||
}
|
||||
}
|
||||
is DetailsAction.CreateTwinWalletAction.Proceed ->
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWallet))
|
||||
is DetailsAction.CreateTwinWalletAction.Cancel -> {
|
||||
|
||||
val step = store.state.detailsState.createTwinWalletState?.step
|
||||
if (step != null && step != CreateTwinWalletStep.FirstStep
|
||||
) {
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.ShowAlert)
|
||||
} else {
|
||||
twinsManager = null
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
}
|
||||
}
|
||||
is DetailsAction.CreateTwinWalletAction.Cancel.Confirm -> {
|
||||
twinsManager = null
|
||||
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
|
||||
}
|
||||
is DetailsAction.CreateTwinWalletAction.LaunchFirstStep -> {
|
||||
store.state.globalState.scanResponse?.let {
|
||||
twinsManager = TwinCardsManager(it, action.context)
|
||||
}
|
||||
scope.launch {
|
||||
val result = twinsManager?.createFirstWallet(action.message)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
SimpleResult.Success ->
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchFirstStep.Success)
|
||||
is SimpleResult.Failure ->
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchFirstStep.Failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DetailsAction.CreateTwinWalletAction.LaunchFirstStep.Success -> {
|
||||
|
||||
}
|
||||
DetailsAction.CreateTwinWalletAction.LaunchFirstStep.Failure -> {
|
||||
|
||||
}
|
||||
is DetailsAction.CreateTwinWalletAction.LaunchSecondStep ->
|
||||
scope.launch {
|
||||
val result = twinsManager?.createSecondWallet(action.initialMessage,
|
||||
action.preparingMessage, action.creatingWalletMessage)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
SimpleResult.Success ->
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchSecondStep.Success)
|
||||
is SimpleResult.Failure ->
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchSecondStep.Failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
DetailsAction.CreateTwinWalletAction.LaunchSecondStep.Success -> {
|
||||
|
||||
}
|
||||
DetailsAction.CreateTwinWalletAction.LaunchSecondStep.Failure -> {
|
||||
|
||||
}
|
||||
is DetailsAction.CreateTwinWalletAction.LaunchThirdStep -> {
|
||||
scope.launch {
|
||||
val result = twinsManager?.complete(action.message)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
is Result.Success ->
|
||||
store.dispatch(
|
||||
DetailsAction.CreateTwinWalletAction
|
||||
.LaunchThirdStep.Success(result.data)
|
||||
)
|
||||
is Result.Failure ->
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchThirdStep.Failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is DetailsAction.CreateTwinWalletAction.LaunchThirdStep.Success -> {
|
||||
scope.launch {
|
||||
store.state.globalState.tapWalletManager.onCardScanned(action.scanResponse)
|
||||
}
|
||||
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
DetailsAction.CreateTwinWalletAction.LaunchThirdStep.Failure -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
package com.tangem.tap.features.details.redux.twins
|
||||
|
||||
import com.tangem.tap.features.details.redux.DetailsAction
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
|
||||
class CreateTwinWalletReducer {
|
||||
companion object {
|
||||
fun handle(
|
||||
action: DetailsAction.CreateTwinWalletAction, state: DetailsState
|
||||
): DetailsState {
|
||||
return when (action) {
|
||||
is DetailsAction.CreateTwinWalletAction.ShowWarning -> {
|
||||
state.copy(createTwinWalletState = CreateTwinWalletState(
|
||||
scanResponse = null,
|
||||
twinCardNumber = action.twinCardNumber
|
||||
?: state.createTwinWalletState?.twinCardNumber,
|
||||
createTwinWallet = action.createTwinWallet,
|
||||
showAlert = false,
|
||||
allowRecreatingWallet = state.createTwinWalletState?.allowRecreatingWallet
|
||||
))
|
||||
}
|
||||
DetailsAction.CreateTwinWalletAction.NotEmpty -> state
|
||||
DetailsAction.CreateTwinWalletAction.ShowAlert -> {
|
||||
state.copy(createTwinWalletState = state.createTwinWalletState?.copy(
|
||||
showAlert = true
|
||||
))
|
||||
}
|
||||
DetailsAction.CreateTwinWalletAction.HideAlert -> {
|
||||
state.copy(createTwinWalletState = state.createTwinWalletState?.copy(
|
||||
showAlert = false
|
||||
))
|
||||
}
|
||||
is DetailsAction.CreateTwinWalletAction.Proceed -> {
|
||||
state
|
||||
}
|
||||
DetailsAction.CreateTwinWalletAction.Cancel -> state
|
||||
DetailsAction.CreateTwinWalletAction.Cancel.Confirm -> state
|
||||
is DetailsAction.CreateTwinWalletAction.LaunchFirstStep -> state
|
||||
|
||||
DetailsAction.CreateTwinWalletAction.LaunchFirstStep.Success -> {
|
||||
state.copy(createTwinWalletState = state.createTwinWalletState?.copy(
|
||||
step = CreateTwinWalletStep.SecondStep
|
||||
))
|
||||
}
|
||||
DetailsAction.CreateTwinWalletAction.LaunchFirstStep.Failure -> state
|
||||
|
||||
is DetailsAction.CreateTwinWalletAction.LaunchSecondStep -> state
|
||||
DetailsAction.CreateTwinWalletAction.LaunchSecondStep.Success ->
|
||||
state.copy(createTwinWalletState = state.createTwinWalletState?.copy(
|
||||
step = CreateTwinWalletStep.ThirdStep
|
||||
))
|
||||
DetailsAction.CreateTwinWalletAction.LaunchSecondStep.Failure -> {
|
||||
state
|
||||
}
|
||||
is DetailsAction.CreateTwinWalletAction.LaunchThirdStep -> {
|
||||
state
|
||||
}
|
||||
is DetailsAction.CreateTwinWalletAction.LaunchThirdStep.Success -> {
|
||||
state
|
||||
}
|
||||
DetailsAction.CreateTwinWalletAction.LaunchThirdStep.Failure -> {
|
||||
state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -16,8 +16,9 @@ import com.tangem.tap.domain.twins.isTangemTwin
|
|||
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.details.redux.twins.CreateTwinWallet
|
||||
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.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fragment_details.*
|
||||
|
|
@ -95,9 +96,7 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber<Det
|
|||
tv_erase_wallet.show()
|
||||
tv_erase_wallet.text = getText(R.string.details_row_title_twins_recreate)
|
||||
tv_erase_wallet.setOnClickListener {
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.ShowWarning(
|
||||
null, CreateTwinWallet.RecreateWallet
|
||||
))
|
||||
store.dispatch(CreateTwinWalletAction.ShowWarning(null, CreateTwinWallet.RecreateWallet))
|
||||
}
|
||||
} else {
|
||||
tv_erase_wallet.hide()
|
||||
|
|
@ -140,9 +139,9 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber<Det
|
|||
if (state.appCurrencyState.showAppCurrencyDialog &&
|
||||
!state.appCurrencyState.fiatCurrencies.isNullOrEmpty()) {
|
||||
currencySelectionDialog.show(
|
||||
state.appCurrencyState.fiatCurrencies,
|
||||
state.appCurrencyState.fiatCurrencyName,
|
||||
requireContext()
|
||||
state.appCurrencyState.fiatCurrencies,
|
||||
state.appCurrencyState.fiatCurrencyName,
|
||||
requireContext()
|
||||
)
|
||||
} else {
|
||||
currencySelectionDialog.clear()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tap.features.wallet.ui
|
||||
package com.tangem.tap.features.onboarding.products.twins
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
|
|
@ -6,17 +6,21 @@ import androidx.activity.OnBackPressedCallback
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.squareup.picasso.Picasso
|
||||
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
|
||||
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.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
|
||||
import kotlinx.android.synthetic.main.fragment_twin_cards.*
|
||||
import kotlinx.android.synthetic.main.fragment_twin_cards_welcome.*
|
||||
import kotlinx.android.synthetic.main.layout_twin_cards.*
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class OnboardingTwinsFragment : Fragment(R.layout.fragment_twin_cards) {
|
||||
class OnboardingTwinsFragment : Fragment(R.layout.fragment_twin_cards_welcome) {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
@ -57,8 +61,15 @@ class OnboardingTwinsFragment : Fragment(R.layout.fragment_twin_cards) {
|
|||
|
||||
private fun setOnClickListeners() {
|
||||
btn_continue.setOnClickListener {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
scope.launch {
|
||||
val global = store.state.globalState
|
||||
val scanResponse = global.onboardingManager?.scanResponse ?: return@launch
|
||||
global.tapWalletManager.onCardScanned(scanResponse)
|
||||
withMainContext {
|
||||
store.dispatchDebugErrorNotification("Делаем онбоардинг")
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,7 +18,6 @@ import com.tangem.tap.mainScope
|
|||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fragment_add_tokens.*
|
||||
import kotlinx.android.synthetic.main.fragment_details_twin_cards.toolbar
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.*
|
||||
import org.rekotlin.StoreSubscriber
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
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()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
package com.tangem.tap.features.twins.redux
|
||||
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
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.scope
|
||||
import com.tangem.tap.store
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.rekotlin.Action
|
||||
import org.rekotlin.DispatchFunction
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
class CreateTwinWalletMiddleware {
|
||||
companion object {
|
||||
val handler = twinsWalletMiddleware
|
||||
}
|
||||
}
|
||||
|
||||
private val twinsWalletMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
handle(action, dispatch)
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var twinsManager: TwinCardsManager? = null
|
||||
|
||||
private fun handle(action: Action, dispatch: DispatchFunction) {
|
||||
val action = action as? CreateTwinWalletAction ?: return
|
||||
|
||||
when (action) {
|
||||
is CreateTwinWalletAction.ShowWarning -> {
|
||||
val wallet = store.state.detailsState.wallets.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)
|
||||
} else {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.CreateTwinWalletWarning))
|
||||
}
|
||||
}
|
||||
is CreateTwinWalletAction.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)
|
||||
} else {
|
||||
twinsManager = null
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
}
|
||||
}
|
||||
is CreateTwinWalletAction.Cancel.Confirm -> {
|
||||
twinsManager = null
|
||||
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
|
||||
}
|
||||
is CreateTwinWalletAction.LaunchFirstStep -> {
|
||||
store.state.globalState.scanResponse?.let {
|
||||
twinsManager = TwinCardsManager(it, action.context)
|
||||
}
|
||||
scope.launch {
|
||||
val result = twinsManager?.createFirstWallet(action.message)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
SimpleResult.Success ->
|
||||
store.dispatch(CreateTwinWalletAction.LaunchFirstStep.Success)
|
||||
is SimpleResult.Failure ->
|
||||
store.dispatch(CreateTwinWalletAction.LaunchFirstStep.Failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CreateTwinWalletAction.LaunchFirstStep.Success -> {
|
||||
|
||||
}
|
||||
CreateTwinWalletAction.LaunchFirstStep.Failure -> {
|
||||
|
||||
}
|
||||
is CreateTwinWalletAction.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)
|
||||
is SimpleResult.Failure ->
|
||||
store.dispatch(CreateTwinWalletAction.LaunchSecondStep.Failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
CreateTwinWalletAction.LaunchSecondStep.Success -> {
|
||||
|
||||
}
|
||||
CreateTwinWalletAction.LaunchSecondStep.Failure -> {
|
||||
|
||||
}
|
||||
is CreateTwinWalletAction.LaunchThirdStep -> {
|
||||
scope.launch {
|
||||
val result = twinsManager?.complete(action.message)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
is Result.Success ->
|
||||
store.dispatch(
|
||||
CreateTwinWalletAction
|
||||
.LaunchThirdStep.Success(result.data)
|
||||
)
|
||||
is Result.Failure ->
|
||||
store.dispatch(CreateTwinWalletAction.LaunchThirdStep.Failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is CreateTwinWalletAction.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 -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
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,4 +1,4 @@
|
|||
package com.tangem.tap.features.details.redux.twins
|
||||
package com.tangem.tap.features.twins.redux
|
||||
|
||||
import com.tangem.tap.domain.tasks.product.ScanResponse
|
||||
import com.tangem.tap.domain.twins.TwinCardNumber
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tap.features.details.ui.twins
|
||||
package com.tangem.tap.features.twins.ui
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
|
|
@ -11,17 +11,17 @@ 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.DetailsAction
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.features.details.redux.twins.CreateTwinWallet
|
||||
import com.tangem.tap.features.details.redux.twins.CreateTwinWalletStep
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWallet
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletAction
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletStep
|
||||
import com.tangem.tap.features.wallet.redux.Artwork
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fragment_details_twin_cards.*
|
||||
import kotlinx.android.synthetic.main.fragment_twin_cards_create.*
|
||||
import org.rekotlin.StoreSubscriber
|
||||
|
||||
class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards),
|
||||
class CreateTwinWalletFragment : Fragment(R.layout.fragment_twin_cards_create),
|
||||
StoreSubscriber<DetailsState> {
|
||||
|
||||
private var dialog: Dialog? = null
|
||||
|
|
@ -30,7 +30,7 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards),
|
|||
super.onCreate(savedInstanceState)
|
||||
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.Cancel)
|
||||
store.dispatch(CreateTwinWalletAction.Cancel)
|
||||
}
|
||||
})
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
|
|
@ -56,7 +56,7 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards),
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
toolbar.setNavigationOnClickListener {
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.Cancel)
|
||||
store.dispatch(CreateTwinWalletAction.Cancel)
|
||||
}
|
||||
|
||||
Picasso.get()
|
||||
|
|
@ -96,7 +96,7 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards),
|
|||
v_step_2.setBackgroundColor(defaultColor)
|
||||
v_step_3.setBackgroundColor(defaultColor)
|
||||
btn_tap.setOnClickListener {
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchFirstStep(
|
||||
store.dispatch(CreateTwinWalletAction.LaunchFirstStep(
|
||||
Message(getString(
|
||||
R.string.details_twins_recreate_title_format,
|
||||
twinCardNumberString
|
||||
|
|
@ -105,7 +105,7 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards),
|
|||
))
|
||||
}
|
||||
btn_tap.text = getString(R.string.details_twins_recreate_button_format,
|
||||
twinCardNumber.number.toString())
|
||||
twinCardNumber.number.toString())
|
||||
twinCardNumberString
|
||||
}
|
||||
CreateTwinWalletStep.SecondStep -> {
|
||||
|
|
@ -117,10 +117,10 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards),
|
|||
v_step_2.setBackgroundColor(selectedColor)
|
||||
v_step_3.setBackgroundColor(defaultColor)
|
||||
btn_tap.setOnClickListener {
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.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)),
|
||||
store.dispatch(CreateTwinWalletAction.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)),
|
||||
))
|
||||
}
|
||||
btn_tap.text = getString(R.string.details_twins_recreate_button_format, "2")
|
||||
|
|
@ -135,10 +135,10 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards),
|
|||
v_step_2.setBackgroundColor(selectedColor)
|
||||
v_step_3.setBackgroundColor(selectedColor)
|
||||
btn_tap.setOnClickListener {
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.LaunchThirdStep(
|
||||
Message(getString(
|
||||
R.string.details_twins_recreate_title_format, twinCardNumberString)
|
||||
)
|
||||
store.dispatch(CreateTwinWalletAction.LaunchThirdStep(
|
||||
Message(getString(
|
||||
R.string.details_twins_recreate_title_format, twinCardNumberString)
|
||||
)
|
||||
))
|
||||
}
|
||||
btn_tap.text = getString(R.string.details_twins_recreate_button_format, twinCardNumberString)
|
||||
|
|
@ -154,13 +154,13 @@ class CreateTwinWalletFragment : Fragment(R.layout.fragment_details_twin_cards),
|
|||
dialog = MaterialAlertDialogBuilder(requireContext())
|
||||
.setMessage(R.string.details_twins_recreate_alert)
|
||||
.setPositiveButton(R.string.common_ok) { _, _ ->
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.Cancel.Confirm)
|
||||
store.dispatch(CreateTwinWalletAction.Cancel.Confirm)
|
||||
}
|
||||
.setNegativeButton(R.string.common_cancel) { _, _ ->
|
||||
dialog?.cancel()
|
||||
}
|
||||
.setOnCancelListener {
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.HideAlert)
|
||||
store.dispatch(CreateTwinWalletAction.HideAlert)
|
||||
}
|
||||
.create()
|
||||
dialog?.show()
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tap.features.details.ui.twins
|
||||
package com.tangem.tap.features.twins.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
|
|
@ -7,15 +7,15 @@ 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.details.redux.DetailsAction
|
||||
import com.tangem.tap.features.details.redux.twins.CreateTwinWallet
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWallet
|
||||
import com.tangem.tap.features.twins.redux.CreateTwinWalletAction
|
||||
import com.tangem.tap.features.wallet.redux.Artwork
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fragment_details_twin_cards_warning.*
|
||||
import kotlinx.android.synthetic.main.fragment_twin_cards_warning.*
|
||||
import kotlinx.android.synthetic.main.layout_twin_cards_orange.*
|
||||
|
||||
class TwinWalletWarningFragment : Fragment(R.layout.fragment_details_twin_cards_warning) {
|
||||
class TwinWalletWarningFragment : Fragment(R.layout.fragment_twin_cards_warning) {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
@ -39,10 +39,7 @@ class TwinWalletWarningFragment : Fragment(R.layout.fragment_details_twin_cards_
|
|||
}
|
||||
|
||||
btn_cancel.setOnClickListener { store.dispatch(NavigationAction.PopBackTo()) }
|
||||
btn_start.setOnClickListener {
|
||||
store.dispatch(
|
||||
DetailsAction.CreateTwinWalletAction.Proceed)
|
||||
}
|
||||
btn_start.setOnClickListener { store.dispatch(CreateTwinWalletAction.Proceed) }
|
||||
Picasso.get()
|
||||
.load(Artwork.TWIN_CARD_1)
|
||||
.placeholder(R.drawable.card_placeholder)
|
||||
|
|
@ -11,19 +11,17 @@ import com.tangem.common.services.Result
|
|||
import com.tangem.operations.attestation.OnlineCardVerifier
|
||||
import com.tangem.tap.*
|
||||
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
|
||||
import com.tangem.tap.common.extensions.copyToClipboard
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.common.extensions.shareText
|
||||
import com.tangem.tap.common.extensions.*
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
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.details.redux.DetailsAction
|
||||
import com.tangem.tap.features.details.redux.twins.CreateTwinWallet
|
||||
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.wallet.redux.*
|
||||
import com.tangem.tap.network.NetworkStateChanged
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -87,7 +85,7 @@ class WalletMiddleware {
|
|||
globalState?.tapWalletManager?.loadFiatRate(
|
||||
fiatCurrency = globalState.appCurrency,
|
||||
currencies = walletState?.wallets?.mapNotNull { it.currency }
|
||||
?: emptyList()
|
||||
?: emptyList()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -95,16 +93,15 @@ class WalletMiddleware {
|
|||
}
|
||||
is WalletAction.CreateWallet -> {
|
||||
if (walletState?.twinCardsState != null) {
|
||||
store.dispatch(DetailsAction.CreateTwinWalletAction.ShowWarning(
|
||||
globalState?.scanResponse?.card?.cardId?.let {
|
||||
TwinsHelper.getTwinCardNumber(it)
|
||||
},
|
||||
CreateTwinWallet.CreateWallet
|
||||
))
|
||||
val cardId = globalState?.scanResponse?.card?.cardId
|
||||
val twinCardNumber = cardId?.let { TwinsHelper.getTwinCardNumber(it) }
|
||||
store.dispatch(
|
||||
CreateTwinWalletAction.ShowWarning(twinCardNumber, CreateTwinWallet.CreateWallet)
|
||||
)
|
||||
} else {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.createWallet(
|
||||
globalState?.scanResponse?.card?.cardId
|
||||
globalState?.scanResponse?.card?.cardId
|
||||
)
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
|
|
@ -236,12 +233,12 @@ class WalletMiddleware {
|
|||
when (currency) {
|
||||
is Currency.Blockchain -> {
|
||||
val amountToSend = amounts?.find { it.currencySymbol == currency.blockchain.currency }
|
||||
?: return WalletAction.Send.ChooseCurrency(amounts)
|
||||
?: return WalletAction.Send.ChooseCurrency(amounts)
|
||||
PrepareSendScreen(amountToSend, selectedWalletData.fiatRate, walletManager)
|
||||
}
|
||||
is Currency.Token -> {
|
||||
val amountToSend = amounts?.find { it.currencySymbol == currency.token.symbol }
|
||||
?: return WalletAction.Send.ChooseCurrency(amounts)
|
||||
?: return WalletAction.Send.ChooseCurrency(amounts)
|
||||
prepareSendActionForToken(amountToSend, state, selectedWalletData, wallet, walletManager)
|
||||
}
|
||||
}
|
||||
|
|
@ -257,8 +254,8 @@ class WalletMiddleware {
|
|||
}
|
||||
|
||||
private fun prepareSendActionForToken(
|
||||
amount: Amount, state: WalletState?, selectedWalletData: WalletData?, wallet: Wallet?,
|
||||
walletManager: WalletManager?
|
||||
amount: Amount, state: WalletState?, selectedWalletData: WalletData?, wallet: Wallet?,
|
||||
walletManager: WalletManager?
|
||||
): PrepareSendScreen {
|
||||
val coinRate = state?.getWalletData(wallet?.blockchain)?.fiatRate
|
||||
val tokenRate = if (state?.isMultiwalletAllowed == true) {
|
||||
|
|
@ -267,7 +264,7 @@ class WalletMiddleware {
|
|||
selectedWalletData?.currencyData?.token?.fiatRate
|
||||
}
|
||||
return PrepareSendScreen(
|
||||
wallet?.amounts?.get(AmountType.Coin), coinRate, walletManager,
|
||||
amount, tokenRate)
|
||||
wallet?.amounts?.get(AmountType.Coin), coinRate, walletManager,
|
||||
amount, tokenRate)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@ import com.tangem.tap.features.wallet.ui.adapters.PendingTransactionsAdapter
|
|||
import com.tangem.tap.features.wallet.ui.dialogs.AmountToSendDialog
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fragment_details_twin_cards.*
|
||||
import kotlinx.android.synthetic.main.fragment_wallet_details.*
|
||||
import kotlinx.android.synthetic.main.fragment_wallet_details.toolbar
|
||||
import kotlinx.android.synthetic.main.item_currency_wallet.view.*
|
||||
import kotlinx.android.synthetic.main.item_popular_token.view.*
|
||||
import kotlinx.android.synthetic.main.layout_balance_error.*
|
||||
|
|
@ -98,12 +96,12 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
|
|||
|
||||
tv_currency_title.text = selectedWallet.currencyData.currency
|
||||
val currency = selectedWallet.currency
|
||||
if (currency is Currency.Token) {
|
||||
tv_currency_subtitle.text = currency.blockchain.tokenDisplayName()
|
||||
tv_currency_subtitle.show()
|
||||
if (currency is Currency.Token) {
|
||||
tv_currency_subtitle.text = currency.blockchain.tokenDisplayName()
|
||||
tv_currency_subtitle.show()
|
||||
} else {
|
||||
tv_currency_subtitle.hide()
|
||||
}
|
||||
tv_currency_subtitle.hide()
|
||||
}
|
||||
|
||||
|
||||
showPendingTransactionsIfPresent(selectedWallet.pendingTransactions)
|
||||
|
|
@ -129,9 +127,9 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
|
|||
srl_wallet_details.setOnRefreshListener {
|
||||
if (selectedWallet.currencyData.status != BalanceStatus.Loading) {
|
||||
store.dispatch(WalletAction.LoadWallet(
|
||||
allowToBuy = selectedWallet.tradeCryptoState.buyingAllowed,
|
||||
allowToSell = selectedWallet.tradeCryptoState.sellingAllowed,
|
||||
blockchain = selectedWallet.currency?.blockchain
|
||||
allowToBuy = selectedWallet.tradeCryptoState.buyingAllowed,
|
||||
allowToSell = selectedWallet.tradeCryptoState.sellingAllowed,
|
||||
blockchain = selectedWallet.currency?.blockchain
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
@ -180,8 +178,8 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
|
|||
tv_address.text = state.walletAddresses.selectedAddress.address
|
||||
tv_explore?.setOnClickListener {
|
||||
store.dispatch(WalletAction.ExploreAddress(
|
||||
state.walletAddresses.selectedAddress.exploreUrl,
|
||||
requireContext()))
|
||||
state.walletAddresses.selectedAddress.exploreUrl,
|
||||
requireContext()))
|
||||
}
|
||||
iv_qr_code.setImageBitmap(state.walletAddresses.selectedAddress.shareUrl.toQrCode())
|
||||
}
|
||||
|
|
@ -192,8 +190,8 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
|
|||
if (state.error == ErrorType.NoInternetConnection) {
|
||||
srl_wallet_details?.isRefreshing = false
|
||||
(activity as? SnackbarHandler)?.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 {
|
||||
|
|
@ -249,8 +247,8 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
|
|||
tv_error_title.text = getText(R.string.wallet_error_no_account)
|
||||
tv_error_descriptions.text =
|
||||
getString(
|
||||
R.string.wallet_error_no_account_subtitle_format,
|
||||
data.amountToCreateAccount, data.currencySymbol
|
||||
R.string.wallet_error_no_account_subtitle_format,
|
||||
data.amountToCreateAccount, data.currencySymbol
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue