diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/Disclaimer.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/Disclaimer.kt index 6f09751342..f92bc4be2f 100644 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/Disclaimer.kt +++ b/app/src/main/java/com/tangem/tap/features/disclaimer/Disclaimer.kt @@ -8,8 +8,8 @@ import android.net.Uri interface Disclaimer { fun type(): DisclaimerType fun getUri(): Uri - fun accept() - fun isAccepted(): Boolean + suspend fun accept() + suspend fun isAccepted(): Boolean } abstract class BaseDisclaimer( @@ -18,32 +18,28 @@ abstract class BaseDisclaimer( val baseUrl = "https://tangem.com" - override fun accept() { - dataProvider.storage().accept(getPreferenceKey()) + override suspend fun accept() { + dataProvider.accept() } - override fun isAccepted(): Boolean = dataProvider.storage().isAccepted(getPreferenceKey()) - - protected open fun getPreferenceKey(): String = type().name + override suspend fun isAccepted(): Boolean = dataProvider.isAccepted() } class DummyDisclaimer : Disclaimer { override fun type(): DisclaimerType = DisclaimerType.Tangem override fun getUri(): Uri = Uri.parse("https://tangem.com/tangem_tos.html") - override fun accept() {} - override fun isAccepted(): Boolean = false + override suspend fun accept() {} + override suspend fun isAccepted(): Boolean = false } class TangemDisclaimer(dataProvider: DisclaimerDataProvider) : BaseDisclaimer(dataProvider) { override fun type(): DisclaimerType = DisclaimerType.Tangem override fun getUri(): Uri = Uri.parse("$baseUrl/tangem_tos.html") - override fun getPreferenceKey(): String = "tangem_tos_accepted" } class Start2CoinDisclaimer(dataProvider: DisclaimerDataProvider) : BaseDisclaimer(dataProvider) { override fun type(): DisclaimerType = DisclaimerType.Start2Coin override fun getUri(): Uri = Uri.parse("$baseUrl/" + filename(dataProvider.getLanguage(), getRegion())) - override fun getPreferenceKey(): String = "start2Coin_tos_accepted_${getRegion()}" @Suppress("ComplexMethod") private fun filename(languageCode: String, regionCode: String?): String { diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/DisclaimerDataProvider.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/DisclaimerDataProvider.kt index 9d3b4aeda6..ba3c82563d 100644 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/DisclaimerDataProvider.kt +++ b/app/src/main/java/com/tangem/tap/features/disclaimer/DisclaimerDataProvider.kt @@ -1,12 +1,11 @@ package com.tangem.tap.features.disclaimer -import com.tangem.data.source.preferences.storage.DisclaimerPrefStorage - /** [REDACTED_AUTHOR] */ interface DisclaimerDataProvider { fun getLanguage(): String fun getCardId(): String - fun storage(): DisclaimerPrefStorage + suspend fun accept() + suspend fun isAccepted(): Boolean } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/DisclaimerType.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/DisclaimerType.kt index b01b2b6f60..152ade0763 100644 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/DisclaimerType.kt +++ b/app/src/main/java/com/tangem/tap/features/disclaimer/DisclaimerType.kt @@ -2,8 +2,8 @@ package com.tangem.tap.features.disclaimer import com.tangem.domain.common.TapWorkarounds.isStart2Coin import com.tangem.domain.models.scan.CardDTO -import com.tangem.data.source.preferences.storage.DisclaimerPrefStorage -import com.tangem.tap.preferencesStorage +import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.store import java.util.Locale /** @@ -25,7 +25,7 @@ enum class DisclaimerType { } fun DisclaimerType.createDisclaimer(cardDTO: CardDTO): Disclaimer { - val dataProvider = provideDisclaimerDataProvider(cardDTO.cardId) + val dataProvider = provideDisclaimerDataProvider(cardDTO.cardId, this) return when (this) { DisclaimerType.Tangem -> TangemDisclaimer(dataProvider) DisclaimerType.Start2Coin -> Start2CoinDisclaimer(dataProvider) @@ -34,10 +34,24 @@ fun DisclaimerType.createDisclaimer(cardDTO: CardDTO): Disclaimer { fun CardDTO.createDisclaimer(): Disclaimer = DisclaimerType.get(this).createDisclaimer(this) -private fun provideDisclaimerDataProvider(cardId: String): DisclaimerDataProvider { +private fun provideDisclaimerDataProvider(cardId: String, disclaimerType: DisclaimerType): DisclaimerDataProvider { + val cardRepository = store.state.daggerGraphState.get(DaggerGraphState::cardRepository) return object : DisclaimerDataProvider { override fun getLanguage(): String = Locale.getDefault().language override fun getCardId(): String = cardId - override fun storage(): DisclaimerPrefStorage = preferencesStorage.disclaimerPrefStorage + + override suspend fun accept() { + when (disclaimerType) { + DisclaimerType.Tangem -> cardRepository.acceptTangemTOS() + DisclaimerType.Start2Coin -> cardRepository.acceptStart2CoinTOS(cardId) + } + } + + override suspend fun isAccepted(): Boolean { + return when (disclaimerType) { + DisclaimerType.Tangem -> cardRepository.isTangemTOSAccepted() + DisclaimerType.Start2Coin -> cardRepository.isStart2CoinTOSAccepted(cardId) + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerMiddleware.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerMiddleware.kt index e71184aff2..3e152187ea 100644 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/disclaimer/redux/DisclaimerMiddleware.kt @@ -3,7 +3,9 @@ package com.tangem.tap.features.disclaimer.redux import com.tangem.core.navigation.AppScreen import com.tangem.core.navigation.NavigationAction import com.tangem.tap.common.redux.AppState +import com.tangem.tap.mainScope import com.tangem.tap.store +import kotlinx.coroutines.launch import org.rekotlin.Action import org.rekotlin.Middleware @@ -26,9 +28,11 @@ private fun handleDisclaimerMiddleware(action: Action, appState: AppState) { store.dispatch(NavigationAction.NavigateTo(AppScreen.Disclaimer)) } is DisclaimerAction.AcceptDisclaimer -> { - state.disclaimer.accept() - store.dispatch(NavigationAction.PopBackTo()) - state.callback?.onAccept?.invoke() + mainScope.launch { + state.disclaimer.accept() + store.dispatch(NavigationAction.PopBackTo()) + state.callback?.onAccept?.invoke() + } } is DisclaimerAction.OnBackPressed -> { store.dispatch(NavigationAction.PopBackTo()) diff --git a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt index dc438d1872..d6767e13ac 100644 --- a/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/disclaimer/ui/DisclaimerFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.View import android.view.View.OVER_SCROLL_NEVER import android.webkit.WebView +import androidx.lifecycle.lifecycleScope import androidx.transition.TransitionInflater import by.kirich1409.viewbindingdelegate.viewBinding import com.tangem.core.navigation.AppScreen @@ -21,6 +22,7 @@ import com.tangem.tap.features.disclaimer.redux.DisclaimerState import com.tangem.tap.store import com.tangem.wallet.R import com.tangem.wallet.databinding.FragmentDisclaimerBinding +import kotlinx.coroutines.launch import org.rekotlin.StoreSubscriber class DisclaimerFragment : BaseFragment(R.layout.fragment_disclaimer), StoreSubscriber { @@ -92,10 +94,12 @@ class DisclaimerFragment : BaseFragment(R.layout.fragment_disclaimer), StoreSubs store.dispatch(DisclaimerAction.OnBackPressed) } - override fun newState(state: DisclaimerState) = with(binding) { - if (activity == null || view == null) return + override fun newState(state: DisclaimerState) { + return with(binding) { + if (activity == null || view == null) return - updateUiVisibility(state.disclaimer, state.progressState) + updateUiVisibility(state.disclaimer, state.progressState) + } } private fun updateUiVisibility(disclaimer: Disclaimer, progressState: ProgressState?) = with(binding) { @@ -112,7 +116,9 @@ class DisclaimerFragment : BaseFragment(R.layout.fragment_disclaimer), StoreSubs groupError.hide() groupLoading.hide() webView.show() - groupAccept.show(!disclaimer.isAccepted()) + lifecycleScope.launch { + groupAccept.show(!disclaimer.isAccepted()) + } } ProgressState.Error -> { root.beginDelayedTransition() diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesKeys.kt b/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesKeys.kt index 2b74eabdad..4ff06e36b2 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesKeys.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesKeys.kt @@ -3,6 +3,7 @@ package com.tangem.datasource.local.preferences import androidx.datastore.preferences.core.* import com.tangem.datasource.local.preferences.PreferencesKeys.APP_LAUNCH_COUNT_KEY import com.tangem.datasource.local.preferences.PreferencesKeys.FUNDS_FOUND_DATE_KEY +import com.tangem.datasource.local.preferences.PreferencesKeys.IS_TANGEM_TOS_ACCEPTED_KEY import com.tangem.datasource.local.preferences.PreferencesKeys.SAVE_USER_WALLETS_KEY import com.tangem.datasource.local.preferences.PreferencesKeys.SHOW_RATING_DIALOG_AT_LAUNCH_COUNT_KEY import com.tangem.datasource.local.preferences.PreferencesKeys.USED_CARDS_INFO_KEY @@ -57,6 +58,10 @@ object PreferencesKeys { val FEATURE_TOGGLES_KEY by lazy { stringPreferencesKey(name = "featureToggles") } val WAS_TWINS_ONBOARDING_SHOWN by lazy { booleanPreferencesKey(name = "twinsOnboardingShown") } + + val IS_TANGEM_TOS_ACCEPTED_KEY by lazy { booleanPreferencesKey(name = "tangem_tos_accepted") } + + fun getStart2CoinTOSAcceptedKey(region: String?) = booleanPreferencesKey(name = "start2Coin_tos_accepted_$region") } /** Preferences keys set that should be migrated from "PreferencesDataSource" to a new DataStore */ @@ -69,6 +74,7 @@ internal fun getTapPrefKeysToMigrate(): Set { USER_WAS_INTERACT_WITH_RATING_KEY, USED_CARDS_INFO_KEY, WAS_TWINS_ONBOARDING_SHOWN, + IS_TANGEM_TOS_ACCEPTED_KEY, ) .map(Preferences.Key<*>::name) .toSet() diff --git a/data/card/src/main/java/com/tangem/data/card/DefaultCardRepository.kt b/data/card/src/main/java/com/tangem/data/card/DefaultCardRepository.kt index e8328a84ea..0d868f3f10 100644 --- a/data/card/src/main/java/com/tangem/data/card/DefaultCardRepository.kt +++ b/data/card/src/main/java/com/tangem/data/card/DefaultCardRepository.kt @@ -6,6 +6,8 @@ import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.datasource.local.preferences.PreferencesKeys import com.tangem.datasource.local.preferences.utils.getObjectList import com.tangem.datasource.local.preferences.utils.getObjectListSync +import com.tangem.datasource.local.preferences.utils.getSyncOrDefault +import com.tangem.datasource.local.preferences.utils.store import com.tangem.domain.card.repository.CardRepository import com.tangem.utils.extensions.addOrReplace import kotlinx.coroutines.flow.Flow @@ -64,6 +66,28 @@ internal class DefaultCardRepository( return card.isActivationStarted && !card.isActivationFinished } + override suspend fun isTangemTOSAccepted(): Boolean { + return appPreferencesStore.getSyncOrDefault(key = PreferencesKeys.IS_TANGEM_TOS_ACCEPTED_KEY, default = false) + } + + override suspend fun isStart2CoinTOSAccepted(cardId: String): Boolean { + return appPreferencesStore.getSyncOrDefault( + key = PreferencesKeys.getStart2CoinTOSAcceptedKey(region = getRegion(cardId)), + default = false, + ) + } + + override suspend fun acceptTangemTOS() { + return appPreferencesStore.store(key = PreferencesKeys.IS_TANGEM_TOS_ACCEPTED_KEY, true) + } + + override suspend fun acceptStart2CoinTOS(cardId: String) { + appPreferencesStore.store( + key = PreferencesKeys.getStart2CoinTOSAcceptedKey(region = getRegion(cardId)), + value = true, + ) + } + private suspend fun AppPreferencesStore.editUsedCards(cardId: String, update: (UsedCardInfo) -> UsedCardInfo) { editData { mutablePreferences -> val usedCards = mutablePreferences.getUsedCards() @@ -92,4 +116,15 @@ internal class DefaultCardRepository( return appPreferencesStore.getObjectListSync(PreferencesKeys.USED_CARDS_INFO_KEY) .firstOrNull { it.cardId == cardId } } + + private fun getRegion(cardId: String): String? { + if (cardId.isEmpty()) return null + + return when (cardId[1]) { + '0' -> "fr" + '1' -> "ch" + '2' -> "at" + else -> null + } + } } \ No newline at end of file diff --git a/data/source/preferences/src/main/kotlin/com/tangem/data/source/preferences/PreferencesDataSource.kt b/data/source/preferences/src/main/kotlin/com/tangem/data/source/preferences/PreferencesDataSource.kt index 4bcd434fe8..e12d679fd7 100644 --- a/data/source/preferences/src/main/kotlin/com/tangem/data/source/preferences/PreferencesDataSource.kt +++ b/data/source/preferences/src/main/kotlin/com/tangem/data/source/preferences/PreferencesDataSource.kt @@ -3,7 +3,6 @@ package com.tangem.data.source.preferences import android.content.Context import android.content.SharedPreferences import androidx.core.content.edit -import com.tangem.data.source.preferences.storage.DisclaimerPrefStorage import javax.inject.Inject // 🔥FIXME: Only logic to work with preferences must be here, must be separated to repositories @@ -11,14 +10,11 @@ import javax.inject.Inject @Deprecated("Create repository instead") class PreferencesDataSource @Inject internal constructor(applicationContext: Context) { - val disclaimerPrefStorage: DisclaimerPrefStorage - private val preferences: SharedPreferences = applicationContext.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE) init { incrementLaunchCounter() - disclaimerPrefStorage = DisclaimerPrefStorage(preferences) } var shouldShowSaveUserWalletScreen: Boolean diff --git a/data/source/preferences/src/main/kotlin/com/tangem/data/source/preferences/storage/DisclaimerPrefStorage.kt b/data/source/preferences/src/main/kotlin/com/tangem/data/source/preferences/storage/DisclaimerPrefStorage.kt deleted file mode 100644 index e91fb9e27c..0000000000 --- a/data/source/preferences/src/main/kotlin/com/tangem/data/source/preferences/storage/DisclaimerPrefStorage.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.data.source.preferences.storage - -import android.content.SharedPreferences -import androidx.core.content.edit - -/** -[REDACTED_AUTHOR] - */ -@Deprecated("Create repository instead") -class DisclaimerPrefStorage internal constructor( - private val preferences: SharedPreferences, -) { - - fun accept(disclaimerKey: String) { - preferences.edit { putBoolean(disclaimerKey, true) } - } - - fun isAccepted(disclaimerKey: String): Boolean { - return preferences.getBoolean(disclaimerKey, false) - } -} \ No newline at end of file diff --git a/domain/card/src/main/kotlin/com/tangem/domain/card/repository/CardRepository.kt b/domain/card/src/main/kotlin/com/tangem/domain/card/repository/CardRepository.kt index 97a087c85e..68e476443e 100644 --- a/domain/card/src/main/kotlin/com/tangem/domain/card/repository/CardRepository.kt +++ b/domain/card/src/main/kotlin/com/tangem/domain/card/repository/CardRepository.kt @@ -22,4 +22,14 @@ interface CardRepository { @Throws suspend fun isActivationInProgress(cardId: String): Boolean + + @Throws + suspend fun isTangemTOSAccepted(): Boolean + + @Throws + suspend fun isStart2CoinTOSAccepted(cardId: String): Boolean + + suspend fun acceptTangemTOS() + + suspend fun acceptStart2CoinTOS(cardId: String) } \ No newline at end of file