Updated on 2026-08-14

This commit is contained in:
Tangem 2024-07-30 11:03:53 +02:00
parent 1bf78a1f1a
commit f25889d1a0
30 changed files with 149 additions and 275 deletions

View file

@ -24,7 +24,7 @@ internal class DefaultDetailsComponent @AssistedInject constructor(
private val model: DetailsModel = getOrCreateModel(params)
private val userWalletListComponent = userWalletListComponentFactory.create(
context = child(key = "user_wallet_list"),
context = child(key = "user_wallet_list_component"),
)
@Composable

View file

@ -1,17 +1,22 @@
package com.tangem.features.details.utils
import arrow.core.raise.*
import arrow.core.recover
import androidx.compose.ui.res.stringResource
import arrow.core.raise.Raise
import arrow.core.raise.ensureNotNull
import arrow.core.raise.fold
import arrow.core.raise.recover
import com.tangem.common.routing.AppRoute
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.decompose.navigation.popTo
import com.tangem.core.decompose.ui.UiMessageSender
import com.tangem.core.ui.components.SimpleOkDialog
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.isNullOrEmpty
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.message.ContentMessage
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.domain.card.ScanCardProcessor
import com.tangem.domain.models.scan.ScanResponse
@ -21,7 +26,7 @@ import com.tangem.domain.wallets.models.SaveWalletError
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
import com.tangem.domain.wallets.usecase.SelectWalletUseCase
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsSyncUseCase
import com.tangem.features.details.impl.R
import javax.inject.Inject
@ -31,7 +36,7 @@ internal class UserWalletSaver @Inject constructor(
private val scanCardProcessor: ScanCardProcessor,
private val saveWalletUseCase: SaveWalletUseCase,
private val generateWalletNameUseCase: GenerateWalletNameUseCase,
private val selectWalletUseCase: SelectWalletUseCase,
private val shouldSaveUserWalletsSyncUseCase: ShouldSaveUserWalletsSyncUseCase,
private val reduxStateHolder: ReduxStateHolder,
private val messageSender: UiMessageSender,
private val router: Router,
@ -43,8 +48,6 @@ internal class UserWalletSaver @Inject constructor(
val userWallet = createUserWallet(response)
saveWallet(userWallet)
router.popTo<AppRoute.Wallet>()
},
recover = { error ->
val message = error.message
@ -56,28 +59,44 @@ internal class UserWalletSaver @Inject constructor(
)
private suspend fun Raise<Error>.saveWallet(userWallet: UserWallet) {
saveWalletUseCase(userWallet).recover { error ->
when (error) {
is SaveWalletError.WalletAlreadySaved -> selectUserWallet(userWallet)
is SaveWalletError.DataError -> {
val messageRef = ensureNotNull(error.messageId?.let(::resourceReference)) {
Error.Unknown
fold(
block = { saveWalletUseCase(userWallet).bind() },
recover = { error ->
when (error) {
is SaveWalletError.WalletAlreadySaved -> {
if (shouldSaveUserWalletsSyncUseCase()) {
selectUserWallet()
} else {
router.popTo<AppRoute.Wallet>()
}
}
is SaveWalletError.DataError -> {
val messageRef = ensureNotNull(error.messageId?.let(::resourceReference)) {
Error.Unknown
}
raise(Error.Message(messageRef))
raise(Error.Message(messageRef))
}
}
}
}.bind()
},
transform = {
// call only if wallet is successfully saved
reduxStateHolder.onUserWalletSelected(userWallet)
reduxStateHolder.onUserWalletSelected(userWallet)
router.popTo<AppRoute.Wallet>()
},
)
}
private suspend fun Raise<Error>.selectUserWallet(userWallet: UserWallet) {
withError({ Error.Unknown }) {
selectWalletUseCase(userWallet.walletId).bind()
}
router.popTo<AppRoute.Wallet>()
private fun selectUserWallet() {
messageSender.send(
message = ContentMessage { onDismiss ->
SimpleOkDialog(
message = stringResource(id = R.string.user_wallet_list_error_wallet_already_saved),
onDismissDialog = onDismiss,
)
},
)
}
private suspend fun Raise<Error>.createUserWallet(response: ScanResponse): UserWallet {

View file

@ -59,7 +59,11 @@ internal fun DisclaimerScreen(state: DisclaimerUM) {
.background(backgroundColor)
.statusBarsPadding(),
) {
Column(modifier = Modifier.padding(bottom = bottomPadding)) {
Column(
modifier = Modifier
.padding(bottom = bottomPadding)
.fillMaxSize(),
) {
TangemTopAppBar(
title = resourceReference(R.string.disclaimer_title),
startButton = TopAppBarButtonUM(
@ -110,6 +114,7 @@ private fun DisclaimerContent(url: String, isTosAccepted: Boolean) {
it.setBackgroundColor(backgroundColor.toArgb())
},
client = remember { DisclaimerWebViewClient() },
modifier = Modifier.fillMaxSize(),
)
AnimatedVisibility(
@ -117,6 +122,9 @@ private fun DisclaimerContent(url: String, isTosAccepted: Boolean) {
label = "Loading state change animation",
enter = fadeIn(),
exit = fadeOut(),
modifier = Modifier
.fillMaxSize()
.background(backgroundColor),
) {
Box(
modifier = Modifier

View file

@ -12,7 +12,6 @@ import androidx.compose.material.pullrefresh.pullRefresh
import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.material3.Scaffold
import androidx.compose.material3.ScaffoldDefaults
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@ -32,6 +31,7 @@ import com.tangem.core.ui.components.marketprice.MarketPriceBlock
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
import com.tangem.core.ui.components.notifications.Notification
import com.tangem.core.ui.components.notifications.OkxPromoNotification
import com.tangem.core.ui.components.snackbar.TangemSnackbarHost
import com.tangem.core.ui.components.transactions.state.TxHistoryState
import com.tangem.core.ui.components.transactions.txHistoryItems
import com.tangem.core.ui.event.EventEffect
@ -64,7 +64,16 @@ internal fun TokenDetailsScreen(state: TokenDetailsState) {
val snackbarHostState = remember { SnackbarHostState() }
Scaffold(
topBar = { TokenDetailsTopAppBar(config = state.topAppBarConfig) },
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
snackbarHost = {
TangemSnackbarHost(
modifier = Modifier.padding(
start = TangemTheme.dimens.spacing16,
end = TangemTheme.dimens.spacing16,
bottom = bottomBarHeight + TangemTheme.dimens.spacing16,
),
hostState = snackbarHostState,
)
},
contentWindowInsets = ScaffoldDefaults.contentWindowInsets.exclude(WindowInsets.navigationBars),
containerColor = TangemTheme.colors.background.secondary,
) { scaffoldPaddings ->

View file

@ -368,7 +368,9 @@ private fun BaseScaffoldWithMarkets(
WalletSnackbarHost(
snackbarHostState = it,
event = state.event,
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing16),
modifier = Modifier
.padding(bottom = TangemTheme.dimens.spacing4)
.navigationBarsPadding(),
)
},
containerColor = TangemTheme.colors.background.secondary,

View file

@ -341,6 +341,8 @@ internal class WalletViewModel @Inject constructor(
}
private suspend fun deleteWallet(action: WalletsUpdateActionResolver.Action.DeleteWallet) {
walletScreenContentLoader.cancel(action.deletedWalletId)
walletScreenContentLoader.load(
userWallet = action.selectedWallet,
clickIntents = clickIntents,