diff --git a/app/build.gradle b/app/build.gradle index 48f34abcb7..a2c501010a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -93,7 +93,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-88' + implementation 'com.tangem:blockchain:develop-90' // implementation 'com.tangem:blockchain:0.0.1' implementation 'com.tangem.tangem-sdk-kotlin:core:develop-154' implementation 'com.tangem.tangem-sdk-kotlin:android:develop-154' @@ -118,8 +118,9 @@ dependencies { // Camera implementation 'com.otaliastudios:cameraview:2.6.3' - // Image Loading - Picasso - implementation 'com.squareup.picasso:picasso:2.71828' + // Image Loading + implementation 'io.coil-kt:coil:2.1.0' + implementation 'io.coil-kt:coil-compose:2.1.0' // Firebase implementation platform('com.google.firebase:firebase-bom:26.0.0') @@ -172,9 +173,6 @@ dependencies { 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' testImplementation 'junit:junit:4.13.2' diff --git a/app/src/main/assets/tangem-app-config b/app/src/main/assets/tangem-app-config index 64ae04d208..f50133547b 160000 --- a/app/src/main/assets/tangem-app-config +++ b/app/src/main/assets/tangem-app-config @@ -1 +1 @@ -Subproject commit 64ae04d2086e5a605dd4da3cba4af32a60d46c79 +Subproject commit f50133547b5e19fb7ad32e64370573d60f6791fd diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index b58485ab88..2e6c7b534b 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -1,6 +1,8 @@ package com.tangem.tap import android.app.Application +import coil.ImageLoader +import coil.ImageLoaderFactory import com.appsflyer.AppsFlyerLib import com.google.firebase.ktx.Firebase 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.network.common.MoshiConverter 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.appReducer import com.tangem.tap.common.redux.global.GlobalAction @@ -43,7 +45,7 @@ lateinit var currenciesRepository: CurrenciesRepository lateinit var walletConnectRepository: WalletConnectRepository lateinit var shopService: TangemShopService -class TapApplication : Application() { +class TapApplication : Application(), ImageLoaderFactory { override fun onCreate() { super.onCreate() @@ -61,7 +63,6 @@ class TapApplication : Application() { NetworkConnectivity.createInstance(store, this) preferencesStorage = PreferencesStorage(this) - PicassoHelper.initPicassoWithCaching(this) currenciesRepository = CurrenciesRepository( this, store.state.domainNetworks.tangemTechService ) @@ -75,6 +76,10 @@ class TapApplication : Application() { initAppsFlyer() } + override fun newImageLoader(): ImageLoader { + return createCoilImageLoader(context = this) + } + private fun loadConfigs() { val moshi = MoshiConverter.defaultMoshi() val localLoader = FeaturesLocalLoader(this, moshi) @@ -108,11 +113,6 @@ class TapApplication : Application() { } data class LogConfig( - // disables both [internal, http] - val picasso: Boolean = BuildConfig.DEBUG, - val picassoInternal: Boolean = true, - val picassoHttp: Boolean = true, - + val coil: Boolean = BuildConfig.DEBUG, val storeAction: Boolean = BuildConfig.DEBUG, - ) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt index 5cf9b2d3ad..3cb5aa96c8 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt @@ -62,6 +62,7 @@ fun Blockchain.getNetworkName(): String { Blockchain.Ethereum, Blockchain.EthereumTestnet -> "ERC20" Blockchain.BSC, Blockchain.BSCTestnet -> "BEP20" Blockchain.Binance, Blockchain.BinanceTestnet -> "BEP2" + Blockchain.Tron, Blockchain.TronTestnet -> "TRC20" else -> "" } } diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Picasso.kt b/app/src/main/java/com/tangem/tap/common/extensions/Picasso.kt deleted file mode 100644 index dbeefadbe8..0000000000 --- a/app/src/main/java/com/tangem/tap/common/extensions/Picasso.kt +++ /dev/null @@ -1,135 +0,0 @@ -package com.tangem.tap.common.extensions - -import android.graphics.* -import android.widget.TextView -import androidx.constraintlayout.utils.widget.ImageFilterView -import com.squareup.picasso.Callback -import com.squareup.picasso.Picasso -import com.squareup.picasso.Transformation -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.domain.extensions.getCustomIconUrl -import com.tangem.tap.domain.tokens.getIconUrl -import com.tangem.wallet.R - -fun Picasso.loadCurrenciesIcon( - imageView: ImageFilterView, - textView: TextView, - token: Token? = null, - blockchain: Blockchain, -) { - - val url: String? = if (token != null) { - token.id?.let { getIconUrl(it) } ?: token.getCustomIconUrl() - ?: IconsUtil.getTokenIconUri(blockchain, token)?.toString() - } else { - getIconUrl(blockchain.toNetworkId()) - } - - imageView.setImageDrawable(null) - imageView.colorFilter = null - textView.text = null - - when { - token?.symbol == QCX -> { - this.load(R.drawable.ic_qcx)?.into(imageView) - } - token?.symbol == VOYR -> { - this.load(R.drawable.ic_voyr)?.into(imageView) - } - url != 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 - } - }) - } - else -> { - setOfflineCurrencyImage(imageView, textView, token, blockchain) - } - } -} - -private const val QCX = "QCX" -private const val VOYR = "VOYRME" - -private fun setOfflineCurrencyImage( - imageView: ImageFilterView, - textView: TextView, - token: Token?, - blockchain: Blockchain, -) { - when (token) { - null -> setBlockchainImage(imageView, textView, blockchain) - else -> setTokenImage(imageView, textView, token, blockchain) - } -} - -private fun setBlockchainImage( - imageView: ImageFilterView, - textView: TextView, - blockchain: Blockchain, -) { - imageView.setImageResource(blockchain.getRoundIconRes()) - imageView.colorFilter = null - if (blockchain.isTestnet()) imageView.saturation = 0f - textView.text = null -} - -private fun setTokenImage( - imageView: ImageFilterView, - textView: TextView, - token: Token, - tokenBlockchain: Blockchain -) { - imageView.setImageResource(R.drawable.shape_circle) - if (tokenBlockchain.isTestnet()) { - imageView.saturation = 0f - } else { - imageView.setColorFilter(token.getColor()) - } - textView.text = token.symbol.take(1) -} - -private class RoundedCornersTransform : Transformation { - - override fun transform(source: Bitmap): Bitmap { - val size = source.width.coerceAtMost(source.height) - val x = (source.width - size) / 2 - val y = (source.height - size) / 2 - val squaredBitmap = Bitmap.createBitmap(source, x, y, size, size) - if (squaredBitmap != source) source.recycle() - - val paint = Paint().apply { - shader = BitmapShader(squaredBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP) - isAntiAlias = true - } - - val rectF = RectF(0f, 0f, source.width.toFloat(), source.height.toFloat()) - val radius = size / 8f - val bitmap = Bitmap.createBitmap(size, size, source.config) - Canvas(bitmap).drawRoundRect(rectF, radius, radius, paint) - squaredBitmap.recycle() - - return bitmap - } - - override fun key(): String = "rounded_corners" -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Specific.kt b/app/src/main/java/com/tangem/tap/common/extensions/Specific.kt index b431b780ad..219e9339da 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Specific.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Specific.kt @@ -53,8 +53,7 @@ fun BigDecimal.toFiatString( fiatCurrencyName: String, formatWithSpaces: Boolean = false ): String { - var fiatValue = rateValue.multiply(this) - fiatValue = fiatValue.setScale(2, RoundingMode.HALF_UP) + val fiatValue = rateValue.multiply(this) return fiatValue.toFormattedFiatValue(fiatCurrencyName, formatWithSpaces) } @@ -67,7 +66,8 @@ fun BigDecimal.toFormattedFiatValue( fiatCurrencyName: String, formatWithSpaces: Boolean = false ): String { - val fiatValue = if (formatWithSpaces) this.formatWithSpaces() else this + val fiatValue = this.setScale(2, RoundingMode.HALF_UP) + .let { if (formatWithSpaces) it.formatWithSpaces() else it } return " ${fiatValue}  $fiatCurrencyName" } diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Token.kt b/app/src/main/java/com/tangem/tap/common/extensions/Token.kt index fdfb83ef77..10897bc069 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Token.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Token.kt @@ -1,6 +1,8 @@ package com.tangem.tap.common.extensions +import android.graphics.Color import androidx.annotation.ColorInt +import androidx.core.graphics.luminance import androidx.core.graphics.toColorInt import com.tangem.blockchain.common.Token import com.tangem.wallet.R @@ -9,8 +11,13 @@ import com.tangem.wallet.R fun Token.getColor(): Int { return try { ("#" + this.contractAddress.subSequence(2..7).toString()) - .toColorInt() + .toColorInt() } catch (exception: Exception) { R.color.lightGray4 } +} + +@ColorInt +fun Token.getTextColor(): Int { + return if (this.getColor().luminance > 0.5) Color.BLACK else Color.WHITE } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/images/Coil.kt b/app/src/main/java/com/tangem/tap/common/images/Coil.kt new file mode 100644 index 0000000000..64b7b76734 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/images/Coil.kt @@ -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) } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/images/Picasso.kt b/app/src/main/java/com/tangem/tap/common/images/Picasso.kt deleted file mode 100644 index 81c52ca693..0000000000 --- a/app/src/main/java/com/tangem/tap/common/images/Picasso.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.tangem.tap.common.images - -import android.app.Application -import com.squareup.picasso.OkHttp3Downloader -import com.squareup.picasso.Picasso -import com.tangem.tap.logConfig -import com.tangem.wallet.BuildConfig -import okhttp3.Cache -import okhttp3.CacheControl -import okhttp3.OkHttpClient -import okhttp3.logging.HttpLoggingInterceptor -import timber.log.Timber -import java.io.File -import java.util.concurrent.TimeUnit - -class PicassoHelper { - companion object { - private const val KEEP_CACHE_MAX_DAYS = 7 - - fun initPicassoWithCaching(application: Application) { - val picasso = Picasso.Builder(application) - .downloader(OkHttp3Downloader(getOkHttpForPicasso(application))) - .build() - picasso.isLoggingEnabled = logIsEnabled() - picasso.setIndicatorsEnabled(BuildConfig.DEBUG) - Picasso.setSingletonInstance(picasso) - } - - private fun getOkHttpForPicasso(application: Application): OkHttpClient { - return OkHttpClient.Builder().apply { - cache(Cache(File(application.filesDir, "artworks"), Long.MAX_VALUE)) - callTimeout(15000, TimeUnit.MILLISECONDS) - - if (logIsEnabled()) { - addDebugInterceptors(this) - } - - addInterceptor { chain -> - val cacheControl = CacheControl.Builder() - .maxStale(KEEP_CACHE_MAX_DAYS, TimeUnit.DAYS) - .build() - val origRequest = chain.request() - val neverExpireRequest = origRequest.newBuilder() - .cacheControl(cacheControl) - .build() - chain.proceed(neverExpireRequest) - } - }.build() - - } - - private fun addDebugInterceptors(okHttpBuilder: OkHttpClient.Builder) { - val picassoInterceptor = HttpLoggingInterceptor(PicassoOkHttpLogger()).apply { - level = HttpLoggingInterceptor.Level.BODY - } - okHttpBuilder.addInterceptor(picassoInterceptor) - } - - private fun logIsEnabled(): Boolean = BuildConfig.DEBUG && logConfig.picasso - - } -} - -private class PicassoOkHttpLogger : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Timber.d(message) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/UrlBitmapLoader.kt b/app/src/main/java/com/tangem/tap/domain/UrlBitmapLoader.kt deleted file mode 100644 index c06d9b0001..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/UrlBitmapLoader.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.tangem.tap.domain - -import android.graphics.Bitmap -import android.graphics.drawable.Drawable -import android.os.Handler -import android.os.Looper -import com.squareup.picasso.Picasso -import com.squareup.picasso.Target -import com.tangem.common.services.Result - -/** -[REDACTED_AUTHOR] - */ -class UrlBitmapLoader { - private val mainHandler = Handler(Looper.getMainLooper()) - - fun loadBitmap(url: String, callback: (Result) -> Unit) { - val target = DownloadTarget(callback) - protectedFromGarbageCollectorTargets.add(target) - mainHandler.post { Picasso.get().load(url).into(target) } - } - - fun loadBitmap(url: String, target: DownloadTarget) { - protectedFromGarbageCollectorTargets.add(target) - Picasso.get().load(url).into(target) - } - -} - -private val protectedFromGarbageCollectorTargets = mutableListOf() - -// It adds the ability to trigger multiple downloads with a unique callback. -open class DownloadTarget( - val callback: (Result) -> Unit, -) : Target { - - override fun onBitmapLoaded(bitmap: Bitmap, from: Picasso.LoadedFrom) { - callback(Result.Success(bitmap)) - protectedFromGarbageCollectorTargets.remove(this) - } - - override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) { - callback.invoke(Result.Failure(e ?: Exception("Unknown exception"))) - protectedFromGarbageCollectorTargets.remove(this) - } - - override fun onPrepareLoad(placeHolderDrawable: Drawable?) { - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt index 06afdcbd3c..982ed86857 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt @@ -112,31 +112,44 @@ private class CreateWalletTangemWallet : ProductCommandProcessor when (result) { is CompletionResult.Success -> { - val createWalletResponses = result.data.createWalletResponses - when { - card.settings.isBackupAllowed -> { - linkPrimaryCard(createWalletResponses, session, callback) - } - card.settings.isHDWalletAllowed -> { - deriveKeys(createWalletResponses, session, callback) - } - else -> { - callback( - CompletionResult.Success( - CreateProductWalletTaskResponse(card = session.environment.card!!) - ) - ) - } - } + proceedWithCreatedWallets(result.data.createWalletResponses, session, callback) } is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) } } } + private fun proceedWithCreatedWallets( + createWalletResponses: List, + session: CardSession, + callback: (result: CompletionResult) -> Unit, + ) { + when { + card.settings.isBackupAllowed -> { + linkPrimaryCard(createWalletResponses, session, callback) + } + card.settings.isHDWalletAllowed -> { + deriveKeys(createWalletResponses, session, callback) + } + else -> { + callback( + CompletionResult.Success( + CreateProductWalletTaskResponse(card = session.environment.card!!) + ) + ) + } + } + } + private fun linkPrimaryCard( createWalletResponse: List, session: CardSession, 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 6888b7f648..2dafa32075 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 @@ -185,8 +185,9 @@ class CurrenciesRepository( tokens.map { async { tangemNetworkService.getTokens( - it.contractAddress, - it.blockchainDao.toBlockchain().toNetworkId() + contractAddress = it.contractAddress, + networkId = it.blockchainDao.toBlockchain().toNetworkId(), + active = true, ) } }.map { it.await() } diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/LoadAvailableCoinsService.kt b/app/src/main/java/com/tangem/tap/domain/tokens/LoadAvailableCoinsService.kt index a0be7dc18a..5b806beecc 100644 --- a/app/src/main/java/com/tangem/tap/domain/tokens/LoadAvailableCoinsService.kt +++ b/app/src/main/java/com/tangem/tap/domain/tokens/LoadAvailableCoinsService.kt @@ -53,6 +53,7 @@ class LoadAvailableCoinsService( val networkIds = supportedBlockchains.toSet().map { it.toNetworkId() } return networkService.getListOfCoins( networkIds = networkIds, + active = true, offset = offset, limit = LOAD_PER_PAGE, searchText = searchInput diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectRepository.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectRepository.kt index 8180023cb9..543640ad2f 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectRepository.kt @@ -5,11 +5,15 @@ import android.content.Context import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonClass import com.squareup.moshi.Types +import com.tangem.common.extensions.hexToBytes +import com.tangem.common.extensions.toHexString import com.tangem.network.common.MoshiConverter import com.tangem.tap.features.details.redux.walletconnect.WalletConnectSession import com.tangem.tap.features.details.redux.walletconnect.WalletForSession import com.trustwallet.walletconnect.models.WCPeerMeta import com.trustwallet.walletconnect.models.session.WCSession +import timber.log.Timber +import java.nio.charset.Charset class WalletConnectRepository(val context: Application) { private val moshi = MoshiConverter.defaultMoshi() @@ -35,17 +39,29 @@ class WalletConnectRepository(val context: Application) { fun loadSavedSessions(): List { return try { val json = context.readFileText(FILE_NAME_PREFIX_SESSIONS) + .hexToUtf8() walletConnectAdapter.fromJson(json)!!.map { it.toSession() } } catch (exception: Exception) { + Timber.e(exception) emptyList() } } private fun saveSessions(sessions: List) { val json = walletConnectAdapter.toJson(sessions.map { SessionDao.fromSession(it) }) + .utf8ToHex() // convert to hex to solve problems with saving text with emojis + Timber.e("WC sessions, saving following json: $json") context.rewriteFile(json, FILE_NAME_PREFIX_SESSIONS) } + private fun String.utf8ToHex(): String { + return this.toByteArray().toHexString() + } + + private fun String.hexToUtf8(): String { + return this.hexToBytes().toString(Charset.defaultCharset()) + } + private fun Context.readFileText(fileName: String): String = this.openFileInput(fileName).bufferedReader().readText() 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 3125784ba9..b31dd02832 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 @@ -10,7 +10,7 @@ import androidx.annotation.LayoutRes import androidx.constraintlayout.widget.ConstraintSet import androidx.core.view.isVisible import androidx.transition.TransitionManager -import com.squareup.picasso.Picasso +import coil.load import com.tangem.blockchain.common.Blockchain import com.tangem.tangem_sdk_new.extensions.fadeIn import com.tangem.tangem_sdk_new.extensions.fadeOut @@ -67,11 +67,11 @@ class OnboardingNoteFragment : BaseOnboardingFragment() { override fun newState(state: OnboardingNoteState) { if (activity == null || view == null) return - Picasso.get() - .load(state.cardArtworkUrl) - .error(R.drawable.card_placeholder_black) - .placeholder(R.drawable.card_placeholder_black) - ?.into(binding.onboardingTopContainer.imvFrontCard) + binding.onboardingTopContainer.imvFrontCard.load(state.cardArtworkUrl) { + placeholder(R.drawable.card_placeholder_black) + error(R.drawable.card_placeholder_black) + fallback(R.drawable.card_placeholder_black) + } pbBinding.pbState.max = state.steps.size - 1 pbBinding.pbState.progress = state.progress 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 996fdd67fe..e2b1e015c4 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 @@ -7,7 +7,7 @@ import androidx.annotation.LayoutRes import androidx.constraintlayout.widget.ConstraintSet import androidx.core.view.isVisible import androidx.transition.TransitionManager -import com.squareup.picasso.Picasso +import coil.load import com.tangem.tap.common.extensions.getDrawableCompat import com.tangem.tap.common.redux.navigation.ShareElement import com.tangem.tap.common.transitions.InternalNoteLayoutTransition @@ -54,11 +54,11 @@ class OnboardingOtherCardsFragment : BaseOnboardingFragment() { resources.getValue(R.dimen.device_scale_factor_for_twins_welcome, typedValue, true) val deviceScaleFactorForWelcomeState = typedValue.float - twinsWidget = TwinsCardWidget(LeapfrogWidget(binding.onboardingTopContainer.cardsContainer), deviceScaleFactorForWelcomeState) { + twinsWidget = TwinsCardWidget( + LeapfrogWidget(binding.onboardingTopContainer.cardsContainer), + deviceScaleFactorForWelcomeState + ) { 285f * deviceScaleFactorForWelcomeState } - btnRefreshBalanceWidget = RefreshBalanceWidget(binding.onboardingTopContainer.onboardingMainContainer) + btnRefreshBalanceWidget = + RefreshBalanceWidget(binding.onboardingTopContainer.onboardingMainContainer) binding.toolbar.title = getText(R.string.twins_recreate_toolbar) - Picasso.get() - .load(Artwork.TWIN_CARD_1) - .error(R.drawable.card_placeholder_black) - .placeholder(R.drawable.card_placeholder_black) - ?.into(binding.onboardingTopContainer.imvTwinFrontCard) + binding.onboardingTopContainer.imvTwinFrontCard.load(Artwork.TWIN_CARD_1) { + placeholder(R.drawable.card_placeholder_black) + error(R.drawable.card_placeholder_black) + fallback(R.drawable.card_placeholder_black) + } - Picasso.get() - .load(Artwork.TWIN_CARD_2) - .error(R.drawable.card_placeholder_white) - .placeholder(R.drawable.card_placeholder_white) - ?.into(binding.onboardingTopContainer.imvTwinBackCard) + binding.onboardingTopContainer.imvTwinBackCard.load(Artwork.TWIN_CARD_2) { + placeholder(R.drawable.card_placeholder_white) + error(R.drawable.card_placeholder_white) + fallback(R.drawable.card_placeholder_white) + } } private fun reconfigureLayoutForTwins(containerBinding: LayoutOnboardingContainerTopBinding) = diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt index b9691488c5..056d5a28bb 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt @@ -11,9 +11,9 @@ import androidx.fragment.app.Fragment import androidx.transition.TransitionInflater import androidx.transition.TransitionManager import by.kirich1409.viewbindingdelegate.viewBinding +import coil.load import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.tabs.TabLayoutMediator -import com.squareup.picasso.Picasso import com.tangem.common.CardIdFormatter import com.tangem.common.core.CardIdDisplayFormat import com.tangem.tangem_sdk_new.ui.widget.leapfrogWidget.LeapfrogWidget @@ -22,7 +22,12 @@ import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show import com.tangem.tap.features.FragmentOnBackPressedHandler import com.tangem.tap.features.addBackPressHandler -import com.tangem.tap.features.onboarding.products.wallet.redux.* +import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction +import com.tangem.tap.features.onboarding.products.wallet.redux.BackupState +import com.tangem.tap.features.onboarding.products.wallet.redux.BackupStep +import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletAction +import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletState +import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletStep import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.AccessCodeDialog import com.tangem.tap.store import com.tangem.wallet.R @@ -124,11 +129,11 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet), } private fun loadImageIntoImageView(url: String?, view: ImageView) { - Picasso.get() - .load(url) - .error(R.drawable.card_placeholder_black) - .placeholder(R.drawable.card_placeholder_black) - ?.into(view) + view.load(url) { + placeholder(R.drawable.card_placeholder_black) + error(R.drawable.card_placeholder_black) + fallback(R.drawable.card_placeholder_black) + } } private fun setupCreateWalletState() = with(binding) { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt index 28a7f06b08..c15813fdaa 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt @@ -7,6 +7,7 @@ import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.features.send.redux.ReceiptAction.RefreshReceipt import com.tangem.tap.features.send.redux.SendScreenAction import com.tangem.tap.features.send.redux.states.* +import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN import com.tangem.tap.store import java.math.BigDecimal @@ -15,10 +16,6 @@ import java.math.BigDecimal */ class ReceiptReducer : SendInternalReducer { - companion object { - const val EMPTY = "-" - } - private lateinit var sendState: SendState private lateinit var amountState: AmountState private lateinit var feeState: FeeState @@ -137,9 +134,9 @@ class ReceiptReducer : SendInternalReducer { ) } else { ReceiptTokenFiat( - amountFiat = EMPTY, - feeFiat = EMPTY, - totalFiat = EMPTY, + amountFiat = UNKNOWN_AMOUNT_SIGN, + feeFiat = UNKNOWN_AMOUNT_SIGN, + totalFiat = UNKNOWN_AMOUNT_SIGN, willSentToken = tokensToSend.stripZeroPlainString(), willSentFeeCoin = feeCoin.stripZeroPlainString(), symbols = symbols @@ -169,7 +166,7 @@ class ReceiptReducer : SendInternalReducer { ReceiptTokenCrypto( amountToken = tokensToSend.stripZeroPlainString(), feeCoin = feeCoin.stripZeroPlainString().addPrecisionSign(), - totalFiat = EMPTY, + totalFiat = UNKNOWN_AMOUNT_SIGN, symbols = symbols ) } @@ -206,7 +203,7 @@ class ReceiptReducer : SendInternalReducer { return when { !isToken && sendState.coinIsConvertible() -> sendState.coinConverter!!.toFiatWithPrecision(value).stripZeroPlainString() isToken && sendState.tokenIsConvertible() -> sendState.tokenConverter!!.toFiatWithPrecision(value).stripZeroPlainString() - else -> EMPTY + else -> UNKNOWN_AMOUNT_SIGN } } diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt index 3c49da49fb..2b71c1ba31 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt @@ -17,12 +17,13 @@ import com.tangem.tap.features.BaseStoreFragment import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.Error import com.tangem.tap.features.send.redux.FeeAction import com.tangem.tap.features.send.redux.SendAction -import com.tangem.tap.features.send.redux.reducers.ReceiptReducer import com.tangem.tap.features.send.redux.states.* import com.tangem.tap.features.send.ui.FeeUiHelper import com.tangem.tap.features.send.ui.SendFragment import com.tangem.tap.features.send.ui.dialogs.SendTransactionFailsDialog import com.tangem.tap.features.send.ui.dialogs.TezosWarningDialog +import com.tangem.tap.features.wallet.redux.WalletState.Companion.ROUGH_SIGN +import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN import com.tangem.tap.features.wallet.ui.adapters.WarningMessagesAdapter import com.tangem.tap.store import com.tangem.wallet.R @@ -257,12 +258,12 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : val mainLayout = clReceiptContainer as ViewGroup val totalLayout = llTotalContainer.llTotal as ViewGroup val totalTokenLayout = llTotalContainer.flTotalTokenCrypto as ViewGroup - fun getString(id: Int, vararg formatStrings: String): String = - mainLayout.context.getString(id, *formatStrings) - val rough = getString(R.string.sign_rough) - fun roughOrEmpty(value: String): String = - if (value == ReceiptReducer.EMPTY) value else "$rough $value" + fun getString(id: Int, vararg formatStrings: String): String = mainLayout.getString(id, *formatStrings) + + fun roughOrEmpty(value: String): String { + return if (value == UNKNOWN_AMOUNT_SIGN) value else "$ROUGH_SIGN $value" + } when (state.visibleTypeOfReceipt) { ReceiptLayoutType.FIAT -> { 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 e75ef8cd06..ce660968f6 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 @@ -301,6 +301,11 @@ data class WalletState( ) } else this } + + companion object { + const val UNKNOWN_AMOUNT_SIGN = "—" + const val ROUGH_SIGN = "≈" + } } sealed interface WalletDialog : StateDialog { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt index f61c3b6a0b..648479c03a 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt @@ -13,6 +13,7 @@ import com.tangem.tap.features.wallet.models.filterByToken import com.tangem.tap.features.wallet.models.getPendingTransactions import com.tangem.tap.features.wallet.models.removeUnknownTransactions import com.tangem.tap.features.wallet.redux.* +import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.BalanceWidgetData import com.tangem.tap.features.wallet.ui.TokenData @@ -127,9 +128,8 @@ class MultiWalletReducer { action.amount.decimals, action.amount.currencySymbol ), fiatAmountFormatted = tokenWalletData.fiatRate?.let { - action.amount.value - ?.toFiatString(it, store.state.globalState.appCurrency.symbol) - }, + action.amount.value?.toFiatString(it, store.state.globalState.appCurrency.symbol) + } ?: UNKNOWN_AMOUNT_SIGN, blockchainAmount = wallet.amounts[AmountType.Coin]?.value ?: BigDecimal.ZERO ), pendingTransactions = pendingTransactions.removeUnknownTransactions(), diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt index d97e1e9942..c3219215ff 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt @@ -14,11 +14,11 @@ import com.tangem.tap.features.wallet.models.filterByToken import com.tangem.tap.features.wallet.models.getPendingTransactions import com.tangem.tap.features.wallet.models.removeUnknownTransactions import com.tangem.tap.features.wallet.redux.* +import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.BalanceWidgetData import com.tangem.tap.features.wallet.ui.TokenData import com.tangem.tap.store -import java.math.RoundingMode class OnWalletLoadedReducer { @@ -55,6 +55,8 @@ class OnWalletLoadedReducer { } val fiatAmount = walletData.fiatRate?.let { coinAmountValue?.toFiatValue(it) } + val fiatAmountFormatted = fiatAmount?.toFormattedFiatValue(fiatCurrency.symbol) ?: UNKNOWN_AMOUNT_SIGN + val newWalletData = walletData.copy( currencyData = walletData.currencyData.copy( status = balanceStatus, @@ -64,7 +66,7 @@ class OnWalletLoadedReducer { amount = coinAmountValue, amountFormatted = formattedAmount, fiatAmount = fiatAmount, - fiatAmountFormatted = fiatAmount?.toFormattedFiatValue(fiatCurrency.symbol) + fiatAmountFormatted = fiatAmountFormatted, ), pendingTransactions = pendingTransactions.removeUnknownTransactions(), mainButton = WalletMainButton.SendButton(isCoinSendButtonEnabled), @@ -82,8 +84,9 @@ class OnWalletLoadedReducer { else -> BalanceStatus.VerifiedOnline } val tokenAmountValue = wallet.getTokenAmount(token)?.value - val tokenFiatAmount = - tokenWalletData?.fiatRate?.let { rate -> tokenAmountValue?.toFiatValue(rate) } + val tokenFiatAmount = tokenWalletData?.fiatRate?.let { tokenAmountValue?.toFiatValue(it) } + val tokenFiatAmountFormatted = tokenFiatAmount?.toFormattedFiatValue(fiatCurrency.symbol) + ?: UNKNOWN_AMOUNT_SIGN val isTokenSendButtonEnabled = newWalletData.shouldEnableTokenSendButton() && pendingTransactions.isEmpty() @@ -97,7 +100,7 @@ class OnWalletLoadedReducer { token.symbol ), fiatAmount = tokenFiatAmount, - fiatAmountFormatted = tokenFiatAmount?.toFormattedFiatValue(fiatCurrency.symbol) + fiatAmountFormatted = tokenFiatAmountFormatted, ), pendingTransactions = tokenPendingTransactions.removeUnknownTransactions(), mainButton = WalletMainButton.SendButton(isTokenSendButtonEnabled), @@ -141,9 +144,8 @@ class OnWalletLoadedReducer { wallet.blockchain.decimals(), wallet.blockchain.currency ) - val fiatRate = walletState.primaryWallet?.fiatRate - val fiatAmountRaw = fiatRate?.multiply(amount)?.setScale(2, RoundingMode.DOWN) - val fiatAmount = fiatRate?.let { amount?.toFiatString(it, fiatCurrencyName) } + val fiatAmount = walletState.primaryWallet?.fiatRate?.let { amount?.toFiatValue(it) } + val fiatAmountFormatted = fiatAmount?.toFormattedFiatValue(fiatCurrencyName) ?: UNKNOWN_AMOUNT_SIGN val pendingTransactions = wallet.getPendingTransactions() val sendButtonEnabled = amount?.isZero() == false && pendingTransactions.isEmpty() @@ -160,8 +162,8 @@ class OnWalletLoadedReducer { blockchainAmount = amount, amount = amount, amountFormatted = formattedAmount, - fiatAmountFormatted = fiatAmount, - fiatAmount = fiatAmountRaw + fiatAmount = fiatAmount, + fiatAmountFormatted = fiatAmountFormatted ), pendingTransactions = pendingTransactions.removeUnknownTransactions(), mainButton = WalletMainButton.SendButton(sendButtonEnabled), diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt index 8690684197..3ab2f769c4 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt @@ -217,8 +217,8 @@ private fun internalReduce(action: Action, state: AppState): WalletState { currency = walletBlockchain.currency, ), fiatAmount = fiatAmount, - fiatAmountFormatted = fiatAmount.toFiatRateString( - fiatCurrencyName = store.state.globalState.appCurrency.symbol + fiatAmountFormatted = fiatAmount.toFormattedFiatValue( + fiatCurrencyName = state.globalState.appCurrency.symbol ), amountToCreateAccount = action.amountToCreateAccount, ) @@ -439,7 +439,7 @@ private fun setMultiWalletFiatRate( wallet?.getTokenAmount(currency.token)?.value?.toFiatValue(rate) } if (currencyData.status == BalanceStatus.NoAccount && fiatAmount == null) { - fiatAmount = BigDecimal.ZERO + fiatAmount = BigDecimal.ZERO.setScale(2) } val fiatAmountFormatted = fiatAmount?.toFormattedFiatValue(appCurrency.symbol) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt index 2be2f19145..c627aa2e32 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt @@ -26,8 +26,8 @@ data class BalanceWidgetData( val blockchainAmount: BigDecimal? = BigDecimal.ZERO, val amount: BigDecimal? = null, val amountFormatted: String? = null, - val fiatAmountFormatted: String? = null, val fiatAmount: BigDecimal? = null, + val fiatAmountFormatted: String? = null, val token: TokenData? = null, val amountToCreateAccount: String? = null, val errorMessage: String? = null 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 a01e075a8b..d86030b5e7 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 @@ -11,7 +11,7 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.transition.TransitionInflater import by.kirich1409.viewbindingdelegate.viewBinding -import com.squareup.picasso.Picasso +import com.tangem.tangem_sdk_new.extensions.dpToPx import com.tangem.tap.common.SnackbarHandler import com.tangem.tap.common.TestActions import com.tangem.tap.common.extensions.* @@ -22,8 +22,10 @@ import com.tangem.tap.features.onboarding.getQRReceiveMessage import com.tangem.tap.features.wallet.models.Currency import com.tangem.tap.features.wallet.models.PendingTransaction import com.tangem.tap.features.wallet.redux.* +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.WalletDetailWarningMessagesAdapter +import com.tangem.tap.features.wallet.ui.images.loadCurrencyIcon import com.tangem.tap.features.wallet.ui.test.TestWalletDetails import com.tangem.tap.store import com.tangem.wallet.R @@ -127,11 +129,11 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), handleCurrencyIcon(selectedWallet) handleWarnings(selectedWallet) + updateViewMeasurements() binding.srlWalletDetails.setOnRefreshListener { if (selectedWallet.currencyData.status != BalanceStatus.Loading) { - store.dispatch( - WalletAction.LoadWallet( + store.dispatch(WalletAction.LoadWallet( blockchain = BlockchainNetwork( selectedWallet.currency.blockchain, selectedWallet.currency.derivationPath, @@ -147,13 +149,27 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), } } + private fun updateViewMeasurements() { + val tvFiatAmount = binding.lWalletDetails.lBalance.tvFiatAmount + val paddingStart = when (tvFiatAmount.text) { + UNKNOWN_AMOUNT_SIGN -> 16f + else -> 12f + } + tvFiatAmount.setPadding( + tvFiatAmount.dpToPx(paddingStart).toInt(), + tvFiatAmount.paddingTop, + tvFiatAmount.paddingEnd, + tvFiatAmount.paddingBottom, + ) + } + private fun setupCurrency(currencyData: BalanceWidgetData, currency: Currency) = with(binding) { tvCurrencyTitle.text = currencyData.currency if (currency is Currency.Token) { - binding.tvCurrencySubtitle.text = currency.blockchain.tokenDisplayName() - binding.tvCurrencySubtitle.show() + tvCurrencySubtitle.text = currency.blockchain.tokenDisplayName() + tvCurrencySubtitle.show() } else { - binding.tvCurrencySubtitle.hide() + tvCurrencySubtitle.hide() } } @@ -185,9 +201,9 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), } private fun handleCurrencyIcon(wallet: WalletData) = with(binding.lWalletDetails.lBalance) { - Picasso.get().loadCurrenciesIcon( - imageView = ivCurrency, - textView = tvTokenLetter, + loadCurrencyIcon( + currencyImageView = ivCurrency, + currencyTextView = tvTokenLetter, blockchain = wallet.currency.blockchain, token = (wallet.currency as? Currency.Token)?.token ) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index 6a113fb7a8..176fa48a14 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -12,7 +12,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.transition.TransitionInflater import by.kirich1409.viewbindingdelegate.viewBinding -import com.squareup.picasso.Picasso +import coil.load import com.tangem.tap.MainActivity import com.tangem.tap.common.extensions.show import com.tangem.tap.common.recyclerView.SpaceItemDecoration @@ -165,11 +165,11 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber 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() +} \ No newline at end of file diff --git a/app/src/main/res/layout/layout_balance.xml b/app/src/main/res/layout/layout_balance.xml index 0e3f124d94..6addd2be86 100644 --- a/app/src/main/res/layout/layout_balance.xml +++ b/app/src/main/res/layout/layout_balance.xml @@ -35,7 +35,8 @@ android:visibility="gone" app:drawableStartCompat="@drawable/ic_ok" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/tv_currency" /> + app:layout_constraintTop_toBottomOf="@id/tv_currency" + tools:visibility="visible" /> + tools:text="3.58 USD" /> + app:layout_constraintStart_toEndOf="@+id/tv_status_verified" + app:layout_constraintTop_toBottomOf="@id/tv_fiat_amount" + tools:text="123.12387628 XTZ" /> + app:layout_constraintTop_toBottomOf="@id/tv_fiat_amount" /> + tools:text="0.00434143 ETH" /> + tools:text="496304.28 RUB" /> + app:layout_constraintTop_toBottomOf="@id/tv_fiat_amount" + tools:text="0.43 BTC" /> + app:layout_constraintTop_toBottomOf="@id/tv_amount" + tools:text="Some error" /> diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index f336695b54..1617484429 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -331,7 +331,7 @@ %1s (%2s) Эта карта не является векселем на предъявителя. В настоящее время мы не можем сопоставить количество подписей на карте с информацией в блокчейне. Это нормально, но в редких случаях может означать, что предыдущий владелец скрывает автономную подпись, что является проблемой безопасности.\n\nНе принимайте эту карту в качестве физического платежа от кого-то, кому Вы не доверяете.\n\nВо всех остальных отношениях - это совершенно безопасно.\n\nTangem — единственный аппаратный кошелек, предлагающий защиту от подсчета подписей. WalletConnect - Запрос на создание транзакции для %2s\n%3s\n\nСумма: %4s\nКомиссия: %5s\nВсего: %6s\nБаланс: %7s + Карта %1s\nЗапрос на создание транзакции для %2s\n%3s\n\nСумма: %4s\nКомиссия: %5s\nВсего: %6s\nБаланс: %7s Запрос на запуск сеанса для карты с идентификатором %1s\nдля %2s\n\nURL: %3s Сессии WalletConnect Сеанс WalletConnect открыт с %s diff --git a/app/src/main/res/values/strings_untranslatable.xml b/app/src/main/res/values/strings_untranslatable.xml deleted file mode 100644 index ff1f090a6f..0000000000 --- a/app/src/main/res/values/strings_untranslatable.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index 649081be00..687dd82c75 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -141,7 +141,7 @@ Card: %s Tap card to bind to wallet connect - Card: %1s + Card: %1s\n Request to create transaction for %2s \n%3s diff --git a/domain/build.gradle b/domain/build.gradle index 169aea23f3..51b7ebb991 100644 --- a/domain/build.gradle +++ b/domain/build.gradle @@ -59,7 +59,7 @@ dependencies { implementation implementation(project(path: ':network')) implementation implementation(project(path: ':common')) - implementation 'com.tangem:blockchain:develop-88' + implementation 'com.tangem:blockchain:develop-90' // implementation 'com.tangem:blockchain:0.0.1' implementation 'com.tangem.tangem-sdk-kotlin:core:develop-154' implementation 'com.tangem.tangem-sdk-kotlin:android:develop-154' diff --git a/domain/src/main/java/com/tangem/domain/common/extensions/TangemTechService.kt b/domain/src/main/java/com/tangem/domain/common/extensions/TangemTechService.kt index f841679ffb..3304349b69 100644 --- a/domain/src/main/java/com/tangem/domain/common/extensions/TangemTechService.kt +++ b/domain/src/main/java/com/tangem/domain/common/extensions/TangemTechService.kt @@ -16,11 +16,13 @@ suspend fun TangemTechService.getTokens( suspend fun TangemTechService.getListOfCoins( networkIds: List, + active: Boolean? = null, searchText: String? = null, offset: Int? = null, limit: Int? = null ): Result = coins( networkIds = networkIds.joinToString(","), + active = active, searchText = searchText, offset = offset, limit = limit diff --git a/gradle.properties b/gradle.properties index 8f60b3bd0b..52a563ad69 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,4 +13,4 @@ org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryErro org.gradle.parallel=true org.gradle.daemon=true android.useAndroidX=true -android.enableJetifier=true \ No newline at end of file +android.enableJetifier=true