Updated on 2026-08-14

This commit is contained in:
Tangem 2024-08-06 17:44:50 +04:00
commit 7a560a72c9
8 changed files with 28 additions and 127 deletions

View file

@ -6,14 +6,13 @@ import android.net.Uri
[REDACTED_AUTHOR]
*/
interface Disclaimer {
fun type(): DisclaimerType
fun getUri(): Uri
suspend fun accept()
suspend fun isAccepted(): Boolean
}
abstract class BaseDisclaimer(
protected val dataProvider: DisclaimerDataProvider,
private val dataProvider: DisclaimerDataProvider,
) : Disclaimer {
val baseUrl = "https://tangem.com"
@ -26,46 +25,11 @@ abstract class BaseDisclaimer(
}
class DummyDisclaimer : Disclaimer {
override fun type(): DisclaimerType = DisclaimerType.Tangem
override fun getUri(): Uri = Uri.parse("https://tangem.com/tangem_tos.html")
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")
}
class Start2CoinDisclaimer(dataProvider: DisclaimerDataProvider) : BaseDisclaimer(dataProvider) {
override fun type(): DisclaimerType = DisclaimerType.Start2Coin
override fun getUri(): Uri = Uri.parse("$baseUrl/" + filename(dataProvider.getLanguage(), getRegion()))
@Suppress("ComplexMethod")
private fun filename(languageCode: String, regionCode: String?): String {
return when {
languageCode == "fr" && regionCode == "ch" -> "start2coin-fr-ch-tangem.html"
languageCode == "de" && regionCode == "ch" -> "start2coin-de-ch-tangem.html"
languageCode == "en" && regionCode == "ch" -> "start2coin-en-ch-tangem.html"
languageCode == "it" && regionCode == "ch" -> "start2coin-it-ch-tangem.html"
languageCode == "fr" && regionCode == "fr" -> "start2coin-fr-fr-tangem.html"
languageCode == "de" && regionCode == "at" -> "start2coin-de-at-tangem.html"
regionCode == "fr" -> "start2coin-fr-fr-tangem.html"
regionCode == "ch" -> "start2coin-en-ch-tangem.html"
regionCode == "at" -> "start2coin-de-at-tangem.html"
else -> "start2coin-fr-fr-tangem.html"
}
}
private fun getRegion(): String? {
val cardId = dataProvider.getCardId()
if (cardId.isEmpty()) return null
return when (cardId[1]) {
'0' -> "fr"
'1' -> "ch"
'2' -> "at"
else -> null
}
}
}

View file

@ -1,58 +1,28 @@
package com.tangem.tap.features.disclaimer
import com.tangem.domain.common.TapWorkarounds.isStart2Coin
import com.tangem.domain.models.scan.CardDTO
import com.tangem.tap.common.extensions.inject
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.store
import java.util.Locale
/**
[REDACTED_AUTHOR]
*/
enum class DisclaimerType {
Tangem,
Start2Coin,
;
companion object {
fun get(cardDTO: CardDTO): DisclaimerType {
return when {
cardDTO.isStart2Coin -> Start2Coin
else -> Tangem
}
}
}
fun CardDTO.createDisclaimer(): Disclaimer {
val dataProvider = provideDisclaimerDataProvider(cardId)
return TangemDisclaimer(dataProvider)
}
fun DisclaimerType.createDisclaimer(cardDTO: CardDTO): Disclaimer {
val dataProvider = provideDisclaimerDataProvider(cardDTO.cardId, this)
return when (this) {
DisclaimerType.Tangem -> TangemDisclaimer(dataProvider)
DisclaimerType.Start2Coin -> Start2CoinDisclaimer(dataProvider)
}
}
fun CardDTO.createDisclaimer(): Disclaimer = DisclaimerType.get(this).createDisclaimer(this)
private fun provideDisclaimerDataProvider(cardId: String, disclaimerType: DisclaimerType): DisclaimerDataProvider {
private fun provideDisclaimerDataProvider(cardId: String): DisclaimerDataProvider {
val cardRepository = store.inject(DaggerGraphState::cardRepository)
return object : DisclaimerDataProvider {
override fun getLanguage(): String = Locale.getDefault().language
override fun getCardId(): String = cardId
override suspend fun accept() {
when (disclaimerType) {
DisclaimerType.Tangem -> cardRepository.acceptTangemTOS()
DisclaimerType.Start2Coin -> cardRepository.acceptStart2CoinTOS(cardId)
}
cardRepository.acceptTangemTOS()
}
override suspend fun isAccepted(): Boolean {
return when (disclaimerType) {
DisclaimerType.Tangem -> cardRepository.isTangemTOSAccepted()
DisclaimerType.Start2Coin -> cardRepository.isStart2CoinTOSAccepted(cardId)
}
return cardRepository.isTangemTOSAccepted()
}
}
}

View file

@ -35,14 +35,7 @@ sealed class AppRoute(val path: String) : Route {
@Serializable
data class Disclaimer(
val isTosAccepted: Boolean,
) : AppRoute(path = "/disclaimer${if (isTosAccepted) "/tos_accepted" else ""}"), RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
companion object {
const val IS_TOS_ACCEPTED_KEY = "isTosAccepted"
}
}
) : AppRoute(path = "/disclaimer${if (isTosAccepted) "/tos_accepted" else ""}")
@Serializable
data object OnboardingNote : AppRoute(path = "/onboarding/note")

View file

@ -95,8 +95,6 @@ object PreferencesKeys {
booleanPreferencesKey(name = "isTokenSwapPromoOkxShown")
}
fun getStart2CoinTOSAcceptedKey(region: String?) = booleanPreferencesKey(name = "start2Coin_tos_accepted_$region")
// region Permission
fun getShouldShowPermission(permission: String) = booleanPreferencesKey("shouldShowPushPermission_$permission")

View file

@ -80,24 +80,10 @@ internal class DefaultCardRepository(
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()
@ -127,16 +113,5 @@ internal class DefaultCardRepository(
.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
}
}
private fun createDefaultUsedCardInfo(cardId: String) = UsedCardInfo(cardId = cardId)
}

View file

@ -26,10 +26,5 @@ interface CardRepository {
@Throws
suspend fun isTangemTOSAccepted(): Boolean
@Throws
suspend fun isStart2CoinTOSAccepted(cardId: String): Boolean
suspend fun acceptTangemTOS()
suspend fun acceptStart2CoinTOS(cardId: String)
}

View file

@ -7,7 +7,6 @@ import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.navigation.finisher.AppFinisher
import com.tangem.features.disclaimer.api.components.DisclaimerComponent
import com.tangem.features.disclaimer.impl.model.DisclaimerModel
import com.tangem.features.disclaimer.impl.ui.DisclaimerScreen
@ -18,7 +17,6 @@ import dagger.assisted.AssistedInject
internal class DefaultDisclaimerComponent @AssistedInject constructor(
@Assisted context: AppComponentContext,
@Assisted private val params: DisclaimerComponent.Params,
private val appFinisher: AppFinisher,
) : DisclaimerComponent, AppComponentContext by context {
private val model: DisclaimerModel = getOrCreateModel(params)
@ -27,13 +25,7 @@ internal class DefaultDisclaimerComponent @AssistedInject constructor(
override fun Content(modifier: Modifier) {
val state by model.state.collectAsStateWithLifecycle()
BackHandler {
if (params.isTosAccepted) {
state.popBack()
} else {
appFinisher.finish()
}
}
BackHandler(onBack = state.popBack)
DisclaimerScreen(state = state)
}

View file

@ -5,6 +5,7 @@ import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.navigation.finisher.AppFinisher
import com.tangem.domain.card.repository.CardRepository
import com.tangem.domain.settings.NeverRequestPermissionUseCase
import com.tangem.domain.settings.NeverToInitiallyAskPermissionUseCase
@ -17,12 +18,14 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@ComponentScoped
@Suppress("LongParameterList")
internal class DisclaimerModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val cardRepository: CardRepository,
private val router: Router,
override val dispatchers: CoroutineDispatcherProvider,
private val neverToInitiallyAskPermissionUseCase: NeverToInitiallyAskPermissionUseCase,
private val neverRequestPermissionUseCase: NeverRequestPermissionUseCase,
private val appFinisher: AppFinisher,
paramsContainer: ParamsContainer,
) : Model() {
@ -33,23 +36,34 @@ internal class DisclaimerModel @Inject constructor(
onAccept = ::onAccept,
url = DISCLAIMER_URL,
isTosAccepted = params.isTosAccepted,
popBack = router::pop,
popBack = ::popBack,
),
)
private fun onAccept(shouldAskPushPermission: Boolean) {
modelScope.launch {
private fun onAccept(shouldAskPushPermission: Boolean) = modelScope.launch {
if (params.isTosAccepted) {
router.pop()
} else {
cardRepository.acceptTangemTOS()
if (shouldAskPushPermission) {
router.push(AppRoute.PushNotification)
} else {
neverToInitiallyAskPermissionUseCase(PUSH_PERMISSION)
neverRequestPermissionUseCase(PUSH_PERMISSION)
router.push(AppRoute.Home)
router.replaceAll(AppRoute.Home)
}
}
}
private fun popBack() {
if (params.isTosAccepted) {
router.pop()
} else {
appFinisher.finish()
}
}
private companion object {
const val DISCLAIMER_URL = "https://tangem.com/tangem_tos.html"
}