Updated on 2026-08-14
This commit is contained in:
parent
2389b1c60b
commit
0e18cbe733
14 changed files with 13 additions and 281 deletions
|
|
@ -1,13 +0,0 @@
|
|||
package com.tangem.tap.common
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
|
||||
object TestActions {
|
||||
|
||||
// It used only for the test actions in debug or debug_beta builds
|
||||
var isTestAmountInjectionForWalletManagerEnabled = false
|
||||
}
|
||||
|
||||
typealias TestAction = Pair<String, () -> Unit>
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
package com.tangem.tap.common.extensions
|
||||
|
||||
import android.content.*
|
||||
import android.content.pm.*
|
||||
import android.content.res.*
|
||||
import android.net.*
|
||||
import androidx.annotation.*
|
||||
import androidx.core.content.*
|
||||
|
||||
/**
|
||||
* Get uri to any resource type via given Resource Instance
|
||||
* @param resId - resource id
|
||||
* @throws Resources.NotFoundException if the given ID does not exist.
|
||||
* @return - Uri to resource by the given ID
|
||||
*/
|
||||
@Throws(Resources.NotFoundException::class)
|
||||
fun Context.resourceUri(@AnyRes resId: Int): Uri {
|
||||
return Uri.parse(
|
||||
ContentResolver.SCHEME_ANDROID_RESOURCE +
|
||||
"://" + resources.getResourcePackageName(resId) +
|
||||
'/' + resources.getResourceTypeName(resId) +
|
||||
'/' + resources.getResourceEntryName(resId),
|
||||
)
|
||||
}
|
||||
|
|
@ -1,56 +1,11 @@
|
|||
@file:Suppress("TooManyFunctions")
|
||||
|
||||
package com.tangem.tap.common.extensions
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.content.ContextCompat
|
||||
|
||||
fun Context.getDrawableCompat(@DrawableRes drawableResId: Int): Drawable? {
|
||||
return ContextCompat.getDrawable(this, drawableResId)
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun Context.getColorCompat(@ColorRes colorRes: Int): Int {
|
||||
return ContextCompat.getColor(this, colorRes)
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun View.getColor(@ColorRes colorRes: Int): Int {
|
||||
return ContextCompat.getColor(context, colorRes)
|
||||
}
|
||||
|
||||
fun View.getString(@StringRes id: Int): String {
|
||||
return context.getString(id)
|
||||
}
|
||||
|
||||
fun View.getString(@StringRes id: Int, vararg formatArgs: String): String {
|
||||
return context.getString(id, *formatArgs)
|
||||
}
|
||||
|
||||
fun View.show(show: Boolean, invokeBeforeStateChanged: (() -> Unit)? = null) {
|
||||
return if (show) this.show(invokeBeforeStateChanged) else this.hide(invokeBeforeStateChanged)
|
||||
}
|
||||
|
||||
fun View.show(invokeBeforeStateChanged: (() -> Unit)? = null) {
|
||||
if (this.visibility == View.VISIBLE) return
|
||||
|
||||
invokeBeforeStateChanged?.invoke()
|
||||
this.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
fun View.hide(invokeBeforeStateChanged: (() -> Unit)? = null) {
|
||||
if (this.visibility == View.GONE) return
|
||||
|
||||
invokeBeforeStateChanged?.invoke()
|
||||
this.visibility = View.GONE
|
||||
}
|
||||
|
||||
fun View.getString(resId: Int, vararg formatArgs: Any?): String {
|
||||
return context.getString(resId, *formatArgs)
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
package com.tangem.tap.domain
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import com.tangem.common.core.TangemError
|
||||
import com.tangem.wallet.R
|
||||
|
||||
interface TapErrors
|
||||
|
||||
interface ArgError {
|
||||
val args: List<Any>?
|
||||
}
|
||||
|
||||
interface MultiMessageError : TapErrors {
|
||||
val errorList: List<TapError>
|
||||
val builder: (List<String>) -> String
|
||||
}
|
||||
|
||||
sealed class TapError(
|
||||
@StringRes val messageResource: Int,
|
||||
override val args: List<Any>? = null,
|
||||
) : Throwable(), TapErrors, ArgError {
|
||||
|
||||
class UnknownError : TapError(R.string.send_error_unknown)
|
||||
open class CustomError(val customMessage: String) : TapError(R.string.common_custom_string, listOf(customMessage))
|
||||
|
||||
class NoInternetConnection : TapError(R.string.wallet_notification_no_internet)
|
||||
|
||||
sealed class WalletManager {
|
||||
class NoAccountError(amountToCreateAccount: String) : CustomError(amountToCreateAccount)
|
||||
class InternalError(message: String) : CustomError(message)
|
||||
class BlockchainIsUnreachableTryLater : TapError(R.string.wallet_balance_blockchain_unreachable_try_later)
|
||||
}
|
||||
}
|
||||
|
||||
sealed class TapSdkError(override val messageResId: Int?) : TangemError(code = 50100) {
|
||||
override var customMessage: String = code.toString()
|
||||
|
||||
class CardForDifferentApp : TapSdkError(R.string.alert_unsupported_card)
|
||||
class CardNotSupportedByRelease : TapSdkError(R.string.error_wrong_card_type)
|
||||
}
|
||||
|
||||
fun TapErrors.assembleErrors(): MutableList<Pair<Int, List<Any>?>> {
|
||||
val idList = mutableListOf<Pair<Int, List<Any>?>>()
|
||||
when (this) {
|
||||
is MultiMessageError -> this.errorList.forEach { idList.addAll(it.assembleErrors()) }
|
||||
is TapError -> idList.add(Pair(this.messageResource, this.args))
|
||||
}
|
||||
return idList
|
||||
}
|
||||
11
app/src/main/java/com/tangem/tap/domain/TapSdkError.kt
Normal file
11
app/src/main/java/com/tangem/tap/domain/TapSdkError.kt
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.tap.domain
|
||||
|
||||
import com.tangem.common.core.TangemError
|
||||
import com.tangem.wallet.R
|
||||
|
||||
sealed class TapSdkError(override val messageResId: Int?) : TangemError(code = 50100) {
|
||||
override var customMessage: String = code.toString()
|
||||
|
||||
class CardForDifferentApp : TapSdkError(R.string.alert_unsupported_card)
|
||||
class CardNotSupportedByRelease : TapSdkError(R.string.error_wrong_card_type)
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
package com.tangem.tap.domain.model
|
||||
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.blockchain.common.TransactionStatus
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
|
||||
data class PendingTransaction(
|
||||
val transactionData: TransactionData.Uncompiled,
|
||||
val type: PendingTransactionType,
|
||||
) {
|
||||
val address: String? = when (type) {
|
||||
PendingTransactionType.Incoming -> nullIfUnknown(transactionData.sourceAddress)
|
||||
PendingTransactionType.Outgoing -> nullIfUnknown(transactionData.destinationAddress)
|
||||
PendingTransactionType.Unknown -> null
|
||||
}
|
||||
|
||||
val currency: String = transactionData.amount.currencySymbol
|
||||
|
||||
private fun nullIfUnknown(address: String): String? = if (address == "unknown") null else address
|
||||
}
|
||||
|
||||
enum class PendingTransactionType { Incoming, Outgoing, Unknown }
|
||||
|
||||
fun TransactionData.Uncompiled.toPendingTransaction(walletAddress: String): PendingTransaction? {
|
||||
if (this.status == TransactionStatus.Confirmed) return null
|
||||
|
||||
val type: PendingTransactionType = when {
|
||||
this.sourceAddress == walletAddress -> PendingTransactionType.Outgoing
|
||||
this.destinationAddress == walletAddress -> PendingTransactionType.Incoming
|
||||
else -> PendingTransactionType.Unknown
|
||||
}
|
||||
return PendingTransaction(this, type)
|
||||
}
|
||||
|
||||
fun List<TransactionData.Uncompiled>.toPendingTransactions(walletAddress: String): List<PendingTransaction> {
|
||||
return this.mapNotNull { it.toPendingTransaction(walletAddress) }
|
||||
}
|
||||
|
||||
fun Wallet.getPendingTransactions(type: PendingTransactionType? = null): List<PendingTransaction> {
|
||||
val txs = recentTransactions.toPendingTransactions(address)
|
||||
return when (type) {
|
||||
null -> txs
|
||||
else -> txs.filter { it.type == type }
|
||||
}
|
||||
}
|
||||
|
||||
fun Wallet.hasPendingTransactions(): Boolean {
|
||||
return getPendingTransactions().isNotEmpty()
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
package com.tangem.tap.domain.model
|
||||
|
||||
import com.tangem.blockchain.common.address.AddressType
|
||||
|
||||
internal data class WalletAddressData(
|
||||
val address: String,
|
||||
val type: AddressType,
|
||||
val shareUrl: String,
|
||||
val exploreUrl: String,
|
||||
)
|
||||
|
|
@ -30,7 +30,6 @@ import com.tangem.domain.models.scan.ScanResponse
|
|||
import com.tangem.domain.onboarding.WasTwinsOnboardingShownUseCase
|
||||
import com.tangem.sdk.extensions.localizedDescriptionRes
|
||||
import com.tangem.tap.common.analytics.paramsInterceptor.CardContextInterceptor
|
||||
import com.tangem.tap.features.disclaimer.createDisclaimer
|
||||
import com.tangem.tap.features.onboarding.OnboardingHelper
|
||||
import com.tangem.tap.mainScope
|
||||
import com.tangem.tap.scope
|
||||
|
|
@ -145,16 +144,12 @@ internal class LegacyScanProcessor @Inject constructor(
|
|||
Analytics.send(analyticsEvent)
|
||||
}
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
@Suppress("UnusedPrivateMember")
|
||||
private suspend inline fun showDisclaimerIfNeed(
|
||||
scanResponse: ScanResponse,
|
||||
crossinline disclaimerWillShow: () -> Unit = {},
|
||||
crossinline nextHandler: suspend (ScanResponse) -> Unit,
|
||||
) {
|
||||
val disclaimer = scanResponse.card.createDisclaimer(cardRepository)
|
||||
|
||||
if (disclaimer.isAccepted()) {
|
||||
if (cardRepository.isTangemTOSAccepted()) {
|
||||
nextHandler(scanResponse)
|
||||
} else {
|
||||
scope.launch {
|
||||
|
|
@ -206,7 +201,6 @@ internal class LegacyScanProcessor @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod", "LongParameterList", "MagicNumber")
|
||||
private suspend inline fun onScanSuccess(
|
||||
scanResponse: ScanResponse,
|
||||
crossinline onProgressStateChange: suspend (showProgress: Boolean) -> Unit,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.tangem.domain.card.repository.CardRepository
|
|||
import com.tangem.domain.core.chain.Chain
|
||||
import com.tangem.domain.core.chain.ResultChain
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.tap.features.disclaimer.createDisclaimer
|
||||
|
||||
/**
|
||||
* Handles disclaimer display after the card scanning operation.
|
||||
|
|
@ -25,14 +24,11 @@ internal class DisclaimerChain(
|
|||
) : ResultChain<ScanCardException, ScanResponse>() {
|
||||
|
||||
override suspend fun launch(previousChainResult: ScanResponse): ScanChainResult {
|
||||
val disclaimer = previousChainResult.card.createDisclaimer(cardRepository)
|
||||
|
||||
return if (disclaimer.isAccepted()) {
|
||||
return if (cardRepository.isTangemTOSAccepted()) {
|
||||
previousChainResult.right()
|
||||
} else {
|
||||
disclaimerWillShow()
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
appRouter.push(route = AppRoute.Disclaimer(isTosAccepted = false))
|
||||
|
||||
previousChainResult.right()
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
package com.tangem.tap.features.disclaimer
|
||||
|
||||
import android.net.Uri
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface Disclaimer {
|
||||
fun getUri(): Uri
|
||||
suspend fun accept()
|
||||
suspend fun isAccepted(): Boolean
|
||||
}
|
||||
|
||||
abstract class BaseDisclaimer(
|
||||
private val dataProvider: DisclaimerDataProvider,
|
||||
) : Disclaimer {
|
||||
|
||||
val baseUrl = "https://tangem.com"
|
||||
|
||||
override suspend fun accept() {
|
||||
dataProvider.accept()
|
||||
}
|
||||
|
||||
override suspend fun isAccepted(): Boolean = dataProvider.isAccepted()
|
||||
}
|
||||
|
||||
class TangemDisclaimer(dataProvider: DisclaimerDataProvider) : BaseDisclaimer(dataProvider) {
|
||||
override fun getUri(): Uri = Uri.parse("$baseUrl/tangem_tos.html")
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package com.tangem.tap.features.disclaimer
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface DisclaimerDataProvider {
|
||||
fun getLanguage(): String
|
||||
fun getCardId(): String
|
||||
suspend fun accept()
|
||||
suspend fun isAccepted(): Boolean
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
package com.tangem.tap.features.disclaimer
|
||||
|
||||
import com.tangem.domain.card.repository.CardRepository
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import java.util.Locale
|
||||
|
||||
fun CardDTO.createDisclaimer(cardRepository: CardRepository): Disclaimer {
|
||||
val dataProvider = provideDisclaimerDataProvider(cardId, cardRepository)
|
||||
return TangemDisclaimer(dataProvider)
|
||||
}
|
||||
|
||||
private fun provideDisclaimerDataProvider(cardId: String, cardRepository: CardRepository): DisclaimerDataProvider {
|
||||
return object : DisclaimerDataProvider {
|
||||
override fun getLanguage(): String = Locale.getDefault().language
|
||||
override fun getCardId(): String = cardId
|
||||
|
||||
override suspend fun accept() {
|
||||
cardRepository.acceptTangemTOS()
|
||||
}
|
||||
|
||||
override suspend fun isAccepted(): Boolean {
|
||||
return cardRepository.isTangemTOSAccepted()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
package com.tangem.tap.features.intentHandler
|
||||
|
||||
interface AffectsNavigation
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package com.tangem.tap.features.intentHandler
|
||||
|
||||
import android.content.Intent
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface IntentHandler {
|
||||
|
||||
fun handleIntent(intent: Intent?): Boolean
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue