diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 91ad7ebde..a8b0707a0 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -166,6 +166,14 @@ # ---------------- END AlgoSDK ------------------- +# ---------------- BEGIN BouncyCastle ------------------- +-keep class org.bouncycastle.jcajce.provider.** { *; } +-keep class org.bouncycastle.jce.provider.** { *; } + +-dontwarn javax.naming.** +# ---------------- END BouncyCastle ------------------- + + # ---------------- BEGIN WALLET CONNECT ------------------- -keep class org.walletconnect.** { *; } -keep interface org.walletconnect.** { *; } @@ -176,8 +184,6 @@ # ---------------- BEGIN OTHERS ------------------- --keep class com.google.gson.examples.android.model.** { ; } - # Prevent R8 from leaving Data object members always null -keepclassmembers,allowobfuscation class * { @com.google.gson.annotations.SerializedName ; diff --git a/app/src/main/java/com/algorand/android/banner/data/mapper/BannerTypeDecider.kt b/app/src/main/java/com/algorand/android/banner/data/mapper/BannerTypeDecider.kt index f91e8a13a..a5666709b 100644 --- a/app/src/main/java/com/algorand/android/banner/data/mapper/BannerTypeDecider.kt +++ b/app/src/main/java/com/algorand/android/banner/data/mapper/BannerTypeDecider.kt @@ -21,6 +21,7 @@ class BannerTypeDecider @Inject constructor() { fun getBannerType(bannerTypeResponse: BannerTypeResponse?): BannerType { return when (bannerTypeResponse) { BannerTypeResponse.GOVERNANCE -> BannerType.GOVERNANCE + BannerTypeResponse.STAKING -> BannerType.STAKING BannerTypeResponse.GENERIC -> BannerType.GENERIC BannerTypeResponse.OTHER -> BannerType.GENERIC else -> BannerType.GENERIC diff --git a/app/src/main/java/com/algorand/android/banner/data/model/BannerTypeResponse.kt b/app/src/main/java/com/algorand/android/banner/data/model/BannerTypeResponse.kt index 63d39923d..d7d46ca38 100644 --- a/app/src/main/java/com/algorand/android/banner/data/model/BannerTypeResponse.kt +++ b/app/src/main/java/com/algorand/android/banner/data/model/BannerTypeResponse.kt @@ -21,5 +21,8 @@ enum class BannerTypeResponse { @SerializedName("governance") GOVERNANCE, + @SerializedName("staking") + STAKING, + OTHER } diff --git a/app/src/main/java/com/algorand/android/banner/domain/mapper/BannerMapper.kt b/app/src/main/java/com/algorand/android/banner/domain/mapper/BannerMapper.kt index 09defc5ee..c47511eaa 100644 --- a/app/src/main/java/com/algorand/android/banner/domain/mapper/BannerMapper.kt +++ b/app/src/main/java/com/algorand/android/banner/domain/mapper/BannerMapper.kt @@ -28,6 +28,16 @@ class BannerMapper @Inject constructor() { ) } + fun mapToStakingBanner(bannerDetailDTO: BannerDetailDTO): BaseBanner.StakingBanner { + return BaseBanner.StakingBanner( + bannerId = bannerDetailDTO.bannerId, + title = bannerDetailDTO.title, + description = bannerDetailDTO.description, + buttonTitle = bannerDetailDTO.buttonText, + buttonUrl = bannerDetailDTO.buttonUrl + ) + } + fun mapToGenericBanner(bannerDetailDTO: BannerDetailDTO): BaseBanner.GenericBanner { return BaseBanner.GenericBanner( bannerId = bannerDetailDTO.bannerId, diff --git a/app/src/main/java/com/algorand/android/banner/domain/model/BannerType.kt b/app/src/main/java/com/algorand/android/banner/domain/model/BannerType.kt index 20400600f..05150c30e 100644 --- a/app/src/main/java/com/algorand/android/banner/domain/model/BannerType.kt +++ b/app/src/main/java/com/algorand/android/banner/domain/model/BannerType.kt @@ -14,5 +14,6 @@ package com.algorand.android.banner.domain.model enum class BannerType { GENERIC, - GOVERNANCE + GOVERNANCE, + STAKING } diff --git a/app/src/main/java/com/algorand/android/banner/domain/model/BaseBanner.kt b/app/src/main/java/com/algorand/android/banner/domain/model/BaseBanner.kt index 19edcec53..1f1b72225 100644 --- a/app/src/main/java/com/algorand/android/banner/domain/model/BaseBanner.kt +++ b/app/src/main/java/com/algorand/android/banner/domain/model/BaseBanner.kt @@ -20,6 +20,14 @@ sealed class BaseBanner { abstract val buttonTitle: String? abstract val buttonUrl: String? + data class StakingBanner( + override val bannerId: Long, + override val title: String?, + override val description: String?, + override val buttonTitle: String?, + override val buttonUrl: String? + ) : BaseBanner() + data class GovernanceBanner( override val bannerId: Long, override val title: String?, diff --git a/app/src/main/java/com/algorand/android/banner/domain/usecase/BannersUseCase.kt b/app/src/main/java/com/algorand/android/banner/domain/usecase/BannersUseCase.kt index f537882b5..ac8ea703c 100644 --- a/app/src/main/java/com/algorand/android/banner/domain/usecase/BannersUseCase.kt +++ b/app/src/main/java/com/algorand/android/banner/domain/usecase/BannersUseCase.kt @@ -68,6 +68,7 @@ class BannersUseCase @Inject constructor( private fun getMappedAndFilteredBanner(bannerDto: BannerDetailDTO): BaseBanner { return when (bannerDto.type) { BannerType.GOVERNANCE -> bannerMapper.mapToGovernanceBanner(bannerDto) + BannerType.STAKING -> bannerMapper.mapToStakingBanner(bannerDto) BannerType.GENERIC -> bannerMapper.mapToGenericBanner(bannerDto) else -> bannerMapper.mapToGenericBanner(bannerDto) } diff --git a/app/src/main/java/com/algorand/android/banner/ui/mapper/BaseBannerItemMapper.kt b/app/src/main/java/com/algorand/android/banner/ui/mapper/BaseBannerItemMapper.kt index 9d6597945..00cfa9ccf 100644 --- a/app/src/main/java/com/algorand/android/banner/ui/mapper/BaseBannerItemMapper.kt +++ b/app/src/main/java/com/algorand/android/banner/ui/mapper/BaseBannerItemMapper.kt @@ -37,6 +37,24 @@ class BaseBannerItemMapper @Inject constructor() { ) } + fun mapToStakingBannerItem( + stakingBanner: BaseBanner.StakingBanner, + isButtonVisible: Boolean, + isTitleVisible: Boolean, + isDescriptionVisible: Boolean + ): BaseAccountListItem.BaseBannerItem.StakingBannerItem { + return BaseAccountListItem.BaseBannerItem.StakingBannerItem( + bannerId = stakingBanner.bannerId, + title = stakingBanner.title, + description = stakingBanner.description, + buttonText = stakingBanner.buttonTitle, + buttonUrl = stakingBanner.buttonUrl, + isButtonVisible = isButtonVisible, + isTitleVisible = isTitleVisible, + isDescriptionVisible = isDescriptionVisible + ) + } + fun mapToGenericBannerItem( genericBanner: BaseBanner.GenericBanner, isButtonVisible: Boolean, diff --git a/app/src/main/java/com/algorand/android/banner/ui/viewholder/BaseBannerViewHolder.kt b/app/src/main/java/com/algorand/android/banner/ui/viewholder/BaseBannerViewHolder.kt index a6dd220f3..82c2e7dbd 100644 --- a/app/src/main/java/com/algorand/android/banner/ui/viewholder/BaseBannerViewHolder.kt +++ b/app/src/main/java/com/algorand/android/banner/ui/viewholder/BaseBannerViewHolder.kt @@ -16,12 +16,13 @@ import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.core.view.isVisible +import com.algorand.android.banner.domain.model.BannerType import com.algorand.android.models.BaseViewHolder import com.algorand.android.modules.accounts.domain.model.BaseAccountListItem import com.google.android.material.button.MaterialButton abstract class BaseBannerViewHolder( - private val listener: BannerListener, + protected val listener: BannerListener, itemView: View ) : BaseViewHolder(itemView) { @@ -38,9 +39,11 @@ abstract class BaseBannerViewHolder( initDescriptionTextView(item) } - private fun initActionButton(item: BaseAccountListItem.BaseBannerItem) { + abstract fun initActionButton(item: BaseAccountListItem.BaseBannerItem) + + protected fun initActionButton(item: BaseAccountListItem.BaseBannerItem, bannerType: BannerType) { actionButton?.apply { - setOnClickListener { listener.onActionButtonClick(item.buttonUrl.orEmpty()) } + setOnClickListener { listener.onActionButtonClick(item.buttonUrl.orEmpty(), bannerType) } text = item.buttonText isVisible = item.isButtonVisible } @@ -66,7 +69,7 @@ abstract class BaseBannerViewHolder( interface BannerListener { fun onCloseBannerClick(bannerId: Long) {} - fun onActionButtonClick(url: String) {} + fun onActionButtonClick(url: String, bannerType: BannerType) {} } protected interface BannerViewHolderCreator { diff --git a/app/src/main/java/com/algorand/android/banner/ui/viewholder/GenericBannerViewHolder.kt b/app/src/main/java/com/algorand/android/banner/ui/viewholder/GenericBannerViewHolder.kt index dfc5f6a9c..24d66b479 100644 --- a/app/src/main/java/com/algorand/android/banner/ui/viewholder/GenericBannerViewHolder.kt +++ b/app/src/main/java/com/algorand/android/banner/ui/viewholder/GenericBannerViewHolder.kt @@ -15,7 +15,9 @@ package com.algorand.android.banner.ui.viewholder import android.view.LayoutInflater import android.view.ViewGroup import android.widget.TextView +import com.algorand.android.banner.domain.model.BannerType import com.algorand.android.databinding.ItemGenericBannerBinding +import com.algorand.android.modules.accounts.domain.model.BaseAccountListItem import com.google.android.material.button.MaterialButton class GenericBannerViewHolder( @@ -32,6 +34,10 @@ class GenericBannerViewHolder( override val descriptionTextView: TextView get() = binding.bannerDescriptionTextView + override fun initActionButton(item: BaseAccountListItem.BaseBannerItem) { + initActionButton(item, BannerType.GENERIC) + } + companion object : BannerViewHolderCreator { override fun create(listener: BannerListener, parent: ViewGroup): BaseBannerViewHolder { val binding = ItemGenericBannerBinding.inflate(LayoutInflater.from(parent.context), parent, false) diff --git a/app/src/main/java/com/algorand/android/banner/ui/viewholder/GovernanceBannerViewHolder.kt b/app/src/main/java/com/algorand/android/banner/ui/viewholder/GovernanceBannerViewHolder.kt index c2a9892dd..063b7f004 100644 --- a/app/src/main/java/com/algorand/android/banner/ui/viewholder/GovernanceBannerViewHolder.kt +++ b/app/src/main/java/com/algorand/android/banner/ui/viewholder/GovernanceBannerViewHolder.kt @@ -15,7 +15,9 @@ package com.algorand.android.banner.ui.viewholder import android.view.LayoutInflater import android.view.ViewGroup import android.widget.TextView +import com.algorand.android.banner.domain.model.BannerType import com.algorand.android.databinding.ItemGovernanceBannerBinding +import com.algorand.android.modules.accounts.domain.model.BaseAccountListItem import com.google.android.material.button.MaterialButton class GovernanceBannerViewHolder( @@ -32,6 +34,9 @@ class GovernanceBannerViewHolder( override val descriptionTextView: TextView get() = binding.bannerDescriptionTextView + override fun initActionButton(item: BaseAccountListItem.BaseBannerItem) { + initActionButton(item, BannerType.GOVERNANCE) + } companion object : BannerViewHolderCreator { override fun create(listener: BannerListener, parent: ViewGroup): BaseBannerViewHolder { val binding = ItemGovernanceBannerBinding.inflate(LayoutInflater.from(parent.context), parent, false) diff --git a/app/src/main/java/com/algorand/android/banner/ui/viewholder/StakingBannerViewHolder.kt b/app/src/main/java/com/algorand/android/banner/ui/viewholder/StakingBannerViewHolder.kt new file mode 100644 index 000000000..463acb7a4 --- /dev/null +++ b/app/src/main/java/com/algorand/android/banner/ui/viewholder/StakingBannerViewHolder.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2022 Pera Wallet, LDA + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.algorand.android.banner.ui.viewholder + +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.TextView +import com.algorand.android.banner.domain.model.BannerType +import com.algorand.android.databinding.ItemStakingBannerBinding +import com.algorand.android.modules.accounts.domain.model.BaseAccountListItem +import com.google.android.material.button.MaterialButton + +class StakingBannerViewHolder( + private val binding: ItemStakingBannerBinding, + listener: BannerListener +) : BaseBannerViewHolder(listener, binding.root) { + + override val actionButton: MaterialButton + get() = binding.bannerActionButton + override val closeButton: MaterialButton + get() = binding.bannerCloseButton + override val titleTextView: TextView + get() = binding.bannerTitleTextView + override val descriptionTextView: TextView + get() = binding.bannerDescriptionTextView + + override fun initActionButton(item: BaseAccountListItem.BaseBannerItem) { + initActionButton(item, BannerType.STAKING) + } + + companion object : BannerViewHolderCreator { + override fun create(listener: BannerListener, parent: ViewGroup): BaseBannerViewHolder { + val binding = ItemStakingBannerBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return StakingBannerViewHolder(binding, listener) + } + } +} diff --git a/app/src/main/java/com/algorand/android/modules/accounts/domain/model/BaseAccountListItem.kt b/app/src/main/java/com/algorand/android/modules/accounts/domain/model/BaseAccountListItem.kt index 4e56c12f3..d9d6d1675 100644 --- a/app/src/main/java/com/algorand/android/modules/accounts/domain/model/BaseAccountListItem.kt +++ b/app/src/main/java/com/algorand/android/modules/accounts/domain/model/BaseAccountListItem.kt @@ -26,6 +26,7 @@ sealed class BaseAccountListItem : RecyclerListItem { HEADER, QUICK_ACTIONS, GOVERNANCE_BANNER, + STAKING_BANNER, GENERIC_BANNER, BACKUP_BANNER } @@ -84,6 +85,28 @@ sealed class BaseAccountListItem : RecyclerListItem { } } + data class StakingBannerItem( + override val bannerId: Long, + override val buttonText: String?, + override val buttonUrl: String?, + override val isButtonVisible: Boolean, + override val title: String?, + override val isTitleVisible: Boolean, + override val description: String?, + override val isDescriptionVisible: Boolean + ) : BaseBannerItem() { + + override val itemType: ItemType = ItemType.STAKING_BANNER + + override fun areItemsTheSame(other: RecyclerListItem): Boolean { + return other is StakingBannerItem && other.bannerId == bannerId + } + + override fun areContentsTheSame(other: RecyclerListItem): Boolean { + return other is StakingBannerItem && other == this + } + } + data class GenericBannerItem( override val bannerId: Long, override val buttonText: String?, @@ -182,6 +205,7 @@ sealed class BaseAccountListItem : RecyclerListItem { companion object { val bannerItemTypes = listOf( ItemType.GOVERNANCE_BANNER.ordinal, + ItemType.STAKING_BANNER.ordinal, ItemType.GENERIC_BANNER.ordinal, ItemType.BACKUP_BANNER.ordinal ) diff --git a/app/src/main/java/com/algorand/android/modules/accounts/domain/usecase/AccountsPreviewUseCase.kt b/app/src/main/java/com/algorand/android/modules/accounts/domain/usecase/AccountsPreviewUseCase.kt index 053a5e0bf..88cdf2807 100644 --- a/app/src/main/java/com/algorand/android/modules/accounts/domain/usecase/AccountsPreviewUseCase.kt +++ b/app/src/main/java/com/algorand/android/modules/accounts/domain/usecase/AccountsPreviewUseCase.kt @@ -17,6 +17,7 @@ import com.algorand.android.R import com.algorand.android.banner.domain.model.BaseBanner import com.algorand.android.banner.domain.model.BaseBanner.GenericBanner import com.algorand.android.banner.domain.model.BaseBanner.GovernanceBanner +import com.algorand.android.banner.domain.model.BaseBanner.StakingBanner import com.algorand.android.banner.domain.usecase.BannersUseCase import com.algorand.android.banner.ui.mapper.BaseBannerItemMapper import com.algorand.android.core.AccountManager @@ -347,6 +348,10 @@ class AccountsPreviewUseCase @Inject constructor( mapToGovernanceBannerItem(banner, isButtonVisible, isTitleVisible, isDescriptionVisible) } + is StakingBanner -> { + mapToStakingBannerItem(banner, isButtonVisible, isTitleVisible, isDescriptionVisible) + } + is GenericBanner -> { mapToGenericBannerItem(banner, isButtonVisible, isTitleVisible, isDescriptionVisible) } diff --git a/app/src/main/java/com/algorand/android/modules/accounts/ui/AccountsFragment.kt b/app/src/main/java/com/algorand/android/modules/accounts/ui/AccountsFragment.kt index c99d69093..9e561419f 100644 --- a/app/src/main/java/com/algorand/android/modules/accounts/ui/AccountsFragment.kt +++ b/app/src/main/java/com/algorand/android/modules/accounts/ui/AccountsFragment.kt @@ -27,6 +27,7 @@ import com.algorand.android.HomeNavigationDirections import com.algorand.android.MainActivity import com.algorand.android.MainNavigationDirections import com.algorand.android.R +import com.algorand.android.banner.domain.model.BannerType import com.algorand.android.core.DaggerBaseFragment import com.algorand.android.databinding.FragmentAccountsBinding import com.algorand.android.models.AnnotatedString @@ -104,9 +105,13 @@ class AccountsFragment : DaggerBaseFragment(R.layout.fragment_accounts), navToBackupPassphraseInfoNavigation() } - override fun onBannerActionButtonClick(url: String, isGovernance: Boolean) { - accountsViewModel.onBannerActionButtonClick(isGovernance) - nav(AccountsFragmentDirections.actionAccountsFragmentToBannerFragment(url)) + override fun onBannerActionButtonClick(url: String, bannerType: BannerType) { + accountsViewModel.onBannerActionButtonClick(bannerType) + if (bannerType == BannerType.STAKING) { + nav(AccountsFragmentDirections.actionAccountsFragmentToStakingFragment()) + } else { + nav(AccountsFragmentDirections.actionAccountsFragmentToBannerFragment(url)) + } } override fun onBuySellClick() { diff --git a/app/src/main/java/com/algorand/android/modules/accounts/ui/AccountsViewModel.kt b/app/src/main/java/com/algorand/android/modules/accounts/ui/AccountsViewModel.kt index e24392b42..47ae71424 100644 --- a/app/src/main/java/com/algorand/android/modules/accounts/ui/AccountsViewModel.kt +++ b/app/src/main/java/com/algorand/android/modules/accounts/ui/AccountsViewModel.kt @@ -13,6 +13,7 @@ package com.algorand.android.modules.accounts.ui import androidx.lifecycle.viewModelScope +import com.algorand.android.banner.domain.model.BannerType import com.algorand.android.core.BaseViewModel import com.algorand.android.modules.accounts.domain.model.AccountPreview import com.algorand.android.modules.accounts.domain.usecase.AccountsPreviewUseCase @@ -83,10 +84,12 @@ class AccountsViewModel @Inject constructor( } } - fun onBannerActionButtonClick(isGovernance: Boolean) { - if (isGovernance) { - viewModelScope.launch { - accountsEventTracker.logVisitGovernanceEvent() + fun onBannerActionButtonClick(bannerType: BannerType) { + viewModelScope.launch { + when (bannerType) { + BannerType.GOVERNANCE -> accountsEventTracker.logVisitGovernanceEvent() + BannerType.STAKING -> accountsEventTracker.logVisitStakingEvent() + BannerType.GENERIC -> {} } } } diff --git a/app/src/main/java/com/algorand/android/modules/accounts/ui/adapter/AccountAdapter.kt b/app/src/main/java/com/algorand/android/modules/accounts/ui/adapter/AccountAdapter.kt index 4fe2a8135..857bb16c3 100644 --- a/app/src/main/java/com/algorand/android/modules/accounts/ui/adapter/AccountAdapter.kt +++ b/app/src/main/java/com/algorand/android/modules/accounts/ui/adapter/AccountAdapter.kt @@ -14,10 +14,12 @@ package com.algorand.android.modules.accounts.ui.adapter import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter +import com.algorand.android.banner.domain.model.BannerType import com.algorand.android.banner.ui.viewholder.BackupBannerViewHolder import com.algorand.android.banner.ui.viewholder.BaseBannerViewHolder import com.algorand.android.banner.ui.viewholder.GenericBannerViewHolder import com.algorand.android.banner.ui.viewholder.GovernanceBannerViewHolder +import com.algorand.android.banner.ui.viewholder.StakingBannerViewHolder import com.algorand.android.models.BaseDiffUtil import com.algorand.android.models.BaseViewHolder import com.algorand.android.modules.accounts.domain.model.BaseAccountListItem @@ -28,6 +30,7 @@ import com.algorand.android.modules.accounts.domain.model.BaseAccountListItem.It import com.algorand.android.modules.accounts.domain.model.BaseAccountListItem.ItemType.GOVERNANCE_BANNER import com.algorand.android.modules.accounts.domain.model.BaseAccountListItem.ItemType.HEADER import com.algorand.android.modules.accounts.domain.model.BaseAccountListItem.ItemType.QUICK_ACTIONS +import com.algorand.android.modules.accounts.domain.model.BaseAccountListItem.ItemType.STAKING_BANNER import com.algorand.android.modules.accounts.ui.viewholder.AccountErrorItemViewHolder import com.algorand.android.modules.accounts.ui.viewholder.AccountItemViewHolder import com.algorand.android.modules.accounts.ui.viewholder.AccountsQuickActionsViewHolder @@ -68,8 +71,8 @@ class AccountAdapter( } private val baseBannerListener = object : BaseBannerViewHolder.BannerListener { - override fun onActionButtonClick(url: String) { - accountAdapterListener.onBannerActionButtonClick(url = url, isGovernance = false) + override fun onActionButtonClick(url: String, bannerType: BannerType) { + accountAdapterListener.onBannerActionButtonClick(url = url, bannerType) } override fun onCloseBannerClick(bannerId: Long) { @@ -78,8 +81,18 @@ class AccountAdapter( } private val governanceBaseBannerListener = object : BaseBannerViewHolder.BannerListener { - override fun onActionButtonClick(url: String) { - accountAdapterListener.onBannerActionButtonClick(url = url, isGovernance = true) + override fun onActionButtonClick(url: String, bannerType: BannerType) { + accountAdapterListener.onBannerActionButtonClick(url = url, bannerType) + } + + override fun onCloseBannerClick(bannerId: Long) { + accountAdapterListener.onBannerCloseButtonClick(bannerId) + } + } + + private val stakingBaseBannerListener = object : BaseBannerViewHolder.BannerListener { + override fun onActionButtonClick(url: String, bannerType: BannerType) { + accountAdapterListener.onBannerActionButtonClick(url = url, bannerType = bannerType) } override fun onCloseBannerClick(bannerId: Long) { @@ -125,6 +138,7 @@ class AccountAdapter( ACCOUNT_SUCCESS.ordinal -> AccountItemViewHolder.create(parent, accountClickListener) ACCOUNT_ERROR.ordinal -> AccountErrorItemViewHolder.create(parent, accountErrorClickListener) GOVERNANCE_BANNER.ordinal -> GovernanceBannerViewHolder.create(governanceBaseBannerListener, parent) + STAKING_BANNER.ordinal -> StakingBannerViewHolder.create(stakingBaseBannerListener, parent) GENERIC_BANNER.ordinal -> GenericBannerViewHolder.create(baseBannerListener, parent) BACKUP_BANNER.ordinal -> BackupBannerViewHolder.create(parent, backupBannerListener) QUICK_ACTIONS.ordinal -> AccountsQuickActionsViewHolder.create(parent, accountsQuickActionsListener) @@ -141,7 +155,7 @@ class AccountAdapter( fun onFailedAccountClick(publicKey: String) fun onAccountItemLongPressed(publicKey: String) fun onBannerCloseButtonClick(bannerId: Long) - fun onBannerActionButtonClick(url: String, isGovernance: Boolean) + fun onBannerActionButtonClick(url: String, bannerType: BannerType) fun onBackupBannerActionButtonClick() fun onBuySellClick() fun onSendClick() diff --git a/app/src/main/java/com/algorand/android/modules/tracking/accounts/AccountsEventTracker.kt b/app/src/main/java/com/algorand/android/modules/tracking/accounts/AccountsEventTracker.kt index 8966932fb..b47a29e94 100644 --- a/app/src/main/java/com/algorand/android/modules/tracking/accounts/AccountsEventTracker.kt +++ b/app/src/main/java/com/algorand/android/modules/tracking/accounts/AccountsEventTracker.kt @@ -23,6 +23,7 @@ class AccountsEventTracker @Inject constructor( private val accountsQrScanEventTracker: AccountsQrScanEventTracker, private val accountsQrConnectEventTracker: AccountsQrConnectEventTracker, private val visitGovernanceEventTracker: VisitGovernanceEventTracker, + private val visitStakingEventTracker: VisitStakingEventTracker, private val trySwapClickEventTracker: SwapTutorialTrySwapClickEventTracker, private val laterClickEventTracker: SwapTutorialLaterClickEventTracker, private val accountsFragmentAlgoBuyTapEventTracker: AccountsFragmentAlgoBuyTapEventTracker, @@ -45,6 +46,10 @@ class AccountsEventTracker @Inject constructor( visitGovernanceEventTracker.logVisitGovernanceEvent() } + suspend fun logVisitStakingEvent() { + visitStakingEventTracker.logVisitStakingEvent() + } + suspend fun logSwapTutorialTrySwapClickEvent() { trySwapClickEventTracker.logSwapTutorialTrySwapClickEvent() } diff --git a/app/src/main/java/com/algorand/android/modules/tracking/accounts/VisitStakingEventTracker.kt b/app/src/main/java/com/algorand/android/modules/tracking/accounts/VisitStakingEventTracker.kt new file mode 100644 index 000000000..53cec0373 --- /dev/null +++ b/app/src/main/java/com/algorand/android/modules/tracking/accounts/VisitStakingEventTracker.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2022 Pera Wallet, LDA + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.algorand.android.modules.tracking.accounts + +import com.algorand.android.modules.tracking.core.BaseEventTracker +import com.algorand.android.modules.tracking.core.PeraEventTracker +import javax.inject.Inject + +class VisitStakingEventTracker @Inject constructor( + peraEventTracker: PeraEventTracker +) : BaseEventTracker(peraEventTracker) { + + suspend fun logVisitStakingEvent() { + logEvent(VISIT_STAKING_EVENT_KEY) + } + + companion object { + private const val VISIT_STAKING_EVENT_KEY = "homescr_visitstaking" + } +} diff --git a/app/src/main/res/drawable-hdpi/bg_staking_banner.png b/app/src/main/res/drawable-hdpi/bg_staking_banner.png new file mode 100644 index 000000000..6d32aaec3 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/bg_staking_banner.png differ diff --git a/app/src/main/res/drawable-hdpi/bg_staking_banner_coins.png b/app/src/main/res/drawable-hdpi/bg_staking_banner_coins.png new file mode 100644 index 000000000..b6354418b Binary files /dev/null and b/app/src/main/res/drawable-hdpi/bg_staking_banner_coins.png differ diff --git a/app/src/main/res/drawable-mdpi/bg_staking_banner.png b/app/src/main/res/drawable-mdpi/bg_staking_banner.png new file mode 100644 index 000000000..f81f011da Binary files /dev/null and b/app/src/main/res/drawable-mdpi/bg_staking_banner.png differ diff --git a/app/src/main/res/drawable-mdpi/bg_staking_banner_coins.png b/app/src/main/res/drawable-mdpi/bg_staking_banner_coins.png new file mode 100644 index 000000000..e655e3b18 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/bg_staking_banner_coins.png differ diff --git a/app/src/main/res/drawable-xhdpi/bg_staking_banner.png b/app/src/main/res/drawable-xhdpi/bg_staking_banner.png new file mode 100644 index 000000000..b8ef73c1d Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/bg_staking_banner.png differ diff --git a/app/src/main/res/drawable-xhdpi/bg_staking_banner_coins.png b/app/src/main/res/drawable-xhdpi/bg_staking_banner_coins.png new file mode 100644 index 000000000..3ce365555 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/bg_staking_banner_coins.png differ diff --git a/app/src/main/res/drawable-xxhdpi/bg_staking_banner.png b/app/src/main/res/drawable-xxhdpi/bg_staking_banner.png new file mode 100644 index 000000000..73c1ace89 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/bg_staking_banner.png differ diff --git a/app/src/main/res/drawable-xxhdpi/bg_staking_banner_coins.png b/app/src/main/res/drawable-xxhdpi/bg_staking_banner_coins.png new file mode 100644 index 000000000..67907da77 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/bg_staking_banner_coins.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/bg_staking_banner.png b/app/src/main/res/drawable-xxxhdpi/bg_staking_banner.png new file mode 100644 index 000000000..88bfd88f5 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/bg_staking_banner.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/bg_staking_banner_coins.png b/app/src/main/res/drawable-xxxhdpi/bg_staking_banner_coins.png new file mode 100644 index 000000000..d5aa5e29e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/bg_staking_banner_coins.png differ diff --git a/app/src/main/res/drawable/ic_banner_close_light.xml b/app/src/main/res/drawable/ic_banner_close_light.xml new file mode 100644 index 000000000..d58317be1 --- /dev/null +++ b/app/src/main/res/drawable/ic_banner_close_light.xml @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_arc59_express_send.xml b/app/src/main/res/layout/fragment_arc59_express_send.xml index 9d9e48ef3..1e35fef20 100644 --- a/app/src/main/res/layout/fragment_arc59_express_send.xml +++ b/app/src/main/res/layout/fragment_arc59_express_send.xml @@ -58,6 +58,7 @@ android:layout_height="wrap_content" android:layout_marginHorizontal="@dimen/spacing_xlarge" android:layout_marginTop="@dimen/spacing_xlarge" + android:lineSpacingExtra="6dp" android:paddingBottom="@dimen/spacing_xxxlarge" android:text="@string/your_receiving_wallet" android:textColor="@color/text_gray" @@ -94,6 +95,7 @@ android:layout_height="wrap_content" android:layout_marginStart="@dimen/spacing_small" android:layout_marginEnd="@dimen/spacing_xlarge" + android:lineSpacingExtra="4dp" android:text="@string/your_sending_account_will_send" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/step1IndexTextView" @@ -116,7 +118,8 @@ android:layout_height="wrap_content" android:layout_marginStart="@dimen/spacing_small" android:layout_marginEnd="@dimen/spacing_xlarge" - android:text="@string/your_sending_account_will_send" + android:lineSpacingExtra="4dp" + android:text="@string/your_receiving_account_will_be" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/step2IndexTextView" app:layout_constraintTop_toTopOf="@id/step2IndexTextView" /> @@ -138,7 +141,8 @@ android:layout_height="wrap_content" android:layout_marginStart="@dimen/spacing_small" android:layout_marginEnd="@dimen/spacing_xlarge" - android:text="@string/your_sending_account_will_send" + android:lineSpacingExtra="4dp" + android:text="@string/your_sending_account_over" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/step3IndexTextView" app:layout_constraintTop_toTopOf="@id/step3IndexTextView" /> diff --git a/app/src/main/res/layout/item_staking_banner.xml b/app/src/main/res/layout/item_staking_banner.xml new file mode 100644 index 000000000..d63fbb69f --- /dev/null +++ b/app/src/main/res/layout/item_staking_banner.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c7b7181ad..66e235055 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1428,4 +1428,10 @@ Your Receiving Account will be opted into the asset Your Sending Account will send over the asset Don\'t show this again + + xNote + Try Stake + Pera Wallet now provides an easy and fast way to stake with various dApps. + Stake in Pera + diff --git a/wallet-sdk/src/commonMain/kotlin/com/algorand/common/deeplink/parser/query/MnemonicQueryParser.kt b/wallet-sdk/src/commonMain/kotlin/com/algorand/common/deeplink/parser/query/MnemonicQueryParser.kt index fa86e0ae2..e12797980 100644 --- a/wallet-sdk/src/commonMain/kotlin/com/algorand/common/deeplink/parser/query/MnemonicQueryParser.kt +++ b/wallet-sdk/src/commonMain/kotlin/com/algorand/common/deeplink/parser/query/MnemonicQueryParser.kt @@ -29,7 +29,7 @@ internal class MnemonicQueryParser : DeepLinkQueryParser { @Serializable private data class MnemonicPayload( - @SerialName("version") val version: Double?, + @SerialName("version") val version: Double? = null, @SerialName("mnemonic") val mnemonic: String ) } diff --git a/wallet-sdk/src/commonMain/kotlin/com/algorand/common/deeplink/utils/CoinbaseDeepLinkUtils.kt b/wallet-sdk/src/commonMain/kotlin/com/algorand/common/deeplink/utils/CoinbaseDeepLinkUtils.kt index 916d6a0a8..889e7b0f2 100644 --- a/wallet-sdk/src/commonMain/kotlin/com/algorand/common/deeplink/utils/CoinbaseDeepLinkUtils.kt +++ b/wallet-sdk/src/commonMain/kotlin/com/algorand/common/deeplink/utils/CoinbaseDeepLinkUtils.kt @@ -14,8 +14,8 @@ package com.algorand.common.deeplink.utils import com.algorand.common.deeplink.model.PeraUri -private const val COINBASE_DEEPLINK_ROOT = "algo" +private const val COINBASE_DEEPLINK_ROOT = "algo:" internal fun isCoinbaseDeepLink(uri: PeraUri): Boolean { - return uri.scheme.equals(COINBASE_DEEPLINK_ROOT, ignoreCase = true) + return uri.rawUri.startsWith(COINBASE_DEEPLINK_ROOT, ignoreCase = true) }