Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-31 16:19:25 +04:00
parent e3fe78843c
commit 91bf984cd3
17 changed files with 115 additions and 50 deletions

View file

@ -1,8 +1,9 @@
package com.tangem.tap.di.domain
import com.tangem.domain.balancehiding.DeviceFlipDetector
import com.tangem.domain.balancehiding.IsBalanceHiddenUseCase
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
import com.tangem.domain.balancehiding.UpdateBalanceHidingSettingsUseCase
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
import com.tangem.domain.settings.*
import com.tangem.domain.settings.repositories.AppRatingRepository
@ -63,8 +64,10 @@ internal object SettingsDomainModule {
@Provides
@ViewModelScoped
fun providesIsBalanceHiddenUseCase(balanceHidingRepository: BalanceHidingRepository): IsBalanceHiddenUseCase {
return IsBalanceHiddenUseCase(
fun providesGetBalanceHidingSettingsUseCase(
balanceHidingRepository: BalanceHidingRepository,
): GetBalanceHidingSettingsUseCase {
return GetBalanceHidingSettingsUseCase(
balanceHidingRepository = balanceHidingRepository,
)
}
@ -80,4 +83,12 @@ internal object SettingsDomainModule {
balanceHidingRepository = balanceHidingRepository,
)
}
@Provides
@ViewModelScoped
fun provideUpdateHideBalancesSettingsUseCase(
balanceHidingRepository: BalanceHidingRepository,
): UpdateBalanceHidingSettingsUseCase {
return UpdateBalanceHidingSettingsUseCase(balanceHidingRepository)
}
}

View file

@ -13,7 +13,6 @@ import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.apptheme.model.AppThemeMode
import com.tangem.domain.balancehiding.BalanceHidingSettings
import com.tangem.domain.common.TapWorkarounds.isTangemTwins
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.ScanResponse
@ -280,7 +279,7 @@ class DetailsMiddleware {
val repository = store.state.daggerGraphState.get(DaggerGraphState::balanceHidingRepository)
scope.launch {
val newState = BalanceHidingSettings(
val newState = repository.getBalanceHidingSettings().copy(
isHidingEnabledInSettings = hideBalance,
isBalanceHidden = false,
)

View file

@ -1,7 +1,7 @@
package com.tangem.tap.features.send.ui
import androidx.lifecycle.*
import com.tangem.domain.balancehiding.IsBalanceHiddenUseCase
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
import com.tangem.domain.tokens.FetchPendingTransactionsUseCase
import com.tangem.domain.tokens.UpdateDelayedNetworkStatusUseCase
@ -29,7 +29,7 @@ import javax.inject.Inject
internal class SendViewModel @Inject constructor(
private val dispatchers: CoroutineDispatcherProvider,
private val appStateHolder: AppStateHolder,
private val isBalanceHiddenUseCase: IsBalanceHiddenUseCase,
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val listenToFlipsUseCase: ListenToFlipsUseCase,
private val updateDelayedCurrencyStatusUseCase: UpdateDelayedNetworkStatusUseCase,
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
@ -41,11 +41,11 @@ internal class SendViewModel @Inject constructor(
private val cryptoCurrency: CryptoCurrency? = savedStateHandle[SendRouter.CRYPTO_CURRENCY_KEY]
override fun onCreate(owner: LifecycleOwner) {
isBalanceHiddenUseCase()
getBalanceHidingSettingsUseCase()
.flowWithLifecycle(owner.lifecycle)
.onEach { isBalanceHidden ->
.onEach {
withContext(dispatchers.main) {
appStateHolder.mainStore?.dispatch(AmountAction.HideBalance(isBalanceHidden))
appStateHolder.mainStore?.dispatch(AmountAction.HideBalance(it.isBalanceHidden))
}
}
.launchIn(viewModelScope)

View file

@ -13,6 +13,7 @@ internal class BalanceStateHidingSettingsStore(
return getSyncOrNull() ?: BalanceHidingSettings(
isHidingEnabledInSettings = false,
isBalanceHidden = false,
isBalanceHidingNotificationEnabled = true,
)
}
}

View file

@ -4,6 +4,7 @@ plugins {
}
dependencies {
implementation(projects.domain.core)
implementation(deps.kotlin.coroutines)
implementation(projects.domain.settings)
implementation(projects.domain.balanceHiding.models)

View file

@ -3,4 +3,5 @@ package com.tangem.domain.balancehiding
data class BalanceHidingSettings(
val isHidingEnabledInSettings: Boolean,
val isBalanceHidden: Boolean,
val isBalanceHidingNotificationEnabled: Boolean,
)

View file

@ -2,15 +2,12 @@ package com.tangem.domain.balancehiding
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
class IsBalanceHiddenUseCase(
class GetBalanceHidingSettingsUseCase(
private val balanceHidingRepository: BalanceHidingRepository,
) {
operator fun invoke(): Flow<Boolean> {
return balanceHidingRepository.getBalanceHidingSettingsFlow().map {
it.isBalanceHidden
}
operator fun invoke(): Flow<BalanceHidingSettings> {
return balanceHidingRepository.getBalanceHidingSettingsFlow()
}
}

View file

@ -1,28 +1,43 @@
package com.tangem.domain.balancehiding
import arrow.core.Either
import arrow.core.left
import arrow.core.raise.catch
import com.tangem.domain.balancehiding.error.HideBalancesError
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.collectLatest
class ListenToFlipsUseCase(
private val flipDetector: DeviceFlipDetector,
private val balanceHidingRepository: BalanceHidingRepository,
) {
suspend operator fun invoke(): Flow<Unit> {
return if (balanceHidingRepository.getBalanceHidingSettings().isHidingEnabledInSettings) {
flipDetector.getDeviceFlipFlow().onEach {
val balanceHidingSettings = balanceHidingRepository.getBalanceHidingSettings()
operator fun invoke(): Flow<Either<HideBalancesError, Unit>> = channelFlow {
flipDetector.getDeviceFlipFlow().collectLatest {
val balanceHidingSettings = catch(
block = { balanceHidingRepository.getBalanceHidingSettings() },
catch = {
send(HideBalancesError.DataError(it).left())
return@collectLatest
},
)
balanceHidingRepository.storeBalanceHidingSettings(
balanceHidingSettings.copy(
isBalanceHidden = !balanceHidingSettings.isBalanceHidden,
),
if (balanceHidingSettings.isHidingEnabledInSettings) {
catch(
block = {
balanceHidingRepository.storeBalanceHidingSettings(
balanceHidingSettings.copy(
isBalanceHidden = !balanceHidingSettings.isBalanceHidden,
),
)
},
catch = { send(HideBalancesError.DataError(it).left()) },
)
} else {
send(HideBalancesError.HidingDisabled.left())
}
} else {
emptyFlow()
}
}
}

View file

@ -0,0 +1,29 @@
package com.tangem.domain.balancehiding
import arrow.core.Either
import arrow.core.raise.catch
import arrow.core.raise.either
import com.tangem.domain.balancehiding.error.HideBalancesError
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
class UpdateBalanceHidingSettingsUseCase(
private val balanceHidingRepository: BalanceHidingRepository,
) {
suspend operator fun invoke(
update: BalanceHidingSettings.() -> BalanceHidingSettings,
): Either<HideBalancesError, Unit> = either {
val settings = catch({ balanceHidingRepository.getBalanceHidingSettings() }) {
raise(HideBalancesError.DataError(it))
}
if (settings.isHidingEnabledInSettings) {
catch(
block = { balanceHidingRepository.storeBalanceHidingSettings(update(settings)) },
catch = { raise(HideBalancesError.DataError(it)) },
)
} else {
raise(HideBalancesError.HidingDisabled)
}
}
}

View file

@ -0,0 +1,8 @@
package com.tangem.domain.balancehiding.error
sealed class HideBalancesError {
object HidingDisabled : HideBalancesError()
data class DataError(val cause: Throwable) : HideBalancesError()
}

View file

@ -18,6 +18,7 @@ dependencies {
/** Domain modules **/
implementation(projects.domain.balanceHiding)
implementation(projects.domain.balanceHiding.models)
/** AndroidX */
implementation(deps.androidx.activity.compose)

View file

@ -7,7 +7,7 @@ import androidx.lifecycle.*
import com.tangem.common.Provider
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.ui.utils.InputNumberFormatter
import com.tangem.domain.balancehiding.IsBalanceHiddenUseCase
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
import com.tangem.domain.tokens.model.Network
import com.tangem.feature.swap.analytics.SwapEvents
@ -49,7 +49,7 @@ internal class SwapViewModel @Inject constructor(
private val blockchainInteractor: BlockchainInteractor,
private val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,
private val isBalanceHiddenUseCase: IsBalanceHiddenUseCase,
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val listenToFlipsUseCase: ListenToFlipsUseCase,
savedStateHandle: SavedStateHandle,
) : ViewModel(), DefaultLifecycleObserver {
@ -96,10 +96,10 @@ internal class SwapViewModel @Inject constructor(
}
override fun onCreate(owner: LifecycleOwner) {
isBalanceHiddenUseCase()
getBalanceHidingSettingsUseCase()
.flowWithLifecycle(owner.lifecycle)
.onEach { hidden ->
isBalanceHidden = hidden
.onEach {
isBalanceHidden = it.isBalanceHidden
withContext(dispatchers.main) {
uiState = stateBuilder.updateBalanceHiddenState(uiState, isBalanceHidden)
}

View file

@ -62,6 +62,7 @@ dependencies {
implementation(projects.domain.wallets)
implementation(projects.domain.wallets.models)
implementation(projects.domain.balanceHiding)
implementation(projects.domain.balanceHiding.models)
/** Feature Apis */
implementation(projects.features.tokendetails.api)

View file

@ -13,7 +13,7 @@ import com.tangem.core.ui.components.bottomsheets.tokenreceive.AddressModel
import com.tangem.core.ui.components.transactions.state.TxHistoryState
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.balancehiding.IsBalanceHiddenUseCase
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.domain.tokens.*
@ -60,7 +60,7 @@ internal class TokenDetailsViewModel @Inject constructor(
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
private val removeCurrencyUseCase: RemoveCurrencyUseCase,
private val getNetworkCoinStatusUseCase: GetNetworkCoinStatusUseCase,
private val isBalanceHiddenUseCase: IsBalanceHiddenUseCase,
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val listenToFlipsUseCase: ListenToFlipsUseCase,
private val getCurrencyWarningsUseCase: GetCurrencyWarningsUseCase,
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
@ -108,11 +108,11 @@ internal class TokenDetailsViewModel @Inject constructor(
}
private fun handleBalanceHiding(owner: LifecycleOwner) {
isBalanceHiddenUseCase()
getBalanceHidingSettingsUseCase()
.flowWithLifecycle(owner.lifecycle)
.onEach { hidden ->
.onEach {
uiState = stateFactory.getStateWithUpdatedHidden(
isBalanceHidden = hidden,
isBalanceHidden = it.isBalanceHidden,
)
}
.launchIn(viewModelScope)

View file

@ -65,6 +65,7 @@ dependencies {
implementation(projects.domain.appCurrency)
implementation(projects.domain.appCurrency.models)
implementation(projects.domain.balanceHiding)
implementation(projects.domain.balanceHiding.models)
//TODO: Create api/impl modules for onboarding [REDACTED_JIRA]
implementation(projects.features.onboarding)

View file

@ -7,7 +7,7 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.balancehiding.IsBalanceHiddenUseCase
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
@ -38,7 +38,7 @@ internal class OrganizeTokensViewModel @Inject constructor(
private val toggleTokenListSortingUseCase: ToggleTokenListSortingUseCase,
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val isBalanceHiddenUseCase: IsBalanceHiddenUseCase,
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val listenToFlipsUseCase: ListenToFlipsUseCase,
private val analyticsEventsHandler: AnalyticsEventHandler,
private val dispatchers: CoroutineDispatcherProvider,
@ -74,10 +74,10 @@ internal class OrganizeTokensViewModel @Inject constructor(
override fun onCreate(owner: LifecycleOwner) {
analyticsEventsHandler.send(PortfolioOrganizeTokensAnalyticsEvent.ScreenOpened)
isBalanceHiddenUseCase()
getBalanceHidingSettingsUseCase()
.flowWithLifecycle(owner.lifecycle)
.onEach { hidden ->
isBalanceHidden = hidden
.onEach {
isBalanceHidden = it.isBalanceHidden
stateHolder.updateHiddenState(isBalanceHidden)
}
.launchIn(viewModelScope)

View file

@ -27,7 +27,7 @@ import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.domain.analytics.ChangeCardAnalyticsContextUseCase
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.balancehiding.IsBalanceHiddenUseCase
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
import com.tangem.domain.card.DerivePublicKeysUseCase
import com.tangem.domain.card.ScanCardProcessor
@ -116,7 +116,7 @@ internal class WalletViewModel @Inject constructor(
private val canUseBiometryUseCase: CanUseBiometryUseCase,
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
private val shouldSaveUserWalletsSyncUseCase: ShouldSaveUserWalletsSyncUseCase,
private val isBalanceHiddenUseCase: IsBalanceHiddenUseCase,
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val listenToFlipsUseCase: ListenToFlipsUseCase,
private val removeCurrencyUseCase: RemoveCurrencyUseCase,
private val isCryptoCurrencyCoinCouldHide: IsCryptoCurrencyCoinCouldHideUseCase,
@ -212,12 +212,12 @@ internal class WalletViewModel @Inject constructor(
}
}
isBalanceHiddenUseCase()
getBalanceHidingSettingsUseCase()
.flowWithLifecycle(owner.lifecycle)
.onEach { hidden ->
isBalanceHidden = hidden
WalletStateCache.updateAll { copySealed(isBalanceHidden = hidden) }
uiState = stateFactory.getHiddenBalanceState(isBalanceHidden = hidden)
.onEach {
isBalanceHidden = it.isBalanceHidden
WalletStateCache.updateAll { copySealed(isBalanceHidden = it.isBalanceHidden) }
uiState = stateFactory.getHiddenBalanceState(isBalanceHidden = it.isBalanceHidden)
}
.launchIn(viewModelScope)