From 1280c6e5327ab690a64dffa86116af0c692626fd Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 29 Oct 2021 18:28:46 +0300 Subject: [PATCH 01/76] Updated on 2026-08-14 --- .../onboarding/products/note/OnboardingNoteFragment.kt | 3 +++ .../products/otherCards/OnboardingOtherCardsFragment.kt | 2 ++ app/src/main/res/values/strings_untranslated.xml | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt index 7eb8b3a5fc..e0661b0359 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt @@ -132,6 +132,8 @@ class OnboardingNoteFragment : BaseOnboardingFragment() { imv_card_background.setBackgroundDrawable(requireContext().getDrawableCompat(R.drawable.shape_circle)) updateConstraints(state.currentStep, R.layout.lp_onboarding_create_wallet) + + btn_alternative_action.isVisible = false // temporary } private fun setupTopUpWalletState(state: OnboardingNoteState) { @@ -140,6 +142,7 @@ class OnboardingNoteFragment : BaseOnboardingFragment() { store.dispatch(OnboardingNoteAction.TopUp) } + btn_alternative_action.isVisible = true btn_alternative_action.setText(R.string.onboarding_top_up_button_show_wallet_address) btn_alternative_action.setOnClickListener { store.dispatch(OnboardingNoteAction.ShowAddressInfoDialog) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt index 0072388bcb..22e479721b 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt @@ -87,6 +87,8 @@ class OnboardingOtherCardsFragment : BaseOnboardingFragmentGet a new card Activating card - What does it mean? + How it works? Create a wallet Let’s generate all the keys on your card and create a secure wallet Create wallet From efb2a36f418623a66c05024396a79e83aa598b28 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 29 Oct 2021 18:43:12 +0300 Subject: [PATCH 02/76] Updated on 2026-08-14 --- .../tangem/tap/features/wallet/ui/dialogs/ScanFailsDialog.kt | 2 +- app/src/main/res/values/strings_untranslated.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ScanFailsDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ScanFailsDialog.kt index 0f164965d4..496a8ff731 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ScanFailsDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ScanFailsDialog.kt @@ -21,7 +21,7 @@ class ScanFailsDialog { setPositiveButton(R.string.alert_button_request_support) { _, _ -> store.dispatch(GlobalAction.SendFeedback(ScanFailsEmail())) } - setNegativeButton(R.string.common_cancel) { _, _ -> } + setNeutralButton(R.string.alert_troubleshooting_scan_card_ok) { _, _ -> } setOnDismissListener { store.dispatchDialogHide() } }.create() } diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index eca949a339..e0a8e57348 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -57,6 +57,7 @@ Reason: %s. Do you want to send feedback? Are you having difficulty scanning your card? Please try to tap the card exactly as shown in the animation or request support. + I\'m okay Try again Request support Send feedback From ef58ec6ab1473c2a367d97d4aa62a35c072d010c Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 29 Oct 2021 19:41:20 +0300 Subject: [PATCH 03/76] Updated on 2026-08-14 --- .../tap/features/feedback/FeedbackManager.kt | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt index 6007d61e23..16edbb6987 100644 --- a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt +++ b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt @@ -39,6 +39,7 @@ class FeedbackManager( } fun send(emailData: EmailData) { + emailData.prepare(infoHolder) val fileLog = if (emailData is ScanFailsEmail) createLogFile() else null sendTo( email = getSupportEmail(), @@ -235,6 +236,9 @@ class AdditionalEmailInfo { interface EmailData { val subject: String val mainMessage: String + + fun prepare(infoHolder: AdditionalEmailInfo) {} + fun createOptionalMessage(infoHolder: AdditionalEmailInfo): String fun joinTogether(infoHolder: AdditionalEmailInfo): String { @@ -298,8 +302,23 @@ class SendTransactionFailedEmail(private val error: String) : EmailData { } class FeedbackEmail : EmailData { - override val subject: String = "Tangem Tap feedback" - override val mainMessage: String = "Hi Tangem," + override val subject: String + get() = if (isS2CCard) s2cSubject else tangemSubject + override val mainMessage: String + get() = if (isS2CCard) s2cMainMessage else tangemMainMessage + + private val tangemSubject = "Tangem Tap feedback" + private val tangemMainMessage = "Hi Tangem," + + private val s2cSubject = "Feedback" + private val s2cMainMessage = "Hi support team," + + private var isS2CCard = false + + override fun prepare(infoHolder: AdditionalEmailInfo) { + isS2CCard = TapWorkarounds.isStart2CoinIssuer(infoHolder.cardIssuer) + } + override fun createOptionalMessage(infoHolder: AdditionalEmailInfo): String { val builder = StringBuilder() builder.appendKeyValue("Card ID", infoHolder.cardId) From f43d1c5ae54f2c475665cd0ddaa78de6b276deb4 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 29 Oct 2021 20:40:52 +0300 Subject: [PATCH 04/76] Updated on 2026-08-14 --- app/src/main/AndroidManifest.xml | 7 ++ .../main/java/com/tangem/tap/MainActivity.kt | 2 +- .../tangem/tap/common/extensions/Activity.kt | 63 +++++++++++++ .../tap/features/feedback/FeedbackManager.kt | 89 +++++++------------ 4 files changed, 104 insertions(+), 57 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/common/extensions/Activity.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c2d4929889..f3c400a3ec 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,6 +19,13 @@ + + + + + + + + * + * + * + * + * + */ +fun Activity.sendEmail( + email: String, + subject: String, + message: String, + file: File? = null, + onFail: ((Exception) -> Unit)? = null +) { + fun createEmailShareIntent(recipient: String, subject: String, text: String, file: File? = null): Intent { + val builder = ShareCompat.IntentBuilder.from(this) + .setType("message/rfc822") + .setEmailTo(arrayOf(recipient)) + .setSubject(subject) + .setText(text) + file?.let { builder.setStream(FileProvider.getUriForFile(this, "${packageName}.provider", it)) } + return builder.intent + } + + val originalIntent = createEmailShareIntent(email, subject, message, file) + val emailFilterIntent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")) + + val originalIntentResults = packageManager.queryIntentActivities(originalIntent, 0) + val emailFilterIntentResults = packageManager.queryIntentActivities(emailFilterIntent, 0) + + val targetedIntents = originalIntentResults + .filter { originalResult -> + emailFilterIntentResults.any { + originalResult.activityInfo.packageName == it.activityInfo.packageName + } + } + .map { + createEmailShareIntent(email, subject, message, file).apply { + setPackage(it.activityInfo.packageName) + } + } + .toMutableList() + try { + val chooserIntent = Intent.createChooser(targetedIntents.removeAt(0), "Send mail...") + chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toTypedArray()) + chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + ContextCompat.startActivity(this, chooserIntent, null) + } catch (ex: Exception) { + onFail?.invoke(ex) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt index 16edbb6987..68b6262389 100644 --- a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt +++ b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt @@ -1,19 +1,14 @@ package com.tangem.tap.features.feedback import android.app.Activity -import android.content.ActivityNotFoundException import android.content.Context -import android.content.Intent import android.content.pm.PackageManager -import android.net.Uri import android.os.Build -import androidx.core.app.ShareCompat -import androidx.core.content.ContextCompat -import androidx.core.content.FileProvider import com.tangem.Log import com.tangem.TangemSdkLogger import com.tangem.blockchain.common.* import com.tangem.common.card.Card +import com.tangem.tap.common.extensions.sendEmail import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.domain.TapWorkarounds import timber.log.Timber @@ -28,23 +23,26 @@ import java.util.* [REDACTED_AUTHOR] */ class FeedbackManager( - val infoHolder: AdditionalEmailInfo, - private val logCollector: TangemLogCollector, + val infoHolder: AdditionalEmailInfo, + private val logCollector: TangemLogCollector, ) { private lateinit var activity: Activity - fun updateAcivity(activity: Activity) { + fun updateActivity(activity: Activity) { this.activity = activity } - fun send(emailData: EmailData) { + fun send(emailData: EmailData, onFail: ((Exception) -> Unit)? = null) { + if (!this::activity.isInitialized) return + emailData.prepare(infoHolder) val fileLog = if (emailData is ScanFailsEmail) createLogFile() else null - sendTo( + activity.sendEmail( email = getSupportEmail(), subject = emailData.subject, message = emailData.joinTogether(infoHolder), - fileLog = fileLog + file = fileLog, + onFail = onFail ) } @@ -56,42 +54,6 @@ class FeedbackManager( } } - private fun sendTo(email: String, subject: String, message: String, fileLog: File? = null) { - val emailFilterIntent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")) - val originalIntentResults = activity.packageManager.queryIntentActivities(emailFilterIntent, 0) - val emailFilterIntentResults = activity.packageManager.queryIntentActivities(emailFilterIntent, 0) - val targetedIntents = originalIntentResults - .filter { originalResult -> - emailFilterIntentResults.any { - originalResult.activityInfo.packageName == it.activityInfo.packageName - } - } - .map { - createEmailShareIntent(email, subject, message, fileLog).apply { - setPackage(it.activityInfo.packageName) - } - } - .toMutableList() - try { - val chooserIntent = Intent.createChooser(targetedIntents.removeAt(0), "Send mail...") - chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toTypedArray()) - chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - ContextCompat.startActivity(activity, chooserIntent, null) - } catch (ex: ActivityNotFoundException) { - Timber.e(ex) - } - } - - private fun createEmailShareIntent(recipient: String, subject: String, text: String, file: File? = null): Intent { - val builder = ShareCompat.IntentBuilder.from(activity) - .setType("message/rfc822") - .setEmailTo(arrayOf(recipient)) - .setSubject(subject) - .setText(text) - file?.let { builder.setStream(FileProvider.getUriForFile(activity, "${activity.packageName}.provider", it)) } - return builder.intent - } - private fun createLogFile(): File? { return try { val file = File(activity.filesDir, "logs.txt") @@ -135,12 +97,12 @@ class TangemLogCollector : TangemSdkLogger { class AdditionalEmailInfo { class EmailWalletInfo( - var blockchain: Blockchain = Blockchain.Unknown, - var address: String = "", - var explorerLink: String = "", - var host: String = "", - // var outputsCount: String = "" - // var transactionHex: String = "" + var blockchain: Blockchain = Blockchain.Unknown, + var address: String = "", + var explorerLink: String = "", + var host: String = "", + // var outputsCount: String = "" + // var transactionHex: String = "" ) var appVersion: String = "" @@ -179,7 +141,7 @@ class AdditionalEmailInfo { cardFirmwareVersion = card.firmwareVersion.stringValue cardIssuer = card.issuer.name signedHashesCount = card.wallets - .joinToString(";") { "${it.curve?.curve} - ${it.totalSignedHashes}" } + .joinToString(";") { "${it.curve?.curve} - ${it.totalSignedHashes}" } } fun setWalletsInfo(walletManagers: List) { @@ -239,10 +201,18 @@ interface EmailData { fun prepare(infoHolder: AdditionalEmailInfo) {} + fun appendDelimiter(builder: StringBuilder) { + builder.append("----------\n") + } + + fun appendBlankLine(builder: StringBuilder) { + builder.append("\n") + } + fun createOptionalMessage(infoHolder: AdditionalEmailInfo): String fun joinTogether(infoHolder: AdditionalEmailInfo): String { - return "$mainMessage\n\n\n\n\n" + + return "$mainMessage\n\n\n\n" + "Following information is optional. You can erase it if you don’t want to share it.\n" + createOptionalMessage(infoHolder) } @@ -257,6 +227,7 @@ class RateCanBeBetterEmail : EmailData { return StringBuilder().apply { appendKeyValue("Card ID", infoHolder.cardId) appendKeyValue("Blockchain", walletInfo.blockchain.fullName) + appendBlankLine(this) appendKeyValue("Phone model", infoHolder.phoneModel) appendKeyValue("OS version", infoHolder.osVersion) appendKeyValue("App version", infoHolder.appVersion) @@ -269,6 +240,7 @@ class ScanFailsEmail : EmailData { override val mainMessage: String = "Please tell us what card do you have?" override fun createOptionalMessage(infoHolder: AdditionalEmailInfo): String { return StringBuilder().apply { + appendBlankLine(this) appendKeyValue("Phone model", infoHolder.phoneModel) appendKeyValue("OS version", infoHolder.osVersion) appendKeyValue("App version", infoHolder.appVersion) @@ -284,6 +256,7 @@ class SendTransactionFailedEmail(private val error: String) : EmailData { return StringBuilder().apply { appendKeyValue("Error", error) appendKeyValue("Card ID", infoHolder.cardId) + appendDelimiter(this) appendKeyValue("Blockchain", walletInfo.blockchain.fullName) appendKeyValue("Host", walletInfo.host) appendKeyValue("Token", infoHolder.token) @@ -291,6 +264,7 @@ class SendTransactionFailedEmail(private val error: String) : EmailData { appendKeyValue("Destination address", infoHolder.destinationAddress) appendKeyValue("Amount", infoHolder.amount) appendKeyValue("Fee", infoHolder.fee) + appendBlankLine(this) appendKeyValue("Phone model", infoHolder.phoneModel) appendKeyValue("OS version", infoHolder.osVersion) appendKeyValue("App version", infoHolder.appVersion) @@ -326,11 +300,14 @@ class FeedbackEmail : EmailData { builder.appendKeyValue("Signed hashes", infoHolder.signedHashesCount) infoHolder.walletsInfo.forEach { + appendDelimiter(builder) builder.appendKeyValue("Blockchain", it.blockchain.fullName) builder.appendKeyValue("Host", it.host) builder.appendKeyValue("Wallet address", it.address) builder.appendKeyValue("Explorer link", it.explorerLink) } + appendBlankLine(builder) + // appendKeyValue("Outputs count", infoHolder.outputsCount) builder.appendKeyValue("Phone model", infoHolder.phoneModel) builder.appendKeyValue("OS version", infoHolder.osVersion) From 3e99e1f1c81f6a0590ddf3eb6087e1b1f828754a Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 29 Oct 2021 20:56:31 +0300 Subject: [PATCH 05/76] Updated on 2026-08-14 --- app/src/main/res/layout/lp_onboarding_done.xml | 2 +- app/src/main/res/layout/lp_onboarding_done_activation.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/lp_onboarding_done.xml b/app/src/main/res/layout/lp_onboarding_done.xml index af43383cc7..e6f1cb76fa 100644 --- a/app/src/main/res/layout/lp_onboarding_done.xml +++ b/app/src/main/res/layout/lp_onboarding_done.xml @@ -25,7 +25,7 @@ Date: Fri, 29 Oct 2021 21:52:35 +0300 Subject: [PATCH 06/76] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/features/home/HomeFragment.kt | 6 +++++- .../onboarding/products/twins/ui/TwinsCardsFragment.kt | 7 +++++++ app/src/main/res/layout/fragment_onboarding_main.xml | 1 + app/src/main/res/layout/view_bg_home.xml | 5 ++++- app/src/main/res/layout/view_bg_twins_welcome.xml | 3 +++ 5 files changed, 20 insertions(+), 2 deletions(-) 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 0d337c6da9..f28523564f 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 @@ -18,6 +18,7 @@ import com.tangem.wallet.R import kotlinx.android.synthetic.main.fragment_onboarding_main.* import kotlinx.android.synthetic.main.layout_onboarding_container_bottom.* import kotlinx.android.synthetic.main.layout_onboarding_home_top.* +import kotlinx.android.synthetic.main.view_bg_home.* class HomeFragment : BaseOnboardingFragment() { @@ -39,7 +40,10 @@ class HomeFragment : BaseOnboardingFragment() { val shareTransition = FragmentShareTransition( listOf( ShareElement(imv_front_card, ShareElement.imvFrontCard), - ShareElement(imv_back_card, ShareElement.imvBackCard) + ShareElement(imv_back_card, ShareElement.imvBackCard), + ShareElement(bg_circle_large), + ShareElement(bg_circle_medium), + ShareElement(bg_circle_min), ), FrontCardEnterTransition(), FrontCardExitTransition() diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt index 81e11f7e47..a634d311c0 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt @@ -102,6 +102,9 @@ class TwinsCardsFragment : BaseOnboardingFragment() { imv_twin_front_card.transitionName = ShareElement.imvFrontCard imv_twin_back_card.transitionName = ShareElement.imvBackCard + + // if don't this, the bg_circle_... is overflow the app_bar + app_bar.bringToFront() } override fun subscribeToStore() { @@ -158,6 +161,7 @@ class TwinsCardsFragment : BaseOnboardingFragment() { private fun setupWelcomeState(state: TwinCardsState, mainAction: Action) { twinsWidget.toWelcome(false) { startPostponedEnterTransition() } + onboarding_twins_welcome_bg.show() pb_state.hide() tv_header.setText(R.string.twins_onboarding_subtitle) @@ -169,6 +173,8 @@ class TwinsCardsFragment : BaseOnboardingFragment() { private fun setupWarningState(state: TwinCardsState) { twinsWidget.toWelcome(false) { startPostponedEnterTransition() } + + onboarding_twins_welcome_bg.hide() pb_state.hide() chb_understand.show() @@ -186,6 +192,7 @@ class TwinsCardsFragment : BaseOnboardingFragment() { } private fun setupCreateFirstWalletState(state: TwinCardsState) { + onboarding_twins_welcome_bg.hide() bg_circle_large.hide() bg_circle_medium.hide() bg_circle_min.hide() diff --git a/app/src/main/res/layout/fragment_onboarding_main.xml b/app/src/main/res/layout/fragment_onboarding_main.xml index 40df33aeb5..6d567ce91b 100644 --- a/app/src/main/res/layout/fragment_onboarding_main.xml +++ b/app/src/main/res/layout/fragment_onboarding_main.xml @@ -14,6 +14,7 @@ style="@style/Widget.MaterialComponents.Toolbar.Surface" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="@android:color/transparent" android:fitsSystemWindows="false" app:liftOnScroll="true"> diff --git a/app/src/main/res/layout/view_bg_home.xml b/app/src/main/res/layout/view_bg_home.xml index bff701e6c4..4cba83727d 100644 --- a/app/src/main/res/layout/view_bg_home.xml +++ b/app/src/main/res/layout/view_bg_home.xml @@ -9,6 +9,7 @@ android:layout_width="670dp" android:layout_height="670dp" android:src="@drawable/shape_circle_home_screen" + android:transitionName="bg_circle_large" android:translationX="160dp" android:translationY="-175dp" /> @@ -18,14 +19,16 @@ android:layout_height="650dp" android:src="@drawable/shape_circle" android:tint="@color/backgroundWhite" + android:transitionName="bg_circle_medium" android:translationX="170dp" android:translationY="-165dp" /> diff --git a/app/src/main/res/layout/view_bg_twins_welcome.xml b/app/src/main/res/layout/view_bg_twins_welcome.xml index 5202b1851b..acfee09420 100644 --- a/app/src/main/res/layout/view_bg_twins_welcome.xml +++ b/app/src/main/res/layout/view_bg_twins_welcome.xml @@ -12,6 +12,7 @@ android:scaleType="fitXY" android:src="@drawable/shape_circle" android:tint="#DEDEE0" + android:transitionName="bg_circle_large" android:translationX="-272dp" android:translationY="-200dp" app:layout_constraintStart_toStartOf="parent" @@ -25,6 +26,7 @@ android:scaleType="fitXY" android:src="@drawable/shape_circle" android:tint="#DCDCDC" + android:transitionName="bg_circle_medium" android:translationX="-254dp" android:translationY="-269dp" app:layout_constraintStart_toStartOf="parent" @@ -38,6 +40,7 @@ android:scaleType="fitXY" android:src="@drawable/shape_circle" android:tint="#D9D9D9" + android:transitionName="bg_circle_min" android:translationX="-394dp" android:translationY="-411dp" app:layout_constraintStart_toStartOf="parent" From 262223b43d21dfa69841dda7f2188c2da5881aff Mon Sep 17 00:00:00 2001 From: Tangem Date: Sun, 31 Oct 2021 12:06:56 +0300 Subject: [PATCH 07/76] Updated on 2026-08-14 --- .../disclaimer/ui/DisclaimerFragment.kt | 4 +- .../res/drawable/card_placeholder_black.xml | 120 ++++++------------ 2 files changed, 43 insertions(+), 81 deletions(-) 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 index ec7a45dd3d..82f131a3a2 100644 --- 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 @@ -25,8 +25,8 @@ class DisclaimerFragment : Fragment(R.layout.fragment_disclaimer), } }) val inflater = TransitionInflater.from(requireContext()) - enterTransition = inflater.inflateTransition(R.transition.slide_right) - exitTransition = inflater.inflateTransition(R.transition.fade) + enterTransition = inflater.inflateTransition(android.R.transition.slide_bottom) + exitTransition = inflater.inflateTransition(android.R.transition.slide_top) } override fun onStart() { diff --git a/app/src/main/res/drawable/card_placeholder_black.xml b/app/src/main/res/drawable/card_placeholder_black.xml index 0fef87ee39..83fab8e0f7 100644 --- a/app/src/main/res/drawable/card_placeholder_black.xml +++ b/app/src/main/res/drawable/card_placeholder_black.xml @@ -1,126 +1,88 @@ - - - - - - - - - + android:width="214dp" + android:height="130dp" + android:viewportWidth="214" + android:viewportHeight="130"> + android:pathData="M1.043,8.273C1.019,4.256 4.265,1 8.294,1H205.706C209.735,1 213.019,4.256 213.043,8.273L213.709,121.725C213.733,125.742 210.487,128.998 206.459,128.998H9.046C5.018,128.998 1.733,125.742 1.709,121.725L1.043,8.273Z" /> - - - - - - - + android:pathData="M1.043,8.273C1.019,4.256 4.265,1 8.294,1H205.706C209.735,1 213.019,4.256 213.043,8.273L213.709,121.725C213.733,125.742 210.487,128.998 206.459,128.998H9.046C5.018,128.998 1.733,125.742 1.709,121.725L1.043,8.273Z" + android:strokeWidth="0.5" /> + android:pathData="M25.274,26.4L25.274,32.64L28.079,32.64C28.188,32.639 28.292,32.596 28.369,32.522C28.446,32.447 28.49,32.346 28.491,32.241L28.491,26.4L25.274,26.4Z" /> + android:pathData="M19,32.241C19.001,32.346 19.045,32.447 19.122,32.522C19.199,32.596 19.303,32.639 19.412,32.64L22.217,32.64L22.217,26.4L19,26.4L19,32.241Z" /> + android:pathData="M28.491,23.2L28.491,20.409C28.491,20.301 28.448,20.197 28.372,20.12C28.296,20.043 28.194,20 28.086,20L19.405,20C19.297,20 19.195,20.043 19.119,20.12C19.043,20.197 19,20.301 19,20.409L19,23.2L28.491,23.2Z" /> + android:pathData="M43.503,24.163C42.922,23.921 42.292,23.812 41.661,23.846C40.827,23.844 39.996,23.934 39.183,24.113L39.183,25.532C39.832,25.455 40.483,25.412 41.136,25.4C41.486,25.385 41.836,25.418 42.177,25.5C42.286,25.532 42.385,25.59 42.465,25.669C42.546,25.748 42.605,25.846 42.637,25.953C42.74,26.334 42.783,26.728 42.766,27.122L42.766,27.539C41.997,27.498 41.385,27.476 40.965,27.476C40.519,27.454 40.073,27.539 39.667,27.725C39.347,27.903 39.109,28.195 38.999,28.54C38.847,29.044 38.779,29.569 38.796,30.094C38.74,30.771 38.901,31.448 39.257,32.029C39.445,32.243 39.683,32.409 39.95,32.513C40.216,32.618 40.505,32.659 40.791,32.632C41.127,32.632 42.172,32.605 42.633,32.007C42.709,31.912 42.774,31.808 42.826,31.698L42.877,32.496L44.572,32.496L44.572,27.222C44.596,26.539 44.52,25.857 44.346,25.196C44.284,24.977 44.178,24.772 44.033,24.594C43.888,24.417 43.708,24.27 43.503,24.163ZM42.748,29.256C42.796,29.736 42.713,30.219 42.508,30.656C42.409,30.782 42.272,30.876 42.117,30.924C41.942,30.972 41.76,30.995 41.578,30.992C41.294,31.028 41.006,30.953 40.777,30.783C40.623,30.523 40.558,30.221 40.592,29.922C40.582,29.681 40.607,29.44 40.666,29.206C40.684,29.139 40.716,29.075 40.761,29.021C40.805,28.966 40.861,28.921 40.924,28.889C41.098,28.821 41.285,28.791 41.472,28.803L42.748,28.803L42.748,29.256Z" /> + android:pathData="M58.169,24.645C58.133,24.584 58.095,24.526 58.053,24.471C57.494,23.736 56.162,23.846 56.162,23.846C55.722,23.831 55.29,23.964 54.929,24.222C54.564,24.573 54.329,25.042 54.263,25.55C54.001,27.328 54.001,29.136 54.263,30.914C54.326,31.417 54.555,31.882 54.911,32.233C55.299,32.52 55.774,32.659 56.251,32.623C56.251,32.623 56.278,32.623 56.296,32.623C56.296,32.623 57.498,32.72 58.084,32.104C58.095,32.607 58.062,33.11 57.985,33.606C57.966,33.738 57.915,33.864 57.837,33.971C57.759,34.078 57.656,34.164 57.539,34.222C57.166,34.351 56.773,34.406 56.381,34.382L54.535,34.35L54.535,35.788C54.876,35.853 55.219,35.9 55.563,35.93C55.988,35.972 56.39,35.99 56.774,35.99C57.49,36.044 58.205,35.884 58.834,35.53C59.055,35.374 59.242,35.174 59.386,34.943C59.529,34.71 59.626,34.451 59.67,34.18C59.813,33.297 59.875,32.402 59.853,31.507L59.853,23.979L58.209,23.979L58.169,24.645ZM57.963,30.221C57.936,30.452 57.824,30.664 57.65,30.813C57.447,30.94 57.212,30.999 56.975,30.983C56.711,31.006 56.446,30.95 56.211,30.823C56.028,30.636 55.923,30.385 55.916,30.12C55.815,28.876 55.815,27.625 55.916,26.381C55.923,26.125 56.025,25.882 56.202,25.701C56.442,25.579 56.709,25.526 56.975,25.55C57.227,25.529 57.479,25.599 57.686,25.747C57.87,25.947 57.981,26.207 57.999,26.482C58.066,27.072 58.093,27.666 58.079,28.26C58.101,28.916 58.062,29.573 57.963,30.221Z" /> + android:pathData="M66.713,24.124C66.131,23.787 65.461,23.636 64.793,23.691C64.098,23.642 63.404,23.802 62.799,24.152C62.358,24.473 62.062,24.959 61.975,25.502C61.831,26.388 61.77,27.286 61.793,28.184C61.769,29.083 61.833,29.983 61.984,30.87C62.031,31.139 62.131,31.395 62.278,31.623C62.425,31.851 62.616,32.046 62.84,32.197C63.478,32.531 64.194,32.681 64.911,32.631C65.367,32.63 65.823,32.603 66.276,32.552C66.653,32.517 67.025,32.453 67.392,32.359L67.392,30.916C66.554,31.004 65.867,31.05 65.33,31.05C64.933,31.074 64.535,31.025 64.155,30.907C64.038,30.857 63.936,30.778 63.856,30.677C63.777,30.577 63.723,30.458 63.7,30.331C63.618,29.823 63.585,29.307 63.6,28.792L67.574,28.792L67.574,28.165C67.596,27.241 67.548,26.317 67.433,25.4C67.368,24.896 67.109,24.438 66.713,24.124ZM65.849,27.428L63.6,27.428C63.6,26.95 63.632,26.473 63.696,26C63.704,25.887 63.736,25.777 63.79,25.678C63.843,25.579 63.917,25.492 64.005,25.424C64.473,25.233 64.994,25.233 65.462,25.424C65.548,25.494 65.619,25.583 65.671,25.683C65.723,25.782 65.754,25.892 65.762,26.004C65.833,26.475 65.862,26.952 65.849,27.428Z" /> + android:pathData="M78.824,25.12C78.747,24.744 78.542,24.406 78.243,24.161C77.886,23.928 77.46,23.817 77.032,23.844C77.032,23.844 76.991,23.844 76.963,23.844C76.963,23.844 75.581,23.767 75.01,24.464C74.948,24.542 74.892,24.625 74.844,24.712C74.752,24.478 74.592,24.275 74.383,24.129C74.024,23.923 73.61,23.826 73.195,23.848C73.195,23.848 71.813,23.767 71.242,24.468C71.178,24.545 71.122,24.629 71.076,24.717L71.03,23.984L69.349,23.984L69.349,32.48L71.191,32.48L71.191,28.051C71.182,27.52 71.201,26.988 71.251,26.459C71.263,26.198 71.362,25.949 71.532,25.749C71.736,25.584 71.997,25.506 72.26,25.531C72.493,25.513 72.727,25.557 72.937,25.658C73.015,25.731 73.076,25.819 73.119,25.916C73.162,26.013 73.185,26.118 73.186,26.223C73.234,26.747 73.254,27.272 73.245,27.798L73.245,32.48L75.088,32.48L75.088,28.051C75.088,27.314 75.088,26.785 75.143,26.459C75.156,26.197 75.258,25.946 75.434,25.749C75.642,25.586 75.906,25.508 76.171,25.531C76.405,25.513 76.641,25.557 76.852,25.658C76.929,25.732 76.99,25.82 77.032,25.917C77.074,26.014 77.096,26.118 77.096,26.223C77.147,26.747 77.167,27.272 77.156,27.798L77.156,32.48L78.999,32.48L78.999,26.884C79.009,26.291 78.951,25.699 78.824,25.12Z" /> + android:pathData="M51.691,24.171C51.307,23.928 50.851,23.814 50.394,23.845C50.394,23.845 50.356,23.845 50.338,23.845C50.338,23.845 48.938,23.773 48.364,24.465C48.323,24.514 48.286,24.565 48.252,24.619L48.21,23.981L46.507,23.981L46.507,32.48L48.373,32.48L48.373,28.049C48.363,27.521 48.384,26.992 48.434,26.465C48.448,26.203 48.553,25.952 48.733,25.755C48.958,25.584 49.242,25.503 49.526,25.528C49.774,25.511 50.023,25.555 50.249,25.655C50.333,25.728 50.401,25.816 50.448,25.915C50.496,26.014 50.521,26.121 50.524,26.23C50.578,26.75 50.6,27.273 50.59,27.796L50.59,32.48L52.456,32.48L52.456,26.963C52.471,26.356 52.419,25.749 52.302,25.153C52.226,24.765 52.009,24.417 51.691,24.171Z" /> + android:pathData="M36.543,21.44L34.653,21.44L34.653,23.877L33.477,23.877L33.477,25.434L34.653,25.434L34.653,32.48L36.543,32.48L36.543,25.434L37.981,25.434L37.981,23.877L36.543,23.877L36.543,21.44Z" /> + android:pathData="M23.463,105.118L21.826,104.112L21.904,106H21.024L21.087,104.112L19.441,105.125L19.02,104.335L20.707,103.493L19.016,102.645L19.428,101.882L21.08,102.875L21.001,101H21.874L21.818,102.882L23.451,101.882L23.885,102.645L22.184,103.5L23.895,104.342L23.463,105.118Z" /> + android:pathData="M32.161,105.118L30.524,104.112L30.602,106H29.722L29.785,104.112L28.139,105.125L27.718,104.335L29.405,103.493L27.715,102.645L28.126,101.882L29.778,102.875L29.699,101H30.573L30.517,102.882L32.149,101.882L32.583,102.645L30.883,103.5L32.593,104.342L32.161,105.118Z" /> + android:pathData="M40.86,105.118L39.222,104.112L39.3,106H38.42L38.483,104.112L36.837,105.125L36.416,104.335L38.104,103.493L36.413,102.645L36.825,101.882L38.476,102.875L38.398,101H39.271L39.215,102.882L40.847,101.882L41.282,102.645L39.581,103.5L41.292,104.342L40.86,105.118Z" /> + android:pathData="M49.558,105.118L47.92,104.112L47.998,106H47.119L47.181,104.112L45.535,105.125L45.114,104.335L46.802,103.493L45.111,102.645L45.523,101.882L47.174,102.875L47.096,101H47.969L47.913,102.882L49.546,101.882L49.98,102.645L48.279,103.5L49.99,104.342L49.558,105.118Z" /> + android:pathData="M63.14,105.118L61.502,104.112L61.58,106H60.701L60.763,104.112L59.117,105.125L58.696,104.335L60.384,103.493L58.693,102.645L59.105,101.882L60.756,102.875L60.678,101H61.551L61.495,102.882L63.128,101.882L63.562,102.645L61.861,103.5L63.572,104.342L63.14,105.118Z" /> + android:pathData="M71.838,105.118L70.2,104.112L70.279,106H69.399L69.462,104.112L67.815,105.125L67.394,104.335L69.082,103.493L67.391,102.645L67.803,101.882L69.454,102.875L69.376,101H70.249L70.193,102.882L71.826,101.882L72.26,102.645L70.559,103.5L72.27,104.342L71.838,105.118Z" /> + android:pathData="M80.536,105.118L78.898,104.112L78.977,106H78.097L78.16,104.112L76.514,105.125L76.093,104.335L77.78,103.493L76.089,102.645L76.501,101.882L78.152,102.875L78.074,101H78.947L78.891,102.882L80.524,101.882L80.958,102.645L79.257,103.5L80.968,104.342L80.536,105.118Z" /> + android:fillColor="#A5A5A5" + android:pathData="M89.234,105.118L87.597,104.112L87.675,106H86.795L86.858,104.112L85.212,105.125L84.791,104.335L86.478,103.493L84.788,102.645L85.2,101.882L86.851,102.875L86.772,101H87.646L87.59,102.882L89.222,101.882L89.657,102.645L87.956,103.5L89.666,104.342L89.234,105.118Z" /> + android:fillColor="#A5A5A5" + android:pathData="M102.816,105.118L101.179,104.112L101.257,106H100.377L100.44,104.112L98.794,105.125L98.373,104.335L100.06,103.493L98.369,102.645L98.781,101.882L100.433,102.875L100.354,101H101.227L101.171,102.882L102.804,101.882L103.238,102.645L101.538,103.5L103.248,104.342L102.816,105.118Z" /> + android:fillColor="#A5A5A5" + android:pathData="M111.515,105.118L109.877,104.112L109.955,106H109.075L109.138,104.112L107.492,105.125L107.071,104.335L108.758,103.493L107.068,102.645L107.48,101.882L109.131,102.875L109.053,101H109.926L109.87,102.882L111.502,101.882L111.937,102.645L110.236,103.5L111.947,104.342L111.515,105.118Z" /> + android:fillColor="#A5A5A5" + android:pathData="M120.213,105.118L118.575,104.112L118.653,106H117.774L117.836,104.112L116.19,105.125L115.769,104.335L117.457,103.493L115.766,102.645L116.178,101.882L117.829,102.875L117.751,101H118.624L118.568,102.882L120.201,101.882L120.635,102.645L118.934,103.5L120.645,104.342L120.213,105.118Z" /> + android:fillColor="#A5A5A5" + android:pathData="M128.911,105.118L127.273,104.112L127.352,106H126.472L126.535,104.112L124.888,105.125L124.467,104.335L126.155,103.493L124.464,102.645L124.876,101.882L126.527,102.875L126.449,101H127.322L127.266,102.882L128.899,101.882L129.333,102.645L127.632,103.5L129.343,104.342L128.911,105.118Z" /> + android:fillColor="#A5A5A5" + android:pathData="M142.493,105.118L140.855,104.112L140.933,106H140.054L140.116,104.112L138.47,105.125L138.049,104.335L139.737,103.493L138.046,102.645L138.458,101.882L140.109,102.875L140.031,101H140.904L140.848,102.882L142.481,101.882L142.915,102.645L141.214,103.5L142.925,104.342L142.493,105.118Z" /> + android:fillColor="#A5A5A5" + android:pathData="M151.191,105.118L149.553,104.112L149.632,106H148.752L148.815,104.112L147.169,105.125L146.748,104.335L148.435,103.493L146.744,102.645L147.156,101.882L148.807,102.875L148.729,101H149.602L149.546,102.882L151.179,101.882L151.613,102.645L149.912,103.5L151.623,104.342L151.191,105.118Z" /> + android:fillColor="#A5A5A5" + android:pathData="M159.889,105.118L158.252,104.112L158.33,106H157.45L157.513,104.112L155.867,105.125L155.446,104.335L157.133,103.493L155.443,102.645L155.854,101.882L157.506,102.875L157.427,101H158.3L158.244,102.882L159.877,101.882L160.311,102.645L158.611,103.5L160.321,104.342L159.889,105.118Z" /> + android:fillColor="#A5A5A5" + android:pathData="M168.588,105.118L166.95,104.112L167.028,106H166.148L166.211,104.112L164.565,105.125L164.144,104.335L165.831,103.493L164.141,102.645L164.553,101.882L166.204,102.875L166.126,101H166.999L166.943,102.882L168.575,101.882L169.01,102.645L167.309,103.5L169.02,104.342L168.588,105.118Z" /> From 8d048abd51203ef99619395bd7bc48cd4d314d4e Mon Sep 17 00:00:00 2001 From: Tangem Date: Sun, 31 Oct 2021 17:38:30 +0300 Subject: [PATCH 08/76] Updated on 2026-08-14 --- .../products/note/OnboardingNoteFragment.kt | 25 +++++++++----- .../note/redux/OnboardingNoteState.kt | 6 ++++ .../products/twins/redux/TwinCardsState.kt | 6 ++++ .../products/twins/ui/TwinsCardsFragment.kt | 33 +++++++++++-------- .../main/res/values/strings_untranslated.xml | 3 ++ 5 files changed, 51 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt index e0661b0359..644bf15d51 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt @@ -137,15 +137,24 @@ class OnboardingNoteFragment : BaseOnboardingFragment() { } private fun setupTopUpWalletState(state: OnboardingNoteState) { - btn_main_action.setText(R.string.onboarding_top_up_button_but_crypto) - btn_main_action.setOnClickListener { - store.dispatch(OnboardingNoteAction.TopUp) - } + if (state.isBuyAllowed) { + btn_main_action.setText(R.string.onboarding_top_up_button_but_crypto) + btn_main_action.setOnClickListener { + store.dispatch(OnboardingNoteAction.TopUp) + } - btn_alternative_action.isVisible = true - btn_alternative_action.setText(R.string.onboarding_top_up_button_show_wallet_address) - btn_alternative_action.setOnClickListener { - store.dispatch(OnboardingNoteAction.ShowAddressInfoDialog) + btn_alternative_action.isVisible = true + btn_alternative_action.setText(R.string.onboarding_top_up_button_show_wallet_address) + btn_alternative_action.setOnClickListener { + store.dispatch(OnboardingNoteAction.ShowAddressInfoDialog) + } + } else { + btn_main_action.setText(R.string.onboarding_button_receive_crypto) + btn_main_action.setOnClickListener { + store.dispatch(OnboardingNoteAction.ShowAddressInfoDialog) + } + + btn_alternative_action.isVisible = false } tv_header.setText(R.string.onboarding_top_up_header) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteState.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteState.kt index 5bc772fa3a..5178c2eb72 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteState.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteState.kt @@ -3,7 +3,9 @@ package com.tangem.tap.features.onboarding.products.note.redux import com.tangem.blockchain.common.WalletManager import com.tangem.tap.domain.TapError import com.tangem.tap.features.onboarding.OnboardingWalletBalance +import com.tangem.tap.store import org.rekotlin.StateType +import kotlin.properties.ReadOnlyProperty /** [REDACTED_AUTHOR] @@ -22,6 +24,10 @@ data class OnboardingNoteState( val progress: Int get() = steps.indexOf(currentStep) + + val isBuyAllowed: Boolean by ReadOnlyProperty { thisRef, property -> + store.state.globalState.moonPayUserStatus?.isBuyAllowed ?: false + } } enum class OnboardingNoteStep { diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt index 22834a920e..7e8cea4f57 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt @@ -5,7 +5,9 @@ import com.tangem.tap.domain.TapError import com.tangem.tap.domain.twins.TwinCardNumber import com.tangem.tap.domain.twins.TwinCardsManager import com.tangem.tap.features.onboarding.OnboardingWalletBalance +import com.tangem.tap.store import org.rekotlin.StateType +import kotlin.properties.ReadOnlyProperty /** [REDACTED_AUTHOR] @@ -52,6 +54,10 @@ data class TwinCardsState( val showAlert: Boolean get() = currentStep == TwinCardsStep.CreateSecondWallet || currentStep == TwinCardsStep.CreateThirdWallet + + val isBuyAllowed: Boolean by ReadOnlyProperty { thisRef, property -> + store.state.globalState.moonPayUserStatus?.isBuyAllowed ?: false + } } enum class CreateTwinWalletMode { CreateWallet, RecreateWallet } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt index a634d311c0..140211ceb8 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt @@ -14,7 +14,6 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.common.extensions.VoidCallback import com.tangem.tap.common.extensions.* import com.tangem.tap.common.leapfrogWidget.LeapfrogWidget -import com.tangem.tap.common.postUi import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.common.redux.navigation.ShareElement @@ -290,15 +289,24 @@ class TwinsCardsFragment : BaseOnboardingFragment() { } } - btn_main_action.setText(R.string.onboarding_top_up_button_but_crypto) - btn_main_action.setOnClickListener { - store.dispatch(TwinCardsAction.TopUp) - } + if (state.isBuyAllowed) { + btn_main_action.setText(R.string.onboarding_top_up_button_but_crypto) + btn_main_action.setOnClickListener { + store.dispatch(TwinCardsAction.TopUp) + } - btn_alternative_action.isVisible = true - btn_alternative_action.setText(R.string.onboarding_top_up_button_show_wallet_address) - btn_alternative_action.setOnClickListener { - store.dispatch(TwinCardsAction.ShowAddressInfoDialog) + btn_alternative_action.isVisible = true + btn_alternative_action.setText(R.string.onboarding_top_up_button_show_wallet_address) + btn_alternative_action.setOnClickListener { + store.dispatch(TwinCardsAction.ShowAddressInfoDialog) + } + } else { + btn_main_action.setText(R.string.onboarding_button_receive_crypto) + btn_main_action.setOnClickListener { + store.dispatch(TwinCardsAction.ShowAddressInfoDialog) + } + + btn_alternative_action.isVisible = false } tv_header.setText(R.string.onboarding_top_up_header) @@ -306,13 +314,10 @@ class TwinsCardsFragment : BaseOnboardingFragment() { btnRefreshBalanceWidget.changeState(state.walletBalance.state) if (btnRefreshBalanceWidget.isShowing != true) { - postUi(300) { - btnRefreshBalanceWidget.mainView.setOnClickListener { - store.dispatch(TwinCardsAction.Balance.Update) - } + btnRefreshBalanceWidget.mainView.setOnClickListener { + store.dispatch(TwinCardsAction.Balance.Update) } } - imv_card_background.setBackgroundDrawable(requireContext().getDrawableCompat(R.drawable.shape_rectangle_rounded_8)) updateConstraints(state.currentStep, R.layout.lp_onboarding_topup_wallet_twins) } diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index e0a8e57348..5e515d4049 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -176,6 +176,8 @@ Activating card How it works? + Receive crypto + Create a wallet Let’s generate all the keys on your card and create a secure wallet Create wallet @@ -195,6 +197,7 @@ If the process of re-creating the wallet gets interrupted in any way, you’ll have to start over. Internal error: can\'t create wallet manager + Blockchain is unreachable. Try later From 4674a83d0b32efb43c1edbaab5f6300139bf4b76 Mon Sep 17 00:00:00 2001 From: Tangem Date: Sun, 31 Oct 2021 18:05:04 +0300 Subject: [PATCH 09/76] Updated on 2026-08-14 --- app/src/main/res/values/strings_untranslated.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index 5e515d4049..f189ef8196 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -193,6 +193,8 @@ Your crypto card is activated and ready to be used Continue Balance + Send only %s (%s) to this address. Sending any other currency will result in its irreversible loss. + Send only %s (%s) from %@snetwork to this address. Sending any other currency will result in its irreversible loss. If the process of re-creating the wallet gets interrupted in any way, you’ll have to start over. From dbcb1b57753c8b3f6e93a776e4a8fb9560560990 Mon Sep 17 00:00:00 2001 From: Tangem Date: Sun, 31 Oct 2021 21:17:08 +0300 Subject: [PATCH 10/76] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/domain/extensions/Blockchain.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/tangem/tap/domain/extensions/Blockchain.kt b/app/src/main/java/com/tangem/tap/domain/extensions/Blockchain.kt index 4be4dda58f..5ec3ea7672 100644 --- a/app/src/main/java/com/tangem/tap/domain/extensions/Blockchain.kt +++ b/app/src/main/java/com/tangem/tap/domain/extensions/Blockchain.kt @@ -15,7 +15,7 @@ fun Blockchain.isNoAccountError(exception: Throwable): Boolean { fun Blockchain.amountToCreateAccount(token: Token? = null): BigDecimal? { return when (this) { - Blockchain.Stellar -> if (token?.symbol == NODL) BigDecimal(1.5) else BigDecimal.ZERO + Blockchain.Stellar -> if (token?.symbol == NODL) BigDecimal(1.5) else BigDecimal.ONE Blockchain.XRP -> BigDecimal(10) else -> null } From 96f039595809d4208a117e04c84dc54400c90e59 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 1 Nov 2021 01:08:28 +0300 Subject: [PATCH 11/76] Updated on 2026-08-14 --- .../products/twins/redux/TwinCardsMiddleware.kt | 11 ++++++++++- .../products/twins/ui/TwinsCardsFragment.kt | 12 +++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt index fc245c3db4..761fee04ea 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt @@ -178,7 +178,16 @@ private fun handle(action: Action, dispatch: DispatchFunction) { is Result.Success -> { updateScanResponse(result.data) delay(DELAY_SDK_DIALOG_CLOSE) - withMainContext { store.dispatch(TwinCardsAction.SetStepOfScreen(TwinCardsStep.TopUpWallet)) } + withMainContext { + when (twinCardsState.mode) { + CreateTwinWalletMode.CreateWallet -> { + store.dispatch(TwinCardsAction.SetStepOfScreen(TwinCardsStep.TopUpWallet)) + } + CreateTwinWalletMode.RecreateWallet -> { + store.dispatch(TwinCardsAction.SetStepOfScreen(TwinCardsStep.Done)) + } + } + } } is Result.Failure -> { } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt index 140211ceb8..d0ba56eeb5 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt @@ -37,7 +37,6 @@ import kotlinx.android.synthetic.main.layout_onboarding_container_top.* import kotlinx.android.synthetic.main.view_bg_twins_welcome.* import kotlinx.android.synthetic.main.view_onboarding_progress.* import kotlinx.android.synthetic.main.view_onboarding_tv_balance.* -import org.rekotlin.Action class TwinsCardsFragment : BaseOnboardingFragment() { @@ -150,14 +149,17 @@ class TwinsCardsFragment : BaseOnboardingFragment() { } private fun setupWelcomeOnlyState(state: TwinCardsState) { - setupWelcomeState(state, NavigationAction.NavigateTo(AppScreen.Wallet)) + setupWelcomeState(state) { + store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet)) + store.dispatch(TwinCardsAction.SetStepOfScreen(TwinCardsStep.None)) + } } private fun setupWelcomeState(state: TwinCardsState) { - setupWelcomeState(state, TwinCardsAction.SetStepOfScreen(TwinCardsStep.CreateFirstWallet)) + setupWelcomeState(state) { store.dispatch(TwinCardsAction.SetStepOfScreen(TwinCardsStep.CreateFirstWallet)) } } - private fun setupWelcomeState(state: TwinCardsState, mainAction: Action) { + private fun setupWelcomeState(state: TwinCardsState, mainAction: VoidCallback) { twinsWidget.toWelcome(false) { startPostponedEnterTransition() } onboarding_twins_welcome_bg.show() @@ -167,7 +169,7 @@ class TwinsCardsFragment : BaseOnboardingFragment() { tv_body.text = getString(R.string.twins_onboarding_description_format, state.cardNumber?.pairIndexNumber()) btn_main_action.setText(R.string.common_continue) - btn_main_action.setOnClickListener { store.dispatch(mainAction) } + btn_main_action.setOnClickListener { mainAction() } } private fun setupWarningState(state: TwinCardsState) { From e51220365e969efd0bdc41c96e6bdf788477349f Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 1 Nov 2021 15:08:51 +0300 Subject: [PATCH 12/76] Updated on 2026-08-14 --- app/build.gradle | 5 ++--- app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0b53a8df5e..bdc8173275 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,14 +71,13 @@ dependencies { implementation 'androidx.fragment:fragment-ktx:1.3.6' implementation 'androidx.constraintlayout:constraintlayout:2.1.1' implementation 'com.google.android.material:material:1.4.0' - implementation "androidx.core:core-ktx:1.6.0" implementation 'com.google.android.play:core:1.10.2' implementation 'com.google.android.play:core-ktx:1.8.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' implementation 'com.tangem:blockchain:develop-42' - implementation 'com.tangem.tangem-sdk-kotlin:core:develop-91' - implementation 'com.tangem.tangem-sdk-kotlin:android:develop-91' + implementation 'com.tangem.tangem-sdk-kotlin:core:develop-92' + implementation 'com.tangem.tangem-sdk-kotlin:android:develop-92' // WebView implementation "androidx.browser:browser:1.3.0" 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 3a3acc1a87..27776c28b7 100644 --- a/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt @@ -125,6 +125,7 @@ class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Co companion object { val config = Config( + allowUntrustedCards = true, filter = CardFilter( allowedCardTypes = FirmwareVersion.FirmwareType.values().toList() ) From bc00c1f06c8173fc3cdcec4a59822244e96fd92c Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 2 Nov 2021 18:45:37 +0300 Subject: [PATCH 13/76] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/common/extensions/Store.kt | 4 ++-- .../tap/features/wallet/redux/middlewares/WalletMiddleware.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Store.kt b/app/src/main/java/com/tangem/tap/common/extensions/Store.kt index 17db11e102..50087bbf93 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Store.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Store.kt @@ -18,8 +18,8 @@ fun Store<*>.dispatchOnMain(action: Action) { } } -suspend fun Store<*>.onCardScanned(scanResponse: ScanResponse) { - store.state.globalState.tapWalletManager.onCardScanned(scanResponse) +suspend fun Store<*>.onCardScanned(scanResponse: ScanResponse, addAnalytics: Boolean = true) { + store.state.globalState.tapWalletManager.onCardScanned(scanResponse, addAnalytics) } fun Store<*>.dispatchOpenUrl(url: String) { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index 9ec6e10f13..376a38136b 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -101,7 +101,7 @@ class WalletMiddleware { when (result) { is CompletionResult.Success -> { val scanNoteResponse = globalState.scanResponse?.copy(card = result.data) - scanNoteResponse?.let { store.onCardScanned(scanNoteResponse) } + scanNoteResponse?.let { store.onCardScanned(scanNoteResponse, false) } } is CompletionResult.Failure -> { (result.error as? TangemSdkError)?.let { error -> From 26b07ae924de32a75a84deeacd18778c8360f7c1 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 2 Nov 2021 19:11:42 +0300 Subject: [PATCH 14/76] Updated on 2026-08-14 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index bdc8173275..d08be40ffd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -75,7 +75,7 @@ dependencies { implementation 'com.google.android.play:core-ktx:1.8.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - implementation 'com.tangem:blockchain:develop-42' + implementation 'com.tangem:blockchain:develop-43' implementation 'com.tangem.tangem-sdk-kotlin:core:develop-92' implementation 'com.tangem.tangem-sdk-kotlin:android:develop-92' From 87638025cf6a12ff127e80f4594aeb5c4c3f96c9 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 2 Nov 2021 23:39:24 +0300 Subject: [PATCH 15/76] Updated on 2026-08-14 --- .../tap/features/send/redux/middlewares/AmountMiddleware.kt | 4 ++-- .../features/send/redux/middlewares/RequestFeeMiddleware.kt | 4 ++-- .../tap/features/send/redux/middlewares/SendMiddleware.kt | 2 +- .../com/tangem/tap/features/send/redux/reducers/FeeReducer.kt | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt index dcf3bf5a43..3d59d0a270 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt @@ -68,9 +68,9 @@ class AmountMiddleware { } else { val amountErrors = extractErrorsForAmountField(transactionErrors) if (amountErrors.isNotEmpty()) { + transactionErrors.removeAll(amountErrors) dispatch(AmountAction.SetAmountError(createValidateTransactionError(amountErrors, walletManager))) } - transactionErrors.removeAll(amountErrors) if (transactionErrors.isNotEmpty()) { dispatch(SendAction.SendError(createValidateTransactionError(transactionErrors, walletManager))) } @@ -84,7 +84,7 @@ class AmountMiddleware { dispatch(AmountAction.SetAmount(sendState.amountState.balanceCrypto, false)) if (sendState.amountState.isCoinAmount()) { - dispatch(FeeAction.ChangeLayoutVisibility(main = true, controls = true, chipGroup = true)) + dispatch(FeeAction.ChangeLayoutVisibility(main = true, controls = true)) dispatch(FeeActionUi.ChangeIncludeFee(true)) } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/RequestFeeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/RequestFeeMiddleware.kt index b2523e9e7a..04d5b420d5 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/RequestFeeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/RequestFeeMiddleware.kt @@ -29,7 +29,7 @@ class RequestFeeMiddleware { if (!SendState.isReadyToRequestFee()) { dispatch(FeeAction.FeeCalculation.SetFeeError(FeeAction.Error.ADDRESS_OR_AMOUNT_IS_EMPTY)) - dispatch(FeeAction.ChangeLayoutVisibility(main = false, chipGroup = true)) +// dispatch(FeeAction.ChangeLayoutVisibility(main = false, chipGroup = true)) dispatch(ReceiptAction.RefreshReceipt) dispatch(SendAction.ChangeSendButtonState(sendState.getButtonState())) return @@ -60,7 +60,7 @@ class RequestFeeMiddleware { } is Result.Failure -> { dispatch(FeeAction.FeeCalculation.SetFeeError(FeeAction.Error.REQUEST_FAILED)) - dispatch(FeeAction.ChangeLayoutVisibility(main = false, controls = false, chipGroup = false)) + dispatch(FeeAction.ChangeLayoutVisibility(main = false)) } } dispatch(AmountActionUi.CheckAmountToSend) diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt index 26d2f8dd27..5f3e43fd59 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt @@ -254,7 +254,7 @@ fun extractErrorsForAmountField(errors: EnumSet): EnumSet { - val notAcceptable = listOf(TransactionError.FeeExceedsBalance, TransactionError.FeeExceedsBalance) + val notAcceptable = listOf(TransactionError.AmountExceedsBalance, TransactionError.FeeExceedsBalance) if (!showIntoAmountField.containsAll(notAcceptable)) showIntoAmountField.add(it) } TransactionError.InvalidAmountValue -> showIntoAmountField.add(it) diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/FeeReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/FeeReducer.kt index f5da58ab54..d0a1a13072 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/FeeReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/FeeReducer.kt @@ -45,7 +45,7 @@ class FeeReducer : SendInternalReducer { state.copy( mainLayoutIsVisible = getVisibility(state.mainLayoutIsVisible, action.main), controlsLayoutIsVisible = getVisibility(state.controlsLayoutIsVisible, action.controls), - feeChipGroupIsVisible = getVisibility(state.mainLayoutIsVisible, action.chipGroup) + feeChipGroupIsVisible = getVisibility(state.feeChipGroupIsVisible, action.chipGroup) ) } is FeeAction.FeeCalculation.SetFeeResult -> { From 8dd2e578b4f9c92633e9a478da8c4662f8df5218 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 3 Nov 2021 10:24:09 +0300 Subject: [PATCH 16/76] Updated on 2026-08-14 --- .../com/tangem/tap/domain/TapWalletManager.kt | 8 +-- .../tap/domain/tokens/CurrenciesRepository.kt | 50 +++++++++---------- .../features/tokens/redux/TokensReducer.kt | 4 +- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 14f7b50b6b..7c2ec7f173 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -157,22 +157,22 @@ class TapWalletManager { private fun loadMultiWalletData( card: Card, primaryBlockchain: Blockchain?, primaryWalletManager: WalletManager? ) { - val primaryTokens = primaryWalletManager?.cardTokens ?: emptySet() + val primaryTokens = primaryWalletManager?.cardTokens?.toList() ?: emptyList() val savedCurrencies = currenciesRepository.loadCardCurrencies(card.cardId) if (savedCurrencies == null) { if (primaryBlockchain != null && primaryWalletManager != null) { store.dispatch(WalletAction.MultiWallet.SaveCurrencies( CardCurrencies( - blockchains = setOf(primaryBlockchain), tokens = primaryTokens + blockchains = listOf(primaryBlockchain), tokens = primaryTokens ))) store.dispatch(WalletAction.MultiWallet.AddWalletManagers(primaryWalletManager)) store.dispatch(WalletAction.MultiWallet.AddBlockchains(listOf(primaryBlockchain))) store.dispatch(WalletAction.MultiWallet.AddTokens(primaryTokens.toList())) } else { - val blockchains = setOf(Blockchain.Bitcoin, Blockchain.Ethereum) + val blockchains = listOf(Blockchain.Bitcoin, Blockchain.Ethereum) store.dispatch(WalletAction.MultiWallet.SaveCurrencies( - CardCurrencies(blockchains = blockchains, tokens = emptySet()) + CardCurrencies(blockchains = blockchains, tokens = emptyList()) )) val walletManagers = walletManagerFactory.makeWalletManagersForApp(card, blockchains.toList()) diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt b/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt index 26aa55369c..18ea01ebbc 100644 --- a/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/tokens/CurrenciesRepository.kt @@ -14,14 +14,14 @@ import com.tangem.tap.network.createMoshi class CurrenciesRepository(val context: Application) { private val moshi = createMoshi() - private val blockchainsAdapter: JsonAdapter> = moshi.adapter( - Types.newParameterizedType(Set::class.java, Blockchain::class.java) + private val blockchainsAdapter: JsonAdapter> = moshi.adapter( + Types.newParameterizedType(List::class.java, Blockchain::class.java) ) - private val tokensAdapter: JsonAdapter> = moshi.adapter( - Types.newParameterizedType(Set::class.java, TokenDao::class.java) + private val tokensAdapter: JsonAdapter> = moshi.adapter( + Types.newParameterizedType(List::class.java, TokenDao::class.java) ) - private val obsoleteTokensAdapter: JsonAdapter> = moshi.adapter( - Types.newParameterizedType(Set::class.java, ObsoleteTokenDao::class.java) + private val obsoleteTokensAdapter: JsonAdapter> = moshi.adapter( + Types.newParameterizedType(List::class.java, ObsoleteTokenDao::class.java) ) fun loadCardCurrencies(cardId: String): CardCurrencies? { @@ -51,48 +51,48 @@ class CurrenciesRepository(val context: Application) { } fun removeToken(cardId: String, token: Token) { - val tokens = loadSavedTokens(cardId).filterNot { it == token }.toSet() + val tokens = loadSavedTokens(cardId).filterNot { it == token } saveTokens(cardId, tokens) } fun removeBlockchain(cardId: String, blockchain: Blockchain) { - val blockchains = loadSavedBlockchains(cardId).filterNot { it == blockchain }.toSet() + val blockchains = loadSavedBlockchains(cardId).filterNot { it == blockchain } saveBlockchains(cardId, blockchains) } - private fun loadSavedTokens(cardId: String): Set { + private fun loadSavedTokens(cardId: String): List { val json = try { context.readFileText(getFileNameForTokens(cardId)) } catch (exception: Exception) { - return emptySet() + return emptyList() } return try { - tokensAdapter.fromJson(json)!!.map { it.toToken() }.toSet() + tokensAdapter.fromJson(json)!!.map { it.toToken() } } catch (exception: Exception) { try { - obsoleteTokensAdapter.fromJson(json)!!.map { it.toToken() }.toSet() + obsoleteTokensAdapter.fromJson(json)!!.map { it.toToken() } } catch (exception: Exception) { - emptySet() + emptyList() } } } - private fun saveTokens(cardId: String, tokens: Set) { - val json = tokensAdapter.toJson(tokens.map { TokenDao.fromToken(it) }.toSet()) + private fun saveTokens(cardId: String, tokens: List) { + val json = tokensAdapter.toJson(tokens.map { TokenDao.fromToken(it) }.distinct()) context.rewriteFile(json, getFileNameForTokens(cardId)) } - private fun loadSavedBlockchains(cardId: String): Set { + private fun loadSavedBlockchains(cardId: String): List { return try { val json = context.readFileText(getFileNameForBlockchains(cardId)) - blockchainsAdapter.fromJson(json) ?: emptySet() + blockchainsAdapter.fromJson(json) ?: emptyList() } catch (exception: Exception) { - emptySet() + emptyList() } } - private fun saveBlockchains(cardId: String, blockchains: Set) { + private fun saveBlockchains(cardId: String, blockchains: List) { val json = blockchainsAdapter.toJson(blockchains) context.rewriteFile(json, getFileNameForBlockchains(cardId)) } @@ -224,12 +224,12 @@ data class ObsoleteTokenDao( @JsonClass(generateAdapter = true) data class CardCurrenciesDao( - val tokens: Set, - val blockchains: Set, + val tokens: List, + val blockchains: List, ) { fun toCardCurrencies(): CardCurrencies { return CardCurrencies( - tokens = tokens.map { it.toToken() }.toSet(), + tokens = tokens.map { it.toToken() }.distinct(), blockchains = blockchains ) } @@ -237,7 +237,7 @@ data class CardCurrenciesDao( companion object { fun fromCardCurrencies(cardCurrencies: CardCurrencies): CardCurrenciesDao { return CardCurrenciesDao( - tokens = cardCurrencies.tokens.map { TokenDao.fromToken(it) }.toSet(), + tokens = cardCurrencies.tokens.map { TokenDao.fromToken(it) }.distinct(), blockchains = cardCurrencies.blockchains ) } @@ -245,6 +245,6 @@ data class CardCurrenciesDao( } data class CardCurrencies( - val tokens: Set, - val blockchains: Set, + val tokens: List, + val blockchains: List, ) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/redux/TokensReducer.kt b/app/src/main/java/com/tangem/tap/features/tokens/redux/TokensReducer.kt index 66a7dd928b..878eed1113 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/redux/TokensReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/redux/TokensReducer.kt @@ -33,7 +33,7 @@ private fun internalReduce(action: Action, state: AppState): TokensState { } private fun List.toCardCurrencies(): CardCurrencies { - val tokens = mapNotNull { (it.currency as? Currency.Token)?.token }.toSet() - val blockchains = mapNotNull { (it.currency as? Currency.Blockchain)?.blockchain }.toSet() + val tokens = mapNotNull { (it.currency as? Currency.Token)?.token }.distinct() + val blockchains = mapNotNull { (it.currency as? Currency.Blockchain)?.blockchain }.distinct() return CardCurrencies(tokens = tokens, blockchains = blockchains) } \ No newline at end of file From 66217c1493c0109694a62302d3f0d99111048800 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 3 Nov 2021 10:28:03 +0300 Subject: [PATCH 17/76] Updated on 2026-08-14 --- .../tap/features/wallet/redux/WalletState.kt | 25 ++++++++++++-- .../wallet/ui/adapters/WalletAdapter.kt | 33 ++----------------- 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index 54e7f12586..e766e87035 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -132,12 +132,31 @@ data class WalletState( fun replaceWalletInWallets(walletData: WalletData?): List { if (walletData == null) return wallets - return wallets.filter { it.currencyData.currency != walletData.currencyData.currency } + walletData + var changed = false + val updatedWallets = wallets.map { + if (it.currencyData.currency == walletData.currencyData.currency) { + changed = true + walletData + } else { + it + } + } + return if (changed) updatedWallets else wallets + walletData } fun replaceSomeWallets(newWallets: List): List { - val currencies = newWallets.map { it.currencyData.currency } - return wallets.filter { !currencies.contains(it.currencyData.currency) } + newWallets + val remainingWallets: MutableList = newWallets.toMutableList() + val updatedWallets = wallets.map { wallet -> + val newWallet = newWallets + .firstOrNull { wallet.currencyData.currency == it.currencyData.currency } + if (newWallet == null) { + wallet + } else { + remainingWallets.remove(newWallet) + newWallet + } + } + return updatedWallets + remainingWallets } fun addWalletManagers(newWalletManagers: List): WalletState { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt index b90adc2cb6..f804f6acef 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt @@ -18,7 +18,6 @@ import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.android.synthetic.main.item_currency_wallet.view.* -import java.math.BigDecimal class WalletAdapter : ListAdapter(DiffUtilCallback) { @@ -28,36 +27,8 @@ class WalletAdapter } fun submitList(list: List, primaryBlockchain: Blockchain?, primaryToken: Token? = null) { - val listModified = list.toMutableList() - val primaryBlockchainWallet = when ( - val index = listModified.indexOfFirst { - (it.currency as? Currency.Blockchain)?.blockchain == primaryBlockchain - } - ) { - -1 -> null - else -> listModified.removeAt(index) - } - - - val primaryTokenWallet = if (primaryToken == null) null else when ( - val index = listModified.indexOfFirst { (it.currency as? Currency.Token)?.token == primaryToken } - ) { - -1 -> null - else -> listModified.removeAt(index) - } - - if (list.all { it.currencyData.fiatAmountFormatted == null }) { - val sortedList = listOfNotNull(primaryBlockchainWallet, primaryTokenWallet) + listModified - super.submitList(sortedList) - return - } - - val sorted = listModified.sortedWith( - compareByDescending { it.currencyData.fiatAmount ?: BigDecimal.ZERO } - .thenBy { it.currencyData.currency } - ) - val sortedList = listOfNotNull(primaryBlockchainWallet, primaryTokenWallet) + sorted - super.submitList(sortedList) + // We used this method to sort the list of currencies. Sorting is disabled for now. + super.submitList(list) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WalletsViewHolder { From c58966bcca268f0a7a157db9f53441c4017ed633 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 3 Nov 2021 11:33:17 +0300 Subject: [PATCH 18/76] Updated on 2026-08-14 --- app/src/main/res/values/strings_untranslated.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index f189ef8196..314565b97f 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -89,6 +89,7 @@ ex. USD Coin ex. USDC Added + Remove token //Details Blockchain From 74d04cde075fd2f80a331cf67f0f0220de951dfe Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 3 Nov 2021 11:34:53 +0300 Subject: [PATCH 19/76] Updated on 2026-08-14 --- .../wallet/ui/WalletDetailsFragment.kt | 6 ++--- .../wallet/ui/wallet/SingleWalletView.kt | 24 +++++++++++++++---- .../drawable/ic_arrow_down_short_button.xml | 12 ++++++++++ .../res/layout/fragment_wallet_details.xml | 6 ++--- .../layout/layout_wallet_short_buttons.xml | 9 ++++--- app/src/main/res/menu/wallet_details.xml | 4 ++-- 6 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 app/src/main/res/drawable/ic_arrow_down_short_button.xml diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index f2072f7cf3..9a52c58948 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -84,7 +84,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS btn_share.setOnClickListener { store.dispatch(WalletAction.ShowDialog.QrCode) } - btn_top_up.setOnClickListener { store.dispatch(WalletAction.TradeCryptoAction.Buy) } + btn_trade.setOnClickListener { store.dispatch(WalletAction.TradeCryptoAction.Buy) } btn_sell.setOnClickListener { store.dispatch(WalletAction.TradeCryptoAction.Sell) } } @@ -138,7 +138,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS srl_wallet_details.isRefreshing = false } - btn_top_up.isEnabled = selectedWallet.tradeCryptoState.buyingAllowed + btn_trade.isEnabled = selectedWallet.tradeCryptoState.buyingAllowed btn_sell.show(selectedWallet.tradeCryptoState.sellingAllowed) } @@ -286,7 +286,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { - R.id.meny_remove -> { + R.id.menu_remove -> { store.state.walletState.getSelectedWalletData()?.let { walletData -> store.dispatch(WalletAction.MultiWallet.RemoveWallet(walletData)) store.dispatch(WalletAction.MultiWallet.SelectWallet(null)) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt index 2522ba7135..874c3abfec 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt @@ -142,12 +142,10 @@ class SingleWalletView : WalletView { } btn_show_qr.setOnClickListener { store.dispatch(WalletAction.ShowDialog.QrCode) } - btn_top_up.setOnClickListener { - tradeCryptoAction(state.tradeCryptoState) - } + setupTradeButton(fragment, state.tradeCryptoState) } - private fun tradeCryptoAction(tradeCryptoState: TradeCryptoState) { + private fun setupTradeButton(fragment: WalletFragment, tradeCryptoState: TradeCryptoState) { val allowedToBuy = tradeCryptoState.buyingAllowed val allowedToSell = tradeCryptoState.sellingAllowed val action = when { @@ -156,7 +154,23 @@ class SingleWalletView : WalletView { allowedToBuy && allowedToSell -> WalletAction.ShowDialog.ChooseTradeActionDialog else -> null } - if (action != null) store.dispatch(action) + val text = when { + allowedToBuy && !allowedToSell -> R.string.wallet_button_buy + !allowedToBuy && allowedToSell -> R.string.wallet_button_sell + allowedToBuy && allowedToSell -> R.string.wallet_button_trade + else -> R.string.wallet_button_trade + } + val icon = when { + allowedToBuy && !allowedToSell -> R.drawable.ic_arrow_up_short_btn + !allowedToBuy && allowedToSell -> R.drawable.ic_arrow_down_short_button + allowedToBuy && allowedToSell -> R.drawable.ic_arrows_up_down_short_btn + else -> R.string.wallet_button_trade + } + with(fragment) { + btn_trade.text = getText(text) + btn_trade.setCompoundDrawablesWithIntrinsicBounds(0, icon, 0, 0) + btn_trade.setOnClickListener { if (action != null) store.dispatch(action) } + } } private fun setupButtonsType(state: WalletData, fragment: WalletFragment) = with(fragment) { diff --git a/app/src/main/res/drawable/ic_arrow_down_short_button.xml b/app/src/main/res/drawable/ic_arrow_down_short_button.xml new file mode 100644 index 0000000000..18b58e3f6c --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_down_short_button.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/app/src/main/res/layout/fragment_wallet_details.xml b/app/src/main/res/layout/fragment_wallet_details.xml index 7b61f56d8d..3c69d924f7 100644 --- a/app/src/main/res/layout/fragment_wallet_details.xml +++ b/app/src/main/res/layout/fragment_wallet_details.xml @@ -131,7 +131,7 @@ app:constraint_referenced_ids="l_wallet_details,card_pending_transaction_warning" /> + app:constraint_referenced_ids="btn_trade, btn_sell" /> diff --git a/app/src/main/res/layout/layout_wallet_short_buttons.xml b/app/src/main/res/layout/layout_wallet_short_buttons.xml index be494ee95b..61217164ee 100644 --- a/app/src/main/res/layout/layout_wallet_short_buttons.xml +++ b/app/src/main/res/layout/layout_wallet_short_buttons.xml @@ -9,6 +9,7 @@ android:id="@+id/btn_scan_short" style="@style/TapBlackButton" android:layout_width="0dp" + android:layout_height="52dp" android:layout_marginStart="16dp" android:layout_marginTop="30dp" android:layout_marginBottom="33dp" @@ -17,14 +18,15 @@ android:paddingTop="7dp" android:text="@string/wallet_button_scan" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@id/btn_top_up" + app:layout_constraintEnd_toStartOf="@id/btn_trade" app:layout_constraintStart_toStartOf="parent" app:layout_constraintVertical_bias="1" /> \ No newline at end of file diff --git a/app/src/main/res/menu/wallet_details.xml b/app/src/main/res/menu/wallet_details.xml index 9622311e82..08ba8df389 100644 --- a/app/src/main/res/menu/wallet_details.xml +++ b/app/src/main/res/menu/wallet_details.xml @@ -2,7 +2,7 @@ \ No newline at end of file From 8f5808df689661cddb458ed55a0fcb60cad5fb31 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 3 Nov 2021 11:41:10 +0300 Subject: [PATCH 20/76] Updated on 2026-08-14 --- .../java/com/tangem/tap/features/details/ui/DetailsFragment.kt | 2 ++ 1 file changed, 2 insertions(+) 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 cb51e326dd..ac9be2e1a0 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 @@ -10,6 +10,7 @@ import com.tangem.tap.common.extensions.show 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.domain.isMultiwalletAllowed import com.tangem.tap.domain.twins.getTwinCardIdForUser import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.redux.DetailsState @@ -112,6 +113,7 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber Date: Wed, 3 Nov 2021 12:40:18 +0300 Subject: [PATCH 21/76] Updated on 2026-08-14 --- app/src/main/res/layout/fragment_details.xml | 183 ++++++++++--------- 1 file changed, 92 insertions(+), 91 deletions(-) diff --git a/app/src/main/res/layout/fragment_details.xml b/app/src/main/res/layout/fragment_details.xml index 70c51c9eb3..90df722e29 100644 --- a/app/src/main/res/layout/fragment_details.xml +++ b/app/src/main/res/layout/fragment_details.xml @@ -43,27 +43,46 @@ android:layout_marginEnd="16dp" android:layout_marginBottom="33dp"> + + + + + app:layout_constraintTop_toBottomOf="@id/tv_card_title" /> + + + + + - - + app:layout_constraintTop_toBottomOf="@id/tv_security_title" /> + app:layout_constraintTop_toBottomOf="@id/tv_erase_wallet" /> + @@ -187,6 +222,37 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tv_settings_title" /> + + + + + app:layout_constraintTop_toBottomOf="@id/tv_card_tou" /> - - - - - - - - - - - - - From cbebea5690122ab50852fd4d5b97bcb621056cc8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 3 Nov 2021 13:00:34 +0300 Subject: [PATCH 22/76] Updated on 2026-08-14 --- .../tap/features/wallet/ui/WalletDetailsFragment.kt | 8 +++++--- app/src/main/res/color/menu_item_color.xml | 5 +++++ app/src/main/res/layout/fragment_wallet_details.xml | 1 + app/src/main/res/values/styles.xml | 8 ++++++++ 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 app/src/main/res/color/menu_item_color.xml diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index 9a52c58948..9a4051f137 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -300,9 +300,11 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - if (store.state.walletState.canBeRemoved(store.state.walletState.getSelectedWalletData())) { - inflater.inflate(R.menu.wallet_details, menu) - } + inflater.inflate(R.menu.wallet_details, menu) + val walletCanBeRemoved = store.state.walletState.canBeRemoved( + store.state.walletState.getSelectedWalletData() + ) + menu.getItem(0).isEnabled = walletCanBeRemoved } } diff --git a/app/src/main/res/color/menu_item_color.xml b/app/src/main/res/color/menu_item_color.xml new file mode 100644 index 0000000000..f8d7307051 --- /dev/null +++ b/app/src/main/res/color/menu_item_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_wallet_details.xml b/app/src/main/res/layout/fragment_wallet_details.xml index 3c69d924f7..27da2ac50f 100644 --- a/app/src/main/res/layout/fragment_wallet_details.xml +++ b/app/src/main/res/layout/fragment_wallet_details.xml @@ -23,6 +23,7 @@ android:layout_height="?attr/actionBarSize" app:menu="@menu/wallet_details" app:navigationIcon="@drawable/ic_baseline_arrow_back_24" + android:theme="@style/ThemeOverlay.MyTheme.Toolbar" app:title=" " /> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 43173d1bad..286cddae59 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -20,6 +20,14 @@ @android:color/white + + +