Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-24 17:33:46 +04:00
parent 4aac8dc94c
commit b392e4b176
16 changed files with 119 additions and 323 deletions

View file

@ -13,59 +13,41 @@ android {
dependencies {
/** Api */
implementation(projects.features.home.api)
implementation(projects.features.hotWallet.api)
/** Core modules */
implementation(projects.core.decompose)
implementation(projects.core.ui)
implementation(projects.core.res)
implementation(projects.core.analytics)
implementation(projects.core.analytics.models)
implementation(projects.core.navigation)
implementation(projects.core.utils)
implementation(projects.core.configToggles)
/** Common */
implementation(projects.common.routing)
/** Domain */
implementation(projects.domain.common)
implementation(projects.domain.models)
implementation(projects.domain.core)
implementation(projects.domain.card)
implementation(projects.domain.settings)
implementation(projects.domain.tokens)
implementation(projects.domain.wallets)
implementation(projects.domain.wallets.models)
implementation(projects.domain.legacy)
implementation(projects.domain.feedback)
implementation(projects.domain.feedback.models)
implementation(projects.domain.referral)
/** Referral */
implementation(projects.features.referral.domain)
/** AndroidX libraries */
implementation(deps.androidx.activity.compose)
implementation(deps.lifecycle.runtime.ktx)
/** Compose libraries */
implementation(deps.compose.ui)
implementation(deps.compose.ui.tooling)
implementation(deps.compose.foundation)
implementation(deps.compose.material3)
implementation(deps.compose.animation)
implementation(deps.compose.coil)
implementation(deps.decompose.ext.compose)
/** Tangem libraries */
implementation(tangemDeps.card.android)
implementation(tangemDeps.card.core)
implementation(tangemDeps.blockchain)
/** Other libraries */
implementation(deps.kotlin.immutable.collections)
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)

View file

@ -1,10 +0,0 @@
<?xml version="1.0" ?>
<SmellBaseline>
<ManuallySuppressedIssues/>
<CurrentIssues>
<ID>BooleanPropertyNaming:HomeButtons.kt$HomeButtonsState$val btnScanStateInProgress: Boolean</ID>
<ID>BooleanPropertyNaming:HomeUM.kt$HomeUM$val scanInProgress: Boolean</ID>
<ID>MultilineLambdaItParameter:StoriesProgressBar.kt${ when (index) { currentStep -&gt; it.fillMaxWidth(progress.value) in 0 until currentStep -&gt; it.fillMaxWidth(fraction = 1f) else -&gt; it } }</ID>
<ID>ReusedModifierInstance:HomeButtonsV2.kt$StoriesButton( modifier = modifier, text = stringResourceSafe(id = R.string.common_get_started), useDarkerColors = false, onClick = onGetStartedClick, )</ID>
</CurrentIssues>
</SmellBaseline>

View file

@ -85,7 +85,7 @@ internal class HomeModel @Inject constructor(
private fun createInitialState(): HomeUM {
val initialStories = getRestrictedStories().toImmutableList()
return HomeUM(
scanInProgress = false,
isScanInProgress = false,
isStoriesContainerEnabled = homeFeatureToggles.isStoriesContainerEnabled,
stories = initialStories,
storiesConfig = HomeStoriesConfig(stories = initialStories),
@ -204,7 +204,7 @@ internal class HomeModel @Inject constructor(
}
private fun setLoading(isLoading: Boolean) {
uiState.update { it.copy(scanInProgress = isLoading) }
uiState.update { it.copy(isScanInProgress = isLoading) }
}
private fun handleScanError(error: TangemError) {

View file

@ -50,7 +50,7 @@ internal fun HomeStoriesScreen(state: HomeUM, modifier: Modifier = Modifier) {
StoriesContainer(
modifier = Modifier.fillMaxSize(),
config = state.storiesConfig,
isPauseStories = state.scanInProgress,
isPauseStories = state.isScanInProgress,
) { story, isPaused ->
Column(
modifier = Modifier

View file

@ -26,7 +26,7 @@ private const val SCALE_SWITCH_BARRIER = 1.15f
@Suppress("LongParameterList")
@Composable
fun HorizontalSlidingImage(
internal fun HorizontalSlidingImage(
painter: Painter,
paused: Boolean,
duration: Int,
@ -52,7 +52,7 @@ fun HorizontalSlidingImage(
}
@Composable
fun StoriesTextAnimation(
internal fun StoriesTextAnimation(
slideInDuration: Int = 500,
slideInDelay: Int = 200,
slideDistance: Dp = 60.dp,
@ -94,7 +94,7 @@ fun StoriesTextAnimation(
}
@Composable
fun StoriesBottomImageAnimation(
internal fun StoriesBottomImageAnimation(
firstStepDuration: Int,
totalDuration: Int,
initialScale: Float = 2.5f,

View file

@ -63,7 +63,7 @@ internal fun StoriesScreenV2(state: HomeUM, onGetStartedClick: () -> Unit, modif
storiesSize = state.stories.lastIndex,
currentStoryIndex = currentStoryIndex,
currentStory = currentStory,
isScanInProgress = state.scanInProgress,
isScanInProgress = state.isScanInProgress,
onGoToPreviousStory = goToPreviousStory,
onGoToNextStory = goToNextStory,
onGetStartedClick = onGetStartedClick,

View file

@ -3,7 +3,6 @@ package com.tangem.features.home.impl.ui.compose.content
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
@ -22,33 +21,44 @@ import com.tangem.core.ui.R
import com.tangem.core.ui.utils.dpSize
import com.tangem.core.ui.utils.toPx
@Composable
fun StoriesCurrenciesContent(paused: Boolean, duration: Int) {
val currencyDrawableList = remember {
listOf(
R.drawable.currency0,
R.drawable.currency1,
R.drawable.currency2,
R.drawable.currency3,
R.drawable.currency4,
)
}
private val currencyDrawables = listOf(
R.drawable.currency0,
R.drawable.currency1,
R.drawable.currency2,
R.drawable.currency3,
R.drawable.currency4,
)
private val web3DappDrawables = listOf(
R.drawable.dapps1,
R.drawable.dapps1,
R.drawable.dapps2,
R.drawable.dapps3,
R.drawable.dapps4,
R.drawable.dapps5,
)
private val currencyDesignItemHeight = 82.dp
private val web3DesignItemHeight = 75.dp
private val currencyDecreaseRate = 1f / currencyDrawables.size
private val web3DecreaseRate = 1f / web3DappDrawables.size
private const val WEB3_CHESS_OFFSET_DIVIDER = 3
@Composable
internal fun StoriesCurrenciesContent(paused: Boolean, duration: Int) {
val screenWidth = LocalConfiguration.current.screenWidthDp.dp
val decreaseRate = remember { 1f / currencyDrawableList.size }
val designItemHeight = remember { 82.dp }
BoxWithGradient {
Column(modifier = Modifier.graphicsLayer(clip = false)) {
currencyDrawableList.forEachIndexed { index, drawableResId ->
currencyDrawables.forEachIndexed { index, drawableResId ->
val painter = painterResource(id = drawableResId)
val scaledItemSize = scaleToDesignSize(painter.dpSize(), designItemHeight = designItemHeight)
val scaledItemSize = scaleToDesignSize(painter.dpSize(), designItemHeight = currencyDesignItemHeight)
val itemOversizedScreenWidthBy = scaledItemSize.width - screenWidth
val moveItemToStartOfScreen = itemOversizedScreenWidthBy / 2
val chessOffset = if (index.isEven()) 0.dp else scaledItemSize.halfHeight()
val animateFrom = chessOffset - moveItemToStartOfScreen
val animateTo = 50.dp - 50.dp * index * decreaseRate
val animateTo = 50.dp - 50.dp * index * currencyDecreaseRate
HorizontalSlidingImage(
paused = paused,
@ -65,34 +75,21 @@ fun StoriesCurrenciesContent(paused: Boolean, duration: Int) {
}
}
@Suppress("MagicNumber")
@Composable
fun StoriesWeb3Content(paused: Boolean, duration: Int) {
val dappsItemList = remember {
listOf(
R.drawable.dapps1,
R.drawable.dapps1,
R.drawable.dapps2,
R.drawable.dapps3,
R.drawable.dapps4,
R.drawable.dapps5,
)
}
internal fun StoriesWeb3Content(paused: Boolean, duration: Int) {
val screenWidth = LocalConfiguration.current.screenWidthDp.dp
val decreaseRate = remember { 1f / dappsItemList.size }
val designItemHeight = 75.dp
BoxWithGradient {
Column(modifier = Modifier.graphicsLayer(clip = false)) {
dappsItemList.forEachIndexed { index, drawableResId ->
web3DappDrawables.forEachIndexed { index, drawableResId ->
val painter = painterResource(id = drawableResId)
val scaledItemSize = scaleToDesignSize(painter.dpSize(), designItemHeight = designItemHeight)
val scaledItemSize = scaleToDesignSize(painter.dpSize(), designItemHeight = web3DesignItemHeight)
val itemOversizedScreenWidthBy = scaledItemSize.width - screenWidth
val moveItemToStartOfScreen = itemOversizedScreenWidthBy / 2
val chessOffset = if (index.isEven()) 0.dp else scaledItemSize.width / 3
val chessOffset = if (index.isEven()) 0.dp else scaledItemSize.width / WEB3_CHESS_OFFSET_DIVIDER
val animateFrom = chessOffset - moveItemToStartOfScreen
val animateTo = 70.dp - 70.dp * index * decreaseRate
val animateTo = 70.dp - 70.dp * index * web3DecreaseRate
HorizontalSlidingImage(
paused = paused,
@ -138,6 +135,6 @@ private val BottomGradient: Brush = Brush.verticalGradient(
),
)
fun DpSize.halfHeight(): Dp = this.height / 2
private fun DpSize.halfHeight(): Dp = this.height / 2
fun Int.isEven() = this and 1 == 0
private fun Int.isEven() = this and 1 == 0

View file

@ -13,7 +13,6 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
@ -21,16 +20,21 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.sp
import com.tangem.core.ui.R
import com.tangem.core.ui.components.SpacerH
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemColorPalette
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.home.impl.ui.compose.StoriesTextAnimation
import com.tangem.core.ui.R
@Suppress("LongMethod", "ComplexMethod", "MagicNumber")
private val firstStoryTitleStyle = TextStyle(
fontSize = 46.sp,
fontWeight = FontWeight.SemiBold,
textAlign = TextAlign.Center,
)
@Composable
fun FirstStoriesContent(isPaused: Boolean, duration: Int) {
internal fun FirstStoriesContent(isPaused: Boolean, duration: Int) {
val progress = remember { Animatable(0f) }
LaunchedEffect(isPaused) {
@ -47,16 +51,8 @@ fun FirstStoriesContent(isPaused: Boolean, duration: Int) {
}
}
val style = TextStyle(
fontSize = 46.sp,
fontWeight = FontWeight.SemiBold,
color = Color.White,
textAlign = TextAlign.Center,
)
Column(
modifier = Modifier
.fillMaxSize(),
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
SpacerH(TangemTheme.dimens.spacing94)
@ -67,15 +63,14 @@ fun FirstStoriesContent(isPaused: Boolean, duration: Int) {
Text(
modifier = modifier,
text = stringResourceSafe(R.string.story_meet_title),
style = style,
style = firstStoryTitleStyle,
color = TangemColorPalette.White,
textAlign = TextAlign.Center,
)
}
SpacerH(TangemTheme.dimens.spacing46)
Image(
modifier = Modifier
.fillMaxWidth(),
modifier = Modifier.fillMaxWidth(),
painter = painterResource(R.drawable.img_meet_tangem),
contentScale = ContentScale.Inside,
contentDescription = "Tangem Wallet card",
@ -86,8 +81,5 @@ fun FirstStoriesContent(isPaused: Boolean, duration: Int) {
@Preview
@Composable
private fun FirstStoriesPreview() {
FirstStoriesContent(
false,
8000,
)
FirstStoriesContent(isPaused = false, duration = 8000)
}

View file

@ -1,40 +1,56 @@
package com.tangem.features.home.impl.ui.compose.content
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import com.tangem.core.ui.R
import com.tangem.core.ui.utils.AnimatedValue
import com.tangem.core.ui.utils.asImageBitmap
import com.tangem.core.ui.utils.toAnimatable
/**
[REDACTED_AUTHOR]
*/
@Composable
fun FloatingCardsContent(isPaused: Boolean, stepDuration: Int) {
val imageBitmap = asImageBitmap(R.drawable.img_card_placeholder_wallet_2)
val cards = listOf(
FloatingCard.first(),
FloatingCard.second(),
FloatingCard.third(),
)
internal fun FloatingCardsContent(isPaused: Boolean, stepDuration: Int) {
Box(modifier = Modifier.fillMaxSize()) {
cards.forEach { floatingCard ->
FloatingCard.Item(
floatingCards.forEach { cardValues ->
FloatingCardItem(
isPaused = isPaused,
imageBitmap = imageBitmap,
cardValues = floatingCard,
imageRes = R.drawable.img_card_placeholder_wallet_2,
cardValues = cardValues,
stepDuration = stepDuration,
)
}
}
}
@Composable
private fun FloatingCardItem(
isPaused: Boolean,
stepDuration: Int,
@DrawableRes imageRes: Int,
cardValues: CardValues,
) {
Image(
painter = painterResource(imageRes),
contentDescription = null,
modifier = Modifier
.graphicsLayer(
translationX = cardValues.translateX.toAnimatable(isPaused, stepDuration).value,
translationY = cardValues.translateY.toAnimatable(isPaused, stepDuration).value,
rotationX = cardValues.rotationX.toAnimatable(isPaused, stepDuration).value,
rotationY = cardValues.rotationY.toAnimatable(isPaused, stepDuration).value,
rotationZ = cardValues.rotationZ.toAnimatable(isPaused, stepDuration).value,
scaleX = cardValues.scale.toAnimatable(isPaused, stepDuration).value,
scaleY = cardValues.scale.toAnimatable(isPaused, stepDuration).value,
),
)
}
private data class CardValues(
val translateX: AnimatedValue = AnimatedValue(0f, 0f),
val translateY: AnimatedValue = AnimatedValue(0f, 0f),
@ -44,54 +60,30 @@ private data class CardValues(
val scale: AnimatedValue = AnimatedValue(1f, 1f),
)
private object FloatingCard {
@Suppress("TopLevelComposableFunctions")
@Composable
fun Item(isPaused: Boolean, stepDuration: Int, imageBitmap: ImageBitmap, cardValues: CardValues) {
Image(
bitmap = imageBitmap,
contentDescription = "Floating Tangem card",
modifier = Modifier
.graphicsLayer(
translationX = cardValues.translateX.toAnimatable(isPaused, stepDuration).value,
translationY = cardValues.translateY.toAnimatable(isPaused, stepDuration).value,
rotationX = cardValues.rotationX.toAnimatable(isPaused, stepDuration).value,
rotationY = cardValues.rotationY.toAnimatable(isPaused, stepDuration).value,
rotationZ = cardValues.rotationZ.toAnimatable(isPaused, stepDuration).value,
scaleX = cardValues.scale.toAnimatable(isPaused, stepDuration).value,
scaleY = cardValues.scale.toAnimatable(isPaused, stepDuration).value,
),
)
}
@Suppress("MagicNumber")
fun first(): CardValues = CardValues(
@Suppress("MagicNumber")
private val floatingCards = listOf(
CardValues(
translateX = -400f to -350f,
translateY = 30f to 32f,
rotationX = 10f to 15f,
rotationY = 15f to 15f,
rotationZ = 40f to 27f,
scale = 0.6f to 0.6f,
)
@Suppress("MagicNumber")
fun second(): CardValues = CardValues(
),
CardValues(
translateX = 350f to 300f,
translateY = -70f to 0f,
rotationX = 30f to 48f,
rotationY = 0f to 5f,
rotationZ = -34f to -42f,
scale = 0.47f to 0.35f,
)
@Suppress("MagicNumber")
fun third(): CardValues = CardValues(
),
CardValues(
translateX = 320f to 250f,
translateY = 500f to 500f,
rotationX = 0f to 3f,
rotationY = 10f to 10f,
rotationZ = -45f to -30f,
scale = 0.6f to 0.75f,
)
}
),
)

View file

@ -26,7 +26,7 @@ import com.tangem.features.home.impl.ui.compose.StoriesTextAnimation
import com.tangem.core.ui.R
@Composable
fun StoriesRevolutionaryWallet() {
internal fun StoriesRevolutionaryWallet() {
SplitContent(
topContent = {
TopContent(
@ -45,7 +45,7 @@ fun StoriesRevolutionaryWallet() {
}
@Composable
fun StoriesUltraSecureBackup(isPaused: Boolean, stepDuration: Int) {
internal fun StoriesUltraSecureBackup(isPaused: Boolean, stepDuration: Int) {
SplitContent(
topContent = {
TopContent(
@ -64,7 +64,7 @@ fun StoriesUltraSecureBackup(isPaused: Boolean, stepDuration: Int) {
}
@Composable
fun StoriesCurrencies(isPaused: Boolean, stepDuration: Int) {
internal fun StoriesCurrencies(isPaused: Boolean, stepDuration: Int) {
SplitContent(
topContent = {
TopContent(
@ -80,7 +80,7 @@ fun StoriesCurrencies(isPaused: Boolean, stepDuration: Int) {
}
@Composable
fun StoriesWeb3(isPaused: Boolean, stepDuration: Int) {
internal fun StoriesWeb3(isPaused: Boolean, stepDuration: Int) {
SplitContent(
topContent = {
TopContent(
@ -96,7 +96,7 @@ fun StoriesWeb3(isPaused: Boolean, stepDuration: Int) {
}
@Composable
fun StoriesWalletForEveryone(stepDuration: Int) {
internal fun StoriesWalletForEveryone(stepDuration: Int) {
SplitContent(
topContent = {
TopContent(
@ -127,8 +127,7 @@ fun StoriesWalletForEveryone(stepDuration: Int) {
@Composable
private fun SplitContent(topContent: @Composable () -> Unit, bottomContent: @Composable () -> Unit) {
Column(
modifier = Modifier
.fillMaxSize(),
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top,
) {
@ -140,16 +139,11 @@ private fun SplitContent(topContent: @Composable () -> Unit, bottomContent: @Com
@Composable
private fun TopContent(titleText: String, subtitleText: String) {
SpacerH(TangemTheme.dimens.spacing36)
StoriesTitleText(
text = titleText,
)
StoriesTitleText(text = titleText)
SpacerH16()
StoriesSubtitleText(
subtitleText = subtitleText,
)
StoriesSubtitleText(subtitleText = subtitleText)
}
@Suppress("MagicNumber")
@Composable
private fun StoriesTitleText(text: String) {
StoriesTextAnimation(
@ -157,8 +151,7 @@ private fun StoriesTitleText(text: String) {
slideInDelay = 150,
) { modifier ->
Text(
modifier = modifier
.padding(start = 40.dp, end = 40.dp),
modifier = modifier.padding(horizontal = 40.dp),
text = text,
style = TangemTheme.typography.head,
color = TangemColorPalette.White,
@ -167,7 +160,6 @@ private fun StoriesTitleText(text: String) {
}
}
@Suppress("MagicNumber")
@Composable
private fun StoriesSubtitleText(subtitleText: String) {
StoriesTextAnimation(
@ -175,8 +167,7 @@ private fun StoriesSubtitleText(subtitleText: String) {
slideInDelay = 400,
) { modifier ->
Text(
modifier = modifier
.padding(start = 40.dp, end = 40.dp),
modifier = modifier.padding(horizontal = 40.dp),
text = subtitleText,
style = TangemTheme.typography.body1,
color = TangemColorPalette.Dark1,

View file

@ -1,105 +0,0 @@
package com.tangem.features.home.impl.ui.compose.views
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import com.tangem.core.ui.components.SpacerW12
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.test.StoriesScreenTestTags
import com.tangem.core.ui.R
@Composable
internal fun HomeButtons(
btnScanStateInProgress: Boolean,
onScanButtonClick: () -> Unit,
onShopButtonClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(
horizontalArrangement = Arrangement.SpaceEvenly,
modifier = modifier,
) {
ScanCardButton(
modifier = Modifier
.weight(weight = 1f)
.testTag(StoriesScreenTestTags.SCAN_BUTTON),
showProgress = btnScanStateInProgress,
onClick = onScanButtonClick,
)
SpacerW12()
OrderCardButton(
modifier = Modifier
.weight(weight = 1f)
.testTag(StoriesScreenTestTags.ORDER_BUTTON),
onClick = onShopButtonClick,
)
}
}
@Composable
private fun ScanCardButton(showProgress: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier) {
StoriesButton(
modifier = modifier,
text = stringResourceSafe(id = R.string.home_button_scan),
useDarkerColors = false,
icon = TangemButtonIconPosition.End(iconResId = R.drawable.ic_tangem_24),
onClick = onClick,
showProgress = showProgress,
)
}
@Composable
private fun OrderCardButton(onClick: () -> Unit, modifier: Modifier = Modifier) {
StoriesButton(
modifier = modifier,
text = stringResourceSafe(id = R.string.home_button_order),
useDarkerColors = true,
onClick = onClick,
)
}
// region Preview
@Preview(showBackground = true, widthDp = 360)
@Composable
private fun HomeButtonsPreview(@PreviewParameter(HomeButtonsParameterProvider::class) state: HomeButtonsState) {
TangemThemePreview {
Box(
modifier = Modifier.background(Color.Black),
) {
HomeButtons(
btnScanStateInProgress = state.btnScanStateInProgress,
onScanButtonClick = {},
onShopButtonClick = {},
modifier = Modifier.padding(all = TangemTheme.dimens.spacing16),
)
}
}
}
private class HomeButtonsParameterProvider : CollectionPreviewParameterProvider<HomeButtonsState>(
collection = listOf(
HomeButtonsState(
btnScanStateInProgress = false,
),
HomeButtonsState(
btnScanStateInProgress = true,
),
),
)
private data class HomeButtonsState(
val btnScanStateInProgress: Boolean,
)
// endregion Preview

View file

@ -24,7 +24,7 @@ internal fun HomeButtonsV2(onGetStartedClick: () -> Unit, modifier: Modifier = M
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
StoriesButton(
modifier = modifier,
modifier = Modifier.fillMaxWidth(),
text = stringResourceSafe(id = R.string.common_get_started),
useDarkerColors = false,
onClick = onGetStartedClick,

View file

@ -1,43 +0,0 @@
package com.tangem.features.home.impl.ui.compose.views
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.R
@Composable
internal fun SearchCurrenciesButton(onClick: () -> Unit, modifier: Modifier = Modifier) {
StoriesButton(
modifier = modifier,
text = stringResourceSafe(id = R.string.common_search_tokens),
icon = TangemButtonIconPosition.Start(R.drawable.ic_search_24),
showProgress = false,
useDarkerColors = true,
onClick = onClick,
)
}
// region Preview
@Preview(showBackground = true, widthDp = 360)
@Composable
private fun SearchCurrenciesButtonPreview() {
TangemThemePreview {
Box(
modifier = Modifier
.background(color = Color.Black)
.padding(all = TangemTheme.dimens.spacing16),
) {
SearchCurrenciesButton(modifier = Modifier.fillMaxWidth(), onClick = {})
}
}
}
// endregion Preview

View file

@ -23,7 +23,7 @@ import kotlinx.coroutines.delay
private const val STORIES_ANIMATION_SPEED_ZERO_DURATION = 3000L
@Composable
fun StoriesProgressBar(
internal fun StoriesProgressBar(
steps: Int,
currentStep: Int,
paused: Boolean = false,
@ -82,11 +82,11 @@ fun StoriesProgressBar(
.clip(RoundedCornerShape(TangemTheme.dimens.radius2))
.background(TangemColorPalette.White)
.fillMaxHeight()
.let {
.let { progressModifier ->
when (index) {
currentStep -> it.fillMaxWidth(progress.value)
in 0 until currentStep -> it.fillMaxWidth(fraction = 1f)
else -> it
currentStep -> progressModifier.fillMaxWidth(progress.value)
in 0 until currentStep -> progressModifier.fillMaxWidth(fraction = 1f)
else -> progressModifier
}
},
)

View file

@ -4,8 +4,8 @@ import com.tangem.core.ui.components.stories.model.StoriesContentConfig
import com.tangem.core.ui.components.stories.model.StoryConfig
import kotlinx.collections.immutable.ImmutableList
data class HomeUM(
val scanInProgress: Boolean,
internal data class HomeUM(
val isScanInProgress: Boolean,
val isStoriesContainerEnabled: Boolean,
val stories: ImmutableList<Stories>,
val storiesConfig: HomeStoriesConfig,
@ -20,13 +20,13 @@ data class HomeUM(
* Config for the redesigned Home stories ([StoriesContainer]). The Home intro loops forever and is
* not closable, so [isCloseButtonVisible] is `false` and [onClose] keeps its no-op default.
*/
data class HomeStoriesConfig(
internal data class HomeStoriesConfig(
override val stories: ImmutableList<Stories>,
override val isRestartable: Boolean = true,
override val isCloseButtonVisible: Boolean = false,
) : StoriesContentConfig<Stories>
enum class Stories(override val duration: Int = 6000) : StoryConfig {
internal enum class Stories(override val duration: Int = 6000) : StoryConfig {
TangemIntro,
RevolutionaryWallet,
UltraSecureBackup,
@ -38,6 +38,6 @@ enum class Stories(override val duration: Int = 6000) : StoryConfig {
/**
* For FCA restriction stories
*/
fun getRestrictedStories(): List<Stories> {
internal fun getRestrictedStories(): List<Stories> {
return Stories.entries.filterNot { it == Stories.Currencies }
}

View file

@ -157,13 +157,13 @@ internal class HomeModelTest {
// Act + Assert — loading on
progressSlot.captured.invoke(true)
advanceUntilIdle()
assertThat(model.uiState.value.scanInProgress).isTrue()
assertThat(model.uiState.value.isScanInProgress).isTrue()
assertThat(model.uiState.value.storiesConfig).isSameInstanceAs(initialConfig)
// Act + Assert — loading off
progressSlot.captured.invoke(false)
advanceUntilIdle()
assertThat(model.uiState.value.scanInProgress).isFalse()
assertThat(model.uiState.value.isScanInProgress).isFalse()
assertThat(model.uiState.value.storiesConfig).isSameInstanceAs(initialConfig)
model.onDestroy()