Skip to content

Commit

Permalink
feat(deeplinks): AND-6641 part 3 - Rewards deposit & summary (#4077)
Browse files Browse the repository at this point in the history
  • Loading branch information
dserrano-bc committed Nov 8, 2022
1 parent 8656b2a commit 4c3ff15
Show file tree
Hide file tree
Showing 12 changed files with 408 additions and 36 deletions.
91 changes: 76 additions & 15 deletions app/src/main/java/piuk/blockchain/android/ui/home/MainActivity.kt
Expand Up @@ -101,6 +101,7 @@ import piuk.blockchain.android.ui.home.models.ViewToLaunch
import piuk.blockchain.android.ui.home.ui_tour.UiTourAnalytics
import piuk.blockchain.android.ui.home.ui_tour.UiTourView
import piuk.blockchain.android.ui.interest.InterestDashboardActivity
import piuk.blockchain.android.ui.interest.InterestSummarySheet
import piuk.blockchain.android.ui.kyc.navhost.KycNavHostActivity
import piuk.blockchain.android.ui.kyc.status.KycStatusActivity
import piuk.blockchain.android.ui.linkbank.BankAuthActivity
Expand Down Expand Up @@ -146,6 +147,7 @@ class MainActivity :
UiTourView.Host,
KycUpgradeNowSheet.Host,
NftHost,
InterestSummarySheet.Host,
NavigationRouter<PricesNavigationEvent> {

override val alwaysDisableScreenshots: Boolean
Expand Down Expand Up @@ -706,18 +708,30 @@ class MainActivity :
analytics.logEvent(ReferralAnalyticsEvents.ReferralProgramClicked(Origin.Deeplink))
showReferralBottomSheet(newState.referral.referralInfo)
}
is ViewToLaunch.LaunchTxFlowFromDeepLink -> {
startActivity(
TransactionFlowActivity.newIntent(
this,
action = view.action,
sourceAccount = if (view.account is LaunchFlowForAccount.Account) {
view.account.account
} else {
NullCryptoAccount()
}
is ViewToLaunch.LaunchTxFlowWithAccountForAction -> {
if (view.account is LaunchFlowForAccount.SourceAndTargetAccount) {
startActivity(
TransactionFlowActivity.newIntent(
this,
action = view.action,
sourceAccount = view.account.sourceAccount,
target = view.account.targetAccount
)
)
)
} else {
launchInterestDashboard(LaunchOrigin.DASHBOARD)
}
}
is ViewToLaunch.LaunchRewardsSummaryFromDeepLink -> {
if (view.account is LaunchFlowForAccount.SourceAccount) {
showBottomSheet(
InterestSummarySheet.newInstance(
singleAccount = view.account.account as CryptoAccount
)
)
} else {
launchInterestDashboard(LaunchOrigin.DASHBOARD)
}
}
}.exhaustive

Expand Down Expand Up @@ -893,18 +907,41 @@ class MainActivity :
)
}
}
Destination.CustomerSupportDestination ->
startActivity(SupportCentreActivity.newIntent(this))
Destination.CustomerSupportDestination -> startActivity(SupportCentreActivity.newIntent(this))
Destination.StartKycDestination ->
startActivity(KycNavHostActivity.newIntent(this, CampaignType.None))
Destination.ReferralDestination -> model.process(MainIntent.ShowReferralWhenAvailable)
is Destination.DashboardDestination -> launchPortfolio(reload = true)
is Destination.WalletConnectDestination -> model.process(MainIntent.StartWCSession(destination.url))
is Destination.AssetReceiveDestination -> launchReceive(destination.networkTicker)
is Destination.AssetSellDestination ->
model.process(MainIntent.LaunchTransactionFlowFromDeepLink(destination.networkTicker, AssetAction.Sell))
model.process(
MainIntent.LaunchTransactionFlowFromDeepLink(
cryptoTicker = destination.networkTicker,
action = AssetAction.Sell
)
)
is Destination.AssetSwapDestination ->
model.process(MainIntent.LaunchTransactionFlowFromDeepLink(destination.networkTicker, AssetAction.Swap))
model.process(
MainIntent.LaunchTransactionFlowFromDeepLink(
cryptoTicker = destination.networkTicker,
action = AssetAction.Swap
)
)
is Destination.RewardsDepositDestination ->
model.process(
MainIntent.LaunchTransactionFlowFromDeepLink(
cryptoTicker = destination.networkTicker,
action = AssetAction.InterestDeposit
)
)
is Destination.RewardsSummaryDestination -> {
model.process(
MainIntent.SelectRewardsAccountForAsset(
cryptoTicker = destination.networkTicker
)
)
}
}.exhaustive

model.process(MainIntent.ClearDeepLinkResult)
Expand Down Expand Up @@ -1099,6 +1136,30 @@ class MainActivity :
startBuy()
}

override fun goToActivityFor(account: BlockchainAccount) {
startActivitiesFragment(account)
}

override fun goToInterestDeposit(toAccount: BlockchainAccount) {
model.process(
MainIntent.UpdateViewToLaunch(
ViewToLaunch.LaunchTxFlowWithAccountForAction(
LaunchFlowForAccount.SourceAccount(toAccount), AssetAction.InterestDeposit
)
)
)
}

override fun goToInterestWithdraw(fromAccount: BlockchainAccount) {
model.process(
MainIntent.UpdateViewToLaunch(
ViewToLaunch.LaunchTxFlowWithAccountForAction(
LaunchFlowForAccount.SourceAccount(fromAccount), AssetAction.InterestWithdraw
)
)
)
}

override fun onSheetClosed() {
binding.bottomNavigation.bottomNavigationState = BottomNavigationState.Add
Timber.d("On closed")
Expand Down
Expand Up @@ -111,7 +111,7 @@ sealed class MainIntent : MviIntent<MainState> {
override fun reduce(oldState: MainState): MainState = oldState
}

class UpdateDeepLinkResult(val deeplinkResult: DeepLinkResult) : MainIntent() {
class UpdateDeepLinkResult(private val deeplinkResult: DeepLinkResult) : MainIntent() {
override fun reduce(oldState: MainState): MainState =
oldState.copy(
deeplinkResult = deeplinkResult
Expand Down Expand Up @@ -141,4 +141,8 @@ sealed class MainIntent : MviIntent<MainState> {
class LaunchTransactionFlowFromDeepLink(val cryptoTicker: String, val action: AssetAction) : MainIntent() {
override fun reduce(oldState: MainState): MainState = oldState
}

class SelectRewardsAccountForAsset(val cryptoTicker: String) : MainIntent() {
override fun reduce(oldState: MainState): MainState = oldState
}
}
Expand Up @@ -4,9 +4,11 @@ import android.content.Intent
import android.net.Uri
import com.blockchain.banking.BankPaymentApproval
import com.blockchain.coincore.AssetAction
import com.blockchain.coincore.AssetFilter
import com.blockchain.coincore.BlockchainAccount
import com.blockchain.coincore.Coincore
import com.blockchain.coincore.impl.CryptoNonCustodialAccount
import com.blockchain.coincore.impl.CustodialInterestAccount
import com.blockchain.coincore.impl.CustodialTradingAccount
import com.blockchain.core.chains.ethereum.EthDataManager
import com.blockchain.core.referral.ReferralRepository
Expand Down Expand Up @@ -170,8 +172,8 @@ class MainInteractor internal constructor(
stakingAccountFlag.enabled

fun selectAccountForTxFlow(cryptoTicker: String, action: AssetAction): Single<LaunchFlowForAccount> =
coincore.walletsWithActions(setOf(action)).map { sellAccounts ->
sellAccounts.filter { account ->
coincore.walletsWithActions(setOf(action)).map { accountsForAction ->
accountsForAction.filter { account ->
account.currency.networkTicker == cryptoTicker
}
}.map { sameAssetAccounts ->
Expand All @@ -182,7 +184,7 @@ class MainInteractor internal constructor(

when {
eligibleTradingAccount != null -> {
return@map LaunchFlowForAccount.Account(eligibleTradingAccount)
return@map LaunchFlowForAccount.SourceAccount(eligibleTradingAccount)
}
else -> {
val eligibleNonCustodialAccount = sameAssetAccounts.filterIsInstance<CryptoNonCustodialAccount>()
Expand All @@ -191,7 +193,7 @@ class MainInteractor internal constructor(
}
when {
eligibleNonCustodialAccount != null -> {
return@map LaunchFlowForAccount.Account(eligibleNonCustodialAccount)
return@map LaunchFlowForAccount.SourceAccount(eligibleNonCustodialAccount)
}
else -> {
return@map LaunchFlowForAccount.NoAccount
Expand All @@ -200,4 +202,13 @@ class MainInteractor internal constructor(
}
}
}

fun selectRewardsAccountForAsset(cryptoTicker: String): Single<LaunchFlowForAccount> =
assetCatalogue.assetInfoFromNetworkTicker(cryptoTicker)?.let { cryptoCurrency ->
coincore[cryptoCurrency].accountGroup(AssetFilter.Interest).toSingle()
.map {
val interestAccount = it.accounts.first() as CustodialInterestAccount
LaunchFlowForAccount.SourceAccount(interestAccount)
}
} ?: Single.just(LaunchFlowForAccount.NoAccount)
}
Expand Up @@ -6,6 +6,7 @@ import com.blockchain.analytics.events.LaunchOrigin
import com.blockchain.api.NabuApiException
import com.blockchain.banking.BankPaymentApproval
import com.blockchain.coincore.AssetAction
import com.blockchain.coincore.TransactionTarget
import com.blockchain.commonarch.presentation.mvi.MviModel
import com.blockchain.componentlib.navigation.NavigationItem
import com.blockchain.deeplinking.processor.DeepLinkResult
Expand All @@ -30,6 +31,7 @@ import com.blockchain.walletmode.WalletModeService
import io.reactivex.rxjava3.core.Scheduler
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.Singles
import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.kotlin.subscribeBy
import kotlinx.coroutines.rx3.asObservable
Expand Down Expand Up @@ -259,13 +261,29 @@ class MainModel(
process(MainIntent.UpdateStakingFlag(false))
}
)
is MainIntent.LaunchTransactionFlowFromDeepLink -> {
interactor.selectAccountForTxFlow(intent.cryptoTicker, intent.action)
is MainIntent.LaunchTransactionFlowFromDeepLink ->
// the interest deposit flow requires that there are defined source and target accounts before launch
if (intent.action == AssetAction.InterestDeposit) {
Singles.zip(
interactor.selectAccountForTxFlow(intent.cryptoTicker, intent.action),
interactor.selectRewardsAccountForAsset(intent.cryptoTicker)
).map { (sourceAccount, targetAccount) ->
require(sourceAccount is LaunchFlowForAccount.SourceAccount)
require(targetAccount is LaunchFlowForAccount.SourceAccount)

LaunchFlowForAccount.SourceAndTargetAccount(
sourceAccount = sourceAccount.account,
targetAccount = targetAccount.account as TransactionTarget
)
}
} else {
interactor.selectAccountForTxFlow(intent.cryptoTicker, intent.action)
}
.subscribeBy(
onSuccess = { account ->
process(
MainIntent.UpdateViewToLaunch(
ViewToLaunch.LaunchTxFlowFromDeepLink(account, intent.action)
ViewToLaunch.LaunchTxFlowWithAccountForAction(account, intent.action)
)
)
},
Expand All @@ -276,12 +294,35 @@ class MainModel(

process(
MainIntent.UpdateViewToLaunch(
ViewToLaunch.LaunchTxFlowFromDeepLink(LaunchFlowForAccount.NoAccount, intent.action)
ViewToLaunch.LaunchTxFlowWithAccountForAction(
LaunchFlowForAccount.NoAccount, intent.action
)
)
)
}
)
is MainIntent.SelectRewardsAccountForAsset ->
interactor.selectRewardsAccountForAsset(intent.cryptoTicker)
.subscribeBy(
onSuccess = { account ->
process(
MainIntent.UpdateViewToLaunch(
ViewToLaunch.LaunchRewardsSummaryFromDeepLink(account)
)
)
},
onError = {
Timber.e(
"Error getting default account for Rewards Summary ${it.message}"
)

process(
MainIntent.UpdateViewToLaunch(
ViewToLaunch.LaunchRewardsSummaryFromDeepLink(LaunchFlowForAccount.NoAccount)
)
)
}
)
}
is MainIntent.UpdateStakingFlag,
MainIntent.ResetViewState,
is MainIntent.SelectNetworkForWCSession,
Expand Down
Expand Up @@ -5,6 +5,7 @@ import com.blockchain.analytics.events.LaunchOrigin
import com.blockchain.coincore.AssetAction
import com.blockchain.coincore.BlockchainAccount
import com.blockchain.coincore.CryptoTarget
import com.blockchain.coincore.TransactionTarget
import com.blockchain.commonarch.presentation.mvi.MviState
import com.blockchain.componentlib.navigation.NavigationItem
import com.blockchain.deeplinking.processor.DeepLinkResult
Expand Down Expand Up @@ -73,10 +74,14 @@ sealed class ViewToLaunch {
class LaunchTransactionFlowWithTargets(val targets: Collection<CryptoTarget>) : ViewToLaunch()
class ShowTargetScanError(val error: QrScanError) : ViewToLaunch()
object ShowReferralSheet : ViewToLaunch()
class LaunchTxFlowFromDeepLink(val account: LaunchFlowForAccount, val action: AssetAction) : ViewToLaunch()
class LaunchTxFlowWithAccountForAction(val account: LaunchFlowForAccount, val action: AssetAction) : ViewToLaunch()
class LaunchRewardsSummaryFromDeepLink(val account: LaunchFlowForAccount) : ViewToLaunch()
}

sealed class LaunchFlowForAccount {
class Account(val account: BlockchainAccount) : LaunchFlowForAccount()
class SourceAccount(val account: BlockchainAccount) : LaunchFlowForAccount()
class SourceAndTargetAccount(val sourceAccount: BlockchainAccount, val targetAccount: TransactionTarget) :
LaunchFlowForAccount()

object NoAccount : LaunchFlowForAccount()
}
Expand Up @@ -19,7 +19,6 @@ import com.blockchain.componentlib.viewextensions.gone
import com.blockchain.componentlib.viewextensions.visible
import com.blockchain.core.interest.domain.InterestService
import com.blockchain.core.price.ExchangeRates
import com.blockchain.nabu.datamanagers.CustodialWalletManager
import com.blockchain.presentation.koin.scopedInject
import com.blockchain.utils.secondsToDays
import info.blockchain.balance.AssetInfo
Expand Down Expand Up @@ -64,7 +63,6 @@ class InterestSummarySheet : SlidingModalBottomDialog<DialogSheetInterestDetails

private val disposables = CompositeDisposable()
private val interestService: InterestService by scopedInject()
private val custodialWalletManager: CustodialWalletManager by scopedInject()
private val exchangeRates: ExchangeRates by scopedInject()
private val coincore: Coincore by scopedInject()

Expand Down

0 comments on commit 4c3ff15

Please sign in to comment.