diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt index dce356f1be..b06dc1b5df 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt @@ -53,6 +53,9 @@ val globalMiddleware: Middleware = { dispatch, appState -> is GlobalAction.SendFeedback -> { store.state.globalState.feedbackManager?.send(action.emailData) } + is GlobalAction.UpdateWalletSignedHashes -> { + store.dispatch(WalletAction.Warnings.CheckRemainingSignatures(action.remainingSignatures)) + } } nextDispatch(action) } diff --git a/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessage.kt b/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessage.kt index 8494a61786..3c3ad5f5ce 100644 --- a/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessage.kt +++ b/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessage.kt @@ -19,6 +19,7 @@ data class WarningMessage( @StringRes val messageResId: Int? = null, val origin: Origin = Origin.Remote, @StringRes val buttonTextId: Int? = null, + val messageFormatArg: String? = null ) { val blockchainList: List? by lazy { blockchains?.map { Blockchain.fromId(it.toUpperCase()) } diff --git a/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt b/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt index 8bde4ae283..59e91a7f6a 100644 --- a/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/configurable/warningMessage/WarningMessagesManager.kt @@ -1,5 +1,6 @@ package com.tangem.tap.domain.configurable.warningMessage +import com.tangem.TangemSdkError import com.tangem.blockchain.common.Blockchain import com.tangem.tangem_sdk_new.ui.animation.VoidCallback import com.tangem.tap.common.extensions.containsAny @@ -140,5 +141,20 @@ class WarningMessagesManager( R.string.warning_failed_to_verify_card_message, WarningMessage.Origin.Local ) + + fun remainingSignaturesNotEnough(remainingSignatures: Int): WarningMessage = WarningMessage( + title = "", + message = "", + type = WarningMessage.Type.Permanent, + priority = WarningMessage.Priority.Critical, + listOf(WarningMessage.Location.MainScreen), + blockchains = null, + titleResId = R.string.alert_title, + messageResId = R.string.warning_low_signatures_format, + origin = WarningMessage.Origin.Local, + messageFormatArg = remainingSignatures.toString() + ) + + const val REMAINING_SIGNATURES_WARNING = 10 } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/extensions/Card.kt b/app/src/main/java/com/tangem/tap/domain/extensions/Card.kt index 4dd07f00f5..eb60189b4f 100644 --- a/app/src/main/java/com/tangem/tap/domain/extensions/Card.kt +++ b/app/src/main/java/com/tangem/tap/domain/extensions/Card.kt @@ -41,4 +41,7 @@ fun Card.hasSignedHashes(): Boolean { fun Card.signedHashesCount(): Int { return getWallets().map { it.signedHashes ?: 0 }.sum() -} \ No newline at end of file +} + +val Card.remainingSignatures: Int? + get() = this.getSingleWallet()?.remainingSignatures \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt index 18ffaa31b1..405e96be66 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt @@ -68,6 +68,7 @@ sealed class WalletAction : Action { object SetNeverToShow : Warnings() object RemindLater : Warnings() } + class CheckRemainingSignatures(val remainingSignatures: Int?) : Warnings() } data class UpdateWallet(val currency: CryptoCurrencyName? = null) : WalletAction() { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt index 46a7693492..211e5ef2b1 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt @@ -16,6 +16,7 @@ import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager import com.tangem.tap.domain.extensions.getSingleWallet import com.tangem.tap.domain.extensions.hasSignedHashes +import com.tangem.tap.domain.extensions.remainingSignatures import com.tangem.tap.domain.isMultiwalletAllowed import com.tangem.tap.domain.twins.isTwinCard import com.tangem.tap.features.wallet.redux.WalletAction @@ -48,6 +49,17 @@ class WarningsMiddleware { is WalletAction.Warnings.AppRating.SetNeverToShow -> { preferencesStorage.appRatingLaunchObserver.setNeverToShow() } + is WalletAction.Warnings.CheckRemainingSignatures -> { + if (action.remainingSignatures != null && + action.remainingSignatures <= WarningMessagesManager.REMAINING_SIGNATURES_WARNING + ) { + addWarningMessage( + warning = + WarningMessagesManager.remainingSignaturesNotEnough(action.remainingSignatures), + autoUpdate = true + ) + } + } } } @@ -67,6 +79,7 @@ class WarningsMiddleware { private fun showCardWarningsIfNeeded(globalState: GlobalState?) { globalState?.scanNoteResponse?.card?.let { card -> globalState.warningManager?.removeWarnings(WarningMessage.Origin.Local) + showWarningLowRemainingSignaturesIfNeeded(card) if (card.getType() != CardType.Release) { addWarningMessage(WarningMessagesManager.devCardWarning()) } else if (!preferencesStorage.wasCardScannedBefore(card.cardId)) { @@ -74,7 +87,8 @@ class WarningsMiddleware { } if (card.getType() == CardType.Release) { if (globalState.scanNoteResponse.verifyResponse?.verificationState == - VerifyCardState.VerifiedOffline) { + VerifyCardState.VerifiedOffline + ) { addWarningMessage(WarningMessagesManager.onlineVerificationFailed()) } } @@ -82,8 +96,21 @@ class WarningsMiddleware { } } + private fun showWarningLowRemainingSignaturesIfNeeded(card: Card) { + val remainingSignatures = card.remainingSignatures + if (remainingSignatures != null && + remainingSignatures <= WarningMessagesManager.REMAINING_SIGNATURES_WARNING + ) { + addWarningMessage( + WarningMessagesManager.remainingSignaturesNotEnough( + remainingSignatures + ) + ) + } + } + private fun checkIfWarningNeeded( - card: Card + card: Card ): WarningMessage? { if (card.isTwinCard()) return null @@ -133,9 +160,15 @@ class WarningsMiddleware { } is SimpleResult.Failure -> if (result.error is BlockchainSdkError.SignatureCountNotMatched) { - addWarningMessage(WarningMessagesManager.alreadySignedHashesWarning(), true) + addWarningMessage( + WarningMessagesManager.alreadySignedHashesWarning(), + true + ) } else if (signedHashes > 0) { - addWarningMessage(WarningMessagesManager.alreadySignedHashesWarning(), true) + addWarningMessage( + WarningMessagesManager.alreadySignedHashesWarning(), + true + ) } } } @@ -153,6 +186,9 @@ class WarningsMiddleware { private fun getWarnings(): List { val warningManager = store.state.globalState.warningManager ?: return emptyList() - return warningManager.getWarnings(WarningMessage.Location.MainScreen, store.state.walletState.blockchains) + return warningManager.getWarnings( + WarningMessage.Location.MainScreen, + store.state.walletState.blockchains + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WarningMessagesAdapter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WarningMessagesAdapter.kt index 80b739b21c..c262bbb35c 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WarningMessagesAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WarningMessagesAdapter.kt @@ -54,11 +54,13 @@ class WarningMessageVH(val view: View) : RecyclerView.ViewHolder(view) { } private fun setText(warning: WarningMessage) { - fun getString(resId: Int?, default: String) = - if (resId == null) default else view.getString(resId) + fun getString(resId: Int?, default: String, formatArgs: String? = null) = + if (resId == null) default else view.context.getString(resId, formatArgs) view.tv_title.text = getString(warning.titleResId, warning.title) - view.tv_message.text = getString(warning.messageResId, warning.message) + view.tv_message.text = getString( + resId = warning.messageResId, default = warning.message, formatArgs = warning.messageFormatArg + ) } private fun setBgColor(priority: WarningMessage.Priority) { diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index 762001572e..339ccae0b2 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -111,4 +111,6 @@ this wallet. \n\nIt’s perfectly safe in all other respects. \n\nTangem is the only hardware wallet to offer signature count protection. I understand + + There are only %s signatures available on this card. You must withdraw all of your funds.