Updated on 2026-08-14

This commit is contained in:
Tangem 2026-02-09 12:22:08 +02:00
parent 0365d4cafc
commit b861d63402
11 changed files with 82 additions and 30 deletions

View file

@ -65,8 +65,8 @@ fun BaseTestCase.openMainScreen(
step("Assert 'Main' screen is displayed") {
onMainScreen { screenContainer.assertIsDisplayed() }
}
step("Click on 'Market Tooltip' screen") {
onMarketsTooltipScreen { contentContainer.clickWithAssertion() }
step("Dismiss Market Tooltip by clicking close button") {
onMarketsTooltipScreen { closeButton.clickWithAssertion() }
}
}

View file

@ -13,6 +13,10 @@ class MarketsTooltipPageObject(semanticsProvider: SemanticsNodeInteractionsProvi
val contentContainer: KNode = child {
hasTestTag(MarketTooltipTestTags.CONTAINER)
}
val closeButton: KNode = child {
hasTestTag(MarketTooltipTestTags.CLOSE_BUTTON)
}
}
internal fun BaseTestCase.onMarketsTooltipScreen(function: MarketsTooltipPageObject.() -> Unit) =

View file

@ -2,4 +2,5 @@ package com.tangem.core.ui.test
object MarketTooltipTestTags {
const val CONTAINER = "MARKETS_TOOLTIP_CONTAINER"
const val CLOSE_BUTTON = "MARKETS_TOOLTIP_CLOSE_BUTTON"
}

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="18dp"
android:viewportWidth="18"
android:viewportHeight="18">
<path
android:pathData="M9,0C13.971,0 18,4.029 18,9C18,13.971 13.971,18 9,18C4.029,18 0,13.971 0,9C0,4.029 4.029,0 9,0ZM8.359,4.465V8.358H4.466V9.642H8.359V13.535H9.642V9.642H13.535V8.358H9.642V4.465H8.359Z"
android:fillColor="#0099FF"
android:fillType="evenOdd"/>
</vector>

View file

@ -146,6 +146,17 @@ internal class WalletModel @Inject constructor(
fun onResume() {
suggestToEnableBiometrics()
suggestToOpenMarketsOnResume()
}
private fun suggestToOpenMarketsOnResume() {
modelScope.launch {
if (shouldShowMarketsTooltipUseCase()) {
stateHolder.update {
it.copy(showMarketsOnboarding = true)
}
}
}
}
private fun updateMarketToggle() {
@ -203,8 +214,6 @@ internal class WalletModel @Inject constructor(
it.copy(showMarketsOnboarding = true)
}
}
shouldShowMarketsTooltipUseCase(isShown = true)
}
}

View file

@ -46,7 +46,7 @@ internal interface WalletContentClickIntents {
fun onOrganizeTokensClick()
fun onDismissMarketsOnboarding()
fun onDismissMarketsTooltip()
fun onTokenItemClick(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus)
@ -112,7 +112,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
router.openOrganizeTokensScreen(userWalletId = stateHolder.getSelectedWalletId())
}
override fun onDismissMarketsOnboarding() {
override fun onDismissMarketsTooltip() {
stateHolder.update { it.copy(showMarketsOnboarding = false) }
modelScope.launch {
shouldShowMarketsTooltipUseCase(isShown = true)

View file

@ -222,7 +222,7 @@ internal object WalletScreenPreviewData {
event = consumedEvent(),
isHidingMode = false,
showMarketsOnboarding = false,
onDismissMarketsOnboarding = {},
onDismissMarketsTooltip = {},
isNewMarketEnabled = false,
)

View file

@ -109,7 +109,7 @@ internal class WalletStateController @Inject constructor() {
event = consumedEvent(),
isHidingMode = false,
showMarketsOnboarding = false,
onDismissMarketsOnboarding = {},
onDismissMarketsTooltip = {},
isNewMarketEnabled = false,
)
}

View file

@ -14,5 +14,5 @@ internal data class WalletScreenState(
val isHidingMode: Boolean,
val showMarketsOnboarding: Boolean,
val isNewMarketEnabled: Boolean,
val onDismissMarketsOnboarding: () -> Unit,
val onDismissMarketsTooltip: () -> Unit,
)

View file

@ -44,7 +44,7 @@ internal class InitializeWalletsTransformer(
}
.toImmutableList(),
onWalletChange = clickIntents::onWalletChange,
onDismissMarketsOnboarding = clickIntents::onDismissMarketsOnboarding,
onDismissMarketsTooltip = clickIntents::onDismissMarketsTooltip,
)
}

View file

@ -409,19 +409,22 @@ private inline fun BaseScaffoldWithMarkets(
visible = bottomSheetState.targetValue == TangemSheetValue.Expanded ||
state.showMarketsOnboarding,
onDismissRequest = {
coroutineScope.launch { bottomSheetState.partialExpand() }
state.onDismissMarketsOnboarding()
if (!state.showMarketsOnboarding) {
coroutineScope.launch { bottomSheetState.partialExpand() }
}
},
)
MarketsTooltip(
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 24.dp)
.fillMaxWidth(fraction = 0.7f),
.padding(bottom = 8.dp)
.padding(horizontal = 16.dp)
.fillMaxWidth(),
isVisible = state.showMarketsOnboarding,
availableHeight = maxHeight,
bottomSheetState = bottomSheetState,
onCloseClick = state.onDismissMarketsTooltip,
)
}
},
@ -443,7 +446,7 @@ private inline fun BaseScaffoldWithMarkets(
LaunchedEffect(state.showMarketsOnboarding, bottomSheetState.targetValue) {
if (state.showMarketsOnboarding && bottomSheetState.targetValue == TangemSheetValue.Expanded) {
state.onDismissMarketsOnboarding()
state.onDismissMarketsTooltip()
}
}
}
@ -454,6 +457,7 @@ private fun MarketsTooltip(
availableHeight: Dp,
bottomSheetState: TangemSheetState,
isVisible: Boolean,
onCloseClick: () -> Unit,
modifier: Modifier = Modifier,
) {
val density = LocalDensity.current
@ -494,7 +498,7 @@ private fun MarketsTooltip(
) + fadeIn(),
exit = fadeOut(),
) {
MarketsTooltipContent()
MarketsTooltipContent(onCloseClick = onCloseClick)
}
}
@ -527,12 +531,12 @@ internal fun MarketsHint(isVisible: Boolean, modifier: Modifier = Modifier) {
}
@Composable
private fun MarketsTooltipContent(modifier: Modifier = Modifier) {
val backgroundColor = TangemTheme.colors.background.action
val cornerRadius = CornerRadius(x = 14.dp.toPx())
private fun MarketsTooltipContent(onCloseClick: () -> Unit, modifier: Modifier = Modifier) {
val backgroundColor = TangemTheme.colors.background.primary
val cornerRadius = CornerRadius(x = 16.dp.toPx())
val tipDpSize = DpSize(width = 20.dp, height = 8.dp)
Column(
Row(
modifier = modifier
.padding(bottom = tipDpSize.height)
.drawBehind {
@ -555,18 +559,42 @@ private fun MarketsTooltipContent(modifier: Modifier = Modifier) {
drawPath(color = backgroundColor, path = tipPath)
}
.padding(all = 12.dp),
verticalArrangement = Arrangement.spacedBy(space = 4.dp),
horizontalAlignment = Alignment.Start,
horizontalArrangement = Arrangement.spacedBy(space = 12.dp),
verticalAlignment = Alignment.Top,
) {
Text(
text = stringResourceSafe(id = R.string.markets_tooltip_title),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.primary1,
Icon(
modifier = Modifier.size(size = 18.dp),
painter = painterResource(id = R.drawable.ic_plus_18),
tint = Color.Unspecified,
contentDescription = null,
)
Text(
text = stringResourceSafe(id = R.string.markets_tooltip_message),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.secondary,
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(space = 2.dp),
) {
Text(
text = stringResourceSafe(id = R.string.markets_tooltip_v2_title),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.primary1,
)
Text(
text = stringResourceSafe(id = R.string.markets_tooltip_message),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.secondary,
)
}
Icon(
modifier = Modifier
.size(size = 16.dp)
.clickable(
interactionSource = null,
indication = null,
onClick = onCloseClick,
)
.testTag(MarketTooltipTestTags.CLOSE_BUTTON),
painter = painterResource(id = R.drawable.ic_close_24),
tint = TangemTheme.colors.icon.informative,
contentDescription = null,
)
}
}