Updated on 2026-08-14

This commit is contained in:
Tangem 2026-03-06 17:11:59 +03:00
parent 47db65fdbe
commit 9f2b2eac71
21 changed files with 658 additions and 72 deletions

View file

@ -33,8 +33,12 @@ import com.tangem.core.ui.components.account.AccountIconSize
import com.tangem.core.ui.components.rows.RoundableCornersRow
import com.tangem.core.ui.extensions.pluralStringResourceSafe
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.core.ui.res.LocalTopSnackbarHostState
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.feature.referral.domain.models.ExpectedAward
@ -352,6 +356,8 @@ private fun AdditionalButtons(
val coroutineScope = rememberCoroutineScope()
val resources = LocalContext.current.resources
val isRedesignEnabled = LocalRedesignEnabled.current
val tangemTopSnackbarHostState = LocalTopSnackbarHostState.current
Row(
modifier = Modifier.fillMaxWidth(),
@ -366,10 +372,19 @@ private fun AdditionalButtons(
clipboardManager.setText(AnnotatedString(code))
coroutineScope.launch {
snackbarHostState.showSnackbar(
message = resources.getStringSafe(R.string.referral_promo_code_copied),
duration = SnackbarDuration.Short,
)
if (isRedesignEnabled) {
tangemTopSnackbarHostState.showSnackbar(
SnackbarMessage(
startIconId = R.drawable.ic_check_24,
message = resourceReference(R.string.referral_promo_code_copied),
),
)
} else {
snackbarHostState.showSnackbar(
message = resources.getStringSafe(R.string.referral_promo_code_copied),
duration = SnackbarDuration.Short,
)
}
}
},
modifier = Modifier.weight(1f),

View file

@ -45,6 +45,9 @@ import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.components.token.state.TokenItemState.FiatAmountState
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.core.ui.res.LocalTopSnackbarHostState
import com.tangem.core.ui.res.TangemColorPalette
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@ -104,10 +107,24 @@ internal fun ReferralScreen(stateHolder: ReferralStateHolder) {
val errorSnackbar = stateHolder.errorSnackbar
val coroutineScope = rememberCoroutineScope()
val resources = LocalContext.current.resources
val isRedesignEnabled = LocalRedesignEnabled.current
val topSnackbarHostState = LocalTopSnackbarHostState.current
SideEffect {
if (errorSnackbar != null) {
coroutineScope.launch {
if (isRedesignEnabled) {
topSnackbarHostState.showSnackbar(
message = resources.getMessageForErrorSnackbar(errorSnackbar.throwable),
actionLabel = resources.getStringSafe(R.string.warning_button_ok),
duration = SnackbarMessage.Duration.Indefinite,
)
errorSnackbar.onOkClicked()
return@launch
}
val result = snackbarHostState.showSnackbar(
message = resources.getMessageForErrorSnackbar(errorSnackbar.throwable),
actionLabel = resources.getStringSafe(R.string.warning_button_ok),

View file

@ -8,16 +8,23 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.snackbar.CopiedTextSnackbarHost
import com.tangem.core.ui.res.LocalRedesignEnabled
@Deprecated(
"Use TangemTopSnackbarHost instead. Will be removed with redesign",
)
@Composable
internal fun ContainerWithSnackbarHost(snackbarHostState: SnackbarHostState, content: @Composable () -> Unit) {
Box {
content()
CopiedTextSnackbarHost(
hostState = snackbarHostState,
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 80.dp),
)
if (LocalRedesignEnabled.current.not()) {
CopiedTextSnackbarHost(
hostState = snackbarHostState,
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 80.dp),
)
}
}
}

View file

@ -46,6 +46,9 @@ import com.tangem.core.ui.components.currency.icon.CurrencyIcon
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.components.notifications.Notification
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.core.ui.res.LocalTopSnackbarHostState
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.tokenreceive.entity.ReceiveAddress
@ -203,6 +206,8 @@ private fun AddressBlock(assetsUM: ReceiveAssetsUM, snackbarHostState: SnackbarH
val coroutineScope = rememberCoroutineScope()
val context = LocalContext.current
val resources = context.resources
val isRedesignEnabled = LocalRedesignEnabled.current
val topSnackbarHostState = LocalTopSnackbarHostState.current
assetsUM.addresses
.fastFilter { it.type is ReceiveAddress.Type.Ens }
@ -214,11 +219,20 @@ private fun AddressBlock(assetsUM: ReceiveAssetsUM, snackbarHostState: SnackbarH
assetsUM.onCopyClick(address)
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
coroutineScope.launch {
snackbarHostState.showSnackbar(
message = resources.getStringSafe(
R.string.wallet_notification_address_copied,
),
)
if (isRedesignEnabled) {
topSnackbarHostState.showSnackbar(
SnackbarMessage(
startIconId = R.drawable.ic_check_24,
message = resourceReference(R.string.wallet_notification_address_copied),
),
)
} else {
snackbarHostState.showSnackbar(
message = resources.getStringSafe(
R.string.wallet_notification_address_copied,
),
)
}
}
},
address = address.value,
@ -413,6 +427,8 @@ private fun ButtonsBlock(snackbarHostState: SnackbarHostState, onCopyClick: () -
val coroutineScope = rememberCoroutineScope()
val context = LocalContext.current
val resources = context.resources
val isRedesignEnabled = LocalRedesignEnabled.current
val topSnackbarHostState = LocalTopSnackbarHostState.current
Row(
modifier = Modifier.width(IntrinsicSize.Min),
@ -427,9 +443,18 @@ private fun ButtonsBlock(snackbarHostState: SnackbarHostState, onCopyClick: () -
onCopyClick()
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
coroutineScope.launch {
snackbarHostState.showSnackbar(
message = resources.getStringSafe(R.string.wallet_notification_address_copied),
)
if (isRedesignEnabled) {
topSnackbarHostState.showSnackbar(
SnackbarMessage(
startIconId = R.drawable.ic_check_24,
message = resourceReference(R.string.wallet_notification_address_copied),
),
)
} else {
snackbarHostState.showSnackbar(
message = resources.getStringSafe(R.string.wallet_notification_address_copied),
)
}
}
},
),

View file

@ -31,6 +31,9 @@ import androidx.compose.ui.unit.dp
import com.tangem.core.res.getStringSafe
import com.tangem.core.ui.components.*
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.core.ui.res.LocalTopSnackbarHostState
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.test.TokenReceiveQrCodeBottomSheetTestTags
@ -147,6 +150,9 @@ private fun Buttons(
val context = LocalContext.current
val resources = context.resources
val isRedesignEnabled = LocalRedesignEnabled.current
val tangemTopSnackbarHostState = LocalTopSnackbarHostState.current
Row(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(16.dp),
@ -159,9 +165,18 @@ private fun Buttons(
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
onCopyClick()
coroutineScope.launch {
snackbarHostState.showSnackbar(
message = resources.getStringSafe(R.string.wallet_notification_address_copied),
)
if (isRedesignEnabled) {
tangemTopSnackbarHostState.showSnackbar(
SnackbarMessage(
startIconId = R.drawable.ic_check_24,
message = resourceReference(R.string.wallet_notification_address_copied),
),
)
} else {
snackbarHostState.showSnackbar(
message = resources.getStringSafe(R.string.wallet_notification_address_copied),
)
}
}
},
)

View file

@ -10,6 +10,9 @@ import com.tangem.core.res.getStringSafe
import com.tangem.core.ui.event.EventEffect
import com.tangem.core.ui.event.StateEvent
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.core.ui.res.LocalTopSnackbarHostState
import com.tangem.core.ui.utils.requestPermission
import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent
@ -69,18 +72,17 @@ internal fun WalletEventEffectLegacy(
@Composable
internal fun WalletEventEffect(
walletsPagerState: PagerState,
snackbarHostState: SnackbarHostState,
event: StateEvent<WalletEvent>,
onCollapseBalance: () -> Unit,
) {
val resources = LocalContext.current.resources
var showPermissionRequest by remember { mutableStateOf<Pair<() -> Unit, () -> Unit>?>(null) }
HandlePermissionRequest(
permissionRequestParams = showPermissionRequest,
onPermissionRequestResult = { showPermissionRequest = null },
)
val tangemTopSnackbarHostState = LocalTopSnackbarHostState.current
EventEffect(
event = event,
onTrigger = { value ->
@ -92,12 +94,14 @@ internal fun WalletEventEffect(
walletsPagerState.scrollToPage(page = value.newIndex)
}
is WalletEvent.ShowError -> {
snackbarHostState.showSnackbar(message = value.text.resolveReference(resources))
tangemTopSnackbarHostState.showSnackbar(SnackbarMessage(message = value.text))
}
is WalletEvent.CopyAddress -> {
snackbarHostState.showSnackbar(
message = resources.getStringSafe(R.string.wallet_notification_address_copied),
duration = SnackbarDuration.Short,
tangemTopSnackbarHostState.showSnackbar(
SnackbarMessage(
startIconId = R.drawable.ic_check_24,
message = resourceReference(R.string.wallet_notification_address_copied),
),
)
}
is WalletEvent.DemonstrateWalletsScrollPreview -> {

View file

@ -18,8 +18,6 @@ import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
@ -47,18 +45,14 @@ import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState
import com.tangem.core.ui.components.haze.hazeSourceTangem
import com.tangem.core.ui.components.rememberIsKeyboardVisible
import com.tangem.core.ui.components.sheetscaffold.*
import com.tangem.core.ui.components.snackbar.CopiedTextSnackbar
import com.tangem.core.ui.components.snackbar.TangemSnackbar
import com.tangem.core.ui.ds.topbar.collapsing.TangemCollapsingAppBarBehavior
import com.tangem.core.ui.ds.topbar.collapsing.TangemCollapsingTopBar
import com.tangem.core.ui.ds.topbar.collapsing.rememberTangemExitUntilCollapsedScrollBehavior
import com.tangem.core.ui.event.StateEvent
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.res.*
import com.tangem.feature.wallet.presentation.common.preview.WalletScreenPreviewData
import com.tangem.feature.wallet.presentation.wallet.state.model.NOT_INITIALIZED_WALLET_INDEX
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletBalanceUM
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletScreenState
import com.tangem.feature.wallet.presentation.wallet.ui.components.MarketsHint
import com.tangem.feature.wallet.presentation.wallet.ui.components.MarketsTooltip
@ -85,7 +79,6 @@ internal fun WalletScreen2(
val statusBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getTop(this).toDp() }
val snackbarHostState = remember(::SnackbarHostState)
val walletsPagerState = rememberPagerState(
initialPage = state.selectedWalletIndex,
pageCount = { state.wallets2.size },
@ -104,7 +97,6 @@ internal fun WalletScreen2(
WalletContent2(
state = state,
walletsPagerState = walletsPagerState,
snackbarHostState = snackbarHostState,
behavior = behavior,
bottomSheetContent = bottomSheetContent,
bottomSheetHeaderHeightProvider = bottomSheetHeaderHeightProvider,
@ -113,7 +105,6 @@ internal fun WalletScreen2(
WalletEventEffect(
walletsPagerState = walletsPagerState,
snackbarHostState = snackbarHostState,
event = state.event,
onCollapseBalance = {
if (behavior.state.collapsedFraction < 1f) {
@ -131,7 +122,6 @@ private fun WalletContent2(
state: WalletScreenState,
walletsPagerState: PagerState,
behavior: TangemCollapsingAppBarBehavior,
snackbarHostState: SnackbarHostState,
bottomSheetHeaderHeightProvider: () -> Dp,
onBottomSheetStateChange: (BottomSheetState) -> Unit,
bottomSheetContent: @Composable (() -> Unit),
@ -143,7 +133,6 @@ private fun WalletContent2(
BaseScaffoldWithMarkets(
state = state,
snackbarHostState = snackbarHostState,
bottomSheetHeaderHeightProvider = bottomSheetHeaderHeightProvider,
onBottomSheetStateChange = onBottomSheetStateChange,
bottomSheetContent = bottomSheetContent,
@ -278,7 +267,6 @@ private fun WalletContent2(
@Composable
private inline fun BaseScaffoldWithMarkets(
state: WalletScreenState,
snackbarHostState: SnackbarHostState,
bottomSheetHeaderHeightProvider: () -> Dp,
modifier: Modifier = Modifier,
noinline onBottomSheetStateChange: (BottomSheetState) -> Unit,
@ -290,10 +278,7 @@ private inline fun BaseScaffoldWithMarkets(
val isKeyboardVisible by rememberIsKeyboardVisible()
val scaffoldState = rememberTangemBottomSheetScaffoldState(
bottomSheetState = bottomSheetState,
snackbarHostState = snackbarHostState,
)
val scaffoldState = rememberTangemBottomSheetScaffoldState(bottomSheetState = bottomSheetState)
val density = LocalDensity.current
val bottomBarHeight = with(density) { WindowInsets.systemBars.getBottom(density = this).toDp() }
@ -320,15 +305,6 @@ private inline fun BaseScaffoldWithMarkets(
Box(modifier = modifier) {
TangemBottomSheetScaffold(
snackbarHost = { snackbarHostState ->
WalletSnackbarHost(
snackbarHostState = snackbarHostState,
event = state.event,
modifier = Modifier
.padding(bottom = TangemTheme.dimens2.x1)
.navigationBarsPadding(),
)
},
containerColor = Color.Unspecified,
sheetContainerColor = backgroundColor.value,
scaffoldState = scaffoldState,
@ -482,21 +458,6 @@ private fun BottomSheetStateEffects(
}
}
@Composable
private fun WalletSnackbarHost(
snackbarHostState: SnackbarHostState,
event: StateEvent<WalletEvent>,
modifier: Modifier = Modifier,
) {
SnackbarHost(hostState = snackbarHostState, modifier = modifier) { data ->
if (event is StateEvent.Triggered && event.data is WalletEvent.CopyAddress) {
CopiedTextSnackbar(data)
} else {
TangemSnackbar(data)
}
}
}
@Composable
private fun rememberPageAlpha(pagerState: PagerState, currentPageIndex: Int): State<Float> {
return remember {