diff --git a/app/src/main/java/piuk/blockchain/android/simplebuy/SimpleBuyCheckoutFragment.kt b/app/src/main/java/piuk/blockchain/android/simplebuy/SimpleBuyCheckoutFragment.kt index e6b2022557..0f599dfc2c 100644 --- a/app/src/main/java/piuk/blockchain/android/simplebuy/SimpleBuyCheckoutFragment.kt +++ b/app/src/main/java/piuk/blockchain/android/simplebuy/SimpleBuyCheckoutFragment.kt @@ -47,6 +47,7 @@ import com.blockchain.payments.googlepay.manager.request.BillingAddressParameter import com.blockchain.payments.googlepay.manager.request.GooglePayRequestBuilder import com.blockchain.payments.googlepay.manager.request.defaultAllowedAuthMethods import com.blockchain.payments.googlepay.manager.request.defaultAllowedCardNetworks +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import com.blockchain.presentation.koin.scopedInject import com.blockchain.utils.secondsToDays import com.blockchain.utils.unsafeLazy @@ -77,7 +78,6 @@ import piuk.blockchain.android.simplebuy.sheets.SimpleBuyCancelOrderBottomSheet import piuk.blockchain.android.ui.base.ErrorButtonCopies import piuk.blockchain.android.ui.base.ErrorDialogData import piuk.blockchain.android.ui.base.ErrorSlidingBottomDialog -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.urllinks.ORDER_PRICE_EXPLANATION import piuk.blockchain.android.urllinks.PRIVATE_KEY_EXPLANATION import piuk.blockchain.android.urllinks.TRADING_ACCOUNT_LOCKS diff --git a/app/src/main/java/piuk/blockchain/android/simplebuy/paymentmethods/PaymentMethodChooserBottomSheet.kt b/app/src/main/java/piuk/blockchain/android/simplebuy/paymentmethods/PaymentMethodChooserBottomSheet.kt index 46dc043e05..2f0eb6f660 100644 --- a/app/src/main/java/piuk/blockchain/android/simplebuy/paymentmethods/PaymentMethodChooserBottomSheet.kt +++ b/app/src/main/java/piuk/blockchain/android/simplebuy/paymentmethods/PaymentMethodChooserBottomSheet.kt @@ -9,6 +9,7 @@ import com.blockchain.componentlib.viewextensions.visibleIf import com.blockchain.domain.fiatcurrencies.FiatCurrenciesService import com.blockchain.domain.paymentmethods.model.CardRejectionState import com.blockchain.domain.paymentmethods.model.PaymentMethod +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import com.blockchain.presentation.koin.scopedInject import com.blockchain.utils.unsafeLazy import info.blockchain.balance.FiatCurrency @@ -24,7 +25,6 @@ import piuk.blockchain.android.simplebuy.toAnalyticsString import piuk.blockchain.android.simplebuy.toPaymentTypeAnalyticsString import piuk.blockchain.android.ui.adapters.AdapterDelegatesManager import piuk.blockchain.android.ui.adapters.DelegationAdapter -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.ui.resources.AssetResources class PaymentMethodChooserBottomSheet : SlidingModalBottomDialog() { diff --git a/app/src/main/java/piuk/blockchain/android/ui/activity/ActivitiesFragment.kt b/app/src/main/java/piuk/blockchain/android/ui/activity/ActivitiesFragment.kt index f05a27c8b8..388c09e544 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/activity/ActivitiesFragment.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/activity/ActivitiesFragment.kt @@ -20,6 +20,7 @@ import com.blockchain.componentlib.viewextensions.visible import com.blockchain.core.price.historic.HistoricRateFetcher import com.blockchain.logging.RemoteLogger import com.blockchain.preferences.CurrencyPrefs +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import com.blockchain.presentation.koin.scopedInject import com.google.android.material.snackbar.Snackbar import info.blockchain.balance.AssetInfo @@ -35,7 +36,6 @@ import piuk.blockchain.android.databinding.FragmentActivitiesBinding import piuk.blockchain.android.ui.activity.adapter.ActivitiesDelegateAdapter import piuk.blockchain.android.ui.activity.detail.CryptoActivityDetailsBottomSheet import piuk.blockchain.android.ui.activity.detail.FiatActivityDetailsBottomSheet -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.ui.customviews.account.AccountSelectSheet import piuk.blockchain.android.ui.home.HomeScreenMviFragment import piuk.blockchain.android.ui.home.WalletClientAnalytics diff --git a/app/src/main/java/piuk/blockchain/android/ui/activity/detail/CryptoActivityDetailsBottomSheet.kt b/app/src/main/java/piuk/blockchain/android/ui/activity/detail/CryptoActivityDetailsBottomSheet.kt index 37fc0f800a..08d873a2e6 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/activity/detail/CryptoActivityDetailsBottomSheet.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/activity/detail/CryptoActivityDetailsBottomSheet.kt @@ -28,6 +28,7 @@ import com.blockchain.earn.domain.models.interest.InterestState import com.blockchain.earn.domain.models.staking.StakingState import com.blockchain.nabu.datamanagers.OrderState import com.blockchain.nabu.datamanagers.RecurringBuyFailureReason +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import com.blockchain.presentation.koin.scopedInject import com.google.android.material.snackbar.Snackbar import info.blockchain.balance.AssetInfo @@ -45,7 +46,6 @@ import piuk.blockchain.android.support.SupportCentreActivity import piuk.blockchain.android.ui.activity.ActivityType import piuk.blockchain.android.ui.activity.detail.adapter.ActivityDetailsDelegateAdapter import piuk.blockchain.android.ui.brokerage.BuySellFragment -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.ui.recurringbuy.RecurringBuyAnalytics import piuk.blockchain.android.ui.resources.AssetResources import piuk.blockchain.android.ui.transactionflow.analytics.DepositAnalytics diff --git a/app/src/main/java/piuk/blockchain/android/ui/activity/detail/FiatActivityDetailsBottomSheet.kt b/app/src/main/java/piuk/blockchain/android/ui/activity/detail/FiatActivityDetailsBottomSheet.kt index 767faedb23..838c1361cf 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/activity/detail/FiatActivityDetailsBottomSheet.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/activity/detail/FiatActivityDetailsBottomSheet.kt @@ -13,6 +13,7 @@ import com.blockchain.domain.paymentmethods.model.MobilePaymentType import com.blockchain.domain.paymentmethods.model.PaymentMethodDetails import com.blockchain.nabu.datamanagers.TransactionState import com.blockchain.nabu.datamanagers.TransactionType +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import com.blockchain.presentation.koin.scopedInject import com.blockchain.utils.toFormattedString import com.blockchain.utils.unsafeLazy @@ -22,7 +23,6 @@ import kotlinx.coroutines.launch import piuk.blockchain.android.R import piuk.blockchain.android.databinding.DialogSheetActivityDetailsBinding import piuk.blockchain.android.ui.activity.detail.adapter.FiatDetailsSheetAdapter -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor class FiatActivityDetailsBottomSheet : SlidingModalBottomDialog() { private val model: FiatActivityDetailsModel by scopedInject() diff --git a/app/src/main/java/piuk/blockchain/android/ui/addresses/AddressesActivity.kt b/app/src/main/java/piuk/blockchain/android/ui/addresses/AddressesActivity.kt index 05f02b0aed..b056e694c0 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/addresses/AddressesActivity.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/addresses/AddressesActivity.kt @@ -15,6 +15,7 @@ import com.blockchain.coincore.impl.CryptoNonCustodialAccount import com.blockchain.componentlib.alert.BlockchainSnackbar import com.blockchain.componentlib.alert.SnackbarType import com.blockchain.componentlib.databinding.ToolbarGeneralBinding +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import com.blockchain.presentation.koin.scopedInject import com.blockchain.utils.consume import com.blockchain.utils.unsafeLazy @@ -29,7 +30,6 @@ import piuk.blockchain.android.databinding.ActivityAddressesBinding import piuk.blockchain.android.ui.addresses.adapter.AccountAdapter import piuk.blockchain.android.ui.addresses.adapter.AccountListItem import piuk.blockchain.android.ui.base.MvpActivity -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.ui.customviews.SecondPasswordDialog import piuk.blockchain.android.ui.scan.QrExpected import piuk.blockchain.android.ui.scan.QrScanActivity diff --git a/app/src/main/java/piuk/blockchain/android/ui/auth/newlogin/presentation/AuthNewLoginSheet.kt b/app/src/main/java/piuk/blockchain/android/ui/auth/newlogin/presentation/AuthNewLoginSheet.kt index df61909719..f556dde5ef 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/auth/newlogin/presentation/AuthNewLoginSheet.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/auth/newlogin/presentation/AuthNewLoginSheet.kt @@ -8,13 +8,13 @@ import androidx.recyclerview.widget.RecyclerView import com.blockchain.commonarch.presentation.base.SlidingModalBottomDialog import com.blockchain.commonarch.presentation.mvi.MviBottomSheet import com.blockchain.componentlib.viewextensions.visibleIf +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import com.blockchain.presentation.koin.scopedInject import com.google.android.material.bottomsheet.BottomSheetDialogFragment import piuk.blockchain.android.databinding.AuthNewLoginSheetBinding import piuk.blockchain.android.ui.auth.newlogin.AuthNewLoginBrowserInfo import piuk.blockchain.android.ui.auth.newlogin.AuthNewLoginIpAddress import piuk.blockchain.android.ui.auth.newlogin.AuthNewLoginLocation -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.ui.login.LoginAnalytics class AuthNewLoginSheet : diff --git a/app/src/main/java/piuk/blockchain/android/ui/coinview/presentation/CoinViewActivityV2.kt b/app/src/main/java/piuk/blockchain/android/ui/coinview/presentation/CoinViewActivityV2.kt index 9aa229237c..8ecf10e2f0 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/coinview/presentation/CoinViewActivityV2.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/coinview/presentation/CoinViewActivityV2.kt @@ -16,6 +16,7 @@ import com.blockchain.commonarch.presentation.mvi_v2.NavigationRouter import com.blockchain.commonarch.presentation.mvi_v2.bindViewModel import com.blockchain.componentlib.alert.BlockchainSnackbar import com.blockchain.componentlib.alert.SnackbarType +import com.blockchain.earn.interest.InterestSummarySheet import com.blockchain.earn.staking.StakingSummaryBottomSheet import com.blockchain.earn.staking.viewmodel.StakingError import com.blockchain.extensions.enumValueOfOrNull @@ -41,7 +42,6 @@ import piuk.blockchain.android.ui.dashboard.coinview.interstitials.AccountExplai import piuk.blockchain.android.ui.dashboard.coinview.interstitials.NoBalanceActionBottomSheet import piuk.blockchain.android.ui.dashboard.coinview.recurringbuy.RecurringBuyDetailsSheet import piuk.blockchain.android.ui.dashboard.sheets.KycUpgradeNowSheet -import piuk.blockchain.android.ui.interest.InterestSummarySheet import piuk.blockchain.android.ui.kyc.navhost.KycNavHostActivity import piuk.blockchain.android.ui.recurringbuy.onboarding.RecurringBuyOnboardingActivity import piuk.blockchain.android.ui.transactionflow.analytics.CoinViewSellClickedEvent @@ -393,6 +393,14 @@ class CoinViewActivityV2 : } override fun goToInterestDeposit(toAccount: BlockchainAccount) { + analytics.logEvent( + CoinViewAnalytics.RewardsWithdrawOrAddClicked( + origin = LaunchOrigin.COIN_VIEW, + currency = (toAccount as CryptoAccount).currency.networkTicker, + type = CoinViewAnalytics.Companion.Type.ADD + ) + ) + startActivity( TransactionFlowActivity.newIntent( context = this, @@ -403,6 +411,14 @@ class CoinViewActivityV2 : } override fun goToInterestWithdraw(fromAccount: BlockchainAccount) { + analytics.logEvent( + CoinViewAnalytics.RewardsWithdrawOrAddClicked( + origin = LaunchOrigin.COIN_VIEW, + currency = (fromAccount as CryptoAccount).currency.networkTicker, + type = CoinViewAnalytics.Companion.Type.WITHDRAW + ) + ) + startActivity( TransactionFlowActivity.newIntent( context = this, @@ -425,23 +441,23 @@ class CoinViewActivityV2 : } override fun launchStakingWithdrawal(currency: Currency) { - // TODO - disabled for now + // TODO(dserrano) - STAKING - not yet implemented } override fun launchStakingDeposit(currency: Currency) { viewModel.onIntent(CoinviewIntent.LaunchStakingDepositFlow(currency)) } - override fun goToStakingActivity(currency: Currency) { + override fun goToStakingAccountActivity(currency: Currency) { viewModel.onIntent(CoinviewIntent.LaunchStakingActivity(currency)) } - override fun showStakingLoadingError(error: StakingError) { + override fun showStakingLoadingError(error: StakingError) = BlockchainSnackbar.make( view = window.decorView.rootView, message = when (error) { - StakingError.UnknownAsset -> getString( - R.string.staking_summary_sheet_error_unknown_asset, args.networkTicker + is StakingError.UnknownAsset -> getString( + R.string.staking_summary_sheet_error_unknown_asset, error.assetTicker ) StakingError.Other -> getString(R.string.staking_summary_sheet_error_other) StakingError.None -> getString(R.string.empty) @@ -449,7 +465,6 @@ class CoinViewActivityV2 : duration = Snackbar.LENGTH_SHORT, type = SnackbarType.Error ).show() - } override fun onSheetClosed() {} // host calls/ diff --git a/app/src/main/java/piuk/blockchain/android/ui/customviews/TrendingPairsView.kt b/app/src/main/java/piuk/blockchain/android/ui/customviews/TrendingPairsView.kt index 221f08ed5e..d9fb187af5 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/customviews/TrendingPairsView.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/customviews/TrendingPairsView.kt @@ -10,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView import com.blockchain.coincore.TrendingPair import com.blockchain.componentlib.viewextensions.gone import com.blockchain.componentlib.viewextensions.visible +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.kotlin.subscribeBy diff --git a/app/src/main/java/piuk/blockchain/android/ui/customviews/account/AccountList.kt b/app/src/main/java/piuk/blockchain/android/ui/customviews/account/AccountList.kt index aa21545551..2bf1c638ac 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/customviews/account/AccountList.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/customviews/account/AccountList.kt @@ -20,6 +20,7 @@ import com.blockchain.commonarch.presentation.base.ActivityIndicator import com.blockchain.commonarch.presentation.base.trackProgress import com.blockchain.componentlib.button.ButtonState import com.blockchain.domain.paymentmethods.model.FundsLocks +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.disposables.CompositeDisposable @@ -35,7 +36,6 @@ import piuk.blockchain.android.databinding.ItemAccountSelectGroupBinding import piuk.blockchain.android.ui.adapters.AdapterDelegate import piuk.blockchain.android.ui.adapters.AdapterDelegatesManager import piuk.blockchain.android.ui.adapters.DelegationAdapter -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.ui.customviews.IntroHeaderView import piuk.blockchain.android.util.context diff --git a/app/src/main/java/piuk/blockchain/android/ui/dashboard/PortfolioFragment.kt b/app/src/main/java/piuk/blockchain/android/ui/dashboard/PortfolioFragment.kt index 90abdacc17..4769f75b25 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/dashboard/PortfolioFragment.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/dashboard/PortfolioFragment.kt @@ -28,11 +28,13 @@ import com.blockchain.componentlib.viewextensions.visible import com.blockchain.componentlib.viewextensions.visibleIf import com.blockchain.domain.common.model.PromotionStyleInfo import com.blockchain.domain.referral.model.ReferralInfo +import com.blockchain.earn.interest.InterestSummarySheet import com.blockchain.extensions.minus import com.blockchain.logging.MomentEvent import com.blockchain.logging.MomentLogger import com.blockchain.preferences.CurrencyPrefs import com.blockchain.preferences.DashboardPrefs +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import com.blockchain.presentation.koin.scopedInject import com.blockchain.utils.unsafeLazy import com.blockchain.walletmode.WalletMode @@ -61,7 +63,6 @@ import piuk.blockchain.android.ui.coinview.presentation.CoinViewActivityV2.Compa import piuk.blockchain.android.ui.cowboys.CowboysAnalytics import piuk.blockchain.android.ui.cowboys.CowboysFlowActivity import piuk.blockchain.android.ui.cowboys.FlowStep -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.ui.customviews.BlockedDueToSanctionsSheet import piuk.blockchain.android.ui.customviews.KycBenefitsBottomSheet import piuk.blockchain.android.ui.customviews.VerifyIdentityNumericBenefitItem @@ -96,7 +97,6 @@ import piuk.blockchain.android.ui.dataremediation.QuestionnaireSheet import piuk.blockchain.android.ui.home.HomeScreenMviFragment import piuk.blockchain.android.ui.home.MainActivity import piuk.blockchain.android.ui.home.WalletClientAnalytics -import piuk.blockchain.android.ui.interest.InterestSummarySheet import piuk.blockchain.android.ui.linkbank.BankAuthActivity import piuk.blockchain.android.ui.linkbank.BankAuthSource import piuk.blockchain.android.ui.linkbank.alias.BankAliasLinkContract diff --git a/app/src/main/java/piuk/blockchain/android/ui/dashboard/announcements/rule/InterestAvailableAnnouncement.kt b/app/src/main/java/piuk/blockchain/android/ui/dashboard/announcements/rule/InterestAvailableAnnouncement.kt index a7c3900391..8a29821933 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/dashboard/announcements/rule/InterestAvailableAnnouncement.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/dashboard/announcements/rule/InterestAvailableAnnouncement.kt @@ -2,6 +2,7 @@ package piuk.blockchain.android.ui.dashboard.announcements.rule import androidx.annotation.VisibleForTesting import com.blockchain.analytics.Analytics +import com.blockchain.earn.EarnAnalytics import com.blockchain.walletmode.WalletMode import io.reactivex.rxjava3.core.Single import org.koin.core.component.KoinComponent @@ -12,7 +13,6 @@ import piuk.blockchain.android.ui.dashboard.announcements.AnnouncementRule import piuk.blockchain.android.ui.dashboard.announcements.DismissRecorder import piuk.blockchain.android.ui.dashboard.announcements.DismissRule import piuk.blockchain.android.ui.dashboard.announcements.StandardAnnouncementCard -import piuk.blockchain.android.ui.transactionflow.analytics.EarnAnalytics class InterestAvailableAnnouncement( dismissRecorder: DismissRecorder diff --git a/app/src/main/java/piuk/blockchain/android/ui/dashboard/coinview/CoinViewActivity.kt b/app/src/main/java/piuk/blockchain/android/ui/dashboard/coinview/CoinViewActivity.kt index b525c9672f..e9f811493d 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/dashboard/coinview/CoinViewActivity.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/dashboard/coinview/CoinViewActivity.kt @@ -46,11 +46,13 @@ import com.blockchain.componentlib.viewextensions.visible import com.blockchain.core.price.HistoricalRateList import com.blockchain.core.price.HistoricalTimeSpan import com.blockchain.core.price.Prices24HrWithDelta +import com.blockchain.earn.interest.InterestSummarySheet import com.blockchain.extensions.enumValueOfOrNull import com.blockchain.nabu.BlockedReason import com.blockchain.nabu.models.data.RecurringBuy import com.blockchain.nabu.models.data.RecurringBuyState import com.blockchain.preferences.LocalSettingsPrefs +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import com.blockchain.presentation.koin.scopedInject import com.blockchain.wallet.DefaultLabels import com.blockchain.walletmode.WalletMode @@ -72,7 +74,6 @@ import piuk.blockchain.android.simplebuy.SimpleBuyActivity import piuk.blockchain.android.simplebuy.SimpleBuySyncFactory import piuk.blockchain.android.support.SupportCentreActivity import piuk.blockchain.android.ui.coinview.presentation.CoinViewActivityV2.Companion.ACCOUNT_FOR_ACTIVITY -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.ui.customviews.BlockedDueToSanctionsSheet import piuk.blockchain.android.ui.dashboard.coinview.accounts.AccountsAdapterDelegate import piuk.blockchain.android.ui.dashboard.coinview.interstitials.AccountActionsBottomSheet @@ -80,7 +81,6 @@ import piuk.blockchain.android.ui.dashboard.coinview.interstitials.AccountExplai import piuk.blockchain.android.ui.dashboard.coinview.interstitials.NoBalanceActionBottomSheet import piuk.blockchain.android.ui.dashboard.coinview.recurringbuy.RecurringBuyDetailsSheet import piuk.blockchain.android.ui.dashboard.sheets.KycUpgradeNowSheet -import piuk.blockchain.android.ui.interest.InterestSummarySheet import piuk.blockchain.android.ui.kyc.navhost.KycNavHostActivity import piuk.blockchain.android.ui.recurringbuy.RecurringBuyAnalytics import piuk.blockchain.android.ui.recurringbuy.onboarding.RecurringBuyOnboardingActivity diff --git a/app/src/main/java/piuk/blockchain/android/ui/dashboard/coinview/interstitials/AccountActionsBottomSheet.kt b/app/src/main/java/piuk/blockchain/android/ui/dashboard/coinview/interstitials/AccountActionsBottomSheet.kt index 23038e1a8d..d686996d3d 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/dashboard/coinview/interstitials/AccountActionsBottomSheet.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/dashboard/coinview/interstitials/AccountActionsBottomSheet.kt @@ -37,6 +37,7 @@ import com.blockchain.componentlib.tag.TagType import com.blockchain.componentlib.tag.TagViewState import com.blockchain.componentlib.theme.AppTheme import com.blockchain.componentlib.theme.Grey300 +import com.blockchain.earn.EarnAnalytics import com.blockchain.nabu.BlockedReason import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog @@ -49,7 +50,6 @@ import piuk.blockchain.android.R import piuk.blockchain.android.ui.dashboard.assetdetails.AssetDetailsAnalytics import piuk.blockchain.android.ui.dashboard.assetdetails.assetActionEvent import piuk.blockchain.android.ui.dashboard.coinview.CoinViewAnalytics -import piuk.blockchain.android.ui.transactionflow.analytics.EarnAnalytics import piuk.blockchain.android.ui.transfer.analytics.TransferAnalyticsEvent import piuk.blockchain.android.util.getAccount import piuk.blockchain.android.util.putAccount diff --git a/app/src/main/java/piuk/blockchain/android/ui/dashboard/coinview/recurringbuy/RecurringBuyDetailsSheet.kt b/app/src/main/java/piuk/blockchain/android/ui/dashboard/coinview/recurringbuy/RecurringBuyDetailsSheet.kt index 61addd7d36..f4c368c2eb 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/dashboard/coinview/recurringbuy/RecurringBuyDetailsSheet.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/dashboard/coinview/recurringbuy/RecurringBuyDetailsSheet.kt @@ -15,6 +15,7 @@ import com.blockchain.domain.paymentmethods.model.PaymentMethod import com.blockchain.domain.paymentmethods.model.PaymentMethodType import com.blockchain.nabu.models.data.RecurringBuy import com.blockchain.nabu.models.data.RecurringBuyState +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import com.blockchain.presentation.koin.scopedInject import com.blockchain.utils.toFormattedDateWithoutYear import info.blockchain.balance.AssetInfo @@ -26,7 +27,6 @@ import piuk.blockchain.android.simplebuy.CheckoutAdapterDelegate import piuk.blockchain.android.simplebuy.SimpleBuyCheckoutItem import piuk.blockchain.android.simplebuy.toHumanReadableRecurringBuy import piuk.blockchain.android.simplebuy.toHumanReadableRecurringDate -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor class RecurringBuyDetailsSheet : MviBottomSheet() { diff --git a/app/src/main/java/piuk/blockchain/android/ui/home/MainActivity.kt b/app/src/main/java/piuk/blockchain/android/ui/home/MainActivity.kt index 04f71146f4..796d1835aa 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/home/MainActivity.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/home/MainActivity.kt @@ -37,7 +37,9 @@ import com.blockchain.componentlib.viewextensions.visible import com.blockchain.deeplinking.navigation.Destination import com.blockchain.deeplinking.navigation.DestinationArgs import com.blockchain.domain.referral.model.ReferralInfo +import com.blockchain.earn.EarnAnalytics import com.blockchain.earn.dashboard.EarnDashboardFragment +import com.blockchain.earn.interest.InterestSummarySheet import com.blockchain.extensions.exhaustive import com.blockchain.nfts.NftHost import com.blockchain.nfts.collection.NftCollectionFragment @@ -58,6 +60,7 @@ import com.blockchain.walletmode.WalletMode import com.blockchain.walletmode.WalletModeService import com.google.android.material.bottomsheet.BottomSheetDialogFragment import info.blockchain.balance.AssetInfo +import info.blockchain.balance.Currency import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -102,7 +105,6 @@ 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 @@ -124,7 +126,6 @@ import piuk.blockchain.android.ui.scan.QrScanActivity.Companion.getRawScanData import piuk.blockchain.android.ui.scan.ScanAndConnectBottomSheet import piuk.blockchain.android.ui.settings.SettingsActivity import piuk.blockchain.android.ui.settings.SettingsActivity.Companion.SettingsDestination -import piuk.blockchain.android.ui.transactionflow.analytics.EarnAnalytics import piuk.blockchain.android.ui.transactionflow.flow.TransactionFlowActivity import piuk.blockchain.android.ui.transfer.receive.detail.ReceiveDetailActivity import piuk.blockchain.android.ui.upsell.KycUpgradePromptManager @@ -150,7 +151,8 @@ class MainActivity : KycUpgradeNowSheet.Host, NftHost, InterestSummarySheet.Host, - NavigationRouter { + NavigationRouter, + EarnDashboardFragment.Host { override val alwaysDisableScreenshots: Boolean get() = false @@ -258,7 +260,6 @@ class MainActivity : } if (savedInstanceState == null) { - model.process(MainIntent.LoadFeatureFlags) model.process(MainIntent.PerformInitialChecks(intent)) model.process(MainIntent.CheckReferralCode) @@ -268,7 +269,7 @@ class MainActivity : } } - model.process(MainIntent.RefreshTabs) + model.process(MainIntent.LoadFeatureFlags) } override fun onResume() { @@ -765,6 +766,7 @@ class MainActivity : ) } } + is ViewToLaunch.GoToActivityForAccount -> goToActivityFor(view.account) is ViewToLaunch.LaunchRewardsSummaryFromDeepLink -> { if (view.account is LaunchFlowForAccount.SourceAccount) { showBottomSheet( @@ -1214,6 +1216,22 @@ class MainActivity : ) } + override fun launchStakingWithdrawal(currency: Currency) { + // TODO(dserrano) - STAKING - not yet implemented + } + + override fun launchStakingDeposit(currency: Currency) { + model.process( + MainIntent.SelectStakingAccountForAction(currency, AssetAction.StakingDeposit) + ) + } + + override fun goToStakingActivity(currency: Currency) { + model.process( + MainIntent.SelectStakingAccountForAction(currency, AssetAction.ViewActivity) + ) + } + override fun onSheetClosed() { Timber.d("On closed") binding.bottomNavigation.bottomNavigationState = BottomNavigationState.Add diff --git a/app/src/main/java/piuk/blockchain/android/ui/home/models/MainIntent.kt b/app/src/main/java/piuk/blockchain/android/ui/home/models/MainIntent.kt index 9451893030..4e76d85fda 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/home/models/MainIntent.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/home/models/MainIntent.kt @@ -9,6 +9,7 @@ import com.blockchain.deeplinking.processor.DeepLinkResult import com.blockchain.domain.referral.model.ReferralInfo import com.blockchain.walletconnect.domain.WalletConnectSession import com.blockchain.walletmode.WalletMode +import info.blockchain.balance.Currency sealed class MainIntent : MviIntent { data class PerformInitialChecks(val deeplinkIntent: Intent) : MainIntent() { @@ -151,4 +152,8 @@ sealed class MainIntent : MviIntent { class SelectRewardsAccountForAsset(val cryptoTicker: String) : MainIntent() { override fun reduce(oldState: MainState): MainState = oldState } + + class SelectStakingAccountForAction(val currency: Currency, val assetAction: AssetAction) : MainIntent() { + override fun reduce(oldState: MainState): MainState = oldState + } } diff --git a/app/src/main/java/piuk/blockchain/android/ui/home/models/MainInteractor.kt b/app/src/main/java/piuk/blockchain/android/ui/home/models/MainInteractor.kt index d08f5dfd35..d7412470ad 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/home/models/MainInteractor.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/home/models/MainInteractor.kt @@ -10,6 +10,7 @@ import com.blockchain.coincore.Coincore import com.blockchain.coincore.TransactionTarget import com.blockchain.coincore.impl.CryptoNonCustodialAccount import com.blockchain.coincore.impl.CustodialInterestAccount +import com.blockchain.coincore.impl.CustodialStakingAccount import com.blockchain.coincore.impl.CustodialTradingAccount import com.blockchain.core.chains.ethereum.EthDataManager import com.blockchain.core.referral.ReferralRepository @@ -31,6 +32,7 @@ import com.blockchain.walletmode.WalletModeService import exchange.ExchangeLinking import info.blockchain.balance.AssetCatalogue import info.blockchain.balance.AssetInfo +import info.blockchain.balance.Currency import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.core.Single @@ -248,6 +250,12 @@ class MainInteractor internal constructor( } } ?: Single.just(LaunchFlowForAccount.NoAccount) + fun selectStakingAccountForCurrency(currency: Currency): Single = + coincore[currency].accountGroup(AssetFilter.Staking).toSingle() + .map { + it.accounts.first() as CustodialStakingAccount + } + fun getEnabledWalletMode(): Observable = walletModeService.walletMode.asObservable() diff --git a/app/src/main/java/piuk/blockchain/android/ui/home/models/MainModel.kt b/app/src/main/java/piuk/blockchain/android/ui/home/models/MainModel.kt index 2da94add49..700f724fe2 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/home/models/MainModel.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/home/models/MainModel.kt @@ -330,7 +330,35 @@ class MainModel( ) } ) - is MainIntent.UpdateFlags, + is MainIntent.SelectStakingAccountForAction -> interactor.selectStakingAccountForCurrency(intent.currency) + .subscribeBy( + onSuccess = { account -> + when (val action = intent.assetAction) { + AssetAction.StakingDeposit -> process( + MainIntent.UpdateViewToLaunch( + ViewToLaunch.LaunchTxFlowWithAccountForAction( + LaunchFlowForAccount.TargetAccount(account as TransactionTarget), action + ) + ) + ) + AssetAction.ViewActivity -> + process( + MainIntent.UpdateViewToLaunch(ViewToLaunch.GoToActivityForAccount(account)) + ) + + else -> { + // do nothing + } + } + }, + onError = { + Timber.e("Error getting default account for Staking ${it.message}") + } + ) + is MainIntent.UpdateFlags -> { + process(MainIntent.RefreshTabs) + null + } MainIntent.ResetViewState, is MainIntent.SelectNetworkForWCSession, is MainIntent.UpdateViewToLaunch, diff --git a/app/src/main/java/piuk/blockchain/android/ui/home/models/MainState.kt b/app/src/main/java/piuk/blockchain/android/ui/home/models/MainState.kt index 88c23cce85..c89b36aefe 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/home/models/MainState.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/home/models/MainState.kt @@ -77,6 +77,7 @@ sealed class ViewToLaunch { object ShowReferralSheet : ViewToLaunch() class LaunchTxFlowWithAccountForAction(val account: LaunchFlowForAccount, val action: AssetAction) : ViewToLaunch() class LaunchRewardsSummaryFromDeepLink(val account: LaunchFlowForAccount) : ViewToLaunch() + class GoToActivityForAccount(val account: BlockchainAccount) : ViewToLaunch() } sealed class LaunchFlowForAccount { diff --git a/app/src/main/java/piuk/blockchain/android/ui/interest/InterestDashboardActivity.kt b/app/src/main/java/piuk/blockchain/android/ui/interest/InterestDashboardActivity.kt index 10f871ffe3..e2ff91f85a 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/interest/InterestDashboardActivity.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/interest/InterestDashboardActivity.kt @@ -11,6 +11,8 @@ import com.blockchain.coincore.CryptoAccount import com.blockchain.commonarch.presentation.base.BlockchainActivity import com.blockchain.commonarch.presentation.mvi_v2.NavigationRouter import com.blockchain.componentlib.databinding.ToolbarGeneralBinding +import com.blockchain.earn.EarnAnalytics +import com.blockchain.earn.interest.InterestSummarySheet import com.blockchain.extensions.exhaustive import com.blockchain.utils.consume import io.reactivex.rxjava3.disposables.CompositeDisposable @@ -22,7 +24,6 @@ import piuk.blockchain.android.ui.interest.presentation.InterestDashboardFragmen import piuk.blockchain.android.ui.interest.presentation.InterestDashboardNavigationEvent import piuk.blockchain.android.ui.interest.presentation.InterestDashboardSharedViewModel import piuk.blockchain.android.ui.kyc.navhost.KycNavHostActivity -import piuk.blockchain.android.ui.transactionflow.analytics.EarnAnalytics import piuk.blockchain.android.ui.transactionflow.flow.TransactionFlowActivity import piuk.blockchain.android.util.putAccount diff --git a/app/src/main/java/piuk/blockchain/android/ui/linkbank/yapily/YapilyBankSelectionFragment.kt b/app/src/main/java/piuk/blockchain/android/ui/linkbank/yapily/YapilyBankSelectionFragment.kt index d3e0c9c14f..9164ecebc8 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/linkbank/yapily/YapilyBankSelectionFragment.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/linkbank/yapily/YapilyBankSelectionFragment.kt @@ -9,9 +9,9 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import com.blockchain.analytics.Analytics import com.blockchain.domain.paymentmethods.model.YapilyAttributes +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import org.koin.android.ext.android.inject import piuk.blockchain.android.databinding.FragmentSimpleBuyYapilyBankSelectBinding -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.ui.linkbank.BankAuthAnalytics import piuk.blockchain.android.ui.linkbank.BankAuthFlowNavigator import piuk.blockchain.android.ui.linkbank.BankAuthSource diff --git a/app/src/main/java/piuk/blockchain/android/ui/linkbank/yapily/adapters/YapilyExpandableListItemDelegate.kt b/app/src/main/java/piuk/blockchain/android/ui/linkbank/yapily/adapters/YapilyExpandableListItemDelegate.kt index 10f210fc52..058767812b 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/linkbank/yapily/adapters/YapilyExpandableListItemDelegate.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/linkbank/yapily/adapters/YapilyExpandableListItemDelegate.kt @@ -6,11 +6,11 @@ import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.blockchain.componentlib.viewextensions.visibleIf +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import piuk.blockchain.android.R import piuk.blockchain.android.databinding.ItemYapilyExpandableListBinding import piuk.blockchain.android.databinding.ItemYapilyInfoBinding import piuk.blockchain.android.ui.adapters.AdapterDelegate -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.util.context import piuk.blockchain.android.util.getResolvedColor diff --git a/app/src/main/java/piuk/blockchain/android/ui/resources/AccountIcon.kt b/app/src/main/java/piuk/blockchain/android/ui/resources/AccountIcon.kt index bdaee1be2e..2fd9801423 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/resources/AccountIcon.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/resources/AccountIcon.kt @@ -13,8 +13,8 @@ import com.blockchain.coincore.fiat.FiatAccountGroup import com.blockchain.coincore.impl.AllCustodialWalletsAccount import com.blockchain.coincore.impl.AllNonCustodialWalletsAccount import com.blockchain.coincore.impl.AllWalletsAccount +import com.blockchain.coincore.impl.CryptoAccountCustodialSingleGroup import com.blockchain.coincore.impl.CryptoAccountNonCustodialGroup -import com.blockchain.coincore.impl.CryptoAccountTradingGroup import com.blockchain.coincore.impl.CryptoExchangeAccount import com.blockchain.coincore.impl.CryptoNonCustodialAccount import info.blockchain.balance.Currency @@ -64,7 +64,7 @@ class AccountIcon( is AllWalletsAccount -> R.drawable.ic_all_wallets_white is AllCustodialWalletsAccount -> R.drawable.ic_portfolio is AllNonCustodialWalletsAccount -> R.drawable.ic_defi_wallet - is CryptoAccountTradingGroup -> null + is CryptoAccountCustodialSingleGroup -> null is CryptoAccountNonCustodialGroup -> null is FiatAccountGroup -> null else -> throw IllegalArgumentException("$account is not a valid group") @@ -78,7 +78,7 @@ class AccountIcon( is AllNonCustodialWalletsAccount, is AllCustodialWalletsAccount -> null is FiatAccount, - is CryptoAccountTradingGroup -> account.accounts[0].currency + is CryptoAccountCustodialSingleGroup -> account.accounts[0].currency is CryptoAccountNonCustodialGroup -> account.asset else -> throw IllegalArgumentException("$account is not a valid group") } diff --git a/app/src/main/java/piuk/blockchain/android/ui/swap/SwapFragment.kt b/app/src/main/java/piuk/blockchain/android/ui/swap/SwapFragment.kt index d08d14089d..71c3aa8a0b 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/swap/SwapFragment.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/swap/SwapFragment.kt @@ -26,6 +26,7 @@ import com.blockchain.core.kyc.domain.KycService import com.blockchain.core.kyc.domain.model.KycTier import com.blockchain.core.kyc.domain.model.KycTiers import com.blockchain.core.price.ExchangeRatesDataManager +import com.blockchain.earn.TxFlowAnalyticsAccountType import com.blockchain.extensions.exhaustive import com.blockchain.nabu.BlockedReason import com.blockchain.nabu.Feature @@ -60,7 +61,6 @@ import piuk.blockchain.android.ui.dashboard.sheets.KycUpgradeNowSheet import piuk.blockchain.android.ui.kyc.navhost.KycNavHostActivity import piuk.blockchain.android.ui.resources.AssetResources import piuk.blockchain.android.ui.transactionflow.analytics.SwapAnalyticsEvents -import piuk.blockchain.android.ui.transactionflow.analytics.TxFlowAnalyticsAccountType import piuk.blockchain.android.ui.transactionflow.flow.TransactionFlowActivity import piuk.blockchain.android.urllinks.URL_RUSSIA_SANCTIONS_EU5 import piuk.blockchain.android.urllinks.URL_RUSSIA_SANCTIONS_EU8 diff --git a/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/Analytics.kt b/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/Analytics.kt index 9c78237837..5aaefb586b 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/Analytics.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/Analytics.kt @@ -21,6 +21,8 @@ import com.blockchain.coincore.impl.CryptoNonCustodialAccount import com.blockchain.coincore.impl.txEngine.swap.OUTGOING_FEE import com.blockchain.coincore.impl.txEngine.swap.RECEIVE_AMOUNT import com.blockchain.domain.paymentmethods.model.PaymentMethodType +import com.blockchain.earn.EarnAnalytics +import com.blockchain.earn.TxFlowAnalyticsAccountType import com.blockchain.extensions.withoutNullValues import com.blockchain.logging.RemoteLogger import info.blockchain.balance.Currency @@ -775,26 +777,6 @@ fun TransactionTarget.toCategory(): String = else -> WALLET_TYPE_UNKNOWN } -enum class TxFlowAnalyticsAccountType { - TRADING, USERKEY, SAVINGS, EXTERNAL; - - companion object { - fun fromAccount(account: BlockchainAccount): TxFlowAnalyticsAccountType = - when (account) { - is TradingAccount, - is BankAccount -> TRADING - is InterestAccount -> SAVINGS - else -> USERKEY - } - - fun fromTransactionTarget(transactionTarget: TransactionTarget): TxFlowAnalyticsAccountType { - (transactionTarget as? BlockchainAccount)?.let { - return fromAccount(it) - } ?: return EXTERNAL - } - } -} - private fun FeeLevel.toAnalyticsFee(): AnalyticsFeeType = when (this) { FeeLevel.Custom -> AnalyticsFeeType.CUSTOM diff --git a/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/SellAnalyticsEvent.kt b/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/SellAnalyticsEvent.kt index a1073a093c..317b938166 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/SellAnalyticsEvent.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/SellAnalyticsEvent.kt @@ -2,6 +2,7 @@ package piuk.blockchain.android.ui.transactionflow.analytics import com.blockchain.analytics.AnalyticsEvent import com.blockchain.analytics.events.AnalyticsNames +import com.blockchain.earn.TxFlowAnalyticsAccountType import com.blockchain.extensions.withoutNullValues import info.blockchain.balance.Currency import info.blockchain.balance.CurrencyType diff --git a/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/SendAnalyticsEvent.kt b/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/SendAnalyticsEvent.kt index e9da7b6e31..a0c4019a81 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/SendAnalyticsEvent.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/SendAnalyticsEvent.kt @@ -3,6 +3,7 @@ package piuk.blockchain.android.ui.transactionflow.analytics import com.blockchain.analytics.AnalyticsEvent import com.blockchain.analytics.events.AnalyticsNames import com.blockchain.coincore.FeeLevel +import com.blockchain.earn.TxFlowAnalyticsAccountType import com.blockchain.extensions.withoutNullValues import info.blockchain.balance.Currency import java.io.Serializable diff --git a/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/SwapAnalyticsEvents.kt b/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/SwapAnalyticsEvents.kt index 9a0423943b..6013d7d369 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/SwapAnalyticsEvents.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/SwapAnalyticsEvents.kt @@ -3,6 +3,7 @@ package piuk.blockchain.android.ui.transactionflow.analytics import com.blockchain.analytics.AnalyticsEvent import com.blockchain.analytics.events.AnalyticsNames import com.blockchain.analytics.events.LaunchOrigin +import com.blockchain.earn.TxFlowAnalyticsAccountType import info.blockchain.balance.Currency import info.blockchain.balance.CurrencyType import info.blockchain.balance.Money diff --git a/app/src/main/java/piuk/blockchain/android/ui/transactionflow/flow/ConfirmTransactionFragment.kt b/app/src/main/java/piuk/blockchain/android/ui/transactionflow/flow/ConfirmTransactionFragment.kt index 773756a66c..4034d6a752 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/transactionflow/flow/ConfirmTransactionFragment.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/transactionflow/flow/ConfirmTransactionFragment.kt @@ -14,13 +14,13 @@ import com.blockchain.componentlib.viewextensions.visibleIf import com.blockchain.core.price.ExchangeRates import com.blockchain.extensions.enumValueOfOrNull import com.blockchain.preferences.CurrencyPrefs +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import com.blockchain.presentation.koin.scopedInject import org.koin.android.ext.android.inject import piuk.blockchain.android.databinding.FragmentTxFlowConfirmBinding import piuk.blockchain.android.fraud.domain.service.FraudService import piuk.blockchain.android.simplebuy.sheets.AchTermsAndConditionsBottomSheet import piuk.blockchain.android.simplebuy.sheets.AchWithdrawalHoldInfoBottomSheet -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.ui.transactionflow.engine.TransactionIntent import piuk.blockchain.android.ui.transactionflow.engine.TransactionState import piuk.blockchain.android.ui.transactionflow.engine.TxExecutionStatus diff --git a/app/src/main/java/piuk/blockchain/android/ui/transfer/analytics/TransferAnalyticsEvent.kt b/app/src/main/java/piuk/blockchain/android/ui/transfer/analytics/TransferAnalyticsEvent.kt index 05c1ddbfb3..0cd786eb8d 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/transfer/analytics/TransferAnalyticsEvent.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/transfer/analytics/TransferAnalyticsEvent.kt @@ -5,9 +5,9 @@ import com.blockchain.analytics.events.AnalyticsNames import com.blockchain.analytics.events.LaunchOrigin import com.blockchain.coincore.CryptoAccount import com.blockchain.coincore.SingleAccount +import com.blockchain.earn.TxFlowAnalyticsAccountType import info.blockchain.balance.AssetInfo import java.io.Serializable -import piuk.blockchain.android.ui.transactionflow.analytics.TxFlowAnalyticsAccountType import piuk.blockchain.android.ui.transactionflow.analytics.toCategory sealed class TransferAnalyticsEvent( diff --git a/app/src/main/java/piuk/blockchain/android/ui/transfer/receive/ExpandableAssetsAdapter.kt b/app/src/main/java/piuk/blockchain/android/ui/transfer/receive/ExpandableAssetsAdapter.kt index 5c12b70fe5..afbc284602 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/transfer/receive/ExpandableAssetsAdapter.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/transfer/receive/ExpandableAssetsAdapter.kt @@ -7,6 +7,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.blockchain.coincore.CryptoAccount import com.blockchain.componentlib.viewextensions.visibleIf +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import info.blockchain.balance.AssetInfo import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Scheduler @@ -16,7 +17,6 @@ import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.kotlin.subscribeBy import piuk.blockchain.android.R import piuk.blockchain.android.databinding.ItemAssetExpandableBinding -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.ui.resources.AssetResources import piuk.blockchain.android.util.context import piuk.blockchain.android.util.getResolvedColor diff --git a/app/src/main/java/piuk/blockchain/android/ui/transfer/receive/ReceiveFragment.kt b/app/src/main/java/piuk/blockchain/android/ui/transfer/receive/ReceiveFragment.kt index 0fd60f17c1..5f0e23455e 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/transfer/receive/ReceiveFragment.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/transfer/receive/ReceiveFragment.kt @@ -12,6 +12,8 @@ import com.blockchain.coincore.CryptoAccount import com.blockchain.commonarch.presentation.mvi.MviFragment import com.blockchain.componentlib.viewextensions.gone import com.blockchain.componentlib.viewextensions.visible +import com.blockchain.earn.TxFlowAnalyticsAccountType +import com.blockchain.presentation.customviews.BlockchainListDividerDecor import com.blockchain.presentation.koin.scopedInject import com.blockchain.walletmode.WalletMode import com.blockchain.walletmode.WalletModeService @@ -24,12 +26,10 @@ import org.koin.android.ext.android.inject import piuk.blockchain.android.R import piuk.blockchain.android.campaign.CampaignType import piuk.blockchain.android.databinding.FragmentReceiveBinding -import piuk.blockchain.android.ui.customviews.BlockchainListDividerDecor import piuk.blockchain.android.ui.customviews.account.AccountListViewItem import piuk.blockchain.android.ui.dashboard.sheets.KycUpgradeNowSheet import piuk.blockchain.android.ui.kyc.navhost.KycNavHostActivity import piuk.blockchain.android.ui.resources.AssetResources -import piuk.blockchain.android.ui.transactionflow.analytics.TxFlowAnalyticsAccountType import piuk.blockchain.android.ui.transfer.analytics.TransferAnalyticsEvent import piuk.blockchain.android.ui.transfer.receive.detail.ReceiveDetailActivity import piuk.blockchain.android.util.AfterTextChangedWatcher diff --git a/app/src/main/java/piuk/blockchain/android/ui/transfer/receive/detail/ReceiveDetailActivity.kt b/app/src/main/java/piuk/blockchain/android/ui/transfer/receive/detail/ReceiveDetailActivity.kt index b180f95feb..4e628e083d 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/transfer/receive/detail/ReceiveDetailActivity.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/transfer/receive/detail/ReceiveDetailActivity.kt @@ -18,13 +18,13 @@ import com.blockchain.componentlib.viewextensions.gone import com.blockchain.componentlib.viewextensions.invisible import com.blockchain.componentlib.viewextensions.visible import com.blockchain.componentlib.viewextensions.visibleIf +import com.blockchain.earn.TxFlowAnalyticsAccountType import com.blockchain.presentation.koin.scopedInject import org.koin.android.ext.android.inject import piuk.blockchain.android.R import piuk.blockchain.android.databinding.ActivityReceiveDetailsBinding import piuk.blockchain.android.scan.QRCodeEncoder import piuk.blockchain.android.ui.customviews.account.AccountListViewItem -import piuk.blockchain.android.ui.transactionflow.analytics.TxFlowAnalyticsAccountType import piuk.blockchain.android.ui.transfer.analytics.TransferAnalyticsEvent import piuk.blockchain.android.ui.transfer.receive.plugin.ReceiveMemoView import piuk.blockchain.android.util.copyToClipboardWithConfirmationDialog diff --git a/app/src/main/java/piuk/blockchain/android/ui/transfer/send/TransferSendFragment.kt b/app/src/main/java/piuk/blockchain/android/ui/transfer/send/TransferSendFragment.kt index 3652cb0caa..0f97b030ca 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/transfer/send/TransferSendFragment.kt +++ b/app/src/main/java/piuk/blockchain/android/ui/transfer/send/TransferSendFragment.kt @@ -9,6 +9,7 @@ import com.blockchain.coincore.AssetAction import com.blockchain.coincore.BlockchainAccount import com.blockchain.coincore.CryptoAccount import com.blockchain.coincore.eth.MultiChainAccount +import com.blockchain.earn.TxFlowAnalyticsAccountType import com.blockchain.preferences.OnboardingPrefs import com.google.android.material.bottomsheet.BottomSheetDialogFragment import io.reactivex.rxjava3.disposables.CompositeDisposable @@ -23,7 +24,6 @@ import piuk.blockchain.android.ui.home.ActionActivity import piuk.blockchain.android.ui.home.HomeNavigator import piuk.blockchain.android.ui.locks.LocksDetailsActivity import piuk.blockchain.android.ui.transactionflow.analytics.SendAnalyticsEvent -import piuk.blockchain.android.ui.transactionflow.analytics.TxFlowAnalyticsAccountType import piuk.blockchain.android.ui.transactionflow.flow.TransactionFlowActivity import piuk.blockchain.android.ui.transactionflow.flow.send.SendNetworkWarningSheet import piuk.blockchain.android.ui.transfer.AccountSelectorFragment diff --git a/app/src/test/java/piuk/blockchain/android/ui/interest/presentation/InterestDashboardViewModelTest.kt b/app/src/test/java/piuk/blockchain/android/ui/interest/presentation/InterestDashboardViewModelTest.kt index 8d5dd4f1ee..4b19df5c66 100644 --- a/app/src/test/java/piuk/blockchain/android/ui/interest/presentation/InterestDashboardViewModelTest.kt +++ b/app/src/test/java/piuk/blockchain/android/ui/interest/presentation/InterestDashboardViewModelTest.kt @@ -1,7 +1,7 @@ package piuk.blockchain.android.ui.interest.presentation import app.cash.turbine.test -import com.blockchain.coincore.impl.CryptoAccountTradingGroup +import com.blockchain.coincore.impl.CryptoAccountCustodialSingleGroup import com.blockchain.coincore.impl.CustodialInterestAccount import com.blockchain.core.kyc.domain.KycService import com.blockchain.core.kyc.domain.model.KycTier @@ -58,7 +58,7 @@ class InterestDashboardViewModelTest { coEvery { getAccountGroupUseCase(any(), any()) } returns Outcome.Success( - CryptoAccountTradingGroup( + CryptoAccountCustodialSingleGroup( "label", listOf(mockk()) ) ) diff --git a/coincore/src/main/java/com/blockchain/coincore/impl/AccountFilter.kt b/coincore/src/main/java/com/blockchain/coincore/impl/AccountFilter.kt index 3bdc845352..8dc5b580f2 100644 --- a/coincore/src/main/java/com/blockchain/coincore/impl/AccountFilter.kt +++ b/coincore/src/main/java/com/blockchain/coincore/impl/AccountFilter.kt @@ -19,15 +19,15 @@ fun SingleAccountList.makeAccountGroup( AssetFilter.NonCustodial -> buildNonCustodialGroup(asset, labels, this) AssetFilter.Trading -> - buildCustodialGroup(labels, this) + buildTradingGroup(labels, this) AssetFilter.Staking -> buildStakingGroup(labels, this) AssetFilter.Interest -> buildInterestGroup(labels, this) - AssetFilter.Custodial -> buildCustodialPlusInterestPlusStakingGroup(labels, this) + AssetFilter.Custodial -> buildAllCustodialAccountsGroup(labels, this) }.exhaustive -private fun buildCustodialPlusInterestPlusStakingGroup( +private fun buildAllCustodialAccountsGroup( labels: DefaultLabels, accountList: List ): AccountGroup? { @@ -52,20 +52,20 @@ private fun buildInterestGroup( ): AccountGroup? { val grpAccounts = accountList.filterIsInstance() return if (grpAccounts.isNotEmpty()) - CryptoAccountTradingGroup( + CryptoAccountCustodialSingleGroup( labels.getDefaultInterestWalletLabel(), grpAccounts ) else null } -private fun buildCustodialGroup( +private fun buildTradingGroup( labels: DefaultLabels, accountList: List ): AccountGroup? { val grpAccounts = accountList.filterIsInstance() return if (grpAccounts.isNotEmpty()) { - CryptoAccountTradingGroup( + CryptoAccountCustodialSingleGroup( labels.getDefaultTradingWalletLabel(), grpAccounts ) } else { @@ -77,9 +77,9 @@ private fun buildStakingGroup( labels: DefaultLabels, accountList: List ): AccountGroup? { - val grpAccounts = accountList.filterIsInstance() + val grpAccounts = accountList.filterIsInstance() return if (grpAccounts.isNotEmpty()) { - CryptoAccountTradingGroup( + CryptoAccountCustodialSingleGroup( labels.getDefaultStakingWalletLabel(), grpAccounts ) } else { diff --git a/coincore/src/main/java/com/blockchain/coincore/impl/CryptoAccountBase.kt b/coincore/src/main/java/com/blockchain/coincore/impl/CryptoAccountBase.kt index e969dd5146..be351b514b 100644 --- a/coincore/src/main/java/com/blockchain/coincore/impl/CryptoAccountBase.kt +++ b/coincore/src/main/java/com/blockchain/coincore/impl/CryptoAccountBase.kt @@ -450,7 +450,7 @@ abstract class CryptoNonCustodialAccount( * so all the methods on this can just delegate directly * to the (required) CryptoSingleAccountCustodialBase */ -class CryptoAccountTradingGroup( +class CryptoAccountCustodialSingleGroup( override val label: String, override val accounts: SingleAccountList, ) : SameCurrencyAccountGroup { diff --git a/common/presentation/build.gradle b/common/presentation/build.gradle index 326176b4ef..c021ec688e 100644 --- a/common/presentation/build.gradle +++ b/common/presentation/build.gradle @@ -1,4 +1,4 @@ -apply from: rootProject.file('gradle/local/common-feature-android.gradle') +apply from: rootProject.file('gradle/local/common-feature-android-presentation.gradle') android { buildFeatures { diff --git a/app/src/main/java/piuk/blockchain/android/ui/customviews/BlockchainListDividerDecor.kt b/common/presentation/src/main/kotlin/com/blockchain/presentation/customviews/BlockchainListDividerDecor.kt similarity index 95% rename from app/src/main/java/piuk/blockchain/android/ui/customviews/BlockchainListDividerDecor.kt rename to common/presentation/src/main/kotlin/com/blockchain/presentation/customviews/BlockchainListDividerDecor.kt index e9f95d563e..3dd8a3a4b1 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/customviews/BlockchainListDividerDecor.kt +++ b/common/presentation/src/main/kotlin/com/blockchain/presentation/customviews/BlockchainListDividerDecor.kt @@ -1,4 +1,4 @@ -package piuk.blockchain.android.ui.customviews +package com.blockchain.presentation.customviews import android.content.Context import android.graphics.Canvas @@ -7,7 +7,7 @@ import android.graphics.drawable.Drawable import android.view.View import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView -import piuk.blockchain.android.R +import com.blockchain.common.R class BlockchainListDividerDecor(context: Context) : RecyclerView.ItemDecoration() { diff --git a/app/src/main/res/anim/layout_animation_fall_down.xml b/common/presentation/src/main/res/anim/layout_animation_fall_down.xml similarity index 100% rename from app/src/main/res/anim/layout_animation_fall_down.xml rename to common/presentation/src/main/res/anim/layout_animation_fall_down.xml diff --git a/app/src/main/res/drawable/divider_item.xml b/common/presentation/src/main/res/drawable/divider_item.xml similarity index 100% rename from app/src/main/res/drawable/divider_item.xml rename to common/presentation/src/main/res/drawable/divider_item.xml diff --git a/app/src/main/res/values-small/dimens.xml b/common/presentation/src/main/res/values-small/dimens.xml similarity index 100% rename from app/src/main/res/values-small/dimens.xml rename to common/presentation/src/main/res/values-small/dimens.xml diff --git a/app/src/main/res/values-sw240dp/dimens.xml b/common/presentation/src/main/res/values-sw240dp/dimens.xml similarity index 100% rename from app/src/main/res/values-sw240dp/dimens.xml rename to common/presentation/src/main/res/values-sw240dp/dimens.xml diff --git a/app/src/main/res/values-sw480dp/dimens.xml b/common/presentation/src/main/res/values-sw480dp/dimens.xml similarity index 100% rename from app/src/main/res/values-sw480dp/dimens.xml rename to common/presentation/src/main/res/values-sw480dp/dimens.xml diff --git a/app/src/main/res/values-sw600dp/dimens.xml b/common/presentation/src/main/res/values-sw600dp/dimens.xml similarity index 100% rename from app/src/main/res/values-sw600dp/dimens.xml rename to common/presentation/src/main/res/values-sw600dp/dimens.xml diff --git a/app/src/main/res/values/color_palette.xml b/common/presentation/src/main/res/values/color_palette.xml similarity index 100% rename from app/src/main/res/values/color_palette.xml rename to common/presentation/src/main/res/values/color_palette.xml diff --git a/app/src/main/res/values/colors.xml b/common/presentation/src/main/res/values/colors.xml similarity index 100% rename from app/src/main/res/values/colors.xml rename to common/presentation/src/main/res/values/colors.xml diff --git a/app/src/main/res/values/dimens.xml b/common/presentation/src/main/res/values/dimens.xml similarity index 100% rename from app/src/main/res/values/dimens.xml rename to common/presentation/src/main/res/values/dimens.xml diff --git a/app/src/main/res/values/preloaded_fonts.xml b/common/presentation/src/main/res/values/preloaded_fonts.xml similarity index 100% rename from app/src/main/res/values/preloaded_fonts.xml rename to common/presentation/src/main/res/values/preloaded_fonts.xml diff --git a/app/src/main/res/values/strings.xml b/common/presentation/src/main/res/values/strings.xml similarity index 100% rename from app/src/main/res/values/strings.xml rename to common/presentation/src/main/res/values/strings.xml diff --git a/app/src/main/res/values/style_buttons.xml b/common/presentation/src/main/res/values/style_buttons.xml similarity index 100% rename from app/src/main/res/values/style_buttons.xml rename to common/presentation/src/main/res/values/style_buttons.xml diff --git a/app/src/main/res/values/style_lists.xml b/common/presentation/src/main/res/values/style_lists.xml similarity index 100% rename from app/src/main/res/values/style_lists.xml rename to common/presentation/src/main/res/values/style_lists.xml diff --git a/app/src/main/res/values/style_text.xml b/common/presentation/src/main/res/values/style_text.xml similarity index 100% rename from app/src/main/res/values/style_text.xml rename to common/presentation/src/main/res/values/style_text.xml diff --git a/app/src/main/res/values/styles.xml b/common/presentation/src/main/res/values/styles.xml similarity index 100% rename from app/src/main/res/values/styles.xml rename to common/presentation/src/main/res/values/styles.xml diff --git a/commonarch/src/main/java/com/blockchain/commonarch/presentation/mvi_v2/MVIFragment.kt b/commonarch/src/main/java/com/blockchain/commonarch/presentation/mvi_v2/MVIFragment.kt index a7dd5c98dc..d0f719a497 100644 --- a/commonarch/src/main/java/com/blockchain/commonarch/presentation/mvi_v2/MVIFragment.kt +++ b/commonarch/src/main/java/com/blockchain/commonarch/presentation/mvi_v2/MVIFragment.kt @@ -1,16 +1,26 @@ package com.blockchain.commonarch.presentation.mvi_v2 import android.os.Bundle +import androidx.annotation.UiThread import androidx.fragment.app.Fragment import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.blockchain.commonarch.presentation.mvi_v2.ModelConfigArgs.ParcelableArgs +import com.google.android.material.bottomsheet.BottomSheetDialogFragment import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch abstract class MVIFragment : Fragment() { abstract fun onStateUpdated(state: TViewState) + + @UiThread + fun showBottomSheet(bottomSheet: BottomSheetDialogFragment?) = + bottomSheet?.show(childFragmentManager, BOTTOM_SHEET) + + companion object { + const val BOTTOM_SHEET = "BOTTOM_SHEET" + } } fun , TArgs : ParcelableArgs> TFragment.withArgs( diff --git a/componentlib/src/main/java/com/blockchain/componentlib/tablerow/BalanceTableRow.kt b/componentlib/src/main/java/com/blockchain/componentlib/tablerow/BalanceTableRow.kt index 22af99012a..28b3b35959 100644 --- a/componentlib/src/main/java/com/blockchain/componentlib/tablerow/BalanceTableRow.kt +++ b/componentlib/src/main/java/com/blockchain/componentlib/tablerow/BalanceTableRow.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.unit.dp import com.blockchain.componentlib.R import com.blockchain.componentlib.basic.Image import com.blockchain.componentlib.basic.ImageResource +import com.blockchain.componentlib.tag.TagType import com.blockchain.componentlib.tag.TagViewState import com.blockchain.componentlib.tag.TagsRow import com.blockchain.componentlib.theme.AppSurface @@ -171,7 +172,7 @@ fun BalanceTableRow_Texts() { @Preview @Composable -fun BalanceTableRow_TitleStart_TwoEnd() { +fun BalanceTableRow_TitleStart_No_Body_Start() { AppTheme { AppSurface { BalanceTableRow( @@ -185,3 +186,44 @@ fun BalanceTableRow_TitleStart_TwoEnd() { } } } + +@Preview +@Composable +fun BalanceTableRow_TitleStart_Tags() { + AppTheme { + AppSurface { + BalanceTableRow( + titleStart = buildAnnotatedString { append("Some title here") }, + titleEnd = buildAnnotatedString { append("100 BTC") }, + bodyEnd = buildAnnotatedString { append("$100") }, + bodyStart = buildAnnotatedString { append("Some body here") }, + onClick = {}, + tags = listOf(TagViewState("One", TagType.Default()), TagViewState("Two", TagType.Success())), + startImageResource = ImageResource.Local( + id = R.drawable.ic_blockchain, + ), + ) + } + } +} + +@Preview +@Composable +fun BalanceTableRow_TitleStart_Tags_Inline() { + AppTheme { + AppSurface { + BalanceTableRow( + titleStart = buildAnnotatedString { append("Some title here") }, + titleEnd = buildAnnotatedString { append("100 BTC") }, + bodyEnd = buildAnnotatedString { append("$100") }, + bodyStart = buildAnnotatedString { append("Some body here") }, + onClick = {}, + tags = listOf(TagViewState("One", TagType.Default()), TagViewState("Two", TagType.Success())), + isInlineTags = true, + startImageResource = ImageResource.Local( + id = R.drawable.ic_blockchain, + ), + ) + } + } +} diff --git a/componentlib/src/main/java/com/blockchain/componentlib/tag/TagsRow.kt b/componentlib/src/main/java/com/blockchain/componentlib/tag/TagsRow.kt index ea5ea43aee..79cd0a3da8 100644 --- a/componentlib/src/main/java/com/blockchain/componentlib/tag/TagsRow.kt +++ b/componentlib/src/main/java/com/blockchain/componentlib/tag/TagsRow.kt @@ -42,6 +42,8 @@ fun TagRowWithHelp() { AppTheme { TagsRow( tags = listOf( + TagViewState("Default", TagType.Default()), + TagViewState("InfoAlt", TagType.InfoAlt()), TagViewState("Warning", TagType.Warning()), TagViewState("Success", TagType.Success()), TagViewState("Error", TagType.Error()) diff --git a/earn/presentation/build.gradle b/earn/presentation/build.gradle index f1df4d5c1b..9dcebac9fb 100644 --- a/earn/presentation/build.gradle +++ b/earn/presentation/build.gradle @@ -28,4 +28,6 @@ dependencies { // Rx implementation Libraries.rxJava implementation Libraries.rxjava3Coroutines + implementation Libraries.rxAndroid + implementation Libraries.rxKotlin } \ No newline at end of file diff --git a/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/EarnAnalytics.kt b/earn/presentation/src/main/java/com/blockchain/earn/EarnAnalytics.kt similarity index 77% rename from app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/EarnAnalytics.kt rename to earn/presentation/src/main/java/com/blockchain/earn/EarnAnalytics.kt index ea6d877df7..f62bf8df36 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/transactionflow/analytics/EarnAnalytics.kt +++ b/earn/presentation/src/main/java/com/blockchain/earn/EarnAnalytics.kt @@ -1,8 +1,13 @@ -package piuk.blockchain.android.ui.transactionflow.analytics +package com.blockchain.earn import com.blockchain.analytics.AnalyticsEvent import com.blockchain.analytics.events.AnalyticsNames import com.blockchain.analytics.events.LaunchOrigin +import com.blockchain.coincore.BankAccount +import com.blockchain.coincore.BlockchainAccount +import com.blockchain.coincore.InterestAccount +import com.blockchain.coincore.TradingAccount +import com.blockchain.coincore.TransactionTarget import info.blockchain.balance.Money import java.io.Serializable @@ -96,3 +101,23 @@ sealed class EarnAnalytics( private const val INTEREST_RATE = "interest_rate" } } + +enum class TxFlowAnalyticsAccountType { + TRADING, USERKEY, SAVINGS, EXTERNAL; + + companion object { + fun fromAccount(account: BlockchainAccount): TxFlowAnalyticsAccountType = + when (account) { + is TradingAccount, + is BankAccount -> TRADING + is InterestAccount -> SAVINGS + else -> USERKEY + } + + fun fromTransactionTarget(transactionTarget: TransactionTarget): TxFlowAnalyticsAccountType { + (transactionTarget as? BlockchainAccount)?.let { + return fromAccount(it) + } ?: return EXTERNAL + } + } +} diff --git a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/EarnDashboardFragment.kt b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/EarnDashboardFragment.kt index 1aa64c3257..72c13b14e2 100644 --- a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/EarnDashboardFragment.kt +++ b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/EarnDashboardFragment.kt @@ -4,32 +4,26 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView -import androidx.compose.ui.platform.LocalLifecycleOwner -import androidx.compose.ui.res.dimensionResource -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.flowWithLifecycle +import com.blockchain.coincore.BlockchainAccount +import com.blockchain.coincore.CryptoAccount import com.blockchain.commonarch.presentation.mvi_v2.MVIFragment import com.blockchain.commonarch.presentation.mvi_v2.ModelConfigArgs import com.blockchain.commonarch.presentation.mvi_v2.NavigationRouter import com.blockchain.commonarch.presentation.mvi_v2.bindViewModel -import com.blockchain.componentlib.system.ShimmerLoadingTableRow +import com.blockchain.componentlib.alert.BlockchainSnackbar +import com.blockchain.componentlib.alert.SnackbarType +import com.blockchain.componentlib.utils.openUrl import com.blockchain.earn.R -import com.blockchain.earn.dashboard.viewmodel.DashboardState import com.blockchain.earn.dashboard.viewmodel.EarnDashboardNavigationEvent import com.blockchain.earn.dashboard.viewmodel.EarnDashboardViewModel import com.blockchain.earn.dashboard.viewmodel.EarnDashboardViewState +import com.blockchain.earn.interest.InterestSummarySheet +import com.blockchain.earn.staking.StakingSummaryBottomSheet +import com.blockchain.earn.staking.viewmodel.StakingError import com.blockchain.koin.payloadScope +import com.google.android.material.snackbar.Snackbar +import info.blockchain.balance.Currency import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.component.KoinScopeComponent import org.koin.core.scope.Scope @@ -37,7 +31,22 @@ import org.koin.core.scope.Scope class EarnDashboardFragment : MVIFragment(), KoinScopeComponent, - NavigationRouter { + NavigationRouter, + InterestSummarySheet.Host, + StakingSummaryBottomSheet.Host { + + interface Host { + fun goToActivityFor(account: BlockchainAccount) + fun goToInterestDeposit(toAccount: BlockchainAccount) + fun goToInterestWithdraw(fromAccount: BlockchainAccount) + fun launchStakingWithdrawal(currency: Currency) + fun launchStakingDeposit(currency: Currency) + fun goToStakingActivity(currency: Currency) + } + + private val host: Host by lazy { + activity as? Host ?: error("Parent activity is not an EarnDashboardFragment.Host") + } override val scope: Scope get() = payloadScope @@ -57,64 +66,75 @@ class EarnDashboardFragment : override fun onStateUpdated(state: EarnDashboardViewState) { } - override fun route(navigationEvent: EarnDashboardNavigationEvent) { + override fun route(navigationEvent: EarnDashboardNavigationEvent) = + when (navigationEvent) { + is EarnDashboardNavigationEvent.OpenRewardsSummarySheet -> { + openInterestSummarySheet(navigationEvent.account) + } + + is EarnDashboardNavigationEvent.OpenStakingSummarySheet -> { + openStakingSummarySheet(navigationEvent.assetTicker) + } + } + + private fun openInterestSummarySheet(account: CryptoAccount) { + showBottomSheet(InterestSummarySheet.newInstance(account)) + } + + private fun openStakingSummarySheet(assetTicker: String) { + showBottomSheet(StakingSummaryBottomSheet.newInstance(assetTicker)) } companion object { fun newInstance() = EarnDashboardFragment() } -} -@Composable -fun EarnDashboardScreen( - viewModel: EarnDashboardViewModel -) { - val lifecycleOwner = LocalLifecycleOwner.current - val stateFlowLifecycleAware = remember(viewModel.viewState, lifecycleOwner) { - viewModel.viewState.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED) + override fun goToActivityFor(account: BlockchainAccount) { + host.goToActivityFor(account) } - val viewState: EarnDashboardViewState? by stateFlowLifecycleAware.collectAsState(null) - viewState?.let { state -> - EarnDashboard(state) + override fun goToInterestDeposit(toAccount: BlockchainAccount) { + host.goToInterestDeposit(toAccount) } -} -@Composable -fun EarnDashboard(state: EarnDashboardViewState) { - when (val s = state.dashboardState) { - DashboardState.Loading -> EarnDashboardLoading() - is DashboardState.ShowError -> { - Text("ShowError ${s.error}") - } - DashboardState.ShowKyc -> { - Text("ShowKyc") - } - is DashboardState.EarningAndDiscover -> { - Text("EarningAndDiscover discover - ${s.discover.size} earning - ${s.earning.size}") - } - is DashboardState.OnlyDiscover -> { - Text("OnlyDiscover") - } + override fun goToInterestWithdraw(fromAccount: BlockchainAccount) { + host.goToInterestWithdraw(fromAccount) + } + + override fun openExternalUrl(url: String) { + requireContext().openUrl(url) } -} -@Composable -fun EarnDashboardLoading() { - Column(modifier = Modifier.padding(dimensionResource(R.dimen.standard_spacing))) { - ShimmerLoadingTableRow(false) - Spacer(modifier = Modifier.height(dimensionResource(R.dimen.standard_spacing))) + override fun launchStakingWithdrawal(currency: Currency) { + host.launchStakingWithdrawal(currency) + } - ShimmerLoadingTableRow(false) - Spacer(modifier = Modifier.height(dimensionResource(R.dimen.standard_spacing))) + override fun launchStakingDeposit(currency: Currency) { + host.launchStakingDeposit(currency) + } - ShimmerLoadingTableRow(true) - Spacer(modifier = Modifier.height(dimensionResource(R.dimen.standard_spacing))) + override fun showStakingLoadingError(error: StakingError) { + view?.let { + BlockchainSnackbar.make( + view = it, + message = when (error) { + is StakingError.UnknownAsset -> getString( + R.string.staking_summary_sheet_error_unknown_asset, error.assetTicker + ) + StakingError.Other -> getString(R.string.staking_summary_sheet_error_other) + StakingError.None -> getString(R.string.empty) + }, + duration = Snackbar.LENGTH_SHORT, + type = SnackbarType.Error + ).show() + } + } - ShimmerLoadingTableRow(true) - Spacer(modifier = Modifier.height(dimensionResource(R.dimen.standard_spacing))) + override fun goToStakingAccountActivity(currency: Currency) { + host.goToStakingActivity(currency) + } - ShimmerLoadingTableRow(true) - Spacer(modifier = Modifier.height(dimensionResource(R.dimen.standard_spacing))) + override fun onSheetClosed() { + // do nothing } } diff --git a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/EarnDashboardScreen.kt b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/EarnDashboardScreen.kt new file mode 100644 index 0000000000..2ce1cf3d73 --- /dev/null +++ b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/EarnDashboardScreen.kt @@ -0,0 +1,241 @@ +package com.blockchain.earn.dashboard + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalLifecycleOwner +import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.buildAnnotatedString +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.flowWithLifecycle +import com.blockchain.componentlib.basic.ComposeColors +import com.blockchain.componentlib.basic.ComposeGravities +import com.blockchain.componentlib.basic.ComposeTypographies +import com.blockchain.componentlib.basic.ImageResource +import com.blockchain.componentlib.basic.SimpleText +import com.blockchain.componentlib.control.Search +import com.blockchain.componentlib.control.TabLayoutLarge +import com.blockchain.componentlib.divider.HorizontalDivider +import com.blockchain.componentlib.filter.FilterState +import com.blockchain.componentlib.filter.LabeledFilterState +import com.blockchain.componentlib.filter.LabeledFiltersGroup +import com.blockchain.componentlib.system.ShimmerLoadingTableRow +import com.blockchain.componentlib.tablerow.BalanceTableRow +import com.blockchain.componentlib.tag.TagType +import com.blockchain.componentlib.tag.TagViewState +import com.blockchain.componentlib.theme.AppTheme +import com.blockchain.earn.R +import com.blockchain.earn.dashboard.viewmodel.DashboardState +import com.blockchain.earn.dashboard.viewmodel.EarnAsset +import com.blockchain.earn.dashboard.viewmodel.EarnDashboardIntent +import com.blockchain.earn.dashboard.viewmodel.EarnDashboardListFilter +import com.blockchain.earn.dashboard.viewmodel.EarnDashboardViewModel +import com.blockchain.earn.dashboard.viewmodel.EarnDashboardViewState +import com.blockchain.earn.dashboard.viewmodel.EarnType + +@Composable +fun EarnDashboardScreen( + viewModel: EarnDashboardViewModel +) { + val lifecycleOwner = LocalLifecycleOwner.current + val stateFlowLifecycleAware = remember(viewModel.viewState, lifecycleOwner) { + viewModel.viewState.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED) + } + val viewState: EarnDashboardViewState? by stateFlowLifecycleAware.collectAsState(null) + + viewState?.let { state -> + EarnDashboard(state, filterAction = { + viewModel.onIntent(EarnDashboardIntent.UpdateListFilter(it)) + }, queryFilter = { + viewModel.onIntent(EarnDashboardIntent.UpdateSearchQuery(it)) + }, onItemClicked = { + viewModel.onIntent(EarnDashboardIntent.ItemSelected(it)) + }) + } +} + +@Composable +fun EarnDashboard( + state: EarnDashboardViewState, + filterAction: (EarnDashboardListFilter) -> Unit, + queryFilter: (String) -> Unit, + onItemClicked: (EarnAsset) -> Unit +) { + when (val s = state.dashboardState) { + DashboardState.Loading -> EarnDashboardLoading() + is DashboardState.ShowError -> { + Text("ShowError ${s.error}") + } + DashboardState.ShowKyc -> { + Text("ShowKyc") + } + is DashboardState.EarningAndDiscover -> { + EarningAndDiscover(s, state.filterBy, filterAction, queryFilter, onItemClicked) + } + is DashboardState.OnlyDiscover -> { + DashboardState.OnlyDiscover(s.discover) + } + } +} + +@Composable +fun EarningAndDiscover( + state: DashboardState.EarningAndDiscover, + filterBy: EarnDashboardListFilter, + filterAction: (EarnDashboardListFilter) -> Unit, + queryFilter: (String) -> Unit, + onItemClicked: (EarnAsset) -> Unit +) { + var selectedTab by remember { mutableStateOf(SelectedTab.Earning) } + + Column { + TabLayoutLarge( + items = listOf("Earning", "Discover"), + selectedItemIndex = selectedTab.index, + hasBottomShadow = true, + onItemSelected = { + selectedTab = SelectedTab.fromInt(it) + } + ) + + when (selectedTab) { + SelectedTab.Earning -> { + EarningScreen(queryFilter, filterAction, filterBy, state, onItemClicked) + } + SelectedTab.Discover -> { + Text("COMING SOON TM") + } + } + } +} + +@Composable +private fun EarningScreen( + queryFilter: (String) -> Unit, + filterAction: (EarnDashboardListFilter) -> Unit, + filterBy: EarnDashboardListFilter, + state: DashboardState.EarningAndDiscover, + onItemClicked: (EarnAsset) -> Unit +) { + var searchedText by remember { mutableStateOf("") } + + Column { + Box(modifier = Modifier.padding(dimensionResource(id = R.dimen.small_spacing))) { + Search(label = stringResource(R.string.staking_dashboard_search), onValueChange = { + searchedText = it + queryFilter(it) + }) + } + + LabeledFiltersGroup( + filters = EarnDashboardListFilter.values().map { filter -> + LabeledFilterState( + text = stringResource(id = filter.title()), + onSelected = { filterAction(filter) }, + state = if (filterBy == filter) FilterState.SELECTED else FilterState.UNSELECTED + ) + }, + modifier = Modifier.padding( + horizontal = AppTheme.dimensions.standardSpacing, + vertical = AppTheme.dimensions.smallSpacing + ) + ) + + if (searchedText.isNotEmpty() && state.earning.isEmpty()) { + SimpleText( + text = stringResource(R.string.staking_dashboard_no_results), + style = ComposeTypographies.Body1, + color = ComposeColors.Body, + gravity = ComposeGravities.Centre + ) + } else { + LazyColumn { + items( + items = state.earning, + itemContent = { + Column { + BalanceTableRow( + titleStart = buildAnnotatedString { append(it.assetName) }, + titleEnd = buildAnnotatedString { append(it.balanceFiat.toStringWithSymbol()) }, + startImageResource = ImageResource.Remote(it.iconUrl), + bodyStart = buildAnnotatedString { + append( + stringResource( + id = R.string.staking_summary_rate_value, it.rate.toString() + ) + ) + }, + tags = listOf( + TagViewState( + when (it.type) { + EarnType.Rewards -> "Passive Rewards" + EarnType.Staking -> "Staking Rewards" + }, + TagType.Default() + ) + ), + isInlineTags = true, + bodyEnd = buildAnnotatedString { append(it.balanceCrypto.toStringWithSymbol()) }, + onClick = { onItemClicked(it) } + ) + + HorizontalDivider( + modifier = Modifier.fillMaxWidth(), dividerColor = AppTheme.colors.medium + ) + } + } + ) + } + } + } +} + +private fun EarnDashboardListFilter.title(): Int = + when (this) { + EarnDashboardListFilter.All -> R.string.earn_dashboard_filter_all + EarnDashboardListFilter.Staking -> R.string.earn_dashboard_filter_staking + EarnDashboardListFilter.Rewards -> R.string.earn_dashboard_filter_rewards + } + +private enum class SelectedTab(val index: Int) { + Earning(0), + Discover(1); + + companion object { + fun fromInt(value: Int) = values().first { it.index == value } + } +} + +@Composable +fun EarnDashboardLoading() { + Column(modifier = Modifier.padding(dimensionResource(R.dimen.standard_spacing))) { + ShimmerLoadingTableRow(false) + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.standard_spacing))) + + ShimmerLoadingTableRow(false) + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.standard_spacing))) + + ShimmerLoadingTableRow(true) + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.standard_spacing))) + + ShimmerLoadingTableRow(true) + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.standard_spacing))) + + ShimmerLoadingTableRow(true) + Spacer(modifier = Modifier.height(dimensionResource(R.dimen.standard_spacing))) + } +} diff --git a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardIntent.kt b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardIntent.kt index 4cb95ce7b9..8cfbf3e31b 100644 --- a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardIntent.kt +++ b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardIntent.kt @@ -3,5 +3,8 @@ package com.blockchain.earn.dashboard.viewmodel import com.blockchain.commonarch.presentation.mvi_v2.Intent sealed interface EarnDashboardIntent : Intent { + class UpdateListFilter(val filter: EarnDashboardListFilter) : EarnDashboardIntent + class UpdateSearchQuery(val searchTerm: String) : EarnDashboardIntent + class ItemSelected(val earnAsset: EarnAsset) : EarnDashboardIntent object LoadEarn : EarnDashboardIntent } diff --git a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardModelState.kt b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardModelState.kt index ca6d2718b9..31eff4d81d 100644 --- a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardModelState.kt +++ b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardModelState.kt @@ -10,9 +10,10 @@ import info.blockchain.balance.AssetInfo data class EarnDashboardModelState( val isLoading: Boolean = true, - val hasAccessToFeature: Boolean = false, val error: EarnDashboardError = EarnDashboardError.None, - val earnData: CombinedEarnData? = null + val earnData: CombinedEarnData? = null, + val queryBy: String = "", + val filterBy: EarnDashboardListFilter = EarnDashboardListFilter.All ) : ModelState data class CombinedEarnData( diff --git a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardNavigationEvent.kt b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardNavigationEvent.kt index e1e08f589e..a5c2324b8e 100644 --- a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardNavigationEvent.kt +++ b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardNavigationEvent.kt @@ -1,5 +1,9 @@ package com.blockchain.earn.dashboard.viewmodel +import com.blockchain.coincore.CryptoAccount import com.blockchain.commonarch.presentation.mvi_v2.NavigationEvent -class EarnDashboardNavigationEvent : NavigationEvent +sealed class EarnDashboardNavigationEvent : NavigationEvent { + class OpenRewardsSummarySheet(val account: CryptoAccount) : EarnDashboardNavigationEvent() + class OpenStakingSummarySheet(val assetTicker: String) : EarnDashboardNavigationEvent() +} diff --git a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardViewModel.kt b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardViewModel.kt index 40f38be6e5..e4a3103ac9 100644 --- a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardViewModel.kt +++ b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardViewModel.kt @@ -1,7 +1,9 @@ package com.blockchain.earn.dashboard.viewmodel import androidx.lifecycle.viewModelScope +import com.blockchain.coincore.AssetFilter import com.blockchain.coincore.Coincore +import com.blockchain.coincore.CryptoAccount import com.blockchain.coincore.toUserFiat import com.blockchain.commonarch.presentation.mvi_v2.ModelConfigArgs import com.blockchain.commonarch.presentation.mvi_v2.MviViewModel @@ -19,12 +21,14 @@ import com.blockchain.nabu.Feature import com.blockchain.nabu.FeatureAccess import com.blockchain.nabu.UserIdentity import com.blockchain.preferences.CurrencyPrefs +import info.blockchain.balance.AssetCatalogue import info.blockchain.balance.AssetInfo import info.blockchain.balance.Money import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch import kotlinx.coroutines.rx3.await +import kotlinx.coroutines.rx3.awaitSingle class EarnDashboardViewModel( private val coincore: Coincore, @@ -32,7 +36,8 @@ class EarnDashboardViewModel( private val interestService: InterestService, private val exchangeRatesDataManager: ExchangeRatesDataManager, private val currencyPrefs: CurrencyPrefs, - private val userIdentity: UserIdentity + private val userIdentity: UserIdentity, + private val assetCatalogue: AssetCatalogue ) : MviViewModel loadEarn() + is EarnDashboardIntent.UpdateListFilter -> updateState { + it.copy( + filterBy = intent.filter + ) + } + is EarnDashboardIntent.UpdateSearchQuery -> updateState { + it.copy( + queryBy = intent.searchTerm + ) + } + is EarnDashboardIntent.ItemSelected -> + when (intent.earnAsset.type) { + EarnType.Rewards -> { + getAccountForInterest(intent) + } + EarnType.Staking -> navigate( + EarnDashboardNavigationEvent.OpenStakingSummarySheet(intent.earnAsset.assetTicker) + ) + } + } + + private suspend fun getAccountForInterest(intent: EarnDashboardIntent.ItemSelected) { + assetCatalogue.fromNetworkTicker(intent.earnAsset.assetTicker)?.let { + navigate( + EarnDashboardNavigationEvent.OpenRewardsSummarySheet( + coincore[it].accountGroup(AssetFilter.Interest).awaitSingle().accounts.first() as CryptoAccount + ) + ) } } private fun reduceDashboardState( isLoading: Boolean, error: EarnDashboardError, - earnData: CombinedEarnData? + earnData: CombinedEarnData?, + // TODO(dserrano) - STAKING - filters for both lists should be independent - next PR + filterBy: EarnDashboardListFilter, + queryBy: String ): DashboardState { if (isLoading) { return DashboardState.Loading @@ -86,59 +124,79 @@ class EarnDashboardViewModel( val earningList = mutableListOf() val discoverList = mutableListOf() earnData.stakingEligibility.map { (asset, eligibility) -> - val balance = earnData.stakingBalances[asset]?.totalBalance ?: Money.zero(asset) if (balance.isPositive) { earningList.add( EarnAsset( - asset, - earnData.stakingRates[asset] ?: 0.0, - eligibility.toEarnEligibility(), - balance, - balance.toUserFiat(exchangeRatesDataManager) + assetTicker = asset.networkTicker, + assetName = asset.name, + iconUrl = asset.logo, + rate = earnData.stakingRates[asset] ?: 0.0, + eligibility = eligibility.toEarnEligibility(), + balanceCrypto = balance, + balanceFiat = balance.toUserFiat(exchangeRatesDataManager), + type = EarnType.Staking ) ) } else { discoverList.add( EarnAsset( - asset, - earnData.stakingRates[asset] ?: 0.0, - eligibility.toEarnEligibility(), - balance, - balance.toUserFiat(exchangeRatesDataManager) + assetTicker = asset.networkTicker, + assetName = asset.name, + iconUrl = asset.logo, + rate = earnData.stakingRates[asset] ?: 0.0, + eligibility = eligibility.toEarnEligibility(), + balanceCrypto = balance, + balanceFiat = balance.toUserFiat(exchangeRatesDataManager), + type = EarnType.Staking ) ) } } earnData.interestEligibility.map { (asset, eligibility) -> - val balance = earnData.interestBalances[asset]?.totalBalance ?: Money.zero(asset) if (balance.isPositive) { earningList.add( EarnAsset( - asset, - earnData.interestRates[asset] ?: 0.0, - eligibility.toEarnEligibility(), - balance, - balance.toUserFiat(exchangeRatesDataManager) + assetTicker = asset.networkTicker, + assetName = asset.name, + iconUrl = asset.logo, + rate = earnData.interestRates[asset] ?: 0.0, + eligibility = eligibility.toEarnEligibility(), + balanceCrypto = balance, + balanceFiat = balance.toUserFiat(exchangeRatesDataManager), + type = EarnType.Rewards ) ) } else { discoverList.add( EarnAsset( - asset, - earnData.interestRates[asset] ?: 0.0, - eligibility.toEarnEligibility(), - balance, - balance.toUserFiat(exchangeRatesDataManager) + assetTicker = asset.networkTicker, + assetName = asset.name, + iconUrl = asset.logo, + rate = earnData.interestRates[asset] ?: 0.0, + eligibility = eligibility.toEarnEligibility(), + balanceCrypto = balance, + balanceFiat = balance.toUserFiat(exchangeRatesDataManager), + type = EarnType.Rewards ) ) } } + + val sortedEarningList = when (filterBy) { + EarnDashboardListFilter.All -> earningList + EarnDashboardListFilter.Staking -> earningList.filter { it.type == EarnType.Staking } + EarnDashboardListFilter.Rewards -> earningList.filter { it.type == EarnType.Rewards } + }.filter { + queryBy.isEmpty() || it.assetName.contains(queryBy, true) || + it.assetTicker.contains(queryBy, true) + } + return DashboardState.EarningAndDiscover( - earningList, discoverList + sortedEarningList, discoverList ) } else { val discoverList = mutableListOf() @@ -149,11 +207,14 @@ class EarnDashboardViewModel( discoverList.add( EarnAsset( - asset, - earnData.stakingRates[asset] ?: 0.0, - eligibility.toEarnEligibility(), - balance, - balance.toUserFiat(exchangeRatesDataManager) + assetTicker = asset.networkTicker, + assetName = asset.name, + iconUrl = asset.logo, + rate = earnData.stakingRates[asset] ?: 0.0, + eligibility = eligibility.toEarnEligibility(), + balanceCrypto = balance, + balanceFiat = balance.toUserFiat(exchangeRatesDataManager), + type = EarnType.Staking ) ) } @@ -164,14 +225,18 @@ class EarnDashboardViewModel( discoverList.add( EarnAsset( - asset, - earnData.interestRates[asset] ?: 0.0, - eligibility.toEarnEligibility(), - balance, - balance.toUserFiat(exchangeRatesDataManager) + assetTicker = asset.networkTicker, + assetName = asset.name, + iconUrl = asset.logo, + rate = earnData.interestRates[asset] ?: 0.0, + eligibility = eligibility.toEarnEligibility(), + balanceCrypto = balance, + balanceFiat = balance.toUserFiat(exchangeRatesDataManager), + type = EarnType.Rewards ) ) } + return DashboardState.OnlyDiscover(discoverList) } } diff --git a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardViewState.kt b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardViewState.kt index 1ca6cb6b31..dc35c7521b 100644 --- a/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardViewState.kt +++ b/earn/presentation/src/main/java/com/blockchain/earn/dashboard/viewmodel/EarnDashboardViewState.kt @@ -1,11 +1,12 @@ package com.blockchain.earn.dashboard.viewmodel import com.blockchain.commonarch.presentation.mvi_v2.ViewState -import info.blockchain.balance.AssetInfo import info.blockchain.balance.Money data class EarnDashboardViewState( - val dashboardState: DashboardState + val dashboardState: DashboardState, + val queryBy: String, + val filterBy: EarnDashboardListFilter ) : ViewState sealed class EarnDashboardError { @@ -16,22 +17,30 @@ sealed class EarnDashboardError { sealed class DashboardState { object Loading : DashboardState() object ShowKyc : DashboardState() - class ShowError(val error: EarnDashboardError) : DashboardState() - class OnlyDiscover(val discover: List) : DashboardState() - class EarningAndDiscover(val earning: List, val discover: List) : DashboardState() + data class ShowError(val error: EarnDashboardError) : DashboardState() + data class OnlyDiscover(val discover: List) : DashboardState() + data class EarningAndDiscover(val earning: List, val discover: List) : DashboardState() } data class EarnAsset( - val asset: AssetInfo, + val assetTicker: String, + val assetName: String, + val iconUrl: String, val rate: Double, val eligibility: EarnEligibility, val balanceCrypto: Money, - val balanceFiat: Money + val balanceFiat: Money, + val type: EarnType ) +sealed class EarnType { + object Staking : EarnType() + object Rewards : EarnType() +} + sealed class EarnEligibility { object Eligible : EarnEligibility() - class NotEligible(val reason: EarnIneligibleReason) : EarnEligibility() + data class NotEligible(val reason: EarnIneligibleReason) : EarnEligibility() } enum class EarnIneligibleReason { @@ -39,3 +48,9 @@ enum class EarnIneligibleReason { KYC_TIER, OTHER } + +enum class EarnDashboardListFilter { + All, + Staking, + Rewards +} diff --git a/app/src/main/java/piuk/blockchain/android/ui/interest/InterestSummaryAdapter.kt b/earn/presentation/src/main/java/com/blockchain/earn/interest/InterestSummaryAdapter.kt similarity index 79% rename from app/src/main/java/piuk/blockchain/android/ui/interest/InterestSummaryAdapter.kt rename to earn/presentation/src/main/java/com/blockchain/earn/interest/InterestSummaryAdapter.kt index ea74ebacfb..bb969a9405 100644 --- a/app/src/main/java/piuk/blockchain/android/ui/interest/InterestSummaryAdapter.kt +++ b/earn/presentation/src/main/java/com/blockchain/earn/interest/InterestSummaryAdapter.kt @@ -1,12 +1,14 @@ -package piuk.blockchain.android.ui.interest +package com.blockchain.earn.interest +import android.annotation.SuppressLint import android.view.LayoutInflater import android.view.ViewGroup import android.widget.TextView import androidx.recyclerview.widget.RecyclerView +import com.blockchain.earn.databinding.ItemInterestSummaryBinding import kotlin.properties.Delegates -import piuk.blockchain.android.databinding.ItemInterestSummaryBinding +@SuppressLint("NotifyDataSetChanged") class InterestSummaryAdapter : RecyclerView.Adapter() { var items: List by Delegates.observable( @@ -17,7 +19,7 @@ class InterestSummaryAdapter : RecyclerView.Adapter() { @@ -87,7 +87,9 @@ class InterestSummarySheet : SlidingModalBottomDialog accounts.filter { account -> account is CryptoAccount && account.currency == asset } @@ -103,13 +105,6 @@ class InterestSummarySheet : SlidingModalBottomDialog dismiss() - host.goToStakingActivity(currency) + host.goToStakingAccountActivity(currency) } ) } diff --git a/earn/presentation/src/main/java/com/blockchain/earn/staking/viewmodel/StakingSummaryIntent.kt b/earn/presentation/src/main/java/com/blockchain/earn/staking/viewmodel/StakingSummaryIntent.kt index 9896239a35..20fa49ce11 100644 --- a/earn/presentation/src/main/java/com/blockchain/earn/staking/viewmodel/StakingSummaryIntent.kt +++ b/earn/presentation/src/main/java/com/blockchain/earn/staking/viewmodel/StakingSummaryIntent.kt @@ -5,5 +5,5 @@ import info.blockchain.balance.Currency sealed interface StakingSummaryIntent : Intent { class LoadData(val currency: Currency) : StakingSummaryIntent - object StakingSummaryLoadError : StakingSummaryIntent + class StakingSummaryLoadError(val assetTicker: String) : StakingSummaryIntent } diff --git a/earn/presentation/src/main/java/com/blockchain/earn/staking/viewmodel/StakingSummaryViewModel.kt b/earn/presentation/src/main/java/com/blockchain/earn/staking/viewmodel/StakingSummaryViewModel.kt index 43e256ba22..b9df11e921 100644 --- a/earn/presentation/src/main/java/com/blockchain/earn/staking/viewmodel/StakingSummaryViewModel.kt +++ b/earn/presentation/src/main/java/com/blockchain/earn/staking/viewmodel/StakingSummaryViewModel.kt @@ -35,7 +35,7 @@ class StakingSummaryViewModel( viewModelScope.launch { coincore[args.cryptoTicker]?.let { onIntent(StakingSummaryIntent.LoadData(it.currency)) - } ?: onIntent(StakingSummaryIntent.StakingSummaryLoadError) + } ?: onIntent(StakingSummaryIntent.StakingSummaryLoadError(args.cryptoTicker)) } } @@ -61,9 +61,9 @@ class StakingSummaryViewModel( override suspend fun handleIntent(modelState: StakingSummaryModelState, intent: StakingSummaryIntent) { when (intent) { is StakingSummaryIntent.LoadData -> loadStakingDetails(intent.currency) - StakingSummaryIntent.StakingSummaryLoadError -> updateState { + is StakingSummaryIntent.StakingSummaryLoadError -> updateState { it.copy( - errorState = StakingError.UnknownAsset + errorState = StakingError.UnknownAsset(intent.assetTicker) ) } } diff --git a/earn/presentation/src/main/java/com/blockchain/earn/staking/viewmodel/StakingSummaryViewState.kt b/earn/presentation/src/main/java/com/blockchain/earn/staking/viewmodel/StakingSummaryViewState.kt index 0f6b6c4649..715e14f5a4 100644 --- a/earn/presentation/src/main/java/com/blockchain/earn/staking/viewmodel/StakingSummaryViewState.kt +++ b/earn/presentation/src/main/java/com/blockchain/earn/staking/viewmodel/StakingSummaryViewState.kt @@ -22,8 +22,8 @@ data class StakingSummaryViewState( val rewardsFrequency: EarnRewardsFrequency ) : ViewState -enum class StakingError { - UnknownAsset, - Other, - None +sealed class StakingError { + class UnknownAsset(val assetTicker: String) : StakingError() + object Other : StakingError() + object None : StakingError() } diff --git a/app/src/main/res/layout/dialog_sheet_interest_details.xml b/earn/presentation/src/main/res/layout/dialog_sheet_interest_details.xml similarity index 98% rename from app/src/main/res/layout/dialog_sheet_interest_details.xml rename to earn/presentation/src/main/res/layout/dialog_sheet_interest_details.xml index cf6b91b7fc..dec85ff4cf 100644 --- a/app/src/main/res/layout/dialog_sheet_interest_details.xml +++ b/earn/presentation/src/main/res/layout/dialog_sheet_interest_details.xml @@ -56,7 +56,7 @@ app:layout_constraintTop_toBottomOf="@id/interest_details_title" tools:text="my account description" /> - There was an error loading the Staking Summary details for %1$s, please try again later There was an unexpected error loading the Staking Summary details, please try again later Unstaking and withdrawing ETH will be available when enabled by the Ethereum network. + All + Staking + Rewards + Search coins + No results + All Prices Tradable