Updated on 2026-08-14

This commit is contained in:
Tangem 2023-11-15 11:11:10 +03:00
commit c067396bcc
11 changed files with 60 additions and 17 deletions

View file

@ -50,7 +50,8 @@ internal class MainViewModel @Inject constructor(
it.isBalanceHidingNotificationEnabled && it.isBalanceHidden
}
.onEach {
if (state.value.modalNotification?.isShow != true) {
if (state.value.modalNotification?.isShow != true && !it.isUpdateFromToast) {
listenToFlipsUseCase.changeUpdateEnabled(false)
stateHolder.updateWithHiddenBalancesNotification()
reduxNavController.navigate(NavigationAction.NavigateTo(AppScreen.ModalNotification))
}
@ -79,7 +80,9 @@ internal class MainViewModel @Inject constructor(
return@onEach
}
displayBalancesHiddenStatusToast(settings)
if (!settings.isUpdateFromToast) {
displayBalancesHiddenStatusToast(settings)
}
previousSettings = settings
}
@ -96,7 +99,10 @@ internal class MainViewModel @Inject constructor(
override fun onHiddenBalanceToastAction() {
viewModelScope.launch {
updateBalanceHidingSettingsUseCase.invoke {
copy(isBalanceHidden = false)
copy(
isBalanceHidden = false,
isUpdateFromToast = true,
)
}
}
}
@ -104,7 +110,10 @@ internal class MainViewModel @Inject constructor(
override fun onShownBalanceToastAction() {
viewModelScope.launch {
updateBalanceHidingSettingsUseCase.invoke {
copy(isBalanceHidden = true)
copy(
isBalanceHidden = true,
isUpdateFromToast = true,
)
}
}
}
@ -112,6 +121,7 @@ internal class MainViewModel @Inject constructor(
override fun onHiddenBalanceNotificationAction(isPermanent: Boolean) {
onDismissBottomSheet()
stateHolder.updateWithHiddenBalancesToast(true)
if (isPermanent) {
viewModelScope.launch {
updateBalanceHidingSettingsUseCase.invoke {
@ -122,6 +132,8 @@ internal class MainViewModel @Inject constructor(
}
override fun onDismissBottomSheet() {
listenToFlipsUseCase.changeUpdateEnabled(true)
stateHolder.updateWithoutModalNotification()
stateHolder.updateWithHiddenBalancesToast(true)
}
}

View file

@ -2,12 +2,14 @@ package com.tangem.tap.features.main.ui
import android.content.DialogInterface
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.screen.ComposeBottomSheetFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.tap.features.main.MainViewModel
@ -37,7 +39,11 @@ internal class ModalNotificationBottomSheetFragment : ComposeBottomSheetFragment
when (val content = notification.content) {
is ModalNotification -> ModalNotificationContent(
modifier = modifier,
modifier = modifier
.background(
color = TangemTheme.colors.background.primary,
shape = TangemTheme.shapes.bottomSheet,
),
notification = content,
)
else -> Unit

View file

@ -88,9 +88,9 @@ private fun ModalNotificationContentPreview_Light(
) {
TangemTheme(isDark = false) {
ModalNotificationContent(
param,
notification = param,
modifier = Modifier.background(
color = TangemTheme.colors.background.plain,
color = TangemTheme.colors.background.primary,
shape = TangemTheme.shapes.bottomSheet,
),
)
@ -104,9 +104,9 @@ private fun ModalNotificationContentPreview_Dark(
) {
TangemTheme(isDark = true) {
ModalNotificationContent(
param,
notification = param,
modifier = Modifier.background(
color = TangemTheme.colors.background.plain,
color = TangemTheme.colors.background.primary,
shape = TangemTheme.shapes.bottomSheet,
),
)

View file

@ -17,10 +17,10 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.inject.Inject
@ -44,13 +44,12 @@ internal class SendViewModel @Inject constructor(
getBalanceHidingSettingsUseCase()
.flowWithLifecycle(owner.lifecycle)
.onEach {
withContext(dispatchers.main) {
appStateHolder.mainStore?.dispatch(AmountAction.HideBalance(it.isBalanceHidden))
}
appStateHolder.mainStore?.dispatch(AmountAction.HideBalance(it.isBalanceHidden))
}
.flowOn(dispatchers.main)
.launchIn(viewModelScope)
viewModelScope.launch {
viewModelScope.launch(dispatchers.main) {
listenToFlipsUseCase()
.flowWithLifecycle(owner.lifecycle)
.collect()

View file

@ -15,6 +15,8 @@ internal class DefaultBalanceHidingRepository(
private val dispatchers: CoroutineDispatcherProvider,
) : BalanceHidingRepository {
override var isUpdateEnabled: Boolean = true
override fun getBalanceHidingSettingsFlow(): Flow<BalanceHidingSettings> {
return balanceHidingSettingsStore.get()
.onStart { emit(getBalanceHidingSettings()) }

View file

@ -17,6 +17,12 @@ class DefaultMarketCryptoCurrencyRepository(
return userMarketCoinsStore.getSyncOrNull(userWalletId)?.coins
?.firstOrNull { it.id == cryptoCurrencyId.rawCurrencyId }
?.networks
?.firstOrNull { it.networkId == apiNetworkId }?.exchangeable ?: false
?.firstOrNull {
if (it.contractAddress != null) {
it.networkId == apiNetworkId && it.contractAddress == cryptoCurrencyId.contractAddress
} else {
it.networkId == apiNetworkId
}
}?.exchangeable ?: false
}
}

View file

@ -4,4 +4,5 @@ data class BalanceHidingSettings(
val isHidingEnabledInSettings: Boolean,
val isBalanceHidden: Boolean,
val isBalanceHidingNotificationEnabled: Boolean,
val isUpdateFromToast: Boolean = false,
)

View file

@ -24,12 +24,13 @@ class ListenToFlipsUseCase(
},
)
if (balanceHidingSettings.isHidingEnabledInSettings) {
if (balanceHidingSettings.isHidingEnabledInSettings && balanceHidingRepository.isUpdateEnabled) {
catch(
block = {
balanceHidingRepository.storeBalanceHidingSettings(
balanceHidingSettings.copy(
isBalanceHidden = !balanceHidingSettings.isBalanceHidden,
isUpdateFromToast = false,
),
)
},
@ -40,4 +41,8 @@ class ListenToFlipsUseCase(
}
}
}
fun changeUpdateEnabled(isUpdateEnabled: Boolean) {
balanceHidingRepository.isUpdateEnabled = isUpdateEnabled
}
}

View file

@ -5,6 +5,8 @@ import kotlinx.coroutines.flow.Flow
interface BalanceHidingRepository {
var isUpdateEnabled: Boolean
fun getBalanceHidingSettingsFlow(): Flow<BalanceHidingSettings>
suspend fun storeBalanceHidingSettings(isBalanceHidden: BalanceHidingSettings)

View file

@ -94,6 +94,8 @@ sealed class CryptoCurrency : Parcelable {
/** Represents a raw cryptocurrency ID. If it is a custom token, the value will be `null`. */
val rawCurrencyId: String? get() = (suffix as? Suffix.RawID)?.rawId
val contractAddress: String? get() = (suffix as? Suffix.RawID)?.contractAddress
/** Represents a raw cryptocurrency's network ID. */
val rawNetworkId: String
get() = when (body) {

View file

@ -23,6 +23,7 @@ import timber.log.Timber
import java.math.BigDecimal
import java.math.RoundingMode
import javax.inject.Inject
import com.tangem.lib.crypto.models.Currency as LibCurrency
@Suppress("LargeClass", "LongParameterList")
internal class SwapInteractorImpl @Inject constructor(
@ -70,7 +71,14 @@ internal class SwapInteractorImpl @Inject constructor(
isExcludeCustom = true,
)
.map { token ->
allLoadedTokens.firstOrNull { it.symbol == token.symbol }?.let {
val contractAddress = (token as? LibCurrency.NonNativeToken)?.contractAddress
allLoadedTokens.firstOrNull {
if (it is Currency.NonNativeToken) {
it.symbol == token.symbol && it.contractAddress == contractAddress
} else {
it.symbol == token.symbol
}
}?.let {
loadedOnWalletsMap.add(it.symbol)
it
} ?: swapCurrencyConverter.convertBack(token)