diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt index 252d3585e6..a5d9fc3932 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt @@ -162,9 +162,9 @@ private class ScanWalletProcessor( session: CardSession, callback: (result: CompletionResult) -> Unit, ) { - val activationIsFinished = preferencesStorage.usedCardsPrefStorage.isActivationFinished(card.cardId) + val activationInProgress = preferencesStorage.usedCardsPrefStorage.isActivationInProgress(card.cardId) - if (card.backupStatus == Card.BackupStatus.NoBackup && !activationIsFinished && card.wallets.isNotEmpty()) { + if (card.backupStatus == Card.BackupStatus.NoBackup && activationInProgress && card.wallets.isNotEmpty()) { StartPrimaryCardLinkingTask().run(session) { linkingResult -> when (linkingResult) { is CompletionResult.Success -> { diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt index f2227fcc32..2917a052fe 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt @@ -14,15 +14,16 @@ class OnboardingHelper { fun isOnboardingCase(response: ScanResponse): Boolean { val cardInfoStorage = preferencesStorage.usedCardsPrefStorage + val cardId = response.card.cardId return when { response.isTangemTwins() -> { if (!response.twinsIsTwinned()) { true } else { - cardInfoStorage.activationIsStarted(response.card.cardId) + cardInfoStorage.isActivationInProgress(cardId) } } - response.card.hasWallets() -> cardInfoStorage.activationIsStarted(response.card.cardId) + response.card.hasWallets() -> cardInfoStorage.isActivationInProgress(cardId) else -> true } } diff --git a/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt b/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt index 723af0df99..40e4cd1bd2 100644 --- a/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt +++ b/app/src/main/java/com/tangem/tap/persistence/PreferencesStorage.kt @@ -33,11 +33,6 @@ class PreferencesStorage(applicationContext: Application) { fun getCountOfLaunches(): Int = preferences.getInt(APP_LAUNCH_COUNT_KEY, 1) - @Deprecated("Use UsedCardsPrefStorage instead") - fun wasCardScannedBefore(cardId: String): Boolean { - return usedCardsPrefStorage.wasScanned(cardId) - } - fun saveDisclaimerAccepted() { preferences.edit { putBoolean(DISCLAIMER_ACCEPTED_KEY, true) } } diff --git a/app/src/main/java/com/tangem/tap/persistence/UsedCardsPrefStorage.kt b/app/src/main/java/com/tangem/tap/persistence/UsedCardsPrefStorage.kt index 5d7f241fb8..f814eb7e16 100644 --- a/app/src/main/java/com/tangem/tap/persistence/UsedCardsPrefStorage.kt +++ b/app/src/main/java/com/tangem/tap/persistence/UsedCardsPrefStorage.kt @@ -11,16 +11,16 @@ import timber.log.Timber */ class UsedCardsPrefStorage( private val preferences: SharedPreferences, - private val jsonConverter: MoshiJsonConverter + private val jsonConverter: MoshiJsonConverter, ) { - internal fun migrate() { - val scannedIds = preferences.getString(SCANNED_CARDS_IDS_KEY, null) ?: return + private val migrationList = mutableListOf( + UserCardInfoToV2(this), + ) - val usedCardsInfo = scannedIds.split(",").map { UsedCardInfo(it.trim(), true) } - if (save(usedCardsInfo.toMutableList())) { - preferences.edit { this.remove(SCANNED_CARDS_IDS_KEY) } - } + internal fun migrate() { + migrationList.forEach { it.migrate() } + migrationList.clear() } fun scanned(cardId: String) { @@ -43,20 +43,28 @@ class UsedCardsPrefStorage( save(foundItem, restoredList) } - fun isActivationFinished(cardId: String): Boolean { - return !(findCardInfo(cardId)?.isActivationStarted ?: true) + fun activationFinished(cardId: String) { + val restoredList = restore() + var foundItem = findCardInfo(cardId, restoredList) ?: UsedCardInfo(cardId) + foundItem = foundItem.copy( + isActivationStarted = true, + isActivationFinished = true, + ) + + save(foundItem, restoredList) } - fun activationIsStarted(cardId: String): Boolean { + fun isActivationStarted(cardId: String): Boolean { return findCardInfo(cardId)?.isActivationStarted ?: false } - fun activationFinished(cardId: String) { - val restoredList = restore() - val foundItem = findCardInfo(cardId, restoredList)?.copy(isActivationStarted = false) - ?: UsedCardInfo(cardId, isActivationStarted = false) + fun isActivationFinished(cardId: String): Boolean { + return findCardInfo(cardId)?.isActivationFinished ?: false + } - save(foundItem, restoredList) + fun isActivationInProgress(cardId: String): Boolean { + val cardInfo = findCardInfo(cardId) ?: return false + return cardInfo.isActivationStarted && !cardInfo.isActivationFinished } private fun findCardInfo(cardId: String, list: MutableList? = null): UsedCardInfo? { @@ -74,7 +82,7 @@ class UsedCardsPrefStorage( private fun save(list: MutableList): Boolean { return try { val json = jsonConverter.toJson(list) - preferences.edit { putString(USED_CARDS_INFO, json) } + preferences.edit { putString(USED_CARDS_INFO_V2, json) } true } catch (ex: Exception) { Timber.e(ex) @@ -83,23 +91,64 @@ class UsedCardsPrefStorage( } private fun restore(): MutableList { - val json = preferences.getString(USED_CARDS_INFO, null) ?: return mutableListOf() + val json = preferences.getString(USED_CARDS_INFO_V2, null) ?: return mutableListOf() return try { jsonConverter.fromJson(json, jsonConverter.typedList(UsedCardInfo::class.java))!! } catch (ex: Exception) { - preferences.edit(true) { remove(USED_CARDS_INFO) } + preferences.edit(true) { remove(USED_CARDS_INFO_V2) } mutableListOf() } } companion object { + private const val USED_CARDS_INFO_V2 = "usedCardsInfo_v2" private const val USED_CARDS_INFO = "usedCardsInfo" - private const val SCANNED_CARDS_IDS_KEY = "scannedCardIds" } + + private class UserCardInfoToV2( + private val storage: UsedCardsPrefStorage, + ) : Migration { + override fun migrate() { + val restoredCardsInfo = restore() + if (restoredCardsInfo.isEmpty()) return + + val newCardsInfo = restoredCardsInfo.map { cardInfo -> + UsedCardInfo( + cardId = cardInfo.cardId, + isScanned = cardInfo.isScanned, + isActivationStarted = true, + isActivationFinished = !cardInfo.isActivationStarted, + ) + }.toMutableList() + storage.save(newCardsInfo) + } + + private fun restore(): MutableList { + val json = storage.preferences.getString(USED_CARDS_INFO, null) ?: return mutableListOf() + return try { + storage.jsonConverter.fromJson(json, storage.jsonConverter.typedList(UsedCardInfoOld::class.java))!! + } catch (ex: Exception) { + mutableListOf() + } finally { + storage.preferences.edit(true) { remove(USED_CARDS_INFO) } + } + } + } + + private data class UsedCardInfo( + val cardId: String, + val isScanned: Boolean = false, + val isActivationStarted: Boolean = false, + val isActivationFinished: Boolean = false, + ) + + private data class UsedCardInfoOld( + val cardId: String, + val isScanned: Boolean = false, + val isActivationStarted: Boolean = false, + ) } -private data class UsedCardInfo( - val cardId: String, - val isScanned: Boolean = false, - val isActivationStarted: Boolean = false, -) \ No newline at end of file +private interface Migration { + fun migrate() +} \ No newline at end of file