From a610e8bf011ba8a8fc40e784962189b5f7c875fa Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 6 Oct 2020 15:53:59 +0300 Subject: [PATCH 01/11] Updated on 2026-08-14 --- app/build.gradle | 6 ++--- .../features/wallet/redux/WalletMiddleware.kt | 24 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b639eb6dab..df88037b21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -67,9 +67,9 @@ dependencies { implementation 'com.google.android.material:material:1.2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' - implementation 'com.tangem:blockchain:1.74.0' - implementation 'com.tangem:core:1.63.0' - implementation 'com.tangem:sdk:1.63.0' + implementation 'com.tangem:blockchain:1.76.0' + implementation 'com.tangem:core:1.64.0' + implementation 'com.tangem:sdk:1.64.0' //lifecycle implementation "androidx.lifecycle:lifecycle-runtime:2.2.0" diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt index da8dc6eeed..18d024a379 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt @@ -3,10 +3,7 @@ package com.tangem.tap.features.wallet.redux import android.content.Intent import android.net.Uri import androidx.core.content.ContextCompat -import com.tangem.blockchain.common.Amount -import com.tangem.blockchain.common.AmountType -import com.tangem.blockchain.common.SignatureCountValidator -import com.tangem.blockchain.common.Wallet +import com.tangem.blockchain.common.* import com.tangem.blockchain.extensions.SimpleResult import com.tangem.commands.Card import com.tangem.commands.common.network.Result @@ -218,22 +215,25 @@ private fun checkIfWarningNeeded( private fun checkHashesCountOnline() { if (store.state.walletState.hashesCountVerified != false) return - if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) return val card = store.state.globalState.scanNoteResponse?.card + if (card == null || preferencesStorage.wasCardScannedBefore(card.cardId)) return + val validator = store.state.globalState.scanNoteResponse?.walletManager as? SignatureCountValidator - scope.launch { - val result = validator?.validateSignatureCount(card?.walletSignedHashes - ?: 0) + val result = validator?.validateSignatureCount(card.walletSignedHashes ?: 0) withContext(Dispatchers.Main) { when (result) { - SimpleResult.Success -> store.dispatch(WalletAction.ConfirmHashesCount) - is SimpleResult.Failure -> store.dispatch( - WalletAction.ShowWarning(WarningType.CardSignedHashesBefore) - ) + SimpleResult.Success -> { + store.dispatch(WalletAction.ConfirmHashesCount) + store.dispatch(WalletAction.SaveCardId) + } + is SimpleResult.Failure -> + if (result.error is BlockchainSdkError.SignatureCountNotMatched) { + store.dispatch(WalletAction.ShowWarning(WarningType.CardSignedHashesBefore)) + } } } } From 9007fffdfc7a4d2cb6796cbae7fbddd146796a59 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 8 Oct 2020 12:16:48 +0300 Subject: [PATCH 02/11] Updated on 2026-08-14 --- .../com/tangem/tap/domain/TangemSdkManager.kt | 12 +- .../java/com/tangem/tap/domain/TapErrors.kt | 32 +-- .../details/ui/CurrencySelectionDialog.kt | 6 +- .../details/ui/DetailsConfirmFragment.kt | 10 +- .../tangem/tap/features/home/HomeFragment.kt | 2 +- .../tap/features/send/BaseStoreFragment.kt | 2 +- .../features/send/redux/SendScreenAction.kt | 2 +- .../tap/features/send/ui/SendFragment.kt | 2 +- .../stateSubscribers/SendStateSubscriber.kt | 43 ++-- .../tap/features/wallet/redux/WalletAction.kt | 2 +- .../tap/features/wallet/ui/BalanceWidget.kt | 16 +- .../wallet/ui/PendingTransactionsAdapter.kt | 8 +- .../tap/features/wallet/ui/WalletFragment.kt | 6 +- .../features/wallet/ui/dialogs/PayIdDialog.kt | 2 +- .../features/wallet/ui/dialogs/QrDialog.kt | 2 +- .../wallet/ui/dialogs/WarningDialog.kt | 6 +- .../main/res/layout/dialog_create_payid.xml | 10 +- app/src/main/res/layout/dialog_qrcode.xml | 2 +- app/src/main/res/layout/fragment_details.xml | 18 +- .../res/layout/fragment_details_security.xml | 2 +- app/src/main/res/layout/fragment_home.xml | 2 +- app/src/main/res/layout/fragment_wallet.xml | 2 +- app/src/main/res/layout/layout_address.xml | 4 +- app/src/main/res/layout/layout_balance.xml | 6 +- .../main/res/layout/layout_balance_error.xml | 2 +- .../main/res/layout/layout_receipt_total.xml | 7 +- .../res/layout/layout_send_address_payid.xml | 2 +- app/src/main/res/layout/layout_send_fee.xml | 10 +- .../main/res/layout/layout_send_receipt.xml | 4 +- app/src/main/res/layout/layout_token.xml | 2 +- .../view_snackbar_max_amount_content.xml | 2 +- app/src/main/res/menu/wallet.xml | 2 +- app/src/main/res/values/strings.xml | 213 ++++++++++-------- 33 files changed, 228 insertions(+), 215 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt b/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt index d122202ca1..d6b7730bcb 100644 --- a/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt @@ -24,17 +24,17 @@ class TangemSdkManager(val activity: ComponentActivity) { suspend fun scanNote(): CompletionResult { return runTaskAsyncReturnOnMain(ScanNoteTask(), - initialMessage = Message(activity.getString(R.string.tap_to_scan))) + initialMessage = Message(activity.getString(R.string.initial_message_scan_header))) } suspend fun createWallet(cardId: String?): CompletionResult { return runTaskAsyncReturnOnMain(CreateWalletAndRescanTask(), cardId, - initialMessage = Message(activity.getString(R.string.tap_to_create_wallet))) + initialMessage = Message(activity.getString(R.string.initial_message_create_wallet_body))) } suspend fun eraseWallet(cardId: String?): CompletionResult { return runTaskAsyncReturnOnMain(PurgeWalletCommand(), cardId, - initialMessage = Message(activity.getString(R.string.tap_to_purge_wallet))) + initialMessage = Message(activity.getString(R.string.initial_message_purge_wallet_body))) } suspend fun setPasscode(cardId: String?): CompletionResult { @@ -42,7 +42,7 @@ class TangemSdkManager(val activity: ComponentActivity) { pinType = PinType.Pin2, newPin1 = tangemSdk.config.defaultPin1.calculateSha256(), newPin2 = null - ), cardId, initialMessage = Message(activity.getString(R.string.tap_to_change_passcode))) + ), cardId, initialMessage = Message(activity.getString(R.string.initial_message_change_passcode_body))) } suspend fun setAccessCode(cardId: String?): CompletionResult { @@ -50,7 +50,7 @@ class TangemSdkManager(val activity: ComponentActivity) { pinType = PinType.Pin1, newPin1 = null, newPin2 = tangemSdk.config.defaultPin2.calculateSha256() - ), cardId, initialMessage = Message(activity.getString(R.string.tap_to_change_access_code))) + ), cardId, initialMessage = Message(activity.getString(R.string.initial_message_change_access_code_body))) } suspend fun setLongTap(cardId: String?): CompletionResult { @@ -58,7 +58,7 @@ class TangemSdkManager(val activity: ComponentActivity) { pinType = PinType.Pin1, newPin1 = tangemSdk.config.defaultPin1.calculateSha256(), newPin2 = tangemSdk.config.defaultPin2.calculateSha256() - ), cardId, initialMessage = Message(activity.getString(R.string.tap_the_card))) + ), cardId, initialMessage = Message(activity.getString(R.string.initial_message_tap_header))) } private suspend fun runTaskAsync( diff --git a/app/src/main/java/com/tangem/tap/domain/TapErrors.kt b/app/src/main/java/com/tangem/tap/domain/TapErrors.kt index 8b01a14b04..e3f8ab3646 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapErrors.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapErrors.kt @@ -20,22 +20,22 @@ sealed class TapError( override val args: List? = null ) : Throwable(), TapErrors, ArgError { - object UnknownError : TapError(R.string.error_unknown) - object PayIdAlreadyCreated : TapError(R.string.error_payid_already_created) - object PayIdCreatingError : TapError(R.string.error_creating_payid) + object UnknownError : TapError(R.string.send_error_unknown) + object PayIdAlreadyCreated : TapError(R.string.wallet_create_payid_error_already_created) + object PayIdCreatingError : TapError(R.string.wallet_create_payid_error_message) object PayIdEmptyField : TapError(R.string.wallet_create_payid_empty) - object UnknownBlockchain : TapError(R.string.wallet_unknown_blockchain) - object NoInternetConnection : TapError(R.string.notification_no_internet) - object InsufficientBalance : TapError(R.string.error_insufficient_balance) - object BlockchainInternalError : TapError(R.string.error_blockchain_internal) - object AmountExceedsBalance : TapError(R.string.amount_exceeds_balance) - object FeeExceedsBalance : TapError(R.string.fee_exceeds_balance) - object TotalExceedsBalance : TapError(R.string.total_exceeds_balance) - object InvalidAmountValue : TapError(R.string.invalid_amount_value) - object InvalidFeeValue : TapError(R.string.invalid_fee_value) - data class DustAmount(override val args: List) : TapError(R.string.dust_amount) - object DustChange : TapError(R.string.dust_change) - data class CreateAccountUnderfunded(override val args: List) : TapError(R.string.create_account_underfunded) + object UnknownBlockchain : TapError(R.string.wallet_error_unsupported_blockchain_subtitle) + object NoInternetConnection : TapError(R.string.wallet_notification_no_internet) + object InsufficientBalance : TapError(R.string.send_error_insufficient_balance) + object BlockchainInternalError : TapError(R.string.send_error_blockchain_internal) + object AmountExceedsBalance : TapError(R.string.send_error_amount_exceeds_balance) + object FeeExceedsBalance : TapError(R.string.send_error_fee_exceeds_balance) + object TotalExceedsBalance : TapError(R.string.send_error_total_exceeds_balance) + object InvalidAmountValue : TapError(R.string.send_error_invalid_amount) + object InvalidFeeValue : TapError(R.string.send_error_invalid_fee_value) + data class DustAmount(override val args: List) : TapError(R.string.send_error_dust_amount_format) + object DustChange : TapError(R.string.send_error_dust_change) + data class CreateAccountUnderfunded(override val args: List) : TapError(R.string.send_error_no_target_accout) data class ValidateTransactionErrors( override val errorList: List, @@ -47,7 +47,7 @@ sealed class TapSdkError(override val messageResId: Int?) : Throwable(), TangemE final override val code: Int = 1 override var customMessage: String = code.toString() - object CardForDifferentApp : TapSdkError(R.string.error_card_for_different_app) + object CardForDifferentApp : TapSdkError(R.string.alert_unsupported_card) } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/CurrencySelectionDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/CurrencySelectionDialog.kt index dc00b896f8..47720dfbc4 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/CurrencySelectionDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/CurrencySelectionDialog.kt @@ -20,11 +20,11 @@ class CurrencySelectionDialog { var currentSelection = currencies.indexOfFirst { it.symbol == currentAppCurrency } dialog = AlertDialog.Builder(context) - .setTitle(context.getString(R.string.details_currency)) - .setNegativeButton(context.getString(R.string.generic_cancel)) { _, _ -> + .setTitle(context.getString(R.string.details_row_title_currency)) + .setNegativeButton(context.getString(R.string.common_cancel)) { _, _ -> store.dispatch(DetailsAction.AppCurrencyAction.Cancel) } - .setPositiveButton(context.getString(R.string.generic_done)) { _, _ -> + .setPositiveButton(context.getString(R.string.common_done)) { _, _ -> val selectedCurrency = currencies[currentSelection] store.dispatch(DetailsAction.AppCurrencyAction.SelectAppCurrency(selectedCurrency.symbol)) } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsConfirmFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsConfirmFragment.kt index d75799b5c1..7439dee4ec 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsConfirmFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsConfirmFragment.kt @@ -58,9 +58,9 @@ class DetailsConfirmFragment : Fragment(R.layout.fragment_details_confirm), when (state.confirmScreenState) { ConfirmScreenState.EraseWallet -> { - toolbar.title = getString(R.string.details_erase_wallet) + toolbar.title = getString(R.string.details_row_title_erase_wallet) tv_warning_description.text = getString(R.string.details_erase_wallet_warning) - btn_confirm.text = getString(R.string.details_erase_wallet) + btn_confirm.text = getString(R.string.details_row_title_erase_wallet) btn_confirm.setCompoundDrawablesRelativeWithIntrinsicBounds( null, null, getDrawable(R.drawable.ic_send), null ) @@ -68,9 +68,9 @@ class DetailsConfirmFragment : Fragment(R.layout.fragment_details_confirm), } ConfirmScreenState.LongTap, ConfirmScreenState.AccessCode, ConfirmScreenState.PassCode -> { - toolbar.title = getString(R.string.details_manage_security) - tv_warning_description.text = getString(R.string.details_manage_security_warning) - btn_confirm.text = getString(R.string.details_save_changes) + toolbar.title = getString(R.string.details_row_title_manage_security) + tv_warning_description.text = getString(R.string.details_security_management_warning) + btn_confirm.text = getString(R.string.common_save_changes) btn_confirm.setCompoundDrawablesRelativeWithIntrinsicBounds( null, null, getDrawable(R.drawable.ic_save), null ) diff --git a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt index 4d4ade93a9..e2729db034 100644 --- a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt @@ -31,7 +31,7 @@ class HomeFragment : Fragment(R.layout.fragment_home), StoreSubscriber Unit) { val snackbar = Snackbar.make(mainView, message, Snackbar.LENGTH_INDEFINITE) - snackbar.setAction(getString(R.string.generic_retry)) { + snackbar.setAction(getString(R.string.common_retry)) { snackbar.dismiss() action() }.show() diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt index 67e22baa41..b0ed6c6bf4 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt @@ -110,7 +110,7 @@ sealed class SendAction : SendScreenAction { data class ChangeSendButtonState(val state: SendButtonState) : SendAction() object SendSuccess : SendAction(), ToastNotificationAction { - override val messageResource: Int = R.string.send_transaction_complete + override val messageResource: Int = R.string.send_transaction_success } data class SendError(override val error: TapError) : SendAction(), ErrorAction diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt index 2e2e4b9ed2..6d3799ea4d 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt @@ -67,7 +67,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { btnSend.setOnClickListener { store.dispatch(SendActionUi.SendAmountToRecipient( - Message(getString(R.string.tap_to_sign)) + Message(getString(R.string.initial_message_sign_header)) )) } } diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt index 349898d061..eb6fb4f317 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt @@ -73,11 +73,11 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber private fun handleAddressPayIdState(fg: BaseStoreFragment, state: AddressPayIdState) { fun parseError(context: Context, error: Error?): String? { val resId = when (error) { - Error.PAY_ID_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.error_payid_unsupported_by_blockchain - Error.PAY_ID_NOT_REGISTERED -> R.string.error_payid_not_registere - Error.PAY_ID_REQUEST_FAILED -> R.string.error_payid_request_failed - Error.ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.error_address_invalid_or_unsupported - Error.ADDRESS_SAME_AS_WALLET -> R.string.error_address_same_as_wallet + Error.PAY_ID_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.send_error_payid_unsupported_by_blockchain + Error.PAY_ID_NOT_REGISTERED -> R.string.send_error_payid_not_registere + Error.PAY_ID_REQUEST_FAILED -> R.string.send_error_payid_request_failed + Error.ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.send_error_address_invalid_or_unsupported + Error.ADDRESS_SAME_AS_WALLET -> R.string.send_error_address_same_as_wallet else -> null } return if (resId == null) null else context.getString(resId, "", "") @@ -139,7 +139,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber fg.tvAmountCurrency.update(state.mainCurrency.currencySymbol) (fg as? SendFragment)?.saveMainCurrency(state.mainCurrency.type) - val balanceText = fg.getString(R.string.send_balance, + val balanceText = fg.getString(R.string.send_balance_subtitle_format, state.mainCurrency.currencySymbol, state.viewBalanceValue) fg.tvBalance.update(balanceText) @@ -173,7 +173,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber } if (state.error == FeeAction.Error.REQUEST_FAILED) { - fg.showRetrySnackbar(fg.requireContext().getString(R.string.error_fee_request_failed)) { + fg.showRetrySnackbar(fg.requireContext().getString(R.string.send_error_fee_request_failed)) { store.dispatch(FeeAction.RequestFee) } } @@ -186,7 +186,8 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber val mainLayout = fg.clReceiptContainer as ViewGroup val totalLayout = fg.llTotal as ViewGroup val totalTokenLayout = fg.flTotalTokenCrypto as ViewGroup - fun getString(id: Int): String = mainLayout.context.getString(id) + fun getString(id: Int, vararg formatStrings: String): String = + mainLayout.context.getString(id, *formatStrings) val rough = getString(R.string.sign_rough) fun roughOrEmpty(value: String): String = if (value == ReceiptReducer.EMPTY) value else "$rough $value" @@ -201,11 +202,9 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber fg.tvReceiptFeeValue.update("${receipt.feeFiat} ${receipt.symbols.fiat}") totalLayout.tvTotalValue.update("${roughOrEmpty(receipt.totalFiat)} ${receipt.symbols.fiat}") - val willSent = SpannableStringBuilder() - .bold { append(receipt.willSentCrypto) }.append(" ") - .append(receipt.symbols.crypto).append(" ") - .append(getString(R.string.send_total_will_be_sent)) - totalLayout.tvWillBeSentValue.update(willSent.toString()) + val willSent = getString(R.string.send_total_subtitle_format, + receipt.willSentCrypto, receipt.symbols.crypto) + totalLayout.tvWillBeSentValue.update(willSent) } ReceiptLayoutType.CRYPTO -> { @@ -235,18 +234,12 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber fg.tvReceiptFeeValue.update("${receipt.feeFiat} ${receipt.symbols.fiat}") totalLayout.tvTotalValue.update("${roughOrEmpty(receipt.totalFiat)} ${receipt.symbols.fiat}") - val willSent = SpannableStringBuilder() - .bold { - append(receipt.symbols.token) - append(" ") - append(receipt.willSentToken) - }.append(" ").append(getString(R.string.generic_and)).append(" ") - .bold { - append(receipt.symbols.crypto).append(" ") - append(receipt.willSentFeeCoin).append(" ") - } - .append(mainLayout.context.getString(R.string.send_total_will_be_sent)) - totalLayout.tvWillBeSentValue.update(willSent.toString()) + val willSent = getString( + R.string.send_total_subtitle_asset_format, + receipt.symbols.token ?: "", receipt.willSentToken, + receipt.symbols.crypto, receipt.willSentFeeCoin + ) + totalLayout.tvWillBeSentValue.update(willSent) } ReceiptLayoutType.TOKEN_CRYPTO -> { val receipt = state.tokenCrypto ?: return 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 5717bdf1ef..3bbbda0d1c 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 @@ -74,7 +74,7 @@ sealed class WalletAction : Action { data class CopyAddress(val context: Context) : WalletAction() { object Success : WalletAction(), NotificationAction { - override val messageResource = R.string.notification_address_copied + override val messageResource = R.string.wallet_notification_address_copied } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt index 4a8cb2ca4f..65c7679e62 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt @@ -68,7 +68,7 @@ class BalanceWidget( R.id.tv_status_verified } else { fragment.tv_status_error.text = - fragment.getText(R.string.wallet_transaction_in_progress) + fragment.getText(R.string.wallet_balance_tx_in_progress) R.id.group_error } showStatus(statusView) @@ -93,7 +93,7 @@ class BalanceWidget( fragment.tv_amount.text = "" fragment.tv_status_error_message.text = data.errorMessage fragment.tv_status_error.text = - fragment.getString(R.string.wallet_blockchain_is_unreachable) + fragment.getString(R.string.wallet_balance_blockchain_unreachable) showStatus(R.id.group_error) fragment.tv_status_error_message.show(!data.errorMessage.isNullOrBlank()) @@ -101,25 +101,25 @@ class BalanceWidget( BalanceStatus.EmptyCard -> { fragment.l_balance.hide() fragment.l_balance_error.show() - fragment.tv_error_title.text = fragment.getText(R.string.wallet_empty_card) - fragment.tv_error_descriptions.text = fragment.getText(R.string.wallet_empty_card_description) + fragment.tv_error_title.text = fragment.getText(R.string.wallet_error_empty_card) + fragment.tv_error_descriptions.text = fragment.getText(R.string.wallet_error_empty_card_subtitle) } BalanceStatus.NoAccount -> { fragment.l_balance.hide() fragment.l_balance_error.show() - fragment.tv_error_title.text = fragment.getText(R.string.wallet_no_account) + fragment.tv_error_title.text = fragment.getText(R.string.wallet_error_no_account) fragment.tv_error_descriptions.text = fragment.getString( - R.string.wallet_no_account_description, + R.string.wallet_error_no_account_subtitle_format, data.amountToCreateAccount, data.currencySymbol ) } BalanceStatus.UnknownBlockchain -> { fragment.l_balance.hide() fragment.l_balance_error.show() - fragment.tv_error_title.text = fragment.getText(R.string.wallet_unknown_blockchain_title) + fragment.tv_error_title.text = fragment.getText(R.string.wallet_error_unsupported_blockchain) fragment.tv_error_descriptions.text = - fragment.getString(R.string.wallet_unknown_blockchain) + fragment.getString(R.string.wallet_error_unsupported_blockchain_subtitle) } } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/PendingTransactionsAdapter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/PendingTransactionsAdapter.kt index 7602ecd237..66b0a11d9c 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/PendingTransactionsAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/PendingTransactionsAdapter.kt @@ -41,12 +41,12 @@ class PendingTransactionsAdapter fun bind(transaction: PendingTransaction) { val transactionDescriptionRes = when (transaction.type) { - PendingTransactionType.Incoming -> R.string.wallet_pending_transaction_incoming - PendingTransactionType.Outcoming -> R.string.wallet_pending_transaction_outcoming + PendingTransactionType.Incoming -> R.string.wallet_pending_tx_receiving + PendingTransactionType.Outcoming -> R.string.wallet_pending_tx_sending } val transactionAddressRes = when (transaction.type) { - PendingTransactionType.Incoming -> R.string.wallet_pending_transaction_incoming_address - PendingTransactionType.Outcoming -> R.string.wallet_pending_transaction_outcoming_address + PendingTransactionType.Incoming -> R.string.wallet_pending_tx_receiving_address_format + PendingTransactionType.Outcoming -> R.string.wallet_pending_tx_sending_address_format } val image = when (transaction.type) { PendingTransactionType.Incoming -> R.drawable.ic_arrow_left diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index c337a895b8..38ac6742a6 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -95,7 +95,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber dismiss() }.setOnDismissListener { @@ -21,8 +21,8 @@ class WarningDialog(context: Context) : AlertDialog(context) { fun show(warningType: WarningType) { val messageRes = when (warningType) { - WarningType.CardSignedHashesBefore -> R.string.warning_card_signed_transactions - WarningType.DevCard -> R.string.wallet_warning_dev_card + WarningType.CardSignedHashesBefore -> R.string.alert_card_signed_transactions + WarningType.DevCard -> R.string.alert_developer_card } dialog.setMessage(dialog.context.getString(messageRes)) dialog.show() diff --git a/app/src/main/res/layout/dialog_create_payid.xml b/app/src/main/res/layout/dialog_create_payid.xml index eee3f1ef91..3c4d10891d 100644 --- a/app/src/main/res/layout/dialog_create_payid.xml +++ b/app/src/main/res/layout/dialog_create_payid.xml @@ -19,7 +19,7 @@ android:ellipsize="middle" android:fontFamily="sans-serif-medium" android:paddingEnd="24dp" - android:text="@string/wallet_dialog_pay_id_button" + android:text="@string/wallet_create_payid" android:textColor="@color/textGray" android:textSize="17sp" app:layout_constraintStart_toStartOf="parent" @@ -31,7 +31,7 @@ android:layout_height="50dp" android:layout_marginStart="24dp" android:layout_marginTop="24dp" - android:hint="@string/wallet_dialog_pay_id_hint" + android:hint="@string/wallet_create_payid_hint" android:inputType="textNoSuggestions|textVisiblePassword" android:paddingStart="4dp" android:paddingEnd="4dp" @@ -46,7 +46,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="24dp" android:paddingBottom="1dp" - android:text="@string/wallet_pay_id_address" + android:text="@string/wallet_create_payid_domain" android:textColor="@color/darkGray4" app:layout_constraintBottom_toBottomOf="@+id/et_payid" app:layout_constraintEnd_toEndOf="parent" @@ -60,7 +60,7 @@ android:layout_marginStart="24dp" android:layout_marginTop="24dp" android:layout_marginEnd="24dp" - android:text="@string/wallet_dialog_pay_id_description" + android:text="@string/wallet_create_payid_info" android:textColor="@color/darkGray1" android:textSize="13sp" app:layout_constraintEnd_toEndOf="parent" @@ -80,7 +80,7 @@ android:insetBottom="0dp" android:paddingTop="8dp" android:paddingBottom="8dp" - android:text="@string/wallet_dialog_pay_id_button" + android:text="@string/wallet_create_payid" android:textColor="@color/blue" android:textSize="14sp" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout/dialog_qrcode.xml b/app/src/main/res/layout/dialog_qrcode.xml index af37e85986..79b7c187e4 100644 --- a/app/src/main/res/layout/dialog_qrcode.xml +++ b/app/src/main/res/layout/dialog_qrcode.xml @@ -49,7 +49,7 @@ android:insetBottom="0dp" android:paddingTop="8dp" android:paddingBottom="8dp" - android:text="@string/generic_done" + android:text="@string/common_done" android:textColor="@color/blue" android:textSize="14sp" /> diff --git a/app/src/main/res/layout/fragment_details.xml b/app/src/main/res/layout/fragment_details.xml index 7dac8c7e31..22386e2aaf 100644 --- a/app/src/main/res/layout/fragment_details.xml +++ b/app/src/main/res/layout/fragment_details.xml @@ -22,7 +22,7 @@ android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:navigationIcon="@drawable/ic_baseline_arrow_back_24" - app:title="@string/details_toolbar_title" /> + app:title="@string/details_title" /> @@ -48,7 +48,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingBottom="14dp" - android:text="@string/details_card_id" + android:text="@string/details_row_title_cid" android:textColor="@color/darkGray6" android:textSize="16sp" @@ -71,7 +71,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingBottom="14dp" - android:text="@string/details_issuer" + android:text="@string/details_row_title_issuer" android:textColor="@color/darkGray6" android:textSize="16sp" app:layout_constraintStart_toStartOf="parent" @@ -92,7 +92,7 @@ android:id="@+id/tv_signed_hashes_title" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/details_signed_hashes" + android:text="@string/details_row_title_signed_hashes" android:textColor="@color/darkGray6" android:textSize="16sp" app:layout_constraintStart_toStartOf="parent" @@ -114,7 +114,7 @@ android:layout_height="wrap_content" android:layout_marginTop="40dp" android:paddingBottom="4dp" - android:text="@string/details_settings" + android:text="@string/details_section_title_settings" android:textAllCaps="true" android:textColor="@color/colorSecondary" android:textSize="13sp" @@ -146,7 +146,7 @@ android:layout_height="wrap_content" android:paddingTop="10dp" android:paddingBottom="10dp" - android:text="@string/details_currency" + android:text="@string/details_row_title_currency" android:textColor="@color/darkGray6" android:textSize="16sp" app:layout_constraintStart_toStartOf="parent" @@ -164,7 +164,7 @@ android:layout_height="wrap_content" android:layout_marginTop="22dp" android:paddingBottom="4dp" - android:text="@string/details_card" + android:text="@string/details_section_title_card" android:textAllCaps="true" android:textColor="@color/colorSecondary" android:textSize="13sp" @@ -197,7 +197,7 @@ android:layout_height="wrap_content" android:paddingTop="10dp" android:paddingBottom="7dp" - android:text="@string/details_manage_security" + android:text="@string/details_row_title_manage_security" android:textColor="@color/darkGray6" android:textSize="16sp" app:layout_constraintStart_toStartOf="parent" @@ -216,7 +216,7 @@ app:drawableEndCompat="@drawable/ic_angle_bracket_right" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tv_security_title" - android:text="@string/details_erase_wallet" /> + android:text="@string/details_row_title_erase_wallet" /> diff --git a/app/src/main/res/layout/fragment_details_security.xml b/app/src/main/res/layout/fragment_details_security.xml index 17aa16be23..ea340717a4 100644 --- a/app/src/main/res/layout/fragment_details_security.xml +++ b/app/src/main/res/layout/fragment_details_security.xml @@ -20,7 +20,7 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" - app:title="@string/details_manage_security" + app:title="@string/details_row_title_manage_security" app:navigationIcon="@drawable/ic_baseline_arrow_back_24" /> diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 55b20af069..b986dc7b5c 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -54,7 +54,7 @@ android:layout_marginTop="100dp" android:paddingStart="30dp" android:paddingEnd="30dp" - android:text="@string/home_do_you_have_card" + android:text="@string/home_welcome" android:textColor="@color/darkGray6" android:textSize="29sp" app:layout_constraintTop_toBottomOf="@id/iv_home_card" /> diff --git a/app/src/main/res/layout/fragment_wallet.xml b/app/src/main/res/layout/fragment_wallet.xml index 367050f06d..99fcce3719 100644 --- a/app/src/main/res/layout/fragment_wallet.xml +++ b/app/src/main/res/layout/fragment_wallet.xml @@ -22,7 +22,7 @@ android:layout_height="?attr/actionBarSize" app:menu="@menu/wallet" app:navigationIcon="@drawable/ic_baseline_arrow_back_24" - app:title="@string/wallet_toolbar_title" /> + app:title="@string/wallet_title" /> diff --git a/app/src/main/res/layout/layout_address.xml b/app/src/main/res/layout/layout_address.xml index 960f7cd9f0..ab3ff4955a 100644 --- a/app/src/main/res/layout/layout_address.xml +++ b/app/src/main/res/layout/layout_address.xml @@ -49,7 +49,7 @@ android:paddingTop="4dp" android:paddingEnd="16dp" android:paddingBottom="25dp" - android:text="@string/wallet_explore_address" + android:text="@string/wallet_address_button_explore" android:textColor="@color/darkGray6" android:textSize="14sp" android:textStyle="bold" @@ -130,7 +130,7 @@ android:layout_height="wrap_content" android:drawablePadding="9dp" android:padding="16dp" - android:text="@string/wallet_create_payid" + android:text="@string/wallet_address_button_create_payid" android:textColor="@color/darkGray6" android:textSize="14sp" android:textStyle="bold" diff --git a/app/src/main/res/layout/layout_balance.xml b/app/src/main/res/layout/layout_balance.xml index 1931632965..de3660b802 100644 --- a/app/src/main/res/layout/layout_balance.xml +++ b/app/src/main/res/layout/layout_balance.xml @@ -29,7 +29,7 @@ android:paddingStart="16dp" android:paddingTop="4dp" android:paddingEnd="16dp" - android:text="@string/wallet_verified_balance" + android:text="@string/wallet_balance_verified" android:textColor="@color/accent" android:textSize="14sp" android:visibility="gone" @@ -45,7 +45,7 @@ android:paddingStart="16dp" android:paddingTop="4dp" android:paddingEnd="16dp" - android:text="@string/wallet_blockchain_is_unreachable" + android:text="@string/wallet_balance_blockchain_unreachable" android:textColor="@color/warning" android:textSize="14sp" android:visibility="gone" @@ -81,7 +81,7 @@ android:paddingStart="16dp" android:paddingTop="4dp" android:paddingEnd="16dp" - android:text="@string/wallet_balance_is_loading" + android:text="@string/wallet_balance_loading" android:textColor="@color/darkGray6" android:textSize="13sp" android:visibility="gone" diff --git a/app/src/main/res/layout/layout_balance_error.xml b/app/src/main/res/layout/layout_balance_error.xml index 3e25481d00..1341d89e1f 100644 --- a/app/src/main/res/layout/layout_balance_error.xml +++ b/app/src/main/res/layout/layout_balance_error.xml @@ -20,7 +20,7 @@ android:id="@+id/tv_error_title" app:layout_constraintStart_toEndOf="@id/iv_balance_error" app:layout_constraintTop_toTopOf="parent" - tools:text="@string/wallet_account_not_created" + tools:text="@string/wallet_error_no_account" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingStart="16dp" diff --git a/app/src/main/res/layout/layout_receipt_total.xml b/app/src/main/res/layout/layout_receipt_total.xml index c24c9bff3c..b130817a2c 100644 --- a/app/src/main/res/layout/layout_receipt_total.xml +++ b/app/src/main/res/layout/layout_receipt_total.xml @@ -24,7 +24,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="start" - android:text="@string/send_total" + android:text="@string/send_total_label" android:textSize="20sp" android:textStyle="bold" /> @@ -45,8 +45,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end" + android:gravity="end" android:layout_marginTop="4dp" - android:text="@string/send_total_will_be_sent" + tools:text="@string/send_total_subtitle_format" android:textColor="@color/darkGray1" /> @@ -62,7 +63,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="start" - android:text="@string/send_total" + android:text="@string/send_total_label" android:textColor="@color/darkGray1" android:textSize="14sp" android:textStyle="bold" /> diff --git a/app/src/main/res/layout/layout_send_address_payid.xml b/app/src/main/res/layout/layout_send_address_payid.xml index 09a4677052..a1423a4ed9 100644 --- a/app/src/main/res/layout/layout_send_address_payid.xml +++ b/app/src/main/res/layout/layout_send_address_payid.xml @@ -11,7 +11,7 @@ android:id="@+id/tilAddressOrPayId" android:layout_width="0dp" android:layout_height="wrap_content" - android:hint="@string/send_address_or_payid" + android:hint="@string/send_destination_hint" app:boxBackgroundColor="@color/backgroundLightGray" app:errorIconDrawable="@null" app:layout_constraintEnd_toEndOf="parent" diff --git a/app/src/main/res/layout/layout_send_fee.xml b/app/src/main/res/layout/layout_send_fee.xml index ebe9b5c629..7170e42d59 100644 --- a/app/src/main/res/layout/layout_send_fee.xml +++ b/app/src/main/res/layout/layout_send_fee.xml @@ -11,7 +11,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" - android:text="@string/send_fee" + android:text="@string/send_network_fee_title" android:textSize="14sp" app:layout_constraintBottom_toBottomOf="@+id/flExpandCollapse" app:layout_constraintStart_toStartOf="parent" @@ -51,21 +51,21 @@ style="@style/ChipNetworkFee" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/send_fee_low" /> + android:text="@string/send_fee_picker_low" /> + android:text="@string/send_fee_picker_normal" /> + android:text="@string/send_fee_picker_priority" /> @@ -75,7 +75,7 @@ android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginEnd="8dp" - android:text="@string/send_fee_include" + android:text="@string/send_fee_include_description" android:textSize="13sp" /> diff --git a/app/src/main/res/layout/layout_send_receipt.xml b/app/src/main/res/layout/layout_send_receipt.xml index ed8665c225..7309706654 100644 --- a/app/src/main/res/layout/layout_send_receipt.xml +++ b/app/src/main/res/layout/layout_send_receipt.xml @@ -12,7 +12,7 @@ android:id="@+id/tvReceiptAmount" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/send_total_amount" + android:text="@string/send_amount_label" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -33,7 +33,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" - android:text="@string/send_total_fee" + android:text="@string/send_fee_label" android:textColor="@color/darkGray1" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/layout/layout_token.xml b/app/src/main/res/layout/layout_token.xml index a1343def65..8e03d11ca1 100644 --- a/app/src/main/res/layout/layout_token.xml +++ b/app/src/main/res/layout/layout_token.xml @@ -10,7 +10,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="2dp" - android:text="@string/wallet_tokens" + android:text="@string/wallet_balance_tokens_title" android:textColor="@color/darkGray1" android:textSize="14sp" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/layout/view_snackbar_max_amount_content.xml b/app/src/main/res/layout/view_snackbar_max_amount_content.xml index 9b905b7aab..de8cdfa27e 100644 --- a/app/src/main/res/layout/view_snackbar_max_amount_content.xml +++ b/app/src/main/res/layout/view_snackbar_max_amount_content.xml @@ -11,7 +11,7 @@ android:id="@+id/tv_message" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/send_set_maximum_amount" + android:text="@string/send_max_amount_label" android:textColor="#F4F5F6" android:textSize="16sp" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/menu/wallet.xml b/app/src/main/res/menu/wallet.xml index 42b5aa07c6..c4947ea75b 100644 --- a/app/src/main/res/menu/wallet.xml +++ b/app/src/main/res/menu/wallet.xml @@ -3,7 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f9600d0a21..df165bb8c6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,129 +2,148 @@ Tangem Tap - Done - Cancel - Retry - and - Warning + No + Save changes + Warning + Retry + Done + Cancel + + Camera access denied + You have not given access to your camera, please adjust your privacy settings + Settings - Tap to scan - Tap the card - Tap to sign - Tap to purge wallet - Tap to create wallet - Tap to change passcode - Tap to change access code - - Address was successfully copied - No internet connection - @string/generic_retry - - Welcome to Tangem.\nDo you have one of our cards? + Welcome to Tangem.\nDo you have one of our cards? Welcome back to Tangem Tap. \nScan your card to start. Yes. Scan it! - Scan card Shop - No + Get ready to tap your \ncard to the back of the \nphone. + Tap in + Scan card + @string/common_no - Tangem Tap + @string/app_name Scan Send Create Wallet - Explore address + Choice wallet option + + Explore address + Create PayID + + Verified Balance + Blockchain is unreachable + Balance is loading… + Transaction is in progress + Tokens + Token + + This card is not supported + Your Tangem card was made to work with a different application. Please see the name and instructions on your card, and install the correct app. + Empty Card + Create wallet to start using Tangem card + Account is not created + Load %1s+ %2s to create account + + Receiving\u0020 + Sending\u0020 + from %s + to %s + Create PayID - Verified Balance - Blockchain is unreachable - Transaction is in progress - Your Tangem card was made to work with a different application. Please see the name and instructions on your card, and install the correct app. - Uh oh! - Balance is loading… - Account is not created - Empty Card - Create wallet to start using Tangem card - Account is not created - Load %1s+ %2s to create account - Tokens - Receiving\u0020 - Sending\u0020 - from %s - to %s - - Create PayID + Card: %s Enter desired PayID first - PayID name - $payid.tangem.com - Your PayID is information unique to you, like your phone number, email or ABN. - %s wallet + PayID name + Create + $payid.tangem.com + Your PayID is information unique to you, like your phone number, email or ABN. + This PayID already exists. Try a different one. + Error response while creating PayID + PayID created successfully and copied to clipboard - The card you scanned is a development card. Don\'t accept it as a payment. - Warning: This card has been already topped up and signed transactions in the past. + %s wallet + + Address was successfully copied + No internet connection + @string/common_retry + + The card you scanned is a development card. Don\'t accept it as a payment. + Warning: This card has been already topped up and signed transactions in the past. Consider immediate withdrawal of all funds if you have received this card from an untrusted source. + This card it is not designed to work with Tangem Tap + You may experience NFC problems with some iPhone 7/7+ during the extraction - This PayID already exists. Try a different one. - Error response while creating PayID. - - This card it is not designed to work with Tangem Tap - - Unknown error - PayID verification failed - PayID unsupported by blockchain - PayID not registered - PayID request failed - Address is invalid or unsupported by blockchain - Address is the same as wallet address - Network fee request is failed - Insufficient balance - Blockchain internal error - Amount Exceeds Balance - Fee Exceeds Balance - Total Exceeds Balance - Invalid Amount - Invalid Fee - Minimum amount is %s - Change is too small - Target account is not created. Send more than %1$s %2$s to create + Unknown error + PayID verification failed + PayID unsupported by blockchain + PayID not registered + PayID request failed + Address is invalid or unsupported by blockchain + Address is the same as wallet address + Network fee request is failed + Insufficient balance + Blockchain internal error + Amount Exceeds Balance + Fee Exceeds Balance + Total Exceeds Balance + Invalid Amount + Invalid Fee + Minimum amount is %s + Change is too small + Target account is not created. Send more than %1$s %2$s to create Send - Address or PayID - Network fee - Include fee - Low - Normal - Priority - Send - Total - Amount - Fee - will be sent - Balance: %1s %2s - Maximum amount - Transaction was signed and sent to the blockchain + Address or PayID + Network fee + Include fee + Low + Normal + Priority + @string/send_title + Total + Amount + Fee + %1s %2s will be sent + ≈ %1s (inc. fee: %2s) + %1s %2s and %3s %4s will be sent + Balance: %1s %2s + Maximum amount + Transaction was signed and sent to the blockchain - Details + Details Card settings prohibits from erasing wallet You balance on this wallet is not zero, or you have unconfirmed transactions This is the currently active option - Card ID - Issuer - Signed - Settings - App currency - Card - Validate card - Manage security - Erase wallet - Save changes + Card ID + Issuer + Signed + %s hashes + App currency + Settings + Card + Validate card + Manage security + Erase wallet Continue + Long Tap Passcode Access Code This mechanism protects against proximity attack on a card. It will enforce a delay between reception and execution of a command. After the first signed transaction this phone will be linked with the card and transactions will be signed immediately. Before execution of any command entailing a change of the card state you will have to enter the passcode. You will have to submit the correct access code before scanning the card. - This action is irreversible. If, after deleting the wallet, someone sends funds to it, then you will not be able to withdraw them. - If you forget the code, you will lose the ability to use the card. There is no way to recover or change your code if you lose it. - + This action is irreversible. If, after deleting the wallet, someone sends funds to it, then you will not be able to withdraw them. + If you forget the code, you will lose the ability to use the card. There is no way to recover or change your code if you lose it. + + Tap to scan + Tap the card + Tap to sign + Tap to erase wallet + Tap to create wallet + Tap to change the passcode + Tap to change the access code + + Invalid PayID \ No newline at end of file From 11f7775787428f2379f09681de49a399a18f0b73 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 12 Oct 2020 19:00:38 +0300 Subject: [PATCH 03/11] Updated on 2026-08-14 --- .../tap/common/extensions/Navigation.kt | 2 + .../com/tangem/tap/common/redux/AppReducer.kt | 4 +- .../com/tangem/tap/common/redux/AppState.kt | 8 +- .../tap/common/redux/global/GlobalAction.kt | 2 +- .../redux/navigation/NavigationState.kt | 2 +- .../features/details/redux/DetailsAction.kt | 2 + .../details/redux/DetailsMiddleware.kt | 5 ++ .../features/details/redux/DetailsReducer.kt | 1 + .../features/details/ui/DetailsFragment.kt | 2 + .../disclaimer/redux/DisclaimerAction.kt | 8 ++ .../disclaimer/redux/DisclaimerMiddleware.kt | 24 ++++++ .../disclaimer/redux/DisclaimerReducer.kt | 21 +++++ .../disclaimer/redux/DisclaimerState.kt | 7 ++ .../disclaimer/ui/DisclaimerFragment.kt | 63 ++++++++++++++ .../tangem/tap/features/home/HomeFragment.kt | 2 - .../tap/features/home/redux/HomeMiddleware.kt | 11 ++- .../tap/features/wallet/ui/WalletFragment.kt | 4 +- .../tap/persistence/PreferencesStorage.kt | 10 +++ app/src/main/res/layout/fragment_details.xml | 25 ++++-- .../main/res/layout/fragment_disclaimer.xml | 82 +++++++++++++++++++ app/src/main/res/values/strings.xml | 52 ++++++++++++ 21 files changed, 319 insertions(+), 18 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerAction.kt create mode 100644 app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerMiddleware.kt create mode 100644 app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerReducer.kt create mode 100644 app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt create mode 100644 app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt create mode 100644 app/src/main/res/layout/fragment_disclaimer.xml diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt index 03246d0461..bb69887342 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt @@ -7,6 +7,7 @@ import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.features.details.ui.DetailsConfirmFragment import com.tangem.tap.features.details.ui.DetailsFragment import com.tangem.tap.features.details.ui.DetailsSecurityFragment +import com.tangem.tap.features.disclaimer.ui.DisclaimerFragment import com.tangem.tap.features.home.HomeFragment import com.tangem.tap.features.send.ui.SendFragment import com.tangem.tap.features.wallet.ui.WalletFragment @@ -42,5 +43,6 @@ private fun fragmentFactory(screen: AppScreen): Fragment { AppScreen.Details -> DetailsFragment() AppScreen.DetailsConfirm -> DetailsConfirmFragment() AppScreen.DetailsSecurity -> DetailsSecurityFragment() + AppScreen.Disclaimer -> DisclaimerFragment() } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt index 3420ef1255..5e80adec68 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt @@ -3,6 +3,7 @@ package com.tangem.tap.common.redux import com.tangem.tap.common.redux.global.globalReducer import com.tangem.tap.common.redux.navigation.NavigationReducer import com.tangem.tap.features.details.redux.DetailsReducer +import com.tangem.tap.features.disclaimer.redux.DisclaimerReducer import com.tangem.tap.features.home.redux.HomeReducer import com.tangem.tap.features.send.redux.reducers.SendScreenReducer import com.tangem.tap.features.wallet.redux.WalletReducer @@ -18,7 +19,8 @@ fun appReducer(action: Action, state: AppState?): AppState { homeState = HomeReducer.reduce(action, state), walletState = WalletReducer.reduce(action, state), sendState = SendScreenReducer.reduce(action, state.sendState), - detailsState = DetailsReducer.reduce(action, state) + detailsState = DetailsReducer.reduce(action, state), + disclaimerState = DisclaimerReducer.reduce(action, state) ) } diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt index 8f5f980c69..d300bb65b7 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt @@ -6,6 +6,8 @@ import com.tangem.tap.common.redux.navigation.NavigationState import com.tangem.tap.common.redux.navigation.navigationMiddleware import com.tangem.tap.features.details.redux.DetailsMiddleware import com.tangem.tap.features.details.redux.DetailsState +import com.tangem.tap.features.disclaimer.redux.DisclaimerMiddleware +import com.tangem.tap.features.disclaimer.redux.DisclaimerState import com.tangem.tap.features.home.redux.HomeState import com.tangem.tap.features.home.redux.homeMiddleware import com.tangem.tap.features.send.redux.middlewares.sendMiddleware @@ -21,7 +23,8 @@ data class AppState( val homeState: HomeState = HomeState(), val walletState: WalletState = WalletState(), val sendState: SendState = SendState(), - val detailsState: DetailsState = DetailsState() + val detailsState: DetailsState = DetailsState(), + val disclaimerState: DisclaimerState = DisclaimerState() ) : StateType { companion object { @@ -29,7 +32,8 @@ data class AppState( return listOf( logMiddleware, navigationMiddleware, notificationsMiddleware, globalMiddleware, homeMiddleware, walletMiddleware, sendMiddleware, - DetailsMiddleware().detailsMiddleware + DetailsMiddleware().detailsMiddleware, + DisclaimerMiddleware().disclaimerMiddleware ) } } diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt index de18ac1a98..c0e641bffe 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt @@ -14,5 +14,5 @@ sealed class GlobalAction : Action { object RestoreAppCurrency : GlobalAction() { data class Success(val appCurrency: FiatCurrencyName) : GlobalAction() } - data class UpdateWalletSignedHashes(val walletSignedHashes: Int) : GlobalAction() + data class UpdateWalletSignedHashes(val walletSignedHashes: Int?) : GlobalAction() } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationState.kt b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationState.kt index 3a062653d8..5edfad540b 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationState.kt @@ -9,4 +9,4 @@ data class NavigationState( val activity: WeakReference? = null ) : StateType -enum class AppScreen { Home, Wallet, Send, Details, DetailsConfirm, DetailsSecurity } \ No newline at end of file +enum class AppScreen { Home, Wallet, Send, Details, DetailsConfirm, DetailsSecurity, Disclaimer } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt index 1b3d174176..a38ca15f92 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt @@ -17,6 +17,8 @@ sealed class DetailsAction : Action { val fiatCurrencies: List? = null, ): DetailsAction() + object ShowDisclaimer : DetailsAction() + sealed class EraseWallet : DetailsAction() { object Check : EraseWallet() diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt index b70f14c6d5..e3a4f73b18 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt @@ -6,6 +6,7 @@ import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction +import com.tangem.tap.features.disclaimer.redux.DisclaimerAction import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.network.coinmarketcap.CoinMarketCapService import com.tangem.tap.preferencesStorage @@ -29,6 +30,10 @@ class DetailsMiddleware { is DetailsAction.EraseWallet -> eraseWalletMiddleware.handle(action) is DetailsAction.AppCurrencyAction -> appCurrencyMiddleware.handle(action) is DetailsAction.ManageSecurity -> manageSecurityMiddleware.handle(action) + is DetailsAction.ShowDisclaimer -> { + store.dispatch(DisclaimerAction.ShowAcceptedDisclaimer) + store.dispatch(NavigationAction.NavigateTo(AppScreen.Disclaimer)) + } } next(action) } diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt index de11a23644..bab4e4649f 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt @@ -30,6 +30,7 @@ private fun internalReduce(action: Action, state: AppState): DetailsState { is DetailsAction.ManageSecurity -> { handleSecurityAction(action, detailsState) } + else -> detailsState } } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt index f4bdf9519a..df604f266d 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt @@ -64,6 +64,8 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber = { dispatch, state -> + { next -> + { action -> + when (action) { + is DisclaimerAction.AcceptDisclaimer -> { + preferencesStorage.saveDisclaimerAccepted() + store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet)) + } + } + next(action) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerReducer.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerReducer.kt new file mode 100644 index 0000000000..40408ea343 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerReducer.kt @@ -0,0 +1,21 @@ +package com.tangem.tap.features.disclaimer.redux + +import com.tangem.tap.common.redux.AppState +import org.rekotlin.Action + +class DisclaimerReducer { + companion object { + fun reduce(action: Action, state: AppState): DisclaimerState = internalReduce(action, state) + } +} + +private fun internalReduce(action: Action, state: AppState): DisclaimerState { + if (action !is DisclaimerAction) return state.disclaimerState + + val disclaimerState = state.disclaimerState + return when (action) { + is DisclaimerAction.AcceptDisclaimer, DisclaimerAction.ShowAcceptedDisclaimer -> { + disclaimerState.copy(accepted = true) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt new file mode 100644 index 0000000000..b92252ae01 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerState.kt @@ -0,0 +1,7 @@ +package com.tangem.tap.features.disclaimer.redux + +import org.rekotlin.StateType + +data class DisclaimerState( + val accepted: Boolean = false +) : StateType diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt new file mode 100644 index 0000000000..fb7ebe023d --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt @@ -0,0 +1,63 @@ +package com.tangem.tap.features.disclaimer.ui + +import android.os.Bundle +import android.view.View +import androidx.activity.OnBackPressedCallback +import androidx.fragment.app.Fragment +import androidx.transition.TransitionInflater +import com.tangem.tap.common.extensions.hide +import com.tangem.tap.common.redux.navigation.NavigationAction +import com.tangem.tap.features.disclaimer.redux.DisclaimerAction +import com.tangem.tap.features.disclaimer.redux.DisclaimerState +import com.tangem.tap.store +import com.tangem.wallet.R +import kotlinx.android.synthetic.main.fragment_disclaimer.* +import org.rekotlin.StoreSubscriber + +class DisclaimerFragment : Fragment(R.layout.fragment_disclaimer), + StoreSubscriber { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + store.dispatch(NavigationAction.PopBackTo()) + } + }) + val inflater = TransitionInflater.from(requireContext()) + enterTransition = inflater.inflateTransition(R.transition.slide_right) + exitTransition = inflater.inflateTransition(R.transition.fade) + } + + override fun onStart() { + super.onStart() + store.subscribe(this) { state -> + state.skipRepeats { oldState, newState -> + oldState.disclaimerState == newState.disclaimerState + }.select { it.disclaimerState } + } + } + + override fun onStop() { + super.onStop() + store.unsubscribe(this) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + toolbar.setNavigationOnClickListener { + store.dispatch(NavigationAction.PopBackTo()) + } + setOnClickListeners() + } + + private fun setOnClickListeners() { + btn_accept.setOnClickListener { store.dispatch(DisclaimerAction.AcceptDisclaimer) } + } + + override fun newState(state: DisclaimerState) { + if (activity == null) return + + if (state.accepted) btn_accept.hide() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt index e2729db034..c12785fd92 100644 --- a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt @@ -54,6 +54,4 @@ class HomeFragment : Fragment(R.layout.fragment_home), StoreSubscriber = { dispatch, state -> is CompletionResult.Success -> { store.dispatch(GlobalAction.RestoreAppCurrency) store.state.globalState.tapWalletManager.onCardScanned(result.data) - navigateToWallet() + showDisclaimerOrNavigateToWallet() } } } @@ -51,6 +51,15 @@ val homeMiddleware: Middleware = { dispatch, state -> } } +private fun showDisclaimerOrNavigateToWallet() { + if (preferencesStorage.wasDisclaimerAccepted()) { + navigateToWallet() + } else { + store.dispatch(NavigationAction.NavigateTo(AppScreen.Disclaimer)) + } +} + + private fun navigateToWallet() { if (store.state.navigationState.backStack.isNotEmpty()) { val currentScreen = store.state.navigationState.backStack.last() diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index 38ac6742a6..d8d0e11931 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -45,7 +45,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber + + + app:layout_constraintTop_toBottomOf="@id/tv_disclaimer" /> - - - - - - + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index df165bb8c6..a9ed98a110 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,6 +8,7 @@ Retry Done Cancel + Accept Camera access denied You have not given access to your camera, please adjust your privacy settings @@ -146,4 +147,55 @@ Invalid PayID + Legal Disclaimer + \n + \n1. Tangem Tap application (Software) + \n + \nThe Software is intended for usage only with Tangem hardware wallets (Cards) via NFC interface. The Software DOES NOT: + \n + \na) Generate, store, transmit, or have access to private (secret) cryptographic keys to blockchain wallets holding digital assets, including crypto-currency. + \n + \nb) Generate, store, transmit, or have access to secret keys, passwords, passphrases, recovery phrases that can be used to restore or to copy private (secret) keys to blockchain wallets holding digital assets, including crypto-currency. + \n + \nc) Provide exchange, trading, investment services on behalf of Tangem AG. + \n + \n2. Risks related to the use of Software + \n + \nTangem will not be responsible for any losses, damages or claims arising from events falling within the scope of the following five categories: + \n + \na) Mistakes made by the user of any cryptocurrency-related software or service, e.g., forgotten passwords, payments sent to wrong addresses, and accidental deletion of blockchain wallets on Cards. + \n + \nb) Problems of Software and/or any blockchain- or cryptocurrency- related software or service, e.g., corrupted files, incorrectly constructed transactions, unsafe cryptographic libraries, malware. + \n + \nc) Technical failures in the hardware of the user, including Cards, of any cryptocurrency-related software or service, e.g., data loss due to a faulty or damaged storage device. + \n + \nd) Security problems experienced by the user of any cryptocurrency-related software or service, e.g., unauthorized access to users’ wallets and/or accounts. + \n + \ne) Actions or inactions of third parties and/or events experienced by third parties, e.g., bankruptcy of service providers, information security attacks on service providers, and fraud conducted by third parties. + \n + \n3. Trading and Investment risks + \n + \nThere is considerable exposure to risk in any crypto-currency or other digital asset exchange transaction. Any transaction involving currencies involves risks including, but not limited to, the potential for changing economic conditions that may substantially affect the price or liquidity of a currency. Investments in crypto-currency exchange speculation may also be susceptible to sharp rises and falls as the relevant market values fluctuate. It is for this reason that when speculating in such markets it is advisable to use only risk capital. + \n + \n4. Electronic Trading Risks + \n + \nBefore you engage in transactions using an electronic system, you should carefully review the rules and regulations of the exchanges offering the system and/or listing the instruments you intend to trade. Online trading has inherent risk due to system response and access times that may vary due to market conditions, system performance, and other factors. You should understand these and additional risks before trading. + \n + \n5. Compliance with tax obligations + \n + \nThe users of the Software are solely responsible to determinate what, if any, taxes apply to their crypto-currency transactions. The owners of, or contributors to, the Software are NOT responsible for determining the taxes that apply to crypto-currency transactions. + \n + \n6. No warranties + \n + \nThe Software is provided on an \“as is\” basis without any warranties of any kind regarding the Software and/or any content, data, materials and/or services provided on the Software. + \n + \n7. Limitation of liability + \n + \nUnless otherwise required by law, in no event shall the owners of, or contributors to, the Software be liable for any damages of any kind, including, but not limited to, loss of use, loss of profits, or loss of data arising out of or in any way connected with the use of the Software. In no way are the owners of, or contributors to, the Software responsible for the actions, decisions, or other behavior taken or not taken by you in reliance upon the Software. + \n + \n8. Last amendment + \n + \nThis disclaimer was amended for the last time on October 1st, 2020. + Terms of service> + \ No newline at end of file From 06fb99fd7dec8679b7735b72290ab216422baf7a Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 13 Oct 2020 13:37:01 +0300 Subject: [PATCH 04/11] Updated on 2026-08-14 --- .../common/text/DecimalDigitsInputFilter.kt | 30 +++++++++++++++---- .../features/send/redux/states/SendState.kt | 9 ++---- .../tap/features/send/ui/SendFragment.kt | 2 +- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/common/text/DecimalDigitsInputFilter.kt b/app/src/main/java/com/tangem/tap/common/text/DecimalDigitsInputFilter.kt index c105940b9d..689095c534 100644 --- a/app/src/main/java/com/tangem/tap/common/text/DecimalDigitsInputFilter.kt +++ b/app/src/main/java/com/tangem/tap/common/text/DecimalDigitsInputFilter.kt @@ -10,9 +10,9 @@ import java.util.regex.Pattern class DecimalDigitsInputFilter( digitsBeforeDecimal: Int, digitsAfterDecimal: Int, - decimalSeparator: String + private val decimalSeparator: String ) : InputFilter { - private val pattern: Pattern = Pattern.compile("(([1-9]{1}[0-9]{0,${digitsBeforeDecimal -1}})?||[0]{1})((\\$decimalSeparator[0-9]{0,$digitsAfterDecimal})?)||(\\$decimalSeparator)?") + private val pattern: Pattern = Pattern.compile("(([1-9]{1}[0-9]{0,${digitsBeforeDecimal - 1}})?||[0]{1})((\\$decimalSeparator[0-9]{0,$digitsAfterDecimal})?)||(\\$decimalSeparator)?") override fun filter(source: CharSequence, sourceStart: Int, sourceEnd: Int, destination: Spanned, destinationStart: Int, destinationEnd: Int): CharSequence? { val destString = destination.toString() @@ -24,7 +24,27 @@ class DecimalDigitsInputFilter( val resultSuffix = newDestination.substring(destinationStart, newDestination.length) val result = resultPrefix + source.toString() + resultSuffix - val hasMatches = pattern.matcher(result).matches() - return if (hasMatches) null else "" + return if (pattern.matcher(result).matches()) { + null + } else { + val replacedWithAppropriateDecimalSeparator = setDecimalSeparator(result, decimalSeparator) + if (pattern.matcher(replacedWithAppropriateDecimalSeparator).matches()) { + decimalSeparator + } else { + "" + } + } } -} \ No newline at end of file + + companion object { + fun setDecimalSeparator(value: String, decimalSeparator: String): String { + if (value.contains(decimalSeparator)) return value + + return if (decimalSeparator == ".") { + value.replace(",", decimalSeparator) + } else { + value.replace(".", decimalSeparator) + } + } + } +} diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt index 97bf169413..8dcb140ce5 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt @@ -6,6 +6,7 @@ import com.tangem.blockchain.common.WalletManager import com.tangem.common.extensions.isZero import com.tangem.tap.common.CurrencyConverter import com.tangem.tap.common.entities.TapCurrency +import com.tangem.tap.common.text.DecimalDigitsInputFilter import com.tangem.tap.domain.TapError import com.tangem.tap.store import org.rekotlin.StateType @@ -143,13 +144,7 @@ data class AmountState( } fun restoreDecimalSeparator(value: String): String { - if (value.contains(decimalSeparator)) return value - - return if (decimalSeparator == ".") { - value.replace(",", decimalSeparator) - } else { - value.replace(".", decimalSeparator) - } + return DecimalDigitsInputFilter.setDecimalSeparator(value, decimalSeparator) } } diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt index 6d3799ea4d..32268f2d88 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt @@ -144,7 +144,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { } } - etAmountToSend.keyListener = DigitsKeyListener.getInstance("0123456789$decimalSeparator") + etAmountToSend.keyListener = DigitsKeyListener.getInstance("0123456789,.") etAmountToSend.setOnFocusChangeListener { v, hasFocus -> snackbarControlledByChangingFocus = true if (hasFocus) { From 58f5f83f4ea9fdb250945d6b85d01d69f837d550 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 13 Oct 2020 11:12:25 +0000 Subject: [PATCH 05/11] Updated on 2026-08-14 --- app/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index df88037b21..1ef67412a4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -67,9 +67,9 @@ dependencies { implementation 'com.google.android.material:material:1.2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' - implementation 'com.tangem:blockchain:1.76.0' - implementation 'com.tangem:core:1.64.0' - implementation 'com.tangem:sdk:1.64.0' + implementation 'com.tangem:blockchain:1.81.0' + implementation 'com.tangem:core:1.67.0' + implementation 'com.tangem:sdk:1.67.0' //lifecycle implementation "androidx.lifecycle:lifecycle-runtime:2.2.0" From 0a5a203b7e9190056ec5be00ada8f937d81a97cc Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 13 Oct 2020 14:32:38 +0300 Subject: [PATCH 06/11] Updated on 2026-08-14 --- .../com/tangem/tap/features/wallet/ui/dialogs/WarningDialog.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/WarningDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/WarningDialog.kt index 55eea608b3..6f70a4f60d 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/WarningDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/WarningDialog.kt @@ -11,7 +11,7 @@ class WarningDialog(context: Context) : AlertDialog(context) { private val dialog: AlertDialog = Builder(context) .setTitle(context.getString(R.string.common_warning)) - .setPositiveButton(context.getString(R.string.general_ok)) { _, _ -> + .setPositiveButton(context.getString(R.string.common_ok)) { _, _ -> dismiss() }.setOnDismissListener { store.dispatch(WalletAction.SaveCardId) From e591255af63aae758e1e3481a4df490e00a735e1 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 14 Oct 2020 14:55:14 +0300 Subject: [PATCH 07/11] Updated on 2026-08-14 --- app/build.gradle | 2 +- .../com/tangem/tap/features/wallet/redux/WalletMiddleware.kt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 1ef67412a4..d3603f973a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -67,7 +67,7 @@ dependencies { implementation 'com.google.android.material:material:1.2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' - implementation 'com.tangem:blockchain:1.81.0' + implementation 'com.tangem:blockchain:1.82.0' implementation 'com.tangem:core:1.67.0' implementation 'com.tangem:sdk:1.67.0' diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt index 18d024a379..125d22f468 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt @@ -233,6 +233,8 @@ private fun checkHashesCountOnline() { is SimpleResult.Failure -> if (result.error is BlockchainSdkError.SignatureCountNotMatched) { store.dispatch(WalletAction.ShowWarning(WarningType.CardSignedHashesBefore)) + } else if (card.walletSignedHashes ?: 0 > 0) { + store.dispatch(WalletAction.ShowWarning(WarningType.CardSignedHashesBefore)) } } } From 3c078b85541f664068fa5883a6a839c23ef98efe Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 14 Oct 2020 14:59:44 +0300 Subject: [PATCH 08/11] Updated on 2026-08-14 --- app/src/main/res/values-de/strings.xml | 56 ++++++++++++++++++++++++++ app/src/main/res/values-fr/strings.xml | 55 +++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 app/src/main/res/values-de/strings.xml create mode 100644 app/src/main/res/values-fr/strings.xml diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml new file mode 100644 index 0000000000..58f18eeb33 --- /dev/null +++ b/app/src/main/res/values-de/strings.xml @@ -0,0 +1,56 @@ + + + + +RECHTLICHER HAFTUNGSAUSSCHLUSS +\n\n1.Tangem Tap App (Software) +  +\n\nDie Software ist nur für die Verwendung mit Tangem hardware Wallets (Karten) über NFC-Schnittstelle geeignet. Die Software: +  +\n\na. generieret, speichert, überträgt KEINE privaten (geheimen) kryptografischen Schlüssel für Blockchain- Wallets mit digitalen Assets, einschließlich Kryptowährung, und hat KEINEN Zugriff darauf. +\n\nb. generieret, speichert, überträgt KEINE geheimen Schlüssel, Passwörter, Passphrasen, Wiederherstellungssätze, die verwendet werden können, um private (geheime) Schlüssel in Blockchain- Wallets, die digitale Assets enthalten, wiederherzustellen oder zu kopieren, einschließlich Kryptowährung, und hat KEINEN Zugriff darauf. +\n\nc. erbringt KEINE Wechsel-, Handels- und Investitionsdienstleistungen im Auftrag der Tangem AG. +  +  +\n\n2. Risiken im Zusammenhang mit der Verwendung von Software +  +\n\nTangem haftet nicht für Verluste, Schäden oder Ansprüche aus den Ereignissen, die in den Geltungsbereich von folgenden fünf Kategorien fallen: +  +\n\na. Fehler, die der Benutzer einer kryptowährungsbezogenen Software oder eines kryptowährungsbezogenen Services macht, z.B. vergessene Passwörter, an falsche Adressen gesendete Zahlungen und zufälliges Löschen von Blockchain-Wallets auf Karten. +\n\nb. Probleme mit Software und/oder blockchain- oder kryptowährungsbezogener Software oder Services, z.B. beschädigte Dateien, falsch konstruierte Transaktionen, unsichere kryptografische Bibliotheken, Schadsoftware. +\n\nc. Technische Ausfälle in der Hardware des Benutzers, einschließlich Karten, jeglicher kryptowährungsbezogener Software oder Services, z.B. Datenverlust infolge eines fehlerhaften oder beschädigten Speichers. +\n\nd. Sicherheitsprobleme, die der Benutzer einer kryptowährungsbezogenen Software oder eines kryptowährungsbezogenen Services hat, z.B. unbefugter Zugriff auf Benutzer-Wallets und/oder -Konten. +\n\ne. Handlungen oder Untätigkeit Dritter und/oder Vorkommnisse bei den Dritten, z.B. Insolvenz von Dienstleistungserbringern, Informationssicherheitsattacken bei den Dienstleistungserbringern und Betrug durch Dritte. +  + +\n\n3.  Tradings- und Investitionsrisiken +  +\n\nBei jeder Kryptowährung oder einer anderen digitalen Assetwechsel-Transaktion besteht ein hohes Risiko. Jede Transaktion mit Währungen birgt Risiken, einschließlich, aber nicht beschränkt auf das Potenzial für sich ändernde wirtschaftliche Bedingungen, die den Preis oder die Liquidität einer Währung erheblich beeinflussen können. Investitionen in Kryptowährungsspekulationen können auch anfällig für starke Anstiege und Rückgänge sein, wenn die relevanten Marktwerte schwanken. Aus diesem Grund ist es bei Spekulationen auf solchen Märkten ratsam, nur das Risikokapital zu verwenden. +  + +\n\n4. Risiken im Zusammenhang mit elektronischem Trading +  +\n\nBevor Sie Transaktionen über ein elektronisches System tätigen, sollten Sie die Regeln und Vorschriften der Börsen, die das System anbieten, und/oder die Instrumente, mit denen Sie handeln möchten, sorgfältig überprüfen. Der Online-Handel birgt ein dazugehörendes Risiko aufgrund der Systemreaktion und der Zugriffszeiten, die aufgrund der Marktbedingungen, der Systemleistung und anderer Faktoren variieren können. Sie sollten diese und andere Risiken vor dem Tradingsbeginn berücksichtigen. +  + +\n\n5. Einhaltung der Steuerpflichten +  +\n\nDie Benutzer der Software müssen allein bestimmen, welche Steuern, wenn überhaupt, für Ihre Kryptowährungstransaktionen gelten. Die Eigentümer oder die Mitwirkenden an der Software sind für die Ermittlung der Steuern, die für Kryptowährungstransaktionen gelten, NICHT verantwortlich. +  + +\n\n6. Garantieausschluss + +\n\nDie Software wird „wie gesehen“ bereitgestellt, ohne jegliche Gewährleistung in Bezug auf die Software und/oder Inhalte, Daten, Materialien und/oder Services, die zur Software gehören. +  + +\n\n7. Haftungsbeschränkung +  +\n\nSofern gesetzlich nichts anderes vorgesehen ist, haften die Eigentümer oder die Mitwirkenden an der Software in keinem Fall für Schäden jeglicher Art, einschließlich, aber nicht beschränkt auf Nutzungsausfall, entgangenen Gewinn oder Datenverlust, die aus der Verwendung der Software oder in Zusammenhang mit der jeglichen Verwendung der Software entstehen. Auf keine Weise sind die Eigentümer oder die Mitwirkenden an der Software für die von Ihnen im Vertrauen auf die Software vorgenommenen oder unterlassenen Handlungen, Entscheidungen oder sonstigen Verhaltensweisen verantwortlich. +  +  +\n\n8. Letzte Änderung +  +\n\nDieser Haftungsausschuss wurde am 1. Oktober 2020 zum letzten Mal geändert. + + + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml new file mode 100644 index 0000000000..971bb1682a --- /dev/null +++ b/app/src/main/res/values-fr/strings.xml @@ -0,0 +1,55 @@ + + + + + +Avertissement +  +\n\n1.Application Tangem Tap (Logiciel) +  +\n\nLe logiciel est destiné à l\’utilisation exclusivement avec les e-portefeuilles Tangem (Cartes) à l\’aide de l\’interface NFC. Le logiciel NE réalise pas ce qui suit : +  +\n\na. Génération, stockage, transmission ou octroi d\’accès aux clés privées (confidentiels) de chiffrement des blockchain-portefeuilles, qui contiennent les avoirs numériques, y compris la crypto-monnaie. +\n\nb. Génération, stockage, transmission ou octroi d\’accès aux clés confidentielles, aux mots de passe, phrases secrètes, phrases de restitution, qui pourront être utilisées pour la restitution ou pour le clonage des clés privées (confidentiels) de chiffrement des blockchain-portefeuilles, contenant les avoirs numériques, y compris la crypto-monnaie. +\n\nc. Prestation des services de bourse, de commerce, d\’investissement du nom de Tangem AG. +  +  +\n\n2. Risques, liés avec l\’utilisation du logiciel +  +\n\nTangem n\’assume aucune responsabilité pour tous les dommages, préjudice ou prétentions, qui peuvent survenir comme résultat des évènements, se rapportant à une de cinq catégories suivantes : +  +  +\n\na. Les erreurs, commises par l\’utilisateur de tout logiciel ou service liés avec la crypto-monnaie, par exemple, les mots de passe oubliés, les paiements envoyés aux adresses incorrectes, et élimination occasionnelle des blockchain-portefeuilles sur les Cartes. +\n\nb. Les problèmes du Logiciel et/ou de tout progiciel ou service liés avec blockchain ou avec la crypto-monnaie, par exemple, les fichiers endommagés, les transaction créées d\’une manière incorrecte, les bibliothèques cryptographiques non sécurisées, les logiciels malveillants. +\n\nc. Les défaillances techniques du hardware de l\’utilisateur, y compris les Cartes, de tout logiciel ou service liés avec la crypto-monnaie, par exemple, la perte des données à cause des périphériques défectives ou endommagées de stockage. +\n\nd. Les problèmes de la sécurité, subis par l\’utilisateur de tout logiciel ou service liés avec la crypto-monnaie, par exemple, l\’accès non autorisé aux portefeuilles et/ou comptes des utilisateurs. +\n\ne. Les actions ou l\’inaction des tierces personnes et/ou les évènements subis par les tierces personnes, par exemple, la faillite du prestataire de services, les attaques sur la sécurité informatique des prestataires de services et la fraude commise par des tierces personnes. +  +\n\n3.  Risques commerciales et d\’investissement +  +\n\nToute échange de crypto-monnaie ou d\’autres avoirs numériques implique les risques importants. Toute transaction liée avec la monnaie implique les risques, qui incluent, entre autres, la possibilité de modification des conditions économiques, qui peuvent influencer d\’une manière significative le prix ou la disponibilité de la monnaie. Les investissements dans les spéculations boursières avec les crypto-monnaies peuvent aussi être exposés aux montées et chutes en flèche lors des fluctuations des valeurs marchandes correspondants. C\'est pour cette raison, que lors de la spéculation sur tels marchés, il est conseillé d\’utiliser seulement le capital-risque. +  + +\n\n4. Risques de commerce électronique +  +\n\nAvant de passer aux transactions en utilisant le système électronique, Vous devez prendre connaissance, d\’une manière bien attentive, des règles et des dispositions stipulées par les bourses qui offrent ce système, et/ou les listes des titres de placement que vous voulez négocier. Le commerce en ligne possède le risque inaliénable lié avec la vitesse de réponse du système et avec le temps d\’accès qui peuvent varier en fonction des conditions de marché, du rendement du système et d\’autres facteurs. Avant de commencer les négoces, vous devez comprendre ces risques aussi que les risques supplémentaires. +  +\n\n5. Respect des obligations fiscales +  +\n\nLes utilisateurs du Logiciel assument toute la responsabilité pour définir, quels impôts sont appliqués à leurs transactions avec la crypto-monnaie, au cas où il y a de tels impôts. Les propriétaires et les participants à l\’élaboration du Logiciel n\’assument pas la responsabilité pour la définition des impôts qui sont appliqués aux transactions avec la crypto-monnaie. +  +\n\n6. Absence de garanties +
 +\n\nLe logiciel est concédé sous les conditions « tel quel », sans aucune garantie à l\’égard du Logiciel et/ou de tout le contenu, données, matériaux et/ou services, présentes dans ce Logiciel. +  +\n\n7. Restriction de la responsabilité +  +\n\nSauf disposition contraire prévue par la législation, les propriétaires et les participants à l\’élaboration du Logiciel n\’assument pas la responsabilité pour aucun dommage, y compris l\’indisponibilité, la perte de profit ou la perte des données, qui surviennent comme résultat de l\’utilisation ou bien qui sont liés d\’une certaine manière avec l\’utilisation du Logiciel. Les propriétaires et les participants à l\’élaboration du Logiciel n\’assument pas la responsabilité pour les actions, les résolutions ou pour une autre conduite que vous manifestez ou pas par l\’intermédiaire du Logiciel. +  +  +\n\n8. Dernière modification +  +\n\nCette avertissement a été modifié, pour la dernière fois, le 1 octobre 2020. + + + \ No newline at end of file From e5c5b18c090f3585f6b25252c5a55ef7416a046a Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 14 Oct 2020 17:59:25 +0300 Subject: [PATCH 09/11] Updated on 2026-08-14 --- app/build.gradle | 6 +- .../java/com/tangem/tap/domain/TapErrors.kt | 10 +- .../features/details/redux/DetailsAction.kt | 2 +- .../tangem/tap/features/home/HomeFragment.kt | 2 +- .../tap/features/send/ui/SendFragment.kt | 2 +- .../stateSubscribers/SendStateSubscriber.kt | 4 +- .../tap/features/wallet/ui/WalletFragment.kt | 2 +- .../res/layout/fragment_details_security.xml | 2 +- app/src/main/res/layout/fragment_home.xml | 2 +- app/src/main/res/layout/fragment_send.xml | 2 +- app/src/main/res/values-de/strings.xml | 116 +++++++++++- app/src/main/res/values-fr/strings.xml | 113 +++++++++++ app/src/main/res/values/strings.xml | 177 +++++++++--------- 13 files changed, 334 insertions(+), 106 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d3603f973a..99b43a1293 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -67,9 +67,9 @@ dependencies { implementation 'com.google.android.material:material:1.2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' - implementation 'com.tangem:blockchain:1.82.0' - implementation 'com.tangem:core:1.67.0' - implementation 'com.tangem:sdk:1.67.0' + implementation 'com.tangem:blockchain:1.83.0' + implementation 'com.tangem:core:1.68.0' + implementation 'com.tangem:sdk:1.68.0' //lifecycle implementation "androidx.lifecycle:lifecycle-runtime:2.2.0" diff --git a/app/src/main/java/com/tangem/tap/domain/TapErrors.kt b/app/src/main/java/com/tangem/tap/domain/TapErrors.kt index e3f8ab3646..6e5388a40d 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapErrors.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapErrors.kt @@ -28,14 +28,14 @@ sealed class TapError( object NoInternetConnection : TapError(R.string.wallet_notification_no_internet) object InsufficientBalance : TapError(R.string.send_error_insufficient_balance) object BlockchainInternalError : TapError(R.string.send_error_blockchain_internal) - object AmountExceedsBalance : TapError(R.string.send_error_amount_exceeds_balance) - object FeeExceedsBalance : TapError(R.string.send_error_fee_exceeds_balance) - object TotalExceedsBalance : TapError(R.string.send_error_total_exceeds_balance) - object InvalidAmountValue : TapError(R.string.send_error_invalid_amount) + object AmountExceedsBalance : TapError(R.string.send_validation_amount_exceeds_balance) + object FeeExceedsBalance : TapError(R.string.send_validation_invalid_fee) + object TotalExceedsBalance : TapError(R.string.send_validation_invalid_total) + object InvalidAmountValue : TapError(R.string.send_validation_invalid_amount) object InvalidFeeValue : TapError(R.string.send_error_invalid_fee_value) data class DustAmount(override val args: List) : TapError(R.string.send_error_dust_amount_format) object DustChange : TapError(R.string.send_error_dust_change) - data class CreateAccountUnderfunded(override val args: List) : TapError(R.string.send_error_no_target_accout) + data class CreateAccountUnderfunded(override val args: List) : TapError(R.string.send_error_no_target_account) data class ValidateTransactionErrors( override val errorList: List, diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt index a38ca15f92..448e0a48ad 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt @@ -24,7 +24,7 @@ sealed class DetailsAction : Action { object Check : EraseWallet() object Proceed : EraseWallet() { object NotAllowedByCard: EraseWallet(), NotificationAction { - override val messageResource = R.string.details_notification_erase_wallet_not_allowed + override val messageResource = R.string.error_purge_prohibited } object NotEmpty: EraseWallet(), NotificationAction { override val messageResource = R.string.details_notification_erase_wallet_not_possible diff --git a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt index c12785fd92..b8b8aa52fc 100644 --- a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt @@ -32,7 +32,7 @@ class HomeFragment : Fragment(R.layout.fragment_home), StoreSubscriber R.string.send_error_payid_unsupported_by_blockchain - Error.PAY_ID_NOT_REGISTERED -> R.string.send_error_payid_not_registere + Error.PAY_ID_NOT_REGISTERED -> R.string.send_error_payid_not_registered Error.PAY_ID_REQUEST_FAILED -> R.string.send_error_payid_request_failed - Error.ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.send_error_address_invalid_or_unsupported + Error.ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.send_validation_invalid_address Error.ADDRESS_SAME_AS_WALLET -> R.string.send_error_address_same_as_wallet else -> null } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index d8d0e11931..c3e7f6c8fe 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -151,7 +151,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber + Nein + Änderungen speichern + Warnung + Erneut versuchen + Erledigt + Abbrechen + Akzeptieren - + Der Kamerazugriff wurde verweigert + Sie haben keinen Zugang zur Kamera erteilt, bitte passen Sie Ihre Datenschutzeinstellungen an + Einstellungen + Willkommen bei Tangem. Haben Sie eine dieser Karten? + Willkommen bei Tangem Tap. Scannen Sie Ihre Karten um zu starten. + Ja! Bitte scannen + Einkaufen + Halten Sie die \ncard hinter dem \nphone bereit und scannen Sie sie. + Eintippen + Karte scannen + Scannen + Absenden + ein Wallet erstellen + Tangem Tap + eine Walletoption wählen + Token + Tokens + Verifizierte Bilanz + Die Bilanz wird aufgeladen… + Blockchain ist nicht erreichbar + Das Konto ist nicht erstellt + %s+ %s aufladen um ein Konto zu erstellen + Leere Karte + Erstellen Sie ein Wallet um die Tangem-Karte verwenden zu können + Diese Karte wird nicht unterstützt + Ihre Tangem-Karte wurde für die Arbeit mit einer anderen App ausgestellt. Bitte sehen Sie sich den Namen und die Anleitung auf Ihrer Karte an und installieren Sie eine korrekte App + Die Transaktion läuft… + Senden\u0020 + an %s + Erhalten\u0020 + von %s + Adresse erkunden + ZahlungsID erstellen + %s Wallet + ZahlungsID erstellen + Karte: %s + ZahlungsID Name + $payid.tangem.com + Erstellen + ZahlungsID sind Ihre einzigartigen Identifikationsdaten wie Telefonnummer, E-Mail-Adresse oder ABN. + Ihre ZahlungsID wurde erfolgreich erstellt und zum Clipboard kopiert + Fehlerantwort beim Erstellen der ZahlungsID + Diese ZahlungsID existiert bereits. Versuchen Sie mit einer anderen erneut. + Adresse oder ZahlungsID + Absenden + Netzgebühr + Betrag + Gebühr + Gesamt + Höchstbetrag + Ungültige Adresse + Ungültiger Betrag + Der Betrag geht über die Bilanz hinaus + Der Gesamtbetrag geht über die Bilanz hinaus + Die Gebühr geht über die Bilanz hinaus + Niedrig + Normal + Priorität + inkl. Gebühr + %s %s wird gesendet + ≈ %s (inkl. Gebühr: %s) + %s %s und %s %s werden gesendet + Bilanz: %s %s + Die Transaktion wurde erfolgreich signiert und an den Blockchain-Knoten gesendet. Die Walletbilanz wird aktualisiert + Details + KartenID + Emittent + Signiert + %s Hasch + App Währung + Einstellungen + Karte + Karte validieren + Sicherheit verwalteny + Wallet löschen + Dieser Vorgang ist irriversibel. Wenn jemand nach dem Löschen des Wallets Geld überweist, können Sie es nicht mehr abheben. + Sollten Sie den Code verloren haben, haben Sie keinen Zugriff auf die Karte. Sie können Ihren Code nicht wiederherstellen und nicht ändern, wenn Sie ihn verlieren. + Sicherheit verwalten + Langes Tippen + Dieser Mechanismus schützt vor Annäherungsangriffen auf eine Karte. Es wird eine Verzögerung zwischen dem Empfang und der Ausführung eines Befehls erzwungen. Nach der ersten signierten Transaktion wird dieses Telefon mit der Karte verknüpft und die Transaktionen werden sofort signiert + Passcode + Bevor Sie einen Befehl ausführen, der eine Änderung des Kartenstatus zur Folge hat, müssen Sie den Passcode eingeben. + Zugangscode + Sie müssen den richtigen Zugangscode eingeben, bevor Sie die Karte scannen. + Sie können NFC-Probleme mit einigen iPhone 7/7+ während der Extraktion haben + Warnung: Diese Karte wurde früher bereits aufgeladen und Transaktionen wurden damit signiert.\n Ziehen Sie eine sofortige Auszahlung aller Beträge in Betracht, wenn Sie diese Karte von einer nicht vertrauenswürdigen Quelle erhalten haben. + + Diese Karte ist für die Zusammenarbeit mit Tangem Tap nicht geeignet + Die von Ihnen gescannte Karte ist eine Entwicklungskarte. Akzeptieren Sie sie nicht als Zahlungsmittel + Die vor September 2019 ausgestellten Karten können mit iPhone momentan nicht extrahiert werden. Wir arbeiten eng mit Apple zusammen, damit es in den nächsten Versionen von iOS möglich wäre. + Tippen um zu signieren + Scannen Sie die Karte mit Ihrem Handy wie oben gezeigt + Tippen Sie um das Wallet zu löschen + Tippen Sie um ein Wallet zu erstellen + Tippen Sie um den Zugangscode zu ändern + Tippen Sie um den Passcode zu ändern + Ungültige ZahlungsID + + + RECHTLICHER HAFTUNGSAUSSCHLUSS \n\n1.Tangem Tap App (Software)   @@ -53,4 +159,12 @@ RECHTLICHER HAFTUNGSAUSSCHLUSS \n\nDieser Haftungsausschuss wurde am 1. Oktober 2020 zum letzten Mal geändert. + Nutzungsbedingungen + + Keine Internetverbindung + Tippen um zu scannen + Tippen um zu scannen + Das Zielkonto ist nicht erstellt. Der abzusendende Betrag soll %1$s %2$s + Gebühr oder mehr sein + Erhalt der Gebühr fehlgeschlagen + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 971bb1682a..126594da92 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -1,6 +1,111 @@ + Non + Sauvegarder les modifications + Alerte + Réessayer + Exécuté + Annuler + J\'accepte + + L’accès à la caméra est refusé + Vous n\'avez pas octroyé l’accès à votre caméra, veuillez modifier vos paramètres de confidentialité + Paramètres + Bienvenue à Tangem. Avez-vous une de nos cartes + Encore une fois, bienvenue dans Tangem Tap. \nScannez votre carte pour commencer. + Oui! Scannez-la. + Magasin + Préparez-vous à appuyer votre carte au dos de votre téléphone. + Appuyez + Scannez la carte + Scanner + Envoyer + Créer un portefeuille + Tangem Tap + Choisir une variante de portefeuille + Jeton d\'authentification + Jetons d\'authentification + Solde confirmé + Solde est en cours de téléchargement … + Blockchain est inaccessible + Compte n’est pas créé + Téléchargez% @ +% @ pour créer un compte + Carte vide + Créez un portefeuille pour commencer à utiliser votre carte Tangem + Cette carte n\'est pas prise en charge + Votre carte Tangem a été créée pour fonctionner avec une autre application. Regardez le nom et les instructions sur votre carte et installez l\'application pertinente + Transaction en cours… + Envoi\u0020 + jusqu’à %s + Réception \u0020 + de %s + Explorer l\'adresse + Créer PayID + Portefeuille %s + Créer PayID + Carte: %s + Dénomination PayID + $payid.tangem.com + Créer + Votre PayID est une information qui vous est propre, comme un numéro de téléphone, une adresse du courrier électronique ou un ABN. + PayID a été créé avec succès et copié dans le presse-papiers + Mauvaise réponse lors de la création de PayID + Ce PayID existe déjà. Essayez une autre variante. + Adresse ou PayID + Envoyer + Commissions du réseau + Somme + Commissions + Total + Somme maximale + Adresse incorrecte + Somme incorrecte + Le montant dépasse le solde + Le total dépasse le solde + Les commissions dépassent le solde + Bas + Normal + Priorité + Inclure les commissions + Sera envoyé %s %s + ≈ %s (incl. les commissions : %s) + Sera envoyé %s %s et %s %s + Solde : %s %s + La transaction a été signée avec succès et envoyée au nœud de blockchain. Le solde du portefeuille sera mis à jour après un certain temps + Référénces + ID de la carte + Emetteur + Signé + %s hashes + Monnaie de l’application + Paramètres + Carte + Valider la carte + Gestion de la sécurité + Annuler le portefeuille + Cette action est irréversible. Si, après avoir annulé le portefeuille, quelqu\'un lui envoie des fonds, vous ne pourrez pas les retirer. + Si vous oubliez le code, vous perdrez la possibilité d\'utiliser la carte. Si vous perdez le code, il sera impossible de le restaurer ou modifier. + Gestion de la sécurité + Tenez la carte fermement + Ce mécanisme protège contre les attaques sans contact sur la carte. Il y a un délai entre la réception et l\'exécution de la commande. Après la première transaction signée, ce téléphone sera associé à la carte et les transactions seront signées immédiatement. + Mot de passe + Avant d\'exécuter une commande qui modifie l\'état de la carte, vous devrez entrer un mot de passe. + Code d’accès + Vous devrez entrer le mot de passe correct avant de scanner la carte + Vous pouvez rencontrer des problèmes NFC avec certains iPhone 7/7 + lors de l’extraction + Attention: cette carte a déjà été rechargée et a signé des transactions avant. Envisagez la possibilité de retirer tous les fonds immédiatement si vous avez reçu cette carte d\'une source non fiable. + Cette carte n\'est pas conçue pour fonctionner avec Tangem Tap + La carte que vous avez scannée est une carte de développement. Ne l\'acceptez pas comme paiement + Les cartes Tangem émises avant septembre 2019 ne peuvent actuellement pas être extraites à l\'aide de l\'iPhone. Nous travaillons activement avec Apple pour rendre cela possible dans les futures versions d\'iOS. + Touchez pour signer + Appuyez votre carte au téléphone comme indiqué ci-dessus + Touchez, pour annuler un portefeuille + Touchez, pour créer un portefeuille + Touchez, pour modifier le code d’accès + Touchez, pour modifier le mot de passe + PayID incorrect + Avertissement @@ -52,4 +157,12 @@ Avertissement \n\nCette avertissement a été modifié, pour la dernière fois, le 1 octobre 2020. + Conditions d\'utilisation + + Pas de connexion internet + Touchez pour scanner + Touchez pour scanner + Le compte cible n\'a pas été créé. Le montant à envoyer doit être de %1$s %2$s + commissions ou plus + Échec de réception des commissions + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a9ed98a110..8142ff23cc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -9,112 +9,81 @@ Done Cancel Accept - + Camera access denied You have not given access to your camera, please adjust your privacy settings Settings Welcome to Tangem.\nDo you have one of our cards? Welcome back to Tangem Tap. \nScan your card to start. - Yes. Scan it! Shop Get ready to tap your \ncard to the back of the \nphone. Tap in Scan card - @string/common_no + Yes! Scan it. - @string/app_name Scan Send - Create Wallet + Create wallet + Tangem Tap Choice wallet option + Token + Tokens + Verified Balance + Balance is loading… + Blockchain is unreachable + + Account is not created + Load %1$s+ %2$s to create account + Empty card + Create wallet to start using Tangem card + This card is not supported + Your Tangem card was made to work with a different application. Please see the name and instructions on your card, and install the correct app + + Transaction is in progress… + to %s + from %s + Receiving\u0020 + Sending\u0020 + Explore address Create PayID - - Verified Balance - Blockchain is unreachable - Balance is loading… - Transaction is in progress - Tokens - Token - - This card is not supported - Your Tangem card was made to work with a different application. Please see the name and instructions on your card, and install the correct app. - Empty Card - Create wallet to start using Tangem card - Account is not created - Load %1s+ %2s to create account - - Receiving\u0020 - Sending\u0020 - from %s - to %s + $s wallet Create PayID Card: %s - Enter desired PayID first PayID name + $payid.tangem.com Create - $payid.tangem.com Your PayID is information unique to you, like your phone number, email or ABN. - This PayID already exists. Try a different one. - Error response while creating PayID PayID created successfully and copied to clipboard + Error response while creating PayID + This PayID already exists. Try a different one. - %s wallet - - Address was successfully copied - No internet connection - @string/common_retry - - The card you scanned is a development card. Don\'t accept it as a payment. - Warning: This card has been already topped up and signed transactions in the past. - Consider immediate withdrawal of all funds if you have received this card from an untrusted source. - This card it is not designed to work with Tangem Tap - You may experience NFC problems with some iPhone 7/7+ during the extraction - - Unknown error - PayID verification failed - PayID unsupported by blockchain - PayID not registered - PayID request failed - Address is invalid or unsupported by blockchain - Address is the same as wallet address - Network fee request is failed - Insufficient balance - Blockchain internal error - Amount Exceeds Balance - Fee Exceeds Balance - Total Exceeds Balance - Invalid Amount - Invalid Fee - Minimum amount is %s - Change is too small - Target account is not created. Send more than %1$s %2$s to create - - Send Address or PayID + Send Network fee - Include fee + Amount + Fee + Total + Maximum amount + Invalid address + Invalid amount + Amount Exceeds Balance + Total Exceeds Balance + Fee Exceeds Balance Low Normal Priority - @string/send_title - Total - Amount - Fee - %1s %2s will be sent - ≈ %1s (inc. fee: %2s) - %1s %2s and %3s %4s will be sent - Balance: %1s %2s - Maximum amount - Transaction was signed and sent to the blockchain + Include fee + %1$s %2$s will be sent + ≈ %1$s (inc. fee: %2$s) + %1$s %2$s and %3$s %4$s will be sent + Balance: %1$s %2$s + Transaction has been successfully signed and sent to blockchain node. Wallet balance will be updated in a while Details - Card settings prohibits from erasing wallet - You balance on this wallet is not zero, or you have unconfirmed transactions - This is the currently active option Card ID Issuer Signed @@ -123,27 +92,30 @@ Settings Card Validate card - Manage security + Manage Security Erase wallet - Continue - - Long Tap - Passcode - Access Code - This mechanism protects against proximity attack on a card. It will enforce a delay between reception and execution of a command. After the first signed transaction this phone will be linked with the card and transactions will be signed immediately. - Before execution of any command entailing a change of the card state you will have to enter the passcode. - You will have to submit the correct access code before scanning the card. - This action is irreversible. If, after deleting the wallet, someone sends funds to it, then you will not be able to withdraw them. If you forget the code, you will lose the ability to use the card. There is no way to recover or change your code if you lose it. + Manage Security + Long Tap + This mechanism protects against proximity attack on a card. It will enforce a delay between reception and execution of a command. After the first signed transaction this phone will be linked with the card and transactions will be signed immediately. + Passcode + Before execution any command entailing a change of the card state you will have to enter the passcode. + Access code + You will have to submit the correct access code before scanning the card + + You may experience NFC problems with some iPhone 7/7+ during the extraction + Warning: This card has been already topped up and signed transactions in the past.\n\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020Consider immediate withdrawal of all funds if you have received this card from an untrusted source. + This card it is not designed to work with Tangem Tap + The card you scanned is a development card. Don’t accept it as a payment + Tangem cards manufactured before September 2019 cannot currently be extracted with an iPhone. We’re working hard with Apple to make it possible in future versions of iOS. - Tap to scan - Tap the card Tap to sign + Tap the card to your phone as shown above Tap to erase wallet Tap to create wallet - Tap to change the passcode Tap to change the access code + Tap to change the passcode Invalid PayID @@ -196,6 +168,35 @@ \n8. Last amendment \n \nThis disclaimer was amended for the last time on October 1st, 2020. - Terms of service> + Terms of service + + Failed to get fee + Target account is not created. Amount to send should be %1$s %2$s + fee or more to create + No internet connection + + Unknown error + PayID verification failed + PayID unsupported by blockchain + PayID not registered + PayID request failed + + Address is the same as wallet address + Insufficient balance + Blockchain internal error + Invalid Fee + Minimum amount is %s + Change is too small + + Address was copied to clipboard + + + Enter desired PayID first + + Tap to scan + Tap the card + + You balance on this wallet is not zero, or you have unconfirmed transactions + This is the currently active option + \ No newline at end of file From 08f42a55f2738a884b30cd1b7c54091906165919 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 14 Oct 2020 18:54:29 +0300 Subject: [PATCH 10/11] Updated on 2026-08-14 --- app/src/main/res/values-fr/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 126594da92..5b035e0b2b 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -30,12 +30,12 @@ Solde est en cours de téléchargement … Blockchain est inaccessible Compte n’est pas créé - Téléchargez% @ +% @ pour créer un compte + Téléchargez %s +%s pour créer un compte Carte vide Créez un portefeuille pour commencer à utiliser votre carte Tangem Cette carte n\'est pas prise en charge Votre carte Tangem a été créée pour fonctionner avec une autre application. Regardez le nom et les instructions sur votre carte et installez l\'application pertinente - Transaction en cours… + Transaction en cours… Envoi\u0020 jusqu’à %s Réception \u0020 From f7c38347489da2db741f2b395d4a1cf4a1b9efae Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 14 Oct 2020 20:10:47 +0300 Subject: [PATCH 11/11] Updated on 2026-08-14 --- .../main/res/layout/fragment_details_confirm.xml | 4 ++-- .../res/layout/fragment_details_security.xml | 2 +- app/src/main/res/layout/fragment_disclaimer.xml | 2 +- app/src/main/res/layout/fragment_home.xml | 4 ++-- app/src/main/res/layout/fragment_send.xml | 2 +- app/src/main/res/layout/fragment_wallet.xml | 4 ++-- app/src/main/res/values-de/strings.xml | 16 ++++++++-------- app/src/main/res/values-fr/strings.xml | 2 +- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app/src/main/res/layout/fragment_details_confirm.xml b/app/src/main/res/layout/fragment_details_confirm.xml index 8aaec159c0..2a6933b594 100644 --- a/app/src/main/res/layout/fragment_details_confirm.xml +++ b/app/src/main/res/layout/fragment_details_confirm.xml @@ -83,8 +83,8 @@ android:layout_height="48dp" android:layout_marginStart="7dp" android:layout_marginTop="30dp" - android:layout_marginEnd="30dp" - tools:text="@string/wallet_button_send" + android:layout_marginEnd="16dp" + tools:text="@string/common_save" tools:icon="@drawable/ic_send" app:layout_constraintStart_toEndOf="@+id/guideline" app:layout_constraintEnd_toEndOf="parent" diff --git a/app/src/main/res/layout/fragment_details_security.xml b/app/src/main/res/layout/fragment_details_security.xml index 7304e50ece..1dd8549df9 100644 --- a/app/src/main/res/layout/fragment_details_security.xml +++ b/app/src/main/res/layout/fragment_details_security.xml @@ -184,7 +184,7 @@ android:layout_height="48dp" android:layout_marginStart="7dp" android:layout_marginTop="30dp" - android:layout_marginEnd="30dp" + android:layout_marginEnd="16dp" android:text="@string/common_continue" app:icon="@drawable/ic_save" app:layout_constraintStart_toEndOf="@+id/guideline" diff --git a/app/src/main/res/layout/fragment_disclaimer.xml b/app/src/main/res/layout/fragment_disclaimer.xml index c509c0fd9e..3efa0e31fa 100644 --- a/app/src/main/res/layout/fragment_disclaimer.xml +++ b/app/src/main/res/layout/fragment_disclaimer.xml @@ -70,7 +70,7 @@ android:layout_height="48dp" android:layout_marginStart="7dp" android:layout_marginTop="30dp" - android:layout_marginEnd="30dp" + android:layout_marginEnd="16dp" android:text="@string/common_accept" app:icon="@drawable/ic_send" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 6bc0d387aa..5bff544835 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -64,7 +64,7 @@ style="@style/TapBlackButton" android:layout_width="0dp" android:layout_height="48dp" - android:layout_marginStart="30dp" + android:layout_marginStart="16dp" android:layout_marginBottom="33dp" android:text="@string/common_no" app:icon="@drawable/ic_shop" @@ -87,7 +87,7 @@ android:layout_width="0dp" android:layout_height="48dp" android:layout_marginStart="8dp" - android:layout_marginEnd="30dp" + android:layout_marginEnd="16dp" android:layout_marginBottom="33dp" android:text="@string/home_button_yes" app:icon="@drawable/ic_send" diff --git a/app/src/main/res/layout/fragment_send.xml b/app/src/main/res/layout/fragment_send.xml index 2bd0d5d07d..35b5a31030 100644 --- a/app/src/main/res/layout/fragment_send.xml +++ b/app/src/main/res/layout/fragment_send.xml @@ -97,7 +97,7 @@ app:layout_constraintStart_toEndOf="@+id/guideline" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" - android:layout_marginEnd="30dp" + android:layout_marginEnd="16dp" android:layout_marginStart="8dp"> Erstellen Sie ein Wallet um die Tangem-Karte verwenden zu können Diese Karte wird nicht unterstützt Ihre Tangem-Karte wurde für die Arbeit mit einer anderen App ausgestellt. Bitte sehen Sie sich den Namen und die Anleitung auf Ihrer Karte an und installieren Sie eine korrekte App - Die Transaktion läuft… + Die Transaktion läuft… Senden\u0020 an %s Erhalten\u0020 von %s Adresse erkunden - ZahlungsID erstellen + PayID erstellen %s Wallet - ZahlungsID erstellen + PayID erstellen Karte: %s - ZahlungsID Name + PayID Name $payid.tangem.com Erstellen - ZahlungsID sind Ihre einzigartigen Identifikationsdaten wie Telefonnummer, E-Mail-Adresse oder ABN. - Ihre ZahlungsID wurde erfolgreich erstellt und zum Clipboard kopiert + PayID sind Ihre einzigartigen Identifikationsdaten wie Telefonnummer, E-Mail-Adresse oder ABN. + Ihre PayID wurde erfolgreich erstellt und zum Clipboard kopiert Fehlerantwort beim Erstellen der ZahlungsID - Diese ZahlungsID existiert bereits. Versuchen Sie mit einer anderen erneut. - Adresse oder ZahlungsID + Diese PayID existiert bereits. Versuchen Sie mit einer anderen erneut. + Adresse oder PayID Absenden Netzgebühr Betrag diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 5b035e0b2b..4bf21924ff 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -87,7 +87,7 @@ Cette action est irréversible. Si, après avoir annulé le portefeuille, quelqu\'un lui envoie des fonds, vous ne pourrez pas les retirer. Si vous oubliez le code, vous perdrez la possibilité d\'utiliser la carte. Si vous perdez le code, il sera impossible de le restaurer ou modifier. Gestion de la sécurité - Tenez la carte fermement + Tenez la carte fermement Ce mécanisme protège contre les attaques sans contact sur la carte. Il y a un délai entre la réception et l\'exécution de la commande. Après la première transaction signée, ce téléphone sera associé à la carte et les transactions seront signées immédiatement. Mot de passe Avant d\'exécuter une commande qui modifie l\'état de la carte, vous devrez entrer un mot de passe.