Updated on 2026-08-14

This commit is contained in:
Tangem 2023-03-31 15:44:31 +03:00
parent 1ee9fa0b45
commit 86139d5f45
11 changed files with 202 additions and 2 deletions

View file

@ -4,6 +4,7 @@ import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.blockchain.common.WalletManager
import com.tangem.common.doOnFailure
import com.tangem.common.extensions.guard
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.common.extensions.toCoinId
@ -20,6 +21,8 @@ import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.userWalletsListManager
import com.tangem.tap.walletCurrenciesManager
import com.tangem.tap.walletStoresManager
import kotlinx.coroutines.flow.firstOrNull
import timber.log.Timber
import java.math.BigDecimal
import com.tangem.tap.features.wallet.models.Currency as WalletCurrency
@ -117,6 +120,28 @@ class UserWalletManagerImpl(
)
}
override suspend fun hideAllTokens() {
val userWallet = userWalletsListManager.selectedUserWalletSync.guard {
Timber.e("No user wallets selected")
return
}
val currencies = walletStoresManager.get(userWallet.walletId)
.firstOrNull()
?.flatMap { walletStore ->
walletStore.walletsData.map { it.currency }
}
.guard {
Timber.d("No currencies found")
return
}
walletCurrenciesManager.removeCurrencies(userWallet, currenciesToRemove = currencies)
.doOnFailure { e ->
Timber.e(e, "Unable to delete all currencies")
}
}
override fun getWalletAddress(networkId: String, derivationPath: String?): String {
val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" }
val walletManager = getActualWalletManager(blockchain, derivationPath)

View file

@ -29,4 +29,7 @@ dependencies {
/** Feature Apis */
implementation(project(":features:tester:api"))
/** Other modules */
implementation(project(":libs:crypto"))
}

View file

@ -10,6 +10,8 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.tangem.core.ui.components.SystemBarsEffect
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.tester.presentation.actions.TesterActionsScreen
import com.tangem.feature.tester.presentation.actions.TesterActionsViewModel
import com.tangem.feature.tester.presentation.featuretoggles.ui.FeatureTogglesScreen
import com.tangem.feature.tester.presentation.featuretoggles.viewmodels.FeatureTogglesViewModel
import com.tangem.feature.tester.presentation.menu.state.TesterMenuContentState
@ -59,6 +61,7 @@ internal class TesterActivity : ComponentActivity() {
state = TesterMenuContentState(
onBackClick = innerTesterRouter::back,
onFeatureTogglesClick = { innerTesterRouter.open(TesterScreen.FEATURE_TOGGLES) },
onTesterActionsClick = { innerTesterRouter.open(TesterScreen.TESTER_ACTIONS) },
),
)
}
@ -70,6 +73,14 @@ internal class TesterActivity : ComponentActivity() {
FeatureTogglesScreen(state = viewModel.uiState)
}
composable(route = TesterScreen.TESTER_ACTIONS.name) {
val viewModel = hiltViewModel<TesterActionsViewModel>().apply {
setupNavigation(innerTesterRouter)
}
TesterActionsScreen(state = viewModel.uiState)
}
}
}
}

View file

@ -0,0 +1,12 @@
package com.tangem.feature.tester.presentation.actions
internal data class TesterActionsContentState(
val onBackClick: () -> Unit,
val hideAllCurrencies: HideAllCurrenciesState,
)
internal sealed interface HideAllCurrenciesState {
data class Clickable(val onClick: () -> Unit) : HideAllCurrenciesState
object Progress : HideAllCurrenciesState
}

View file

@ -0,0 +1,94 @@
package com.tangem.feature.tester.presentation.actions
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.tester.impl.R
@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun TesterActionsScreen(
state: TesterActionsContentState,
modifier: Modifier = Modifier,
) {
LazyColumn(
modifier = modifier
.fillMaxSize()
.background(TangemTheme.colors.background.secondary),
) {
stickyHeader {
AppBarWithBackButton(
text = stringResource(R.string.tester_actions),
onBackClick = state.onBackClick,
)
}
item {
val onClick = remember(state.hideAllCurrencies) {
{ (state.hideAllCurrencies as? HideAllCurrenciesState.Clickable)?.onClick?.invoke() ?: Unit }
}
TesterActionItem(
progress = state.hideAllCurrencies is HideAllCurrenciesState.Progress,
onClick = onClick,
)
}
}
}
@Composable
private fun TesterActionItem(
progress: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Box(modifier = modifier.padding(all = TangemTheme.dimens.spacing16)) {
PrimaryButton(
modifier = Modifier.fillMaxWidth(),
text = stringResource(R.string.hide_all_currencies),
onClick = onClick,
showProgress = progress,
)
}
}
// region Preview
@Composable
private fun TesterActionsScreenSample(
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier
.background(TangemTheme.colors.background.primary),
) {
TesterActionsScreen(state = TesterActionsContentState({}, HideAllCurrenciesState.Clickable({})))
}
}
@Preview(showBackground = true, widthDp = 360)
@Composable
private fun TesterActionsScreenPreview_Light() {
TangemTheme {
TesterActionsScreenSample()
}
}
@Preview(showBackground = true, widthDp = 360)
@Composable
private fun TesterActionsScreenPreview_Dark() {
TangemTheme(isDark = true) {
TesterActionsScreenSample()
}
}
// endregion Preview

View file

@ -0,0 +1,42 @@
package com.tangem.feature.tester.presentation.actions
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.tangem.feature.tester.presentation.navigation.InnerTesterRouter
import com.tangem.lib.crypto.UserWalletManager
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
internal class TesterActionsViewModel @Inject constructor(
private val userWalletManager: UserWalletManager,
) : ViewModel() {
var uiState: TesterActionsContentState by mutableStateOf(initialState)
private set
private val initialState: TesterActionsContentState
get() = TesterActionsContentState(
onBackClick = { /* [REDACTED_TODO_COMMENT] */ },
hideAllCurrencies = HideAllCurrenciesState.Clickable(this::hideAllCurrencies),
)
fun setupNavigation(router: InnerTesterRouter) {
uiState = uiState.copy(onBackClick = router::back)
}
private fun hideAllCurrencies() = viewModelScope.launch {
uiState = uiState.copy(
hideAllCurrencies = HideAllCurrenciesState.Progress,
)
userWalletManager.hideAllTokens()
uiState = uiState.copy(
hideAllCurrencies = HideAllCurrenciesState.Clickable(this@TesterActionsViewModel::hideAllCurrencies),
)
}
}

View file

@ -5,8 +5,10 @@ package com.tangem.feature.tester.presentation.menu.state
*
* @property onBackClick the lambda to be invoked when back button is pressed
* @property onFeatureTogglesClick the lambda to be invoked when feature toggles button is pressed
* @property onTesterActionsClick the lambda to be invoked when tester actions button is pressed
*/
data class TesterMenuContentState(
val onBackClick: () -> Unit,
val onFeatureTogglesClick: () -> Unit,
val onTesterActionsClick: () -> Unit,
)

View file

@ -54,6 +54,11 @@ internal fun TesterMenuScreen(state: TesterMenuContentState) {
modifier = Modifier.fillMaxWidth(),
enabled = false,
)
PrimaryButton(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.tester_actions),
onClick = state.onTesterActionsClick,
)
}
}
}
@ -66,6 +71,7 @@ private fun PreviewTesterMenuScreen_InLightTheme() {
state = TesterMenuContentState(
onBackClick = {},
onFeatureTogglesClick = {},
onTesterActionsClick = {},
),
)
}
@ -79,6 +85,7 @@ private fun PreviewTesterMenuScreen_InDarkTheme() {
state = TesterMenuContentState(
onBackClick = {},
onFeatureTogglesClick = {},
onTesterActionsClick = {},
),
)
}

View file

@ -6,5 +6,5 @@ package com.tangem.feature.tester.presentation.navigation
[REDACTED_AUTHOR]
*/
internal enum class TesterScreen {
MENU, FEATURE_TOGGLES
MENU, FEATURE_TOGGLES, TESTER_ACTIONS
}

View file

@ -3,4 +3,6 @@
<string name="tester_menu" translatable="false">Tester menu</string>
<string name="feature_toggles" translatable="false">Feature toggles</string>
<string name="stand_toggles" translatable="false">Stand toggles</string>
</resources>
<string name="tester_actions" translatable="false">Tester actions</string>
<string name="hide_all_currencies" translatable="false">Hide all currencies</string>
</resources>

View file

@ -40,6 +40,8 @@ interface UserWalletManager {
@Throws(IllegalStateException::class)
suspend fun addToken(currency: Currency, derivationPath: String?)
suspend fun hideAllTokens()
fun refreshWallet()
/**