Updated on 2026-08-14
|
|
@ -8,6 +8,7 @@ import androidx.activity.compose.BackHandler
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
|
|
@ -16,6 +17,7 @@ import androidx.lifecycle.lifecycleScope
|
|||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
import com.tangem.core.navigation.NavigationAction
|
||||
import com.tangem.core.ui.components.SystemBarsEffect
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.domain.tokens.TokensAction
|
||||
import com.tangem.tap.common.analytics.events.IntroductionProcess
|
||||
|
|
@ -52,6 +54,12 @@ class HomeFragment : Fragment(), StoreSubscriber<HomeState> {
|
|||
BackHandler {
|
||||
requireActivity().finish()
|
||||
}
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(
|
||||
color = Color.Transparent,
|
||||
darkIcons = false,
|
||||
)
|
||||
}
|
||||
ScreenContent()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,18 +12,13 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.learn2earn.presentation.ui.Learn2earnStoriesScreen
|
||||
import com.tangem.tap.features.home.compose.content.*
|
||||
|
|
@ -43,7 +38,6 @@ fun StoriesScreen(
|
|||
onShopButtonClick: () -> Unit,
|
||||
onSearchTokensClick: () -> Unit,
|
||||
) {
|
||||
val systemUiController = rememberSystemUiController()
|
||||
val state = homeState.value
|
||||
|
||||
var currentStory by remember { mutableStateOf(state.firstStory) }
|
||||
|
|
@ -62,13 +56,6 @@ fun StoriesScreen(
|
|||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(key1 = currentStory.isDarkBackground) {
|
||||
systemUiController.setSystemBarsColor(
|
||||
color = Color.Transparent,
|
||||
darkIcons = !currentStory.isDarkBackground,
|
||||
)
|
||||
}
|
||||
|
||||
StoriesScreenContent(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
config = StoriesScreenContentConfig(
|
||||
|
|
@ -90,13 +77,12 @@ fun StoriesScreen(
|
|||
@Composable
|
||||
private fun StoriesScreenContent(config: StoriesScreenContentConfig, modifier: Modifier = Modifier) {
|
||||
var isPressed by remember { mutableStateOf(value = false) }
|
||||
var hideContent by remember { mutableStateOf(value = true) }
|
||||
|
||||
val isPaused = isPressed || config.isScanInProgress
|
||||
val currentStoryDuration = config.currentStory.duration
|
||||
|
||||
Box(
|
||||
modifier = modifier.background(Color(0xFF090E13)),
|
||||
modifier = modifier.background(Color(0xFF010101)),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
|
|
@ -138,14 +124,6 @@ private fun StoriesScreenContent(config: StoriesScreenContentConfig, modifier: M
|
|||
},
|
||||
)
|
||||
}
|
||||
if (!config.currentStory.isDarkBackground) {
|
||||
Image(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
painter = painterResource(id = R.drawable.ic_overlay),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.FillBounds,
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
|
@ -166,30 +144,23 @@ private fun StoriesScreenContent(config: StoriesScreenContentConfig, modifier: M
|
|||
contentDescription = null,
|
||||
contentScale = ContentScale.FillHeight,
|
||||
modifier = Modifier
|
||||
.padding(start = 16.dp, top = 10.dp)
|
||||
.height(17.dp)
|
||||
.alpha(if (hideContent) 0f else 1f)
|
||||
.padding(
|
||||
start = TangemTheme.dimens.spacing16,
|
||||
top = TangemTheme.dimens.spacing16,
|
||||
)
|
||||
.height(TangemTheme.dimens.size18)
|
||||
.align(Alignment.Start),
|
||||
colorFilter = if (config.currentStory.isDarkBackground) {
|
||||
null
|
||||
} else {
|
||||
ColorFilter.tint(TangemColorPalette.Dark6)
|
||||
},
|
||||
)
|
||||
when (config.currentStory) {
|
||||
Stories.OneInchPromo -> Learn2earnStoriesScreen(config.onLearn2earnClick)
|
||||
Stories.TangemIntro -> FirstStoriesContent(
|
||||
isPaused = isPaused,
|
||||
duration = currentStoryDuration,
|
||||
isNewWalletAvailable = config.currentStory.isNewWalletAvailable,
|
||||
) {
|
||||
hideContent = it
|
||||
}
|
||||
Stories.RevolutionaryWallet -> StoriesRevolutionaryWallet(currentStoryDuration)
|
||||
)
|
||||
Stories.RevolutionaryWallet -> StoriesRevolutionaryWallet()
|
||||
is Stories.UltraSecureBackup -> StoriesUltraSecureBackup(
|
||||
isPaused = isPaused,
|
||||
stepDuration = currentStoryDuration,
|
||||
isNewWalletAvailable = config.currentStory.isNewWalletAvailable,
|
||||
)
|
||||
Stories.Currencies -> StoriesCurrencies(isPaused, currentStoryDuration)
|
||||
Stories.Web3 -> StoriesWeb3(isPaused, currentStoryDuration)
|
||||
|
|
@ -223,7 +194,6 @@ private fun StoriesScreenContent(config: StoriesScreenContentConfig, modifier: M
|
|||
) {
|
||||
HomeButtons(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
isDarkBackground = config.currentStory.isDarkBackground,
|
||||
btnScanStateInProgress = config.isScanInProgress,
|
||||
onScanButtonClick = config.onScanButtonClick,
|
||||
onShopButtonClick = config.onShopButtonClick,
|
||||
|
|
|
|||
|
|
@ -5,79 +5,56 @@ import androidx.compose.foundation.Image
|
|||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
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.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.components.SpacerH16
|
||||
import com.tangem.core.ui.components.SpacerH32
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.features.home.compose.StoriesBottomImageAnimation
|
||||
import com.tangem.tap.features.home.compose.StoriesTextAnimation
|
||||
import com.tangem.wallet.R
|
||||
|
||||
@Composable
|
||||
fun StoriesRevolutionaryWallet(stepDuration: Int) {
|
||||
fun StoriesRevolutionaryWallet() {
|
||||
SplitContent(
|
||||
topContent = {
|
||||
TopContent(
|
||||
titleText = stringResource(id = R.string.story_awe_title),
|
||||
subtitleText = stringResource(id = R.string.story_awe_description).annotated(),
|
||||
isDarkBackground = true,
|
||||
subtitleText = stringResource(id = R.string.story_awe_description),
|
||||
)
|
||||
},
|
||||
bottomContent = {
|
||||
StoriesBottomImageAnimation(
|
||||
totalDuration = stepDuration,
|
||||
firstStepDuration = 300,
|
||||
) { modifier ->
|
||||
StoriesImage(
|
||||
modifier = modifier,
|
||||
drawableResId = R.drawable.revolutionary_wallet,
|
||||
isDarkBackground = true,
|
||||
)
|
||||
}
|
||||
SpacerH32()
|
||||
StoriesImage(
|
||||
modifier = Modifier,
|
||||
drawableResId = R.drawable.img_revolutionary_wallet,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun StoriesUltraSecureBackup(isPaused: Boolean, stepDuration: Int, isNewWalletAvailable: MutableState<Boolean>) {
|
||||
val subtitleText = buildAnnotatedString {
|
||||
append(stringResource(id = R.string.story_backup_description_1))
|
||||
append(" ")
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(stringResource(id = R.string.story_backup_description_2_bold))
|
||||
}
|
||||
append(" ")
|
||||
append(stringResource(id = R.string.story_backup_description_3))
|
||||
}
|
||||
fun StoriesUltraSecureBackup(isPaused: Boolean, stepDuration: Int) {
|
||||
SplitContent(
|
||||
topContent = {
|
||||
TopContent(
|
||||
titleText = stringResource(id = R.string.story_backup_title),
|
||||
subtitleText = subtitleText,
|
||||
isDarkBackground = false,
|
||||
subtitleText = stringResource(id = R.string.story_backup_description),
|
||||
)
|
||||
},
|
||||
bottomContent = {
|
||||
SpacerH32()
|
||||
FloatingCardsContent(
|
||||
isPaused = isPaused,
|
||||
stepDuration = stepDuration,
|
||||
isNewWalletAvailable = isNewWalletAvailable,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -89,11 +66,11 @@ fun StoriesCurrencies(isPaused: Boolean, stepDuration: Int) {
|
|||
topContent = {
|
||||
TopContent(
|
||||
titleText = stringResource(id = R.string.story_currencies_title),
|
||||
subtitleText = stringResource(id = R.string.story_currencies_description).annotated(),
|
||||
isDarkBackground = false,
|
||||
subtitleText = stringResource(id = R.string.story_currencies_description),
|
||||
)
|
||||
},
|
||||
bottomContent = {
|
||||
SpacerH32()
|
||||
StoriesCurrenciesContent(paused = isPaused, duration = stepDuration)
|
||||
},
|
||||
)
|
||||
|
|
@ -105,11 +82,11 @@ fun StoriesWeb3(isPaused: Boolean, stepDuration: Int) {
|
|||
topContent = {
|
||||
TopContent(
|
||||
titleText = stringResource(id = R.string.story_web3_title),
|
||||
subtitleText = stringResource(id = R.string.story_web3_description).annotated(),
|
||||
isDarkBackground = false,
|
||||
subtitleText = stringResource(id = R.string.story_web3_description),
|
||||
)
|
||||
},
|
||||
bottomContent = {
|
||||
SpacerH(TangemTheme.dimens.spacing70)
|
||||
StoriesWeb3Content(paused = isPaused, duration = stepDuration)
|
||||
},
|
||||
)
|
||||
|
|
@ -121,20 +98,21 @@ fun StoriesWalletForEveryone(stepDuration: Int) {
|
|||
topContent = {
|
||||
TopContent(
|
||||
titleText = stringResource(id = R.string.story_finish_title),
|
||||
subtitleText = stringResource(id = R.string.story_finish_description).annotated(),
|
||||
isDarkBackground = true,
|
||||
subtitleText = stringResource(id = R.string.story_finish_description),
|
||||
)
|
||||
},
|
||||
bottomContent = {
|
||||
StoriesBottomImageAnimation(
|
||||
totalDuration = stepDuration,
|
||||
firstStepDuration = 500,
|
||||
) { modifier ->
|
||||
StoriesImage(
|
||||
modifier = modifier,
|
||||
drawableResId = R.drawable.wallet_for_everyone,
|
||||
isDarkBackground = true,
|
||||
)
|
||||
SpacerH32()
|
||||
BoxWithGradient {
|
||||
StoriesBottomImageAnimation(
|
||||
totalDuration = stepDuration,
|
||||
firstStepDuration = 500,
|
||||
) { modifier ->
|
||||
StoriesImage(
|
||||
modifier = modifier,
|
||||
drawableResId = R.drawable.img_tangem_for_everyone,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
@ -154,22 +132,20 @@ private fun SplitContent(topContent: @Composable () -> Unit, bottomContent: @Com
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun TopContent(titleText: String, subtitleText: AnnotatedString, isDarkBackground: Boolean) {
|
||||
SpacerH32()
|
||||
private fun TopContent(titleText: String, subtitleText: String) {
|
||||
SpacerH(TangemTheme.dimens.spacing36)
|
||||
StoriesTitleText(
|
||||
text = titleText,
|
||||
isDarkBackground = isDarkBackground,
|
||||
)
|
||||
SpacerH16()
|
||||
StoriesSubtitleText(
|
||||
subtitleText = subtitleText,
|
||||
)
|
||||
SpacerH32()
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
@Composable
|
||||
private fun StoriesTitleText(text: String, isDarkBackground: Boolean) {
|
||||
private fun StoriesTitleText(text: String) {
|
||||
StoriesTextAnimation(
|
||||
slideInDuration = 500,
|
||||
slideInDelay = 150,
|
||||
|
|
@ -178,10 +154,8 @@ private fun StoriesTitleText(text: String, isDarkBackground: Boolean) {
|
|||
modifier = modifier
|
||||
.padding(start = 40.dp, end = 40.dp),
|
||||
text = text,
|
||||
fontSize = 32.sp,
|
||||
lineHeight = 38.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = if (isDarkBackground) Color.White else Color(0xFF090E13),
|
||||
style = TangemTheme.typography.head,
|
||||
color = TangemColorPalette.White,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
|
|
@ -189,9 +163,7 @@ private fun StoriesTitleText(text: String, isDarkBackground: Boolean) {
|
|||
|
||||
@Suppress("MagicNumber")
|
||||
@Composable
|
||||
private fun StoriesSubtitleText(subtitleText: AnnotatedString) {
|
||||
val color = Color(0xFFA6AAAD)
|
||||
|
||||
private fun StoriesSubtitleText(subtitleText: String) {
|
||||
StoriesTextAnimation(
|
||||
slideInDuration = 500,
|
||||
slideInDelay = 400,
|
||||
|
|
@ -199,35 +171,28 @@ private fun StoriesSubtitleText(subtitleText: AnnotatedString) {
|
|||
Text(
|
||||
modifier = modifier
|
||||
.padding(start = 40.dp, end = 40.dp),
|
||||
fontWeight = FontWeight.Normal,
|
||||
text = subtitleText,
|
||||
fontSize = 20.sp,
|
||||
lineHeight = 26.sp,
|
||||
color = color,
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemColorPalette.Dark1,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StoriesImage(@DrawableRes drawableResId: Int, isDarkBackground: Boolean, modifier: Modifier = Modifier) {
|
||||
private fun StoriesImage(@DrawableRes drawableResId: Int, modifier: Modifier = Modifier) {
|
||||
Image(
|
||||
painter = painterResource(id = drawableResId),
|
||||
contentDescription = null,
|
||||
contentScale = if (isDarkBackground) ContentScale.Inside else ContentScale.FillWidth,
|
||||
contentScale = ContentScale.FillWidth,
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun String.annotated(): AnnotatedString {
|
||||
val source = this
|
||||
return buildAnnotatedString { append(source) }
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun RevolutionaryWalletPreview() {
|
||||
StoriesRevolutionaryWallet(6000)
|
||||
StoriesRevolutionaryWallet()
|
||||
}
|
||||
|
||||
@Preview
|
||||
|
|
@ -236,9 +201,6 @@ private fun UltraSecureBackupPreview() {
|
|||
StoriesUltraSecureBackup(
|
||||
false,
|
||||
6000,
|
||||
remember {
|
||||
mutableStateOf(true)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ fun StoriesCurrenciesContent(paused: Boolean, duration: Int) {
|
|||
val decreaseRate = remember { 1f / currencyDrawableList.size }
|
||||
val designItemHeight = remember { 82.dp }
|
||||
|
||||
LightenBox {
|
||||
BoxWithGradient {
|
||||
Column(modifier = Modifier.graphicsLayer(clip = false)) {
|
||||
currencyDrawableList.forEachIndexed { index, drawableResId ->
|
||||
val painter = painterResource(id = drawableResId)
|
||||
|
|
@ -72,7 +72,7 @@ fun StoriesCurrenciesContent(paused: Boolean, duration: Int) {
|
|||
fun StoriesWeb3Content(paused: Boolean, duration: Int) {
|
||||
val dappsItemList = remember {
|
||||
listOf(
|
||||
R.drawable.dapps0,
|
||||
R.drawable.dapps1,
|
||||
R.drawable.dapps1,
|
||||
R.drawable.dapps2,
|
||||
R.drawable.dapps3,
|
||||
|
|
@ -84,7 +84,7 @@ fun StoriesWeb3Content(paused: Boolean, duration: Int) {
|
|||
val decreaseRate = remember { 1f / dappsItemList.size }
|
||||
val designItemHeight = 75.dp
|
||||
|
||||
LightenBox {
|
||||
BoxWithGradient {
|
||||
Column(modifier = Modifier.graphicsLayer(clip = false)) {
|
||||
dappsItemList.forEachIndexed { index, drawableResId ->
|
||||
val painter = painterResource(id = drawableResId)
|
||||
|
|
@ -111,7 +111,7 @@ fun StoriesWeb3Content(paused: Boolean, duration: Int) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun LightenBox(content: @Composable () -> Unit) {
|
||||
internal fun BoxWithGradient(content: @Composable () -> Unit) {
|
||||
val bottomInsetsPx = WindowInsets.navigationBars.getBottom(LocalDensity.current)
|
||||
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
|
|
@ -133,9 +133,9 @@ private fun scaleToDesignSize(itemSize: DpSize, designItemHeight: Dp): DpSize {
|
|||
|
||||
private val BottomGradient: Brush = Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
TangemColorPalette.White.copy(alpha = 0f),
|
||||
TangemColorPalette.White.copy(alpha = 0.75f),
|
||||
TangemColorPalette.White.copy(alpha = 0.95f),
|
||||
TangemColorPalette.White,
|
||||
TangemColorPalette.Black.copy(alpha = 0f),
|
||||
TangemColorPalette.Black.copy(alpha = 0.75f),
|
||||
TangemColorPalette.Black.copy(alpha = 0.95f),
|
||||
TangemColorPalette.Black,
|
||||
),
|
||||
)
|
||||
|
|
@ -1,46 +1,36 @@
|
|||
package com.tangem.tap.features.home.compose.content
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
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.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.compose.FontSizeRange
|
||||
import com.tangem.tap.common.compose.TextAutoSize
|
||||
import com.tangem.tap.features.home.compose.StoriesBottomImageAnimation
|
||||
import com.tangem.tap.features.home.compose.StoriesTextAnimation
|
||||
import com.tangem.wallet.R
|
||||
|
||||
@Suppress("LongMethod", "ComplexMethod", "MagicNumber")
|
||||
@Composable
|
||||
fun FirstStoriesContent(
|
||||
isPaused: Boolean,
|
||||
duration: Int,
|
||||
isNewWalletAvailable: MutableState<Boolean>,
|
||||
onHideContent: (Boolean) -> Unit,
|
||||
) {
|
||||
val bottomInsetsPx = WindowInsets.navigationBars.getBottom(LocalDensity.current)
|
||||
|
||||
val screenState = remember { mutableStateOf(StartingScreenState.INIT) }
|
||||
fun FirstStoriesContent(isPaused: Boolean, duration: Int) {
|
||||
val progress = remember { Animatable(0f) }
|
||||
|
||||
LaunchedEffect(isPaused) {
|
||||
|
|
@ -57,142 +47,51 @@ fun FirstStoriesContent(
|
|||
}
|
||||
}
|
||||
|
||||
when (progress.value) {
|
||||
in 0f..0.2f -> screenState.value = StartingScreenState.INIT
|
||||
in 0.2f..0.3f -> screenState.value = StartingScreenState.BUY
|
||||
in 0.3f..0.4f -> screenState.value = StartingScreenState.STORE
|
||||
in 0.4f..0.5f -> screenState.value = StartingScreenState.SEND
|
||||
in 0.5f..0.6f -> screenState.value = StartingScreenState.PAY
|
||||
in 0.6f..0.7f -> screenState.value = StartingScreenState.EXCHANGE
|
||||
in 0.7f..0.8f -> screenState.value = StartingScreenState.BORROW
|
||||
in 0.8f..1f -> screenState.value = StartingScreenState.LEND
|
||||
in 1f..1.2f -> screenState.value = StartingScreenState.SHOW_CARD
|
||||
in 1.2f..2f -> screenState.value = StartingScreenState.MEET_TANGEM
|
||||
}
|
||||
|
||||
if (screenState.value == StartingScreenState.INIT) onHideContent(true)
|
||||
if (screenState.value == StartingScreenState.BUY) onHideContent(false)
|
||||
|
||||
val style = TextStyle(
|
||||
fontSize = 60.sp,
|
||||
fontSize = 46.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = Color.White,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
val textId = screenState.textId()
|
||||
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
if (screenState.isSplashingTextDisplaying()) {
|
||||
TextAutoSize(
|
||||
modifier = Modifier
|
||||
.align(Alignment.Center)
|
||||
.padding(start = 20.dp, end = 20.dp, bottom = 100.dp),
|
||||
text = textId?.let { stringResource(textId) } ?: "",
|
||||
textStyle = style,
|
||||
fontSizeRange = FontSizeRange(20.sp, 60.sp),
|
||||
)
|
||||
} else {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(0.7f),
|
||||
) {
|
||||
if (screenState.isMeetTangemDisplaying()) {
|
||||
StoriesTextAnimation(
|
||||
slideInDelay = 0,
|
||||
) { modifier ->
|
||||
TextAutoSize(
|
||||
modifier = modifier
|
||||
.padding(start = 20.dp, end = 20.dp, top = 50.dp)
|
||||
.alpha(if (screenState.value == StartingScreenState.SHOW_CARD) 0f else 1f),
|
||||
text = textId?.let { stringResource(textId) } ?: "",
|
||||
textStyle = style,
|
||||
fontSizeRange = FontSizeRange(30.sp, 50.sp),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1.2f)
|
||||
.wrapContentSize(),
|
||||
) {
|
||||
val painter = if (isNewWalletAvailable.value) {
|
||||
painterResource(id = R.drawable.img_meet_tangem2)
|
||||
} else {
|
||||
painterResource(id = R.drawable.img_meet_tangem)
|
||||
}
|
||||
StoriesBottomImageAnimation(
|
||||
totalDuration = duration,
|
||||
firstStepDuration = 400,
|
||||
) { modifier ->
|
||||
Image(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
painter = painter,
|
||||
contentDescription = "Tangem Wallet card",
|
||||
)
|
||||
}
|
||||
}
|
||||
Box {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
SpacerH(TangemTheme.dimens.spacing94)
|
||||
StoriesTextAnimation(
|
||||
slideInDuration = 500,
|
||||
slideInDelay = 150,
|
||||
) { modifier ->
|
||||
Text(
|
||||
modifier = modifier
|
||||
.weight(1f),
|
||||
text = stringResource(R.string.story_meet_title),
|
||||
style = style,
|
||||
color = TangemColorPalette.White,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
SpacerH(TangemTheme.dimens.spacing46)
|
||||
}
|
||||
|
||||
Box(
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.fillMaxWidth()
|
||||
.height(TangemTheme.dimens.size72 + bottomInsetsPx.dp)
|
||||
.background(BottomGradient),
|
||||
.fillMaxWidth(),
|
||||
painter = painterResource(R.drawable.img_meet_tangem),
|
||||
contentScale = ContentScale.FillWidth,
|
||||
contentDescription = "Tangem Wallet card",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private val BottomGradient: Brush = Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
TangemColorPalette.Black.copy(alpha = 0f),
|
||||
TangemColorPalette.Black.copy(alpha = 0.75f),
|
||||
TangemColorPalette.Black.copy(alpha = 0.95f),
|
||||
TangemColorPalette.Black,
|
||||
),
|
||||
)
|
||||
|
||||
private enum class StartingScreenState {
|
||||
INIT, BUY, STORE, SEND, PAY, EXCHANGE, BORROW, LEND, SHOW_CARD, MEET_TANGEM
|
||||
}
|
||||
|
||||
@StringRes
|
||||
private fun MutableState<StartingScreenState>.textId(): Int? = when (this.value) {
|
||||
StartingScreenState.INIT -> null
|
||||
StartingScreenState.BUY -> R.string.story_meet_buy
|
||||
StartingScreenState.STORE -> R.string.story_meet_store
|
||||
StartingScreenState.SEND -> R.string.story_meet_send
|
||||
StartingScreenState.PAY -> R.string.story_meet_pay
|
||||
StartingScreenState.EXCHANGE -> R.string.story_meet_exchange
|
||||
StartingScreenState.BORROW -> R.string.story_meet_borrow
|
||||
StartingScreenState.LEND -> R.string.story_meet_lend
|
||||
StartingScreenState.SHOW_CARD -> R.string.story_meet_title
|
||||
StartingScreenState.MEET_TANGEM -> R.string.story_meet_title
|
||||
}
|
||||
|
||||
private fun MutableState<StartingScreenState>.isSplashingTextDisplaying(): Boolean {
|
||||
return this.value != StartingScreenState.MEET_TANGEM &&
|
||||
this.value != StartingScreenState.SHOW_CARD
|
||||
}
|
||||
|
||||
private fun MutableState<StartingScreenState>.isMeetTangemDisplaying(): Boolean {
|
||||
return this.value == StartingScreenState.MEET_TANGEM
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun FirstStoriesPreview() {
|
||||
FirstStoriesContent(
|
||||
false,
|
||||
8000,
|
||||
remember {
|
||||
mutableStateOf(false)
|
||||
},
|
||||
) {}
|
||||
)
|
||||
}
|
||||
|
|
@ -1,18 +1,11 @@
|
|||
package com.tangem.tap.features.home.compose.content
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.tap.common.compose.extensions.AnimatedValue
|
||||
import com.tangem.tap.common.compose.extensions.asImageBitmap
|
||||
import com.tangem.tap.common.compose.extensions.toAnimatable
|
||||
|
|
@ -22,13 +15,8 @@ import com.tangem.wallet.R
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
fun FloatingCardsContent(isPaused: Boolean, stepDuration: Int, isNewWalletAvailable: MutableState<Boolean>) {
|
||||
val bottomInsetsPx = WindowInsets.navigationBars.getBottom(LocalDensity.current)
|
||||
val imageBitmap = if (isNewWalletAvailable.value) {
|
||||
asImageBitmap(R.drawable.img_card_placeholder_wallet_2)
|
||||
} else {
|
||||
asImageBitmap(R.drawable.card_placeholder_wallet)
|
||||
}
|
||||
fun FloatingCardsContent(isPaused: Boolean, stepDuration: Int) {
|
||||
val imageBitmap = asImageBitmap(R.drawable.img_card_placeholder_wallet_2)
|
||||
val cards = listOf(
|
||||
FloatingCard.first(),
|
||||
FloatingCard.second(),
|
||||
|
|
@ -44,14 +32,6 @@ fun FloatingCardsContent(isPaused: Boolean, stepDuration: Int, isNewWalletAvaila
|
|||
stepDuration = stepDuration,
|
||||
)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.fillMaxWidth()
|
||||
.height(bottomInsetsPx.dp)
|
||||
.background(BottomGradient),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,12 +94,4 @@ private object FloatingCard {
|
|||
rotationZ = -45f to -30f,
|
||||
scale = 0.6f to 0.75f,
|
||||
)
|
||||
}
|
||||
|
||||
private val BottomGradient: Brush = Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
TangemColorPalette.White.copy(alpha = 0f),
|
||||
TangemColorPalette.White.copy(alpha = 0.75f),
|
||||
TangemColorPalette.White.copy(alpha = 0.95f),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@ import com.tangem.wallet.R
|
|||
@Suppress("MagicNumber")
|
||||
@Composable
|
||||
internal fun HomeButtons(
|
||||
isDarkBackground: Boolean,
|
||||
btnScanStateInProgress: Boolean,
|
||||
onScanButtonClick: () -> Unit,
|
||||
onShopButtonClick: () -> Unit,
|
||||
|
|
@ -36,31 +35,24 @@ internal fun HomeButtons(
|
|||
) {
|
||||
ScanCardButton(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
isDarkBackground = isDarkBackground,
|
||||
showProgress = btnScanStateInProgress,
|
||||
onClick = onScanButtonClick,
|
||||
)
|
||||
SpacerW8()
|
||||
OrderCardButton(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
isDarkBackground = isDarkBackground,
|
||||
onClick = onShopButtonClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ScanCardButton(
|
||||
isDarkBackground: Boolean,
|
||||
showProgress: Boolean,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
private fun ScanCardButton(showProgress: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
TangemButton(
|
||||
modifier = modifier,
|
||||
text = stringResource(id = R.string.home_button_scan),
|
||||
icon = TangemButtonIconPosition.End(iconResId = R.drawable.ic_tangem_24),
|
||||
colors = if (isDarkBackground) DarkBgScanCardButtonColors else LightBgScanCardButtonColors,
|
||||
colors = LightBgScanCardButtonColors,
|
||||
showProgress = showProgress,
|
||||
enabled = true,
|
||||
onClick = onClick,
|
||||
|
|
@ -68,12 +60,12 @@ private fun ScanCardButton(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun OrderCardButton(isDarkBackground: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
private fun OrderCardButton(onClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
TangemButton(
|
||||
modifier = modifier,
|
||||
text = stringResource(id = R.string.home_button_order),
|
||||
icon = TangemButtonIconPosition.None,
|
||||
colors = if (isDarkBackground) DarkBgOrderCardButtonColors else LightBgOrderCardButtonColors,
|
||||
colors = LightBgOrderCardButtonColors,
|
||||
showProgress = false,
|
||||
enabled = true,
|
||||
onClick = onClick,
|
||||
|
|
@ -87,13 +79,6 @@ private val LightBgScanCardButtonColors: ButtonColors = TangemButtonColors(
|
|||
disabledContentColor = TangemColorPalette.Dark6,
|
||||
)
|
||||
|
||||
private val DarkBgScanCardButtonColors: ButtonColors = TangemButtonColors(
|
||||
backgroundColor = TangemColorPalette.Dark5,
|
||||
contentColor = TangemColorPalette.White,
|
||||
disabledBackgroundColor = TangemColorPalette.Dark5,
|
||||
disabledContentColor = TangemColorPalette.White,
|
||||
)
|
||||
|
||||
private val LightBgOrderCardButtonColors: ButtonColors = TangemButtonColors(
|
||||
backgroundColor = TangemColorPalette.Dark6,
|
||||
contentColor = TangemColorPalette.White,
|
||||
|
|
@ -101,24 +86,16 @@ private val LightBgOrderCardButtonColors: ButtonColors = TangemButtonColors(
|
|||
disabledContentColor = TangemColorPalette.White,
|
||||
)
|
||||
|
||||
private val DarkBgOrderCardButtonColors: ButtonColors = TangemButtonColors(
|
||||
backgroundColor = TangemColorPalette.Light1,
|
||||
contentColor = TangemColorPalette.Dark6,
|
||||
disabledBackgroundColor = TangemColorPalette.Light1,
|
||||
disabledContentColor = TangemColorPalette.Dark6,
|
||||
)
|
||||
|
||||
// region Preview
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
private fun HomeButtonsPreview(@PreviewParameter(HomeButtonsParameterProvider::class) state: HomeButtonsState) {
|
||||
TangemTheme {
|
||||
Box(
|
||||
modifier = Modifier.background(if (state.isDarkBackground) Color.Black else Color.White),
|
||||
modifier = Modifier.background(Color.Black),
|
||||
) {
|
||||
HomeButtons(
|
||||
modifier = Modifier.padding(all = TangemTheme.dimens.spacing16),
|
||||
isDarkBackground = state.isDarkBackground,
|
||||
btnScanStateInProgress = state.btnScanStateInProgress,
|
||||
onScanButtonClick = {},
|
||||
onShopButtonClick = {},
|
||||
|
|
@ -130,26 +107,15 @@ private fun HomeButtonsPreview(@PreviewParameter(HomeButtonsParameterProvider::c
|
|||
private class HomeButtonsParameterProvider : CollectionPreviewParameterProvider<HomeButtonsState>(
|
||||
collection = listOf(
|
||||
HomeButtonsState(
|
||||
isDarkBackground = false,
|
||||
btnScanStateInProgress = false,
|
||||
),
|
||||
HomeButtonsState(
|
||||
isDarkBackground = true,
|
||||
btnScanStateInProgress = false,
|
||||
),
|
||||
HomeButtonsState(
|
||||
isDarkBackground = false,
|
||||
btnScanStateInProgress = true,
|
||||
),
|
||||
HomeButtonsState(
|
||||
isDarkBackground = true,
|
||||
btnScanStateInProgress = true,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
private data class HomeButtonsState(
|
||||
val isDarkBackground: Boolean,
|
||||
val btnScanStateInProgress: Boolean,
|
||||
)
|
||||
// endregion Preview
|
||||
|
|
@ -24,8 +24,8 @@ internal fun SearchCurrenciesButton(onClick: () -> Unit, modifier: Modifier = Mo
|
|||
}
|
||||
|
||||
private val SearchCurrenciesButtonColors: ButtonColors = TangemButtonColors(
|
||||
backgroundColor = TangemColorPalette.Light2,
|
||||
contentColor = TangemColorPalette.Dark6,
|
||||
disabledBackgroundColor = TangemColorPalette.Light2,
|
||||
disabledContentColor = TangemColorPalette.Dark6,
|
||||
backgroundColor = TangemColorPalette.Dark5,
|
||||
contentColor = TangemColorPalette.White,
|
||||
disabledBackgroundColor = TangemColorPalette.Dark5,
|
||||
disabledContentColor = TangemColorPalette.White,
|
||||
)
|
||||
|
|
@ -1,19 +1,26 @@
|
|||
package com.tangem.tap.features.home.compose.views
|
||||
|
||||
import android.provider.Settings
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.SpacerW4
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
private const val STORIES_ANIMATION_SPEED_ZERO_DURATION = 3000L
|
||||
|
||||
@Composable
|
||||
fun StoriesProgressBar(
|
||||
|
|
@ -25,10 +32,20 @@ fun StoriesProgressBar(
|
|||
) {
|
||||
val progress = remember(currentStep) { Animatable(0f) }
|
||||
|
||||
val context = LocalContext.current
|
||||
val animatorSpeed = Settings.Global.getFloat(
|
||||
context.contentResolver,
|
||||
Settings.Global.ANIMATOR_DURATION_SCALE,
|
||||
0f,
|
||||
)
|
||||
|
||||
LaunchedEffect(paused, currentStep) {
|
||||
if (paused) {
|
||||
progress.stop()
|
||||
} else {
|
||||
if (animatorSpeed == 0f) {
|
||||
delay(STORIES_ANIMATION_SPEED_ZERO_DURATION)
|
||||
}
|
||||
progress.animateTo(
|
||||
targetValue = 1f,
|
||||
animationSpec = tween(
|
||||
|
|
@ -44,18 +61,23 @@ fun StoriesProgressBar(
|
|||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
// .height()
|
||||
.padding(start = 9.dp, end = 9.dp, top = 16.dp),
|
||||
.padding(
|
||||
start = TangemTheme.dimens.spacing16,
|
||||
end = TangemTheme.dimens.spacing16,
|
||||
top = TangemTheme.dimens.spacing16,
|
||||
),
|
||||
) {
|
||||
for (index in 0..steps) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.height(2.dp)
|
||||
.height(TangemTheme.dimens.size2)
|
||||
.weight(1f)
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius2))
|
||||
.background(Color.White.copy(alpha = 0.4f)),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius2))
|
||||
.background(Color.White)
|
||||
.fillMaxHeight().let {
|
||||
when (index) {
|
||||
|
|
|
|||
|
|
@ -49,15 +49,14 @@ data class HomeState(
|
|||
}
|
||||
|
||||
sealed class Stories(
|
||||
val isDarkBackground: Boolean,
|
||||
val duration: Int,
|
||||
val isNewWalletAvailable: MutableState<Boolean> = mutableStateOf(HomeState.isNewWalletAvailableInit()),
|
||||
) {
|
||||
object OneInchPromo : Stories(true, duration = 8000)
|
||||
object TangemIntro : Stories(true, duration = 8000)
|
||||
object RevolutionaryWallet : Stories(true, duration = 6000)
|
||||
object UltraSecureBackup : Stories(false, duration = 6000)
|
||||
object Currencies : Stories(false, duration = 6000)
|
||||
object Web3 : Stories(false, duration = 6000)
|
||||
object WalletForEveryone : Stories(true, duration = 6000)
|
||||
object OneInchPromo : Stories(duration = 8000)
|
||||
object TangemIntro : Stories(duration = 6000)
|
||||
object RevolutionaryWallet : Stories(duration = 6000)
|
||||
object UltraSecureBackup : Stories(duration = 6000)
|
||||
object Currencies : Stories(duration = 6000)
|
||||
object Web3 : Stories(duration = 6000)
|
||||
object WalletForEveryone : Stories(duration = 6000)
|
||||
}
|
||||
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 140 KiB |
BIN
app/src/main/res/drawable-hdpi/img_revolutionary_wallet.webp
Normal file
|
After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 189 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 66 KiB |
BIN
app/src/main/res/drawable-mdpi/img_revolutionary_wallet.webp
Normal file
|
After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 266 KiB After Width: | Height: | Size: 234 KiB |
BIN
app/src/main/res/drawable-xhdpi/img_revolutionary_wallet.webp
Normal file
|
After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 222 KiB |
|
Before Width: | Height: | Size: 303 KiB |
|
Before Width: | Height: | Size: 512 KiB After Width: | Height: | Size: 509 KiB |
BIN
app/src/main/res/drawable-xxhdpi/img_revolutionary_wallet.webp
Normal file
|
After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 484 KiB After Width: | Height: | Size: 484 KiB |
|
Before Width: | Height: | Size: 616 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/img_meet_tangem.webp
Normal file
|
After Width: | Height: | Size: 901 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/img_revolutionary_wallet.webp
Normal file
|
After Width: | Height: | Size: 243 KiB |
|
Before Width: | Height: | Size: 818 KiB After Width: | Height: | Size: 818 KiB |
|
Before Width: | Height: | Size: 819 KiB |
|
Before Width: | Height: | Size: 917 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 128 KiB |
|
|
@ -384,7 +384,7 @@
|
|||
<string name="shop_total">Итого</string>
|
||||
<string name="story_awe_description">Держите свои криптосбережения в безопасности. Приватные ключи надежно хранятся на карте.</string>
|
||||
<string name="story_awe_title">Революционный аппаратный кошелек</string>
|
||||
<string name="story_backup_description">До **трех карт** с одним кошельком</string>
|
||||
<string name="story_backup_description">До трех карт с одним кошельком</string>
|
||||
<string name="story_backup_description_1">До</string>
|
||||
<string name="story_backup_description_2_bold">трех карт</string>
|
||||
<string name="story_backup_description_3">с одним кошельком</string>
|
||||
|
|
@ -404,7 +404,7 @@
|
|||
<string name="story_meet_store">Храните</string>
|
||||
<string name="story_meet_title">Встречайте Tangem</string>
|
||||
<string name="story_web3_description">Обменивайте, покупайте NFT, получайте займы и делайте вклады в более чем 100 различных децентрализованных сервисах</string>
|
||||
<string name="story_web3_title">Поддержка DeFi</string>
|
||||
<string name="story_web3_title">Поддержка Web 3.0</string>
|
||||
<string name="swapping_approve_information_text">Подтверждения считаются отраслевым стандартом для всех децентрализованных бирж и защищают ваш кошелек от доступа со стороны смарт-контракта без вашего разрешения. По замыслу смарт-контракты не могут получить доступ к вашим токенам, если вы не одобрите доступ со своей стороны. «Разблокируя» свои токены, вы даете смарт-контракту 1inch разрешение тратить ваши активы. Майнеры сети получают компенсацию за газ (оплачиваемый вами) за запись этого действия в блокчейне. Как только разрешение будет предоставлено, вы сможете обменять свой токен.</string>
|
||||
<string name="swapping_approve_information_title">Подтвердить</string>
|
||||
<string name="swapping_error_wrapper">Ошибка: %s</string>
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@
|
|||
<string name="shop_total">總計</string>
|
||||
<string name="story_awe_description">安全地存儲您的加密貨幣,同時將私鑰保存在您的卡中</string>
|
||||
<string name="story_awe_title">創新式的硬體錢包</string>
|
||||
<string name="story_backup_description">最多 **3張實體卡片** 到一個錢包</string>
|
||||
<string name="story_backup_description">最多 3張實體卡片 到一個錢包</string>
|
||||
<string name="story_backup_description_1">最多</string>
|
||||
<string name="story_backup_description_2_bold">3張實體卡片</string>
|
||||
<string name="story_backup_description_3">到一個錢包</string>
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@
|
|||
<string name="feedback_subject_support">Feedback</string>
|
||||
<string name="feedback_subject_support_tangem">Tangem feedback</string>
|
||||
<string name="feedback_subject_tx_failed">Can\'t send a transaction</string>
|
||||
<string name="home_button_order">Order</string>
|
||||
<string name="home_button_order">Order card</string>
|
||||
<string name="home_button_scan">Scan card</string>
|
||||
<string name="initial_message_change_access_code_body">To change the access code tap the card as shown above and do not remove until the end of the operation</string>
|
||||
<string name="initial_message_change_passcode_body">To change the passcode tap the card as shown above and do not remove until the end of the operation</string>
|
||||
|
|
@ -407,7 +407,7 @@
|
|||
<string name="shop_total">Total</string>
|
||||
<string name="story_awe_description">Store your crypto assets secure while keeping private keys contained in your card</string>
|
||||
<string name="story_awe_title">Revolutionary Hardware Wallet</string>
|
||||
<string name="story_backup_description">Up to **3 physical cards** to one wallet</string>
|
||||
<string name="story_backup_description">Up to 3 physical cards to one wallet</string>
|
||||
<string name="story_backup_description_1">Up to</string>
|
||||
<string name="story_backup_description_2_bold">3 physical cards</string>
|
||||
<string name="story_backup_description_3">to one wallet</string>
|
||||
|
|
@ -427,7 +427,7 @@
|
|||
<string name="story_meet_store">Store</string>
|
||||
<string name="story_meet_title">Meet Tangem</string>
|
||||
<string name="story_web3_description">Exchange, buy NFT\'s, make loans and deposits in more than 100 different decentralized services</string>
|
||||
<string name="story_web3_title">DeFi Compatible</string>
|
||||
<string name="story_web3_title">Web 3.0 compatible</string>
|
||||
<string name="swapping_approve_information_text">Approvals are considered an industry standard across all decentralized exchanges and protect your wallet from being accessed by a smart contract without your permission. By design, smart contracts can\'t access your tokens unless you approve access from your end. By \"unlocking\" your tokens, you are give permission to the 1inch smart contract to spend your assets. The miners of the network are compensated with a gas fee (paid by you) to record this action on the blockchain. Once permission has been granted you will be able to swap your token.</string>
|
||||
<string name="swapping_approve_information_title">Approve</string>
|
||||
<string name="swapping_error_wrapper">Error: %s</string>
|
||||
|
|
|
|||
|
|
@ -108,12 +108,15 @@ data class TangemDimens internal constructor(
|
|||
val spacing38: Dp = 38.dp,
|
||||
val spacing40: Dp = 40.dp,
|
||||
val spacing44: Dp = 44.dp,
|
||||
val spacing46: Dp = 46.dp,
|
||||
val spacing48: Dp = 48.dp,
|
||||
val spacing50: Dp = 50.dp,
|
||||
val spacing52: Dp = 52.dp,
|
||||
val spacing54: Dp = 54.dp,
|
||||
val spacing56: Dp = 56.dp,
|
||||
val spacing70: Dp = 70.dp,
|
||||
val spacing92: Dp = 92.dp,
|
||||
val spacing94: Dp = 94.dp,
|
||||
val spacing96: Dp = 96.dp,
|
||||
val spacing154: Dp = 154.dp,
|
||||
// endregion Spacing
|
||||
|
|
|
|||