Updated on 2026-08-14
This commit is contained in:
parent
0c31e7fa6a
commit
18bd8ed03b
9 changed files with 252 additions and 37 deletions
|
|
@ -118,8 +118,10 @@ dependencies {
|
||||||
// Camera
|
// Camera
|
||||||
implementation 'com.otaliastudios:cameraview:2.6.3'
|
implementation 'com.otaliastudios:cameraview:2.6.3'
|
||||||
|
|
||||||
// Image Loading - Picasso
|
// Image Loading
|
||||||
implementation 'com.squareup.picasso:picasso:2.71828'
|
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||||
|
implementation 'io.coil-kt:coil:2.1.0'
|
||||||
|
implementation 'io.coil-kt:coil-compose:2.1.0'
|
||||||
|
|
||||||
// Firebase
|
// Firebase
|
||||||
implementation platform('com.google.firebase:firebase-bom:26.0.0')
|
implementation platform('com.google.firebase:firebase-bom:26.0.0')
|
||||||
|
|
@ -172,9 +174,6 @@ dependencies {
|
||||||
|
|
||||||
implementation "com.github.skydoves:androidveil:1.1.2"
|
implementation "com.github.skydoves:androidveil:1.1.2"
|
||||||
|
|
||||||
implementation("io.coil-kt:coil:2.0.0-rc01")
|
|
||||||
implementation("io.coil-kt:coil-compose:2.0.0-rc01")
|
|
||||||
|
|
||||||
implementation 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.6'
|
implementation 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.6'
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 985642c135606ba1f59fd739127aec03024da79b
|
Subproject commit 7f058ec409b4eaaf8688ecd4bf944ef8d58d3564
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.tangem.tap
|
package com.tangem.tap
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import coil.ImageLoader
|
||||||
|
import coil.ImageLoaderFactory
|
||||||
import com.appsflyer.AppsFlyerLib
|
import com.appsflyer.AppsFlyerLib
|
||||||
import com.google.firebase.ktx.Firebase
|
import com.google.firebase.ktx.Firebase
|
||||||
import com.google.firebase.remoteconfig.ktx.remoteConfig
|
import com.google.firebase.remoteconfig.ktx.remoteConfig
|
||||||
|
|
@ -10,7 +12,7 @@ import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder
|
||||||
import com.tangem.domain.DomainLayer
|
import com.tangem.domain.DomainLayer
|
||||||
import com.tangem.network.common.MoshiConverter
|
import com.tangem.network.common.MoshiConverter
|
||||||
import com.tangem.tap.common.analytics.GlobalAnalyticsHandler
|
import com.tangem.tap.common.analytics.GlobalAnalyticsHandler
|
||||||
import com.tangem.tap.common.images.PicassoHelper
|
import com.tangem.tap.common.images.createCoilImageLoader
|
||||||
import com.tangem.tap.common.redux.AppState
|
import com.tangem.tap.common.redux.AppState
|
||||||
import com.tangem.tap.common.redux.appReducer
|
import com.tangem.tap.common.redux.appReducer
|
||||||
import com.tangem.tap.common.redux.global.GlobalAction
|
import com.tangem.tap.common.redux.global.GlobalAction
|
||||||
|
|
@ -43,7 +45,7 @@ lateinit var currenciesRepository: CurrenciesRepository
|
||||||
lateinit var walletConnectRepository: WalletConnectRepository
|
lateinit var walletConnectRepository: WalletConnectRepository
|
||||||
lateinit var shopService: TangemShopService
|
lateinit var shopService: TangemShopService
|
||||||
|
|
||||||
class TapApplication : Application() {
|
class TapApplication : Application(), ImageLoaderFactory {
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
|
||||||
|
|
@ -61,7 +63,6 @@ class TapApplication : Application() {
|
||||||
|
|
||||||
NetworkConnectivity.createInstance(store, this)
|
NetworkConnectivity.createInstance(store, this)
|
||||||
preferencesStorage = PreferencesStorage(this)
|
preferencesStorage = PreferencesStorage(this)
|
||||||
PicassoHelper.initPicassoWithCaching(this)
|
|
||||||
currenciesRepository = CurrenciesRepository(
|
currenciesRepository = CurrenciesRepository(
|
||||||
this, store.state.domainNetworks.tangemTechService
|
this, store.state.domainNetworks.tangemTechService
|
||||||
)
|
)
|
||||||
|
|
@ -75,6 +76,10 @@ class TapApplication : Application() {
|
||||||
initAppsFlyer()
|
initAppsFlyer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun newImageLoader(): ImageLoader {
|
||||||
|
return createCoilImageLoader(context = this)
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadConfigs() {
|
private fun loadConfigs() {
|
||||||
val moshi = MoshiConverter.defaultMoshi()
|
val moshi = MoshiConverter.defaultMoshi()
|
||||||
val localLoader = FeaturesLocalLoader(this, moshi)
|
val localLoader = FeaturesLocalLoader(this, moshi)
|
||||||
|
|
@ -108,11 +113,6 @@ class TapApplication : Application() {
|
||||||
}
|
}
|
||||||
|
|
||||||
data class LogConfig(
|
data class LogConfig(
|
||||||
// disables both [internal, http]
|
val coil: Boolean = BuildConfig.DEBUG,
|
||||||
val picasso: Boolean = BuildConfig.DEBUG,
|
|
||||||
val picassoInternal: Boolean = true,
|
|
||||||
val picassoHttp: Boolean = true,
|
|
||||||
|
|
||||||
val storeAction: Boolean = BuildConfig.DEBUG,
|
val storeAction: Boolean = BuildConfig.DEBUG,
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
package com.tangem.tap.common.extensions
|
package com.tangem.tap.common.extensions
|
||||||
|
|
||||||
import android.graphics.*
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.BitmapShader
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Paint
|
||||||
|
import android.graphics.RectF
|
||||||
|
import android.graphics.Shader
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.constraintlayout.utils.widget.ImageFilterView
|
import androidx.constraintlayout.utils.widget.ImageFilterView
|
||||||
import com.squareup.picasso.Callback
|
import com.squareup.picasso.Callback
|
||||||
|
|
@ -32,6 +37,28 @@ fun Picasso.loadCurrenciesIcon(
|
||||||
imageView.colorFilter = null
|
imageView.colorFilter = null
|
||||||
textView.text = null
|
textView.text = null
|
||||||
|
|
||||||
|
if (token != null) {
|
||||||
|
setTokenImage(imageView, textView, token, blockchain)
|
||||||
|
}
|
||||||
|
this.load(url)
|
||||||
|
.transform(RoundedCornersTransform())
|
||||||
|
.noPlaceholder()
|
||||||
|
?.into(imageView,
|
||||||
|
object : Callback {
|
||||||
|
override fun onError(e: Exception?) {
|
||||||
|
setOfflineCurrencyImage(imageView, textView, token, blockchain)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSuccess() {
|
||||||
|
if (token != null) {
|
||||||
|
imageView.colorFilter = null
|
||||||
|
textView.text = null
|
||||||
|
}
|
||||||
|
if (blockchain.isTestnet()) imageView.saturation = 0f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
when {
|
when {
|
||||||
token?.symbol == QCX -> {
|
token?.symbol == QCX -> {
|
||||||
this.load(R.drawable.ic_qcx)?.into(imageView)
|
this.load(R.drawable.ic_qcx)?.into(imageView)
|
||||||
|
|
@ -59,7 +86,8 @@ fun Picasso.loadCurrenciesIcon(
|
||||||
}
|
}
|
||||||
if (blockchain.isTestnet()) imageView.saturation = 0f
|
if (blockchain.isTestnet()) imageView.saturation = 0f
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
setOfflineCurrencyImage(imageView, textView, token, blockchain)
|
setOfflineCurrencyImage(imageView, textView, token, blockchain)
|
||||||
|
|
@ -70,36 +98,43 @@ fun Picasso.loadCurrenciesIcon(
|
||||||
private const val QCX = "QCX"
|
private const val QCX = "QCX"
|
||||||
private const val VOYR = "VOYRME"
|
private const val VOYR = "VOYRME"
|
||||||
|
|
||||||
private fun setOfflineCurrencyImage(
|
private fun Picasso.setOfflineCurrencyImage(
|
||||||
imageView: ImageFilterView,
|
imageView: ImageFilterView,
|
||||||
textView: TextView,
|
textView: TextView,
|
||||||
token: Token?,
|
token: Token?,
|
||||||
blockchain: Blockchain,
|
blockchain: Blockchain,
|
||||||
) {
|
) {
|
||||||
when (token) {
|
if (token == null) {
|
||||||
null -> setBlockchainImage(imageView, textView, blockchain)
|
setBlockchainImage(imageView, textView, blockchain)
|
||||||
else -> setTokenImage(imageView, textView, token, blockchain)
|
} else {
|
||||||
|
setTokenImage(imageView, textView, token, blockchain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setBlockchainImage(
|
private fun Picasso.setBlockchainImage(
|
||||||
imageView: ImageFilterView,
|
imageView: ImageFilterView,
|
||||||
textView: TextView,
|
textView: TextView,
|
||||||
blockchain: Blockchain,
|
blockchain: Blockchain,
|
||||||
) {
|
) {
|
||||||
imageView.setImageResource(blockchain.getRoundIconRes())
|
this
|
||||||
|
.load(blockchain.getRoundIconRes())
|
||||||
|
.into(imageView)
|
||||||
|
|
||||||
imageView.colorFilter = null
|
imageView.colorFilter = null
|
||||||
if (blockchain.isTestnet()) imageView.saturation = 0f
|
if (blockchain.isTestnet()) imageView.saturation = 0f
|
||||||
textView.text = null
|
textView.text = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setTokenImage(
|
private fun Picasso.setTokenImage(
|
||||||
imageView: ImageFilterView,
|
imageView: ImageFilterView,
|
||||||
textView: TextView,
|
textView: TextView,
|
||||||
token: Token,
|
token: Token,
|
||||||
tokenBlockchain: Blockchain
|
tokenBlockchain: Blockchain
|
||||||
) {
|
) {
|
||||||
imageView.setImageResource(R.drawable.shape_circle)
|
this
|
||||||
|
.load(R.drawable.shape_circle)
|
||||||
|
.into(imageView)
|
||||||
|
|
||||||
if (tokenBlockchain.isTestnet()) {
|
if (tokenBlockchain.isTestnet()) {
|
||||||
imageView.saturation = 0f
|
imageView.saturation = 0f
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.tangem.tap.common.extensions
|
package com.tangem.tap.common.extensions
|
||||||
|
|
||||||
|
import android.graphics.Color
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
|
import androidx.core.graphics.luminance
|
||||||
import androidx.core.graphics.toColorInt
|
import androidx.core.graphics.toColorInt
|
||||||
import com.tangem.blockchain.common.Token
|
import com.tangem.blockchain.common.Token
|
||||||
import com.tangem.wallet.R
|
import com.tangem.wallet.R
|
||||||
|
|
@ -9,8 +11,13 @@ import com.tangem.wallet.R
|
||||||
fun Token.getColor(): Int {
|
fun Token.getColor(): Int {
|
||||||
return try {
|
return try {
|
||||||
("#" + this.contractAddress.subSequence(2..7).toString())
|
("#" + this.contractAddress.subSequence(2..7).toString())
|
||||||
.toColorInt()
|
.toColorInt()
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
R.color.lightGray4
|
R.color.lightGray4
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ColorInt
|
||||||
|
fun Token.getTextColor(): Int {
|
||||||
|
return if (this.getColor().luminance > 0.5) Color.BLACK else Color.WHITE
|
||||||
}
|
}
|
||||||
50
app/src/main/java/com/tangem/tap/common/images/Coil.kt
Normal file
50
app/src/main/java/com/tangem/tap/common/images/Coil.kt
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.tangem.tap.common.images
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.Log
|
||||||
|
import coil.ImageLoader
|
||||||
|
import coil.util.Logger
|
||||||
|
import com.tangem.tap.logConfig
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
private const val COIL_LOG_TAG = "COIL"
|
||||||
|
|
||||||
|
fun createCoilImageLoader(
|
||||||
|
context: Context
|
||||||
|
): ImageLoader {
|
||||||
|
return ImageLoader.Builder(context)
|
||||||
|
.apply {
|
||||||
|
if (!logConfig.coil) return@apply
|
||||||
|
|
||||||
|
logger(CoilTimberLogger())
|
||||||
|
okHttpClient {
|
||||||
|
OkHttpClient.Builder()
|
||||||
|
.addNetworkInterceptor(
|
||||||
|
HttpLoggingInterceptor { message ->
|
||||||
|
Timber.tag(COIL_LOG_TAG).d(message)
|
||||||
|
}
|
||||||
|
.apply {
|
||||||
|
level = HttpLoggingInterceptor.Level.BODY
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class CoilTimberLogger : Logger {
|
||||||
|
|
||||||
|
override var level: Int = Log.DEBUG
|
||||||
|
|
||||||
|
override fun log(tag: String, priority: Int, message: String?, throwable: Throwable?) {
|
||||||
|
with(Timber.tag(COIL_LOG_TAG)) {
|
||||||
|
throwable?.let { e -> e(e, message) }
|
||||||
|
message?.let { msg -> d(msg) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
package com.tangem.tap.features.wallet.ui
|
package com.tangem.tap.features.wallet.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.*
|
import android.view.Menu
|
||||||
|
import android.view.MenuInflater
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.annotation.ColorRes
|
import androidx.annotation.ColorRes
|
||||||
|
|
@ -11,20 +15,32 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.transition.TransitionInflater
|
import androidx.transition.TransitionInflater
|
||||||
import by.kirich1409.viewbindingdelegate.viewBinding
|
import by.kirich1409.viewbindingdelegate.viewBinding
|
||||||
import com.squareup.picasso.Picasso
|
|
||||||
import com.tangem.tangem_sdk_new.extensions.dpToPx
|
import com.tangem.tangem_sdk_new.extensions.dpToPx
|
||||||
import com.tangem.tap.common.SnackbarHandler
|
import com.tangem.tap.common.SnackbarHandler
|
||||||
import com.tangem.tap.common.TestActions
|
import com.tangem.tap.common.TestActions
|
||||||
import com.tangem.tap.common.extensions.*
|
import com.tangem.tap.common.extensions.appendIfNotNull
|
||||||
|
import com.tangem.tap.common.extensions.beginDelayedTransition
|
||||||
|
import com.tangem.tap.common.extensions.fitChipsByGroupWidth
|
||||||
|
import com.tangem.tap.common.extensions.getColor
|
||||||
|
import com.tangem.tap.common.extensions.getString
|
||||||
|
import com.tangem.tap.common.extensions.hide
|
||||||
|
import com.tangem.tap.common.extensions.show
|
||||||
|
import com.tangem.tap.common.extensions.toQrCode
|
||||||
import com.tangem.tap.common.recyclerView.SpaceItemDecoration
|
import com.tangem.tap.common.recyclerView.SpaceItemDecoration
|
||||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||||
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
|
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
|
||||||
import com.tangem.tap.features.onboarding.getQRReceiveMessage
|
import com.tangem.tap.features.onboarding.getQRReceiveMessage
|
||||||
import com.tangem.tap.features.wallet.models.PendingTransaction
|
import com.tangem.tap.features.wallet.models.PendingTransaction
|
||||||
import com.tangem.tap.features.wallet.redux.*
|
import com.tangem.tap.features.wallet.redux.Currency
|
||||||
|
import com.tangem.tap.features.wallet.redux.ErrorType
|
||||||
|
import com.tangem.tap.features.wallet.redux.ProgressState
|
||||||
|
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||||
|
import com.tangem.tap.features.wallet.redux.WalletData
|
||||||
|
import com.tangem.tap.features.wallet.redux.WalletState
|
||||||
import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN
|
import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN
|
||||||
import com.tangem.tap.features.wallet.ui.adapters.PendingTransactionsAdapter
|
import com.tangem.tap.features.wallet.ui.adapters.PendingTransactionsAdapter
|
||||||
import com.tangem.tap.features.wallet.ui.adapters.WalletDetailWarningMessagesAdapter
|
import com.tangem.tap.features.wallet.ui.adapters.WalletDetailWarningMessagesAdapter
|
||||||
|
import com.tangem.tap.features.wallet.ui.images.loadCurrencyIcon
|
||||||
import com.tangem.tap.features.wallet.ui.test.TestWalletDetails
|
import com.tangem.tap.features.wallet.ui.test.TestWalletDetails
|
||||||
import com.tangem.tap.store
|
import com.tangem.tap.store
|
||||||
import com.tangem.wallet.R
|
import com.tangem.wallet.R
|
||||||
|
|
@ -199,9 +215,9 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details),
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleCurrencyIcon(wallet: WalletData) = with(binding.lWalletDetails.lBalance) {
|
private fun handleCurrencyIcon(wallet: WalletData) = with(binding.lWalletDetails.lBalance) {
|
||||||
Picasso.get().loadCurrenciesIcon(
|
loadCurrencyIcon(
|
||||||
imageView = ivCurrency,
|
currencyImageView = ivCurrency,
|
||||||
textView = tvTokenLetter,
|
currencyTextView = tvTokenLetter,
|
||||||
blockchain = wallet.currency.blockchain,
|
blockchain = wallet.currency.blockchain,
|
||||||
token = (wallet.currency as? Currency.Token)?.token
|
token = (wallet.currency as? Currency.Token)?.token
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,17 @@ import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.squareup.picasso.Picasso
|
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.blockchain.common.Token
|
import com.tangem.blockchain.common.Token
|
||||||
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
||||||
import com.tangem.tap.common.extensions.getString
|
import com.tangem.tap.common.extensions.getString
|
||||||
import com.tangem.tap.common.extensions.hide
|
import com.tangem.tap.common.extensions.hide
|
||||||
import com.tangem.tap.common.extensions.loadCurrenciesIcon
|
|
||||||
import com.tangem.tap.common.extensions.show
|
import com.tangem.tap.common.extensions.show
|
||||||
import com.tangem.tap.features.wallet.redux.Currency
|
import com.tangem.tap.features.wallet.redux.Currency
|
||||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||||
import com.tangem.tap.features.wallet.redux.WalletData
|
import com.tangem.tap.features.wallet.redux.WalletData
|
||||||
import com.tangem.tap.features.wallet.ui.BalanceStatus
|
import com.tangem.tap.features.wallet.ui.BalanceStatus
|
||||||
|
import com.tangem.tap.features.wallet.ui.images.loadCurrencyIcon
|
||||||
import com.tangem.tap.store
|
import com.tangem.tap.store
|
||||||
import com.tangem.wallet.R
|
import com.tangem.wallet.R
|
||||||
import com.tangem.wallet.databinding.ItemCurrencyWalletBinding
|
import com.tangem.wallet.databinding.ItemCurrencyWalletBinding
|
||||||
|
|
@ -98,9 +97,9 @@ class WalletAdapter
|
||||||
lContent.root.show()
|
lContent.root.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
Picasso.get().loadCurrenciesIcon(
|
loadCurrencyIcon(
|
||||||
imageView = ivCurrency,
|
currencyImageView = ivCurrency,
|
||||||
textView = tvTokenLetter,
|
currencyTextView = tvTokenLetter,
|
||||||
token = (wallet.currency as? Currency.Token)?.token,
|
token = (wallet.currency as? Currency.Token)?.token,
|
||||||
blockchain = wallet.currency.blockchain,
|
blockchain = wallet.currency.blockchain,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
package com.tangem.tap.features.wallet.ui.images
|
||||||
|
|
||||||
|
import android.graphics.PorterDuff
|
||||||
|
import android.graphics.PorterDuffColorFilter
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.constraintlayout.utils.widget.ImageFilterView
|
||||||
|
import coil.imageLoader
|
||||||
|
import coil.load
|
||||||
|
import coil.request.ImageRequest
|
||||||
|
import coil.transform.RoundedCornersTransformation
|
||||||
|
import com.tangem.blockchain.common.Blockchain
|
||||||
|
import com.tangem.blockchain.common.IconsUtil
|
||||||
|
import com.tangem.blockchain.common.Token
|
||||||
|
import com.tangem.domain.common.extensions.toNetworkId
|
||||||
|
import com.tangem.tap.common.extensions.getColor
|
||||||
|
import com.tangem.tap.common.extensions.getRoundIconRes
|
||||||
|
import com.tangem.tap.common.extensions.getTextColor
|
||||||
|
import com.tangem.tap.domain.extensions.getCustomIconUrl
|
||||||
|
import com.tangem.tap.domain.tokens.getIconUrl
|
||||||
|
import com.tangem.wallet.R
|
||||||
|
|
||||||
|
private const val QCX = "QCX"
|
||||||
|
private const val VOYR = "VOYRME"
|
||||||
|
|
||||||
|
fun loadCurrencyIcon(
|
||||||
|
currencyImageView: ImageFilterView,
|
||||||
|
currencyTextView: TextView,
|
||||||
|
token: Token?,
|
||||||
|
blockchain: Blockchain,
|
||||||
|
) {
|
||||||
|
when {
|
||||||
|
token == null -> currencyImageView.loadIcon(
|
||||||
|
iconUrl = getIconUrl(blockchain.toNetworkId()),
|
||||||
|
placeholderRes = blockchain.getRoundIconRes(),
|
||||||
|
onStart = {
|
||||||
|
if (blockchain.isTestnet()) {
|
||||||
|
currencyImageView.saturation = 0f
|
||||||
|
} else {
|
||||||
|
currencyImageView.colorFilter = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
token.symbol == QCX -> currencyImageView.load(R.drawable.ic_qcx)
|
||||||
|
token.symbol == VOYR -> currencyImageView.load(R.drawable.ic_voyr)
|
||||||
|
else -> currencyImageView.loadIcon(
|
||||||
|
iconUrl = getTokenIconUrl(token, blockchain),
|
||||||
|
placeholderRes = R.drawable.shape_circle,
|
||||||
|
onStart = {
|
||||||
|
currencyTextView.text = token.symbol.take(1)
|
||||||
|
currencyTextView.setTextColor(token.getTextColor())
|
||||||
|
|
||||||
|
if (blockchain.isTestnet()) {
|
||||||
|
currencyImageView.saturation = 0f
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError = {
|
||||||
|
currencyImageView.colorFilter = PorterDuffColorFilter(
|
||||||
|
/* color = */
|
||||||
|
token.getColor(),
|
||||||
|
/* mode = */
|
||||||
|
PorterDuff.Mode.SRC_ATOP,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onSuccess = {
|
||||||
|
if (!blockchain.isTestnet()) {
|
||||||
|
currencyImageView.colorFilter = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun ImageView.loadIcon(
|
||||||
|
iconUrl: String?,
|
||||||
|
placeholderRes: Int,
|
||||||
|
crossinline onStart: () -> Unit = {},
|
||||||
|
crossinline onSuccess: () -> Unit = {},
|
||||||
|
crossinline onError: () -> Unit = {},
|
||||||
|
) {
|
||||||
|
ImageRequest.Builder(context)
|
||||||
|
.data(iconUrl)
|
||||||
|
.placeholder(placeholderRes)
|
||||||
|
.error(placeholderRes)
|
||||||
|
.fallback(placeholderRes)
|
||||||
|
.transformations(
|
||||||
|
RoundedCornersTransformation(
|
||||||
|
topLeft = 32f,
|
||||||
|
topRight = 32f,
|
||||||
|
bottomLeft = 32f,
|
||||||
|
bottomRight = 32f
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.listener(
|
||||||
|
onStart = { onStart() },
|
||||||
|
onSuccess = { _, _ -> onSuccess() },
|
||||||
|
onError = { _, _ -> onError() }
|
||||||
|
)
|
||||||
|
.target(imageView = this)
|
||||||
|
.build()
|
||||||
|
.also(context.imageLoader::enqueue)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getTokenIconUrl(token: Token, blockchain: Blockchain): String? {
|
||||||
|
return token.id?.let(::getIconUrl)
|
||||||
|
?: token.getCustomIconUrl()
|
||||||
|
?: IconsUtil.getTokenIconUri(blockchain, token)
|
||||||
|
?.toString()
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue