Updated on 2026-08-14

This commit is contained in:
Tangem 2023-04-04 10:32:02 +03:00
parent be67efcca1
commit 40a3ada884
12 changed files with 100 additions and 32 deletions

View file

@ -0,0 +1,11 @@
package com.tangem.tap.features.demo
import com.tangem.datasource.demo.DemoModeData
import com.tangem.tap.proxy.AppStateHolder
import javax.inject.Inject
class DefaultDemoModeData @Inject constructor(private val appStateHolder: AppStateHolder) : DemoModeData {
override val isDemoModeActive: Boolean
get() = appStateHolder.scanResponse?.let { DemoHelper.isDemoCard(it) } == true
}

View file

@ -0,0 +1,18 @@
package com.tangem.tap.features.demo.di
import com.tangem.datasource.demo.DemoModeData
import com.tangem.tap.features.demo.DefaultDemoModeData
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal interface DemoModule {
@Binds
@Singleton
fun bindDemoModeHelper(demoModeHelper: DefaultDemoModeData): DemoModeData
}

View file

@ -10,7 +10,6 @@ import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.details.redux.DetailsState
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
import com.tangem.tap.features.home.LocaleRegionProvider
@ -101,15 +100,7 @@ class DetailsViewModel(private val store: Store<AppState>) {
// TODO: To be available later
}
SettingsElement.ReferralProgram -> {
if (store.state.detailsState.scanResponse?.let { DemoHelper.isDemoCard(it) } == true) {
detailsScreenState.value.showErrorSnackbar.value = EventError.DemoReferralNotAvailable(
onErrorShow = {
detailsScreenState.value.showErrorSnackbar.value = EventError.Empty
},
)
} else {
store.dispatch(NavigationAction.NavigateTo(AppScreen.ReferralProgram))
}
store.dispatch(NavigationAction.NavigateTo(AppScreen.ReferralProgram))
}
SettingsElement.TesterMenu -> {
store.state.daggerGraphState.testerRouter?.startTesterScreen()

View file

@ -0,0 +1,10 @@
package com.tangem.datasource.demo
/**
* Data provides for demo cards
*
*/
interface DemoModeData {
val isDemoModeActive: Boolean
}

View file

@ -2,6 +2,7 @@ package com.tangem.feature.referral.data
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.api.tangemTech.models.StartReferralBody
import com.tangem.datasource.demo.DemoModeData
import com.tangem.feature.referral.converters.ReferralConverter
import com.tangem.feature.referral.domain.ReferralRepository
import com.tangem.feature.referral.domain.models.ReferralData
@ -13,8 +14,12 @@ internal class ReferralRepositoryImpl @Inject constructor(
private val referralApi: TangemTechApi,
private val referralConverter: ReferralConverter,
private val coroutineDispatcher: CoroutineDispatcherProvider,
private val demoModeData: DemoModeData,
) : ReferralRepository {
override val isDemoMode: Boolean
get() = demoModeData.isDemoModeActive
override suspend fun getReferralStatus(walletId: String): ReferralData {
return withContext(coroutineDispatcher.io) {
referralConverter.convert(referralApi.getReferralStatus(walletId))

View file

@ -1,6 +1,7 @@
package com.tangem.feature.referral.di
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.demo.DemoModeData
import com.tangem.feature.referral.converters.ReferralConverter
import com.tangem.feature.referral.data.ReferralRepositoryImpl
import com.tangem.feature.referral.domain.ReferralRepository
@ -21,11 +22,13 @@ class ReferralRepositoryModule {
tangemTechApi: TangemTechApi,
referralConverter: ReferralConverter,
coroutineDispatcherProvider: CoroutineDispatcherProvider,
demoModeData: DemoModeData,
): ReferralRepository {
return ReferralRepositoryImpl(
referralApi = tangemTechApi,
referralConverter = referralConverter,
coroutineDispatcher = coroutineDispatcherProvider,
demoModeData = demoModeData,
)
}
}

View file

@ -4,6 +4,8 @@ import com.tangem.feature.referral.domain.models.ReferralData
interface ReferralInteractor {
val isDemoMode: Boolean
suspend fun getReferralStatus(): ReferralData
suspend fun startReferral(): ReferralData

View file

@ -16,6 +16,9 @@ internal class ReferralInteractorImpl(
private val tokensForReferral = mutableListOf<TokenData>()
override val isDemoMode: Boolean
get() = repository.isDemoMode
override suspend fun getReferralStatus(): ReferralData {
val refStatus = repository.getReferralStatus(userWalletManager.getWalletId())
saveRefTokens(refStatus.tokens)

View file

@ -4,6 +4,8 @@ import com.tangem.feature.referral.domain.models.ReferralData
interface ReferralRepository {
val isDemoMode: Boolean
/** Returns data object of [ReferralData] depends on user program status */
suspend fun getReferralStatus(walletId: String): ReferralData

View file

@ -0,0 +1,6 @@
package com.tangem.feature.referral.models
/**
* Exception that throws when card in demo mode
*/
class DemoModeException : Exception()

View file

@ -59,6 +59,7 @@ import com.tangem.core.ui.components.VerticalSpacer
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.res.TangemColorPalette
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.referral.models.DemoModeException
import com.tangem.feature.referral.models.ReferralStateHolder
import com.tangem.feature.referral.models.ReferralStateHolder.ErrorSnackbar
import com.tangem.feature.referral.models.ReferralStateHolder.ReferralInfoContentState
@ -385,16 +386,8 @@ private fun BoxScope.ErrorSnackbarHost(errorSnackbar: ErrorSnackbar?) {
},
)
val message = if (errorSnackbar.throwable.cause != null) {
String.format(
format = stringResource(id = R.string.referral_error_failed_to_load_info_with_reason),
errorSnackbar.throwable.cause,
)
} else {
stringResource(id = R.string.referral_error_failed_to_load_info)
}
val actionLabel = stringResource(id = R.string.warning_button_ok)
val message = getMessageForErrorSnackbar(errorSnackbar)
SideEffect {
coroutineScope.launch {
val result = snackbarHostState.showSnackbar(
@ -463,6 +456,25 @@ private fun BoxScope.CopySnackbarHost(isCopyButtonPressed: MutableState<Boolean>
}
}
@Composable
private fun getMessageForErrorSnackbar(errorSnackbar: ErrorSnackbar): String {
return when (errorSnackbar.throwable) {
is DemoModeException -> {
stringResource(id = R.string.alert_demo_feature_disabled)
}
else -> {
if (errorSnackbar.throwable.cause != null) {
String.format(
format = stringResource(id = R.string.referral_error_failed_to_load_info_with_reason),
errorSnackbar.throwable.cause,
)
} else {
stringResource(id = R.string.referral_error_failed_to_load_info)
}
}
}
}
@Preview(widthDp = 360, showBackground = true)
@Composable
private fun Preview_ReferralScreen_Participant_InLightTheme() {

View file

@ -11,6 +11,7 @@ import com.tangem.feature.referral.domain.ReferralInteractor
import com.tangem.feature.referral.domain.models.DiscountType
import com.tangem.feature.referral.domain.models.ReferralData
import com.tangem.feature.referral.domain.models.ReferralInfo
import com.tangem.feature.referral.models.DemoModeException
import com.tangem.feature.referral.models.ReferralStateHolder
import com.tangem.feature.referral.models.ReferralStateHolder.ErrorSnackbar
import com.tangem.feature.referral.models.ReferralStateHolder.ReferralInfoState
@ -75,21 +76,25 @@ internal class ReferralViewModel @Inject constructor(
}
private fun participate() {
analyticsEventHandler.send(ReferralEvents.ClickParticipate)
uiState = uiState.copy(referralInfoState = ReferralInfoState.Loading)
viewModelScope.launch(dispatchers.main) {
runCatching(dispatchers.io) { referralInteractor.startReferral() }
.onSuccess(::showContent)
.onFailure {
if (it is UserCancelledException) {
val lastRefData = lastReferralData.value
if (lastRefData != null) {
showContent(lastRefData)
if (referralInteractor.isDemoMode) {
showErrorSnackbar(DemoModeException())
} else {
analyticsEventHandler.send(ReferralEvents.ClickParticipate)
uiState = uiState.copy(referralInfoState = ReferralInfoState.Loading)
viewModelScope.launch(dispatchers.main) {
runCatching(dispatchers.io) { referralInteractor.startReferral() }
.onSuccess(::showContent)
.onFailure {
if (it is UserCancelledException) {
val lastRefData = lastReferralData.value
if (lastRefData != null) {
showContent(lastRefData)
}
} else {
showErrorSnackbar(it)
}
} else {
showErrorSnackbar(it)
}
}
}
}
}