Updated on 2026-08-14

This commit is contained in:
Tangem 2023-09-26 13:20:05 +03:00
parent 30e9769bb2
commit 776cb482ad
12 changed files with 189 additions and 2 deletions

View file

@ -157,4 +157,14 @@ internal object TokensDomainModule {
fun provideGetCurrenciesUseCase(currenciesRepository: CurrenciesRepository): GetCryptoCurrenciesUseCase {
return GetCryptoCurrenciesUseCase(currenciesRepository = currenciesRepository)
}
@Provides
@ViewModelScoped
fun provideIsCryptoCurrencyCoinCouldHideUseCase(
currenciesRepository: CurrenciesRepository,
): IsCryptoCurrencyCoinCouldHideUseCase {
return IsCryptoCurrencyCoinCouldHideUseCase(
currenciesRepository = currenciesRepository,
)
}
}

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M6,19C6,19.53 6.211,20.039 6.586,20.414C6.961,20.789 7.47,21 8,21H16C16.53,21 17.039,20.789 17.414,20.414C17.789,20.039 18,19.53 18,19V7H6V19ZM8,9H16V19H8V9ZM15.5,4L14.5,3H9.5L8.5,4H5V6H19V4H15.5Z"
android:fillColor="#000000"/>
</vector>

View file

@ -39,7 +39,7 @@ class GetCryptoCurrencyActionsUseCase(
return TokenActionsState(
walletId = userWalletId,
cryptoCurrencyStatus = cryptoCurrencyStatus,
states = createListOfActions(userWalletId, cryptoCurrencyStatus.currency),
states = createListOfActions(userWalletId, cryptoCurrencyStatus),
)
}
@ -49,8 +49,13 @@ class GetCryptoCurrencyActionsUseCase(
*/
private suspend fun createListOfActions(
userWalletId: UserWalletId,
cryptoCurrency: CryptoCurrency,
cryptoCurrencyStatus: CryptoCurrencyStatus,
): List<TokenActionsState.ActionState> {
val cryptoCurrency = cryptoCurrencyStatus.currency
if (cryptoCurrencyStatus.value is CryptoCurrencyStatus.MissedDerivation) {
return listOf(TokenActionsState.ActionState.HideToken(true))
}
val activeList = mutableListOf<TokenActionsState.ActionState>()
val disabledList = mutableListOf<TokenActionsState.ActionState>()
@ -85,6 +90,9 @@ class GetCryptoCurrencyActionsUseCase(
disabledList.add(TokenActionsState.ActionState.Sell(false))
}
// hide
activeList.add(TokenActionsState.ActionState.HideToken(true))
return activeList + disabledList
}

View file

@ -0,0 +1,17 @@
package com.tangem.domain.tokens
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.wallets.models.UserWalletId
class IsCryptoCurrencyCoinCouldHideUseCase(
private val currenciesRepository: CurrenciesRepository,
) {
suspend operator fun invoke(userWalletId: UserWalletId, cryptoCurrencyCoin: CryptoCurrency.Coin): Boolean {
return currenciesRepository.getMultiCurrencyWalletCurrenciesSync(
userWalletId = userWalletId,
refresh = false,
).none { it is CryptoCurrency.Token && it.network == cryptoCurrencyCoin.network }
}
}

View file

@ -23,5 +23,7 @@ data class TokenActionsState(
data class Swap(override val enabled: Boolean) : ActionState()
data class Send(override val enabled: Boolean) : ActionState()
data class HideToken(override val enabled: Boolean) : ActionState()
}
}

View file

@ -1,9 +1,16 @@
package com.tangem.feature.wallet.presentation.wallet.state
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.extensions.TextReference
@Immutable
internal sealed class WalletAlertState {
data class WalletAlreadySignedHashes(val onUnderstandClick: () -> Unit) : WalletAlertState()
data class DefaultAlert(
val title: TextReference,
val message: TextReference,
val onActionClick: (() -> Unit)?,
) : WalletAlertState()
}

View file

@ -12,6 +12,12 @@ internal sealed class WalletEvent {
data class ShowToast(val text: TextReference) : WalletEvent()
data class ShowAlert(
val title: TextReference,
val message: TextReference,
val onActionClick: (() -> Unit)?,
) : WalletEvent()
data class CopyAddress(val address: String) : WalletEvent()
data class ShowWalletAlreadySignedHashesMessage(val onUnderstandClick: () -> Unit) : WalletEvent()

View file

@ -72,6 +72,11 @@ internal class TokenActionsProvider(private val clickIntents: WalletClickIntents
icon = R.drawable.ic_copy_24
action = { clickIntents.onCopyAddressClick(cryptoCurrencyStatus) }
}
is TokenActionsState.ActionState.HideToken -> {
title = resourceReference(R.string.token_details_hide_token)
icon = R.drawable.ic_trash_24
action = { clickIntents.onHideTokensClick(cryptoCurrencyStatus) }
}
}
return TokenActionButtonConfig(
text = title,

View file

@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import com.tangem.core.ui.components.BasicDialog
import com.tangem.core.ui.components.DialogButton
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.wallet.state.WalletAlertState
@ -13,6 +14,9 @@ internal fun WalletAlert(config: WalletAlertState, onDismiss: () -> Unit) {
is WalletAlertState.WalletAlreadySignedHashes -> {
WalletAlreadySignedHashesAlert(config = config, onDismiss = onDismiss)
}
is WalletAlertState.DefaultAlert -> {
DefaultAlert(config = config, onDismiss = onDismiss)
}
}
}
@ -31,4 +35,36 @@ private fun WalletAlreadySignedHashesAlert(config: WalletAlertState.WalletAlread
title = stringResource(id = R.string.warning_important_security_info, "\u26A0"),
dismissButton = DialogButton(title = stringResource(id = R.string.common_cancel), onClick = onDismiss),
)
}
@Composable
private fun DefaultAlert(config: WalletAlertState.DefaultAlert, onDismiss: () -> Unit) {
val confirmButton: DialogButton
val dismissButton: DialogButton?
if (config.onActionClick != null) {
confirmButton = DialogButton(
title = stringResource(id = R.string.common_ok),
onClick = {
config.onActionClick.invoke()
onDismiss()
},
)
dismissButton = DialogButton(
title = stringResource(id = R.string.common_cancel),
onClick = onDismiss,
)
} else {
confirmButton = DialogButton(
title = stringResource(id = R.string.common_ok),
onClick = onDismiss,
)
dismissButton = null
}
BasicDialog(
message = config.message.resolveReference(),
confirmButton = confirmButton,
onDismissDialog = onDismiss,
title = config.title.resolveReference(),
dismissButton = dismissButton,
)
}

View file

@ -52,6 +52,15 @@ internal fun WalletEventEffect(
WalletAlertState.WalletAlreadySignedHashes(onUnderstandClick = value.onUnderstandClick),
)
}
is WalletEvent.ShowAlert -> {
onAlertConfigSet(
WalletAlertState.DefaultAlert(
title = value.title,
message = value.message,
onActionClick = value.onActionClick,
),
)
}
is WalletEvent.RateApp -> {
val reviewManager = ReviewManagerFactory.create(context)
val requestTask = reviewManager.requestReviewFlow()

View file

@ -55,6 +55,10 @@ internal interface WalletClickIntents {
fun onCopyAddressClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
fun onHideTokensClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
fun onPerformHideToken(cryptoCurrencyStatus: CryptoCurrencyStatus)
fun onSellClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
fun onManageTokensClick()

View file

@ -19,6 +19,8 @@ import com.tangem.core.navigation.AppScreen
import com.tangem.core.ui.components.bottomsheets.tokenreceive.AddressModel
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.WrappedList
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
@ -106,6 +108,8 @@ internal class WalletViewModel @Inject constructor(
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
private val isBalanceHiddenUseCase: IsBalanceHiddenUseCase,
private val listenToFlipsUseCase: ListenToFlipsUseCase,
private val removeCurrencyUseCase: RemoveCurrencyUseCase,
private val isCryptoCurrencyCoinCouldHide: IsCryptoCurrencyCoinCouldHideUseCase,
private val walletManagersFacade: WalletManagersFacade,
private val reduxStateHolder: ReduxStateHolder,
private val dispatchers: CoroutineDispatcherProvider,
@ -764,6 +768,34 @@ internal class WalletViewModel @Inject constructor(
}
}
override fun onPerformHideToken(cryptoCurrencyStatus: CryptoCurrencyStatus) {
val state = uiState as? WalletState.ContentState ?: return
val userWallet = getWallet(state.walletsListConfig.selectedWalletIndex)
viewModelScope.launch(dispatchers.io) {
removeCurrencyUseCase(userWallet.walletId, cryptoCurrencyStatus.currency)
.fold(
ifLeft = {
showSnackbar(resourceReference(R.string.common_error))
},
ifRight = {
onDismissActionsBottomSheet()
},
)
}
}
override fun onHideTokensClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
viewModelScope.launch(dispatchers.main) {
val state = uiState as? WalletState.ContentState ?: return@launch
val userWallet = getWallet(state.walletsListConfig.selectedWalletIndex)
uiState = stateFactory.getStateAndTriggerEvent(
state = uiState,
event = getHideTokeAlert(userWallet.walletId, cryptoCurrencyStatus),
setUiState = { uiState = it },
)
}
}
override fun onDismissBottomSheet() {
uiState = stateFactory.getStateWithClosedBottomSheet()
}
@ -778,6 +810,48 @@ internal class WalletViewModel @Inject constructor(
}
}
private suspend fun getHideTokeAlert(
userWalletId: UserWalletId,
cryptoCurrencyStatus: CryptoCurrencyStatus,
): WalletEvent.ShowAlert {
val currency = cryptoCurrencyStatus.currency
return if (currency is CryptoCurrency.Coin && !isCryptoCurrencyCoinCouldHide(userWalletId, currency)) {
WalletEvent.ShowAlert(
title = resourceReference(
id = R.string.token_details_unable_hide_alert_title,
formatArgs = WrappedList(listOf(cryptoCurrencyStatus.currency.name)),
),
message = resourceReference(
id = R.string.token_details_unable_hide_alert_message,
formatArgs = WrappedList(
listOf(
cryptoCurrencyStatus.currency.name,
cryptoCurrencyStatus.currency.network.name,
),
),
),
onActionClick = null,
)
} else {
WalletEvent.ShowAlert(
title = resourceReference(
id = R.string.token_details_hide_alert_title,
formatArgs = WrappedList(listOf(cryptoCurrencyStatus.currency.name)),
),
message = resourceReference(R.string.token_details_hide_alert_message),
onActionClick = { onPerformHideToken(cryptoCurrencyStatus) },
)
}
}
private fun showSnackbar(message: TextReference) {
uiState = stateFactory.getStateAndTriggerEvent(
state = uiState,
event = WalletEvent.ShowToast(message),
setUiState = { uiState = it },
)
}
private fun getContentItemsUpdates(index: Int) {
/*
* When wallet is changed it's necessary to stop the last jobs.