From c2876c2fed37689e791b3253d5ce170ec62cdde9 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 22 Sep 2020 12:13:20 +0300 Subject: [PATCH 1/5] Updated on 2026-08-14 --- .../tap/domain/tasks/CreateWalletAndRescanTask.kt | 15 +++++++++++---- .../com/tangem/tap/domain/tasks/ScanNoteTask.kt | 15 +++------------ 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/CreateWalletAndRescanTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/CreateWalletAndRescanTask.kt index cc539e426e..0af8e1f29b 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/CreateWalletAndRescanTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/CreateWalletAndRescanTask.kt @@ -2,17 +2,24 @@ package com.tangem.tap.domain.tasks import com.tangem.CardSession import com.tangem.CardSessionRunnable -import com.tangem.commands.CreateWalletCommand +import com.tangem.commands.ReadCommand import com.tangem.common.CompletionResult +import com.tangem.tasks.CreateWalletTask class CreateWalletAndRescanTask : CardSessionRunnable { override val requiresPin2 = false override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - CreateWalletCommand().run(session) { result -> + CreateWalletTask().run(session) { result -> when (result) { - is CompletionResult.Success -> ScanNoteTask().run(session, callback) - + is CompletionResult.Success -> { + ReadCommand().run(session) { readResult -> + when (readResult) { + is CompletionResult.Success -> ScanNoteTask(readResult.data).run(session, callback) + is CompletionResult.Failure -> callback(CompletionResult.Failure(readResult.error)) + } + } + } is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) } } diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt index e733a18b30..d773a34f8a 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/ScanNoteTask.kt @@ -18,7 +18,7 @@ data class ScanNoteResponse( val verifyResponse: VerifyCardResponse? = null ) : CommandResponse -class ScanNoteTask : CardSessionRunnable { +class ScanNoteTask(val card: Card? = null) : CardSessionRunnable { override val requiresPin2 = false override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { @@ -27,7 +27,8 @@ class ScanNoteTask : CardSessionRunnable { is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) is CompletionResult.Success -> { - val card = result.data + val card = this.card ?: result.data + val walletManager = try { WalletManagerFactory.makeWalletManager(card) } catch (exception: Exception) { @@ -49,14 +50,4 @@ class ScanNoteTask : CardSessionRunnable { } } } -} - -fun Card?.toScanNoteCompletionResult(): CompletionResult { - this ?: return CompletionResult.Failure(TangemSdkError.CardError()) - val walletManager = try { - WalletManagerFactory.makeWalletManager(this) - } catch (exception: Exception) { - return CompletionResult.Success(ScanNoteResponse(null, this)) - } - return CompletionResult.Success(ScanNoteResponse(walletManager, this)) } \ No newline at end of file From 9a14c11e3344361d356770715ae2120510578d43 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 22 Sep 2020 12:15:12 +0300 Subject: [PATCH 2/5] Updated on 2026-08-14 --- .../tangem/tap/features/wallet/redux/WalletState.kt | 6 +++++- .../tangem/tap/features/wallet/ui/WalletFragment.kt | 13 +++++++++---- 2 files changed, 14 insertions(+), 5 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 5e6f65ae2a..442a8245df 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 @@ -21,7 +21,11 @@ data class WalletState( val payIdData: PayIdData = PayIdData(), val walletDialog: WalletDialog? = null, val mainButton: WalletMainButton = WalletMainButton.SendButton(false) -) : StateType +) : StateType { + val showDetails: Boolean = + currencyData.status != com.tangem.tap.features.wallet.ui.BalanceStatus.EmptyCard && + currencyData.status != com.tangem.tap.features.wallet.ui.BalanceStatus.UnknownBlockchain +} sealed class WalletDialog { data class QrDialog( 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 bd7361c2eb..964443aea2 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 @@ -3,18 +3,17 @@ package com.tangem.tap.features.wallet.ui import android.app.Dialog import android.os.Bundle import android.view.Menu +import android.view.Menu.NONE import android.view.MenuInflater import android.view.MenuItem import android.view.View -import android.view.animation.AlphaAnimation -import android.view.animation.Animation import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.transition.TransitionInflater import com.google.android.material.snackbar.Snackbar -import com.tangem.tap.common.extensions.getDrawable +import com.squareup.picasso.Picasso import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show import com.tangem.tap.common.redux.navigation.AppScreen @@ -93,6 +92,12 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber Date: Tue, 22 Sep 2020 12:29:03 +0300 Subject: [PATCH 3/5] Updated on 2026-08-14 --- app/build.gradle | 5 ++- .../java/com/tangem/tap/TapApplication.kt | 2 + .../com/tangem/tap/common/images/Picasso.kt | 39 +++++++++++++++++++ .../com/tangem/tap/domain/TapWalletManager.kt | 19 --------- .../features/wallet/redux/WalletMiddleware.kt | 16 -------- .../features/wallet/redux/WalletReducer.kt | 17 +++++++- .../tap/features/wallet/redux/WalletState.kt | 2 +- .../tap/features/wallet/ui/BalanceWidget.kt | 1 + .../tap/features/wallet/ui/WalletFragment.kt | 27 ++++--------- .../main/res/drawable/card_placeholder.xml | 37 ++++++++++-------- app/src/main/res/layout/fragment_wallet.xml | 11 ------ 11 files changed, 90 insertions(+), 86 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/common/images/Picasso.kt diff --git a/app/build.gradle b/app/build.gradle index f5ebeb41d2..b0a54a390e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -91,9 +91,12 @@ dependencies { // Camera implementation 'com.otaliastudios:cameraview:2.6.3' + // Image Loading - Picasso + implementation 'com.squareup.picasso:picasso:2.71828' + testImplementation 'junit:junit:4.13' testImplementation "com.google.truth:truth:1.0.1" - androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index fdb8c65fd9..b19bfc730e 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -1,6 +1,7 @@ package com.tangem.tap import android.app.Application +import com.tangem.tap.common.images.PicassoHelper import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.appReducer import com.tangem.tap.network.NetworkConnectivity @@ -24,5 +25,6 @@ class TapApplication : Application() { } NetworkConnectivity.createInstance(store, this) preferencesStorage = PreferencesStorage(this) + PicassoHelper.initPicassoWithCaching(this) } } \ 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 new file mode 100644 index 0000000000..c3b1d139a3 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/images/Picasso.kt @@ -0,0 +1,39 @@ +package com.tangem.tap.common.images + +import android.app.Application +import com.squareup.picasso.OkHttp3Downloader +import com.squareup.picasso.Picasso +import okhttp3.Cache +import okhttp3.CacheControl +import okhttp3.OkHttpClient +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.setSingletonInstance(picasso) + } + + private fun getOkHttpForPicasso(application: Application): OkHttpClient { + val okHttpBuilder = OkHttpClient.Builder() + okHttpBuilder.cache(Cache(File(application.filesDir, "artworks"), Long.MAX_VALUE)) + okHttpBuilder.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) + } + return okHttpBuilder.build() + } + } +} \ No newline at end of file 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 cd71354e23..5d57c694c2 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -2,17 +2,14 @@ package com.tangem.tap.domain import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.WalletManager -import com.tangem.commands.Card import com.tangem.commands.CardStatus import com.tangem.commands.common.network.Result -import com.tangem.commands.common.network.TangemService import com.tangem.common.extensions.toHexString import com.tangem.tap.TapConfig import com.tangem.tap.common.redux.global.CryptoCurrencyName import com.tangem.tap.common.redux.global.FiatCurrencyName import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.domain.tasks.ScanNoteResponse -import com.tangem.tap.features.wallet.redux.Artwork import com.tangem.tap.features.wallet.redux.PayIdState import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.network.NetworkConnectivity @@ -26,7 +23,6 @@ import java.math.BigDecimal class TapWalletManager { private val payIdManager = PayIdManager() private val coinMarketCapService = CoinMarketCapService() - private val tangemService = TangemService() suspend fun loadWalletData() { val walletManager = store.state.globalState.scanNoteResponse?.walletManager @@ -37,21 +33,6 @@ class TapWalletManager { updateWallet(walletManager) } - suspend fun loadArtwork(card: Card, artworkId: String) { - val result = - tangemService.getArtwork(card.cardId, card.cardPublicKey!!.toHexString(), artworkId) - withContext(Dispatchers.Main) { - when (result) { - is Result.Success -> { - store.dispatch(WalletAction.LoadArtwork.Success( - Artwork(artworkId, result.data.byteStream().readBytes()) - )) - } - is Result.Failure -> store.dispatch(WalletAction.LoadArtwork.Failure) - } - } - } - suspend fun loadPayId() { val result = loadPayIdIfNeeded() result?.let { handlePayIdResult(it) } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt index f6354b7291..30723845db 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt @@ -19,7 +19,6 @@ import com.tangem.tap.network.NetworkStateChanged import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.tap.tangemSdkManager -import com.tangem.wallet.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -46,21 +45,6 @@ val walletMiddleware: Middleware = { dispatch, state -> store.state.globalState.tapWalletManager.loadFiatRate(store.state.globalState.appCurrency) } } - is WalletAction.LoadArtwork -> { - if (action.artworkId != null) { - scope.launch { - store.state.globalState.tapWalletManager.loadArtwork( - action.card, action.artworkId - ) - } - } else { - val artworkRes = R.drawable.card_default - store.dispatch(WalletAction.LoadArtwork.Success(Artwork( - artworkId = artworkRes.toString(), artworkResId = artworkRes - ))) - } - - } is WalletAction.CreateWallet -> { scope.launch { val result = tangemSdkManager.createWallet( diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt index c348a46df0..771796f0aa 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt @@ -2,6 +2,7 @@ package com.tangem.tap.features.wallet.redux import com.tangem.blockchain.common.AmountType import com.tangem.common.extensions.isZero +import com.tangem.common.extensions.toHexString import com.tangem.tap.common.extensions.toFiatString import com.tangem.tap.common.extensions.toFormattedCurrencyString import com.tangem.tap.common.extensions.toFormattedString @@ -12,6 +13,8 @@ import com.tangem.tap.features.wallet.models.toPendingTransactions 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 com.tangem.wallet.R import org.rekotlin.Action class WalletReducer { @@ -165,8 +168,18 @@ private fun internalReduce(action: Action, state: AppState): WalletState { token = newState.currencyData.token?.copy(fiatAmount = tokenFiatAmount) )) } - is WalletAction.LoadArtwork.Success -> { - newState = newState.copy(cardImage = action.artwork) + is WalletAction.LoadArtwork -> { +// TODO: form URL in Card SDK + var artworkAddress = "https://verify.tangem.com/card/artwork" + artworkAddress += "?artworkId=${action.artworkId}" + artworkAddress += "&CID=${store.state.globalState.scanNoteResponse?.card?.cardId}" + artworkAddress += "&publicKey=${store.state.globalState.scanNoteResponse?.card?.cardPublicKey?.toHexString()}" + val artwork = if (action.artworkId != null) { + Artwork(artworkId = artworkAddress) + } else { + Artwork(artworkResId = R.drawable.card_default) + } + newState = newState.copy(cardImage = artwork) } is WalletAction.ShowQrCode -> { newState = newState.copy( 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 442a8245df..9ed907067c 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 @@ -62,7 +62,7 @@ data class AddressData( ) data class Artwork( - val artworkId: String, + val artworkId: String? = null, val artwork: Bitmap? = null, val artworkResId: Int? = null ) { 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 78e93bddaf..1ae33a2fc3 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 @@ -85,6 +85,7 @@ class BalanceWidget( fragment.tv_status_error_message.text = data.errorMessage showStatus(R.id.group_error) + fragment.tv_status_error_message.show(!data.errorMessage.isNullOrBlank()) } BalanceStatus.EmptyCard -> { fragment.l_balance.hide() 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 964443aea2..1aeee3210d 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 @@ -35,7 +35,6 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber Picasso.get().load(address) + is Int -> Picasso.get().load(address) + else -> null } - } - - private fun prepareShowingCardImage(artworkId: String) { - this.artworkId = artworkId - val fadeInAnimation: Animation = AlphaAnimation(0.0f, 1.0f) - fadeInAnimation.duration = 400 - iv_card.startAnimation(fadeInAnimation) - iv_card_tangem_logo.hide() + picassoRequest?.placeholder(R.drawable.card_placeholder) + ?.error(R.drawable.card_placeholder) + ?.into(iv_card) } private fun handleDialogs(walletDialog: WalletDialog?) { diff --git a/app/src/main/res/drawable/card_placeholder.xml b/app/src/main/res/drawable/card_placeholder.xml index 917ac784e2..1cfef76e78 100644 --- a/app/src/main/res/drawable/card_placeholder.xml +++ b/app/src/main/res/drawable/card_placeholder.xml @@ -1,19 +1,22 @@ - + + + - - - - - - \ No newline at end of file + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_wallet.xml b/app/src/main/res/layout/fragment_wallet.xml index 8ef1ecf464..17b4723d89 100644 --- a/app/src/main/res/layout/fragment_wallet.xml +++ b/app/src/main/res/layout/fragment_wallet.xml @@ -60,17 +60,6 @@ android:scaleType="fitCenter" android:src="@drawable/card_placeholder" app:layout_constraintTop_toTopOf="parent" /> - - Date: Tue, 22 Sep 2020 11:16:24 +0000 Subject: [PATCH 4/5] 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 b0a54a390e..f6b39ce537 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,7 +64,7 @@ dependencies { implementation 'com.google.android.material:material:1.2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' - implementation 'com.tangem:blockchain:1.37.0' + implementation 'com.tangem:blockchain:1.39.0' //lifecycle implementation "androidx.lifecycle:lifecycle-runtime:2.2.0" From e805a900600f18212b62ea30282dd1efd23ca327 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 22 Sep 2020 11:26:54 +0000 Subject: [PATCH 5/5] 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 f6b39ce537..3e0dc1e312 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,7 +64,7 @@ dependencies { implementation 'com.google.android.material:material:1.2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' - implementation 'com.tangem:blockchain:1.39.0' + implementation 'com.tangem:blockchain:1.40.0' //lifecycle implementation "androidx.lifecycle:lifecycle-runtime:2.2.0"