Updated on 2026-08-14
This commit is contained in:
parent
af8fc1732d
commit
62f8b1dbf1
52 changed files with 1053 additions and 186 deletions
|
|
@ -1,21 +1,20 @@
|
|||
package com.tangem.tap.features.customtoken.impl.presentation
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.tangem.core.ui.components.SystemBarsEffect
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.screen.ComposeFragment
|
||||
import com.tangem.core.ui.theme.AppThemeModeHolder
|
||||
import com.tangem.tap.features.customtoken.impl.presentation.ui.AddCustomTokenScreen
|
||||
import com.tangem.tap.features.customtoken.impl.presentation.viewmodels.AddCustomTokenViewModel
|
||||
import com.tangem.wallet.R
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Add custom token screen
|
||||
|
|
@ -23,29 +22,29 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
internal class AddCustomTokenFragment : Fragment() {
|
||||
internal class AddCustomTokenFragment : ComposeFragment() {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
with(TransitionInflater.from(requireContext())) {
|
||||
enterTransition = inflateTransition(R.transition.fade)
|
||||
exitTransition = inflateTransition(R.transition.fade)
|
||||
@Inject
|
||||
override lateinit var appThemeModeHolder: AppThemeModeHolder
|
||||
|
||||
override fun TransitionInflater.inflateTransitions(): Boolean {
|
||||
enterTransition = inflateTransition(R.transition.fade)
|
||||
exitTransition = inflateTransition(R.transition.fade)
|
||||
return true
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun ScreenContent(modifier: Modifier) {
|
||||
val viewModel = hiltViewModel<AddCustomTokenViewModel>().apply {
|
||||
LocalLifecycleOwner.current.lifecycle.addObserver(this)
|
||||
}
|
||||
|
||||
return ComposeView(inflater.context).apply {
|
||||
setContent {
|
||||
isTransitionGroup = true
|
||||
|
||||
val viewModel = hiltViewModel<AddCustomTokenViewModel>().apply {
|
||||
LocalLifecycleOwner.current.lifecycle.addObserver(this)
|
||||
}
|
||||
|
||||
TangemTheme {
|
||||
AddCustomTokenScreen(
|
||||
modifier = Modifier.systemBarsPadding(),
|
||||
stateHolder = viewModel.uiState,
|
||||
)
|
||||
}
|
||||
}
|
||||
val statusBarColor = TangemTheme.colors.background.secondary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(color = statusBarColor)
|
||||
}
|
||||
AddCustomTokenScreen(
|
||||
modifier = Modifier.systemBarsPadding(),
|
||||
stateHolder = viewModel.uiState,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -25,10 +25,20 @@ internal fun AddCustomTokenScreen(stateHolder: AddCustomTokenStateHolder, modifi
|
|||
|
||||
@Preview(showSystemUi = true)
|
||||
@Composable
|
||||
private fun Preview_AddCustomTokenScreen(
|
||||
private fun Preview_AddCustomTokenScreen_Light(
|
||||
@PreviewParameter(AddCustomTokenScreenProvider::class) stateHolder: AddCustomTokenStateHolder,
|
||||
) {
|
||||
TangemTheme {
|
||||
TangemTheme(isDark = false) {
|
||||
AddCustomTokenScreen(stateHolder)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showSystemUi = true)
|
||||
@Composable
|
||||
private fun Preview_AddCustomTokenScreen_Dark(
|
||||
@PreviewParameter(AddCustomTokenScreenProvider::class) stateHolder: AddCustomTokenStateHolder,
|
||||
) {
|
||||
TangemTheme(isDark = true) {
|
||||
AddCustomTokenScreen(stateHolder)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,10 @@ import com.tangem.tap.features.details.ui.cardsettings.resolveReference
|
|||
*/
|
||||
@Composable
|
||||
internal fun AddCustomTokenToolbar(title: TextReference, onBackButtonClick: () -> Unit) {
|
||||
TopAppBar(backgroundColor = TangemTheme.colors.background.secondary) {
|
||||
TopAppBar(
|
||||
backgroundColor = TangemTheme.colors.background.secondary,
|
||||
elevation = TangemTheme.dimens.elevation0,
|
||||
) {
|
||||
IconButton(onClick = onBackButtonClick) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_back_24),
|
||||
|
|
|
|||
|
|
@ -72,8 +72,16 @@ private fun AddCustomTokenWarning(warning: AddCustomTokenWarning) {
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_AddCustomTokenWarnings() {
|
||||
private fun Preview_AddCustomTokenWarnings_Light() {
|
||||
TangemTheme {
|
||||
AddCustomTokenWarnings(warnings = AddCustomTokenPreviewData.createWarnings())
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_AddCustomTokenWarnings_Dark() {
|
||||
TangemTheme(isDark = true) {
|
||||
AddCustomTokenWarnings(warnings = AddCustomTokenPreviewData.createWarnings())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +1,20 @@
|
|||
package com.tangem.tap.features.tokens.impl.presentation
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.tangem.core.ui.components.SystemBarsEffect
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.screen.ComposeFragment
|
||||
import com.tangem.core.ui.theme.AppThemeModeHolder
|
||||
import com.tangem.tap.features.tokens.impl.presentation.ui.TokensListScreen
|
||||
import com.tangem.tap.features.tokens.impl.presentation.viewmodels.TokensListViewModel
|
||||
import com.tangem.wallet.R
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Fragment with list of tokens
|
||||
|
|
@ -24,33 +22,29 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
internal class TokensListFragment : Fragment() {
|
||||
internal class TokensListFragment : ComposeFragment() {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
with(TransitionInflater.from(requireContext())) {
|
||||
enterTransition = inflateTransition(R.transition.fade)
|
||||
exitTransition = inflateTransition(R.transition.fade)
|
||||
@Inject
|
||||
override lateinit var appThemeModeHolder: AppThemeModeHolder
|
||||
|
||||
override fun TransitionInflater.inflateTransitions(): Boolean {
|
||||
enterTransition = inflateTransition(R.transition.fade)
|
||||
exitTransition = inflateTransition(R.transition.fade)
|
||||
return true
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun ScreenContent(modifier: Modifier) {
|
||||
val viewModel = hiltViewModel<TokensListViewModel>().apply {
|
||||
LocalLifecycleOwner.current.lifecycle.addObserver(this)
|
||||
}
|
||||
|
||||
return ComposeView(inflater.context).apply {
|
||||
setContent {
|
||||
isTransitionGroup = true
|
||||
|
||||
val viewModel = hiltViewModel<TokensListViewModel>().apply {
|
||||
LocalLifecycleOwner.current.lifecycle.addObserver(this)
|
||||
}
|
||||
|
||||
TangemTheme {
|
||||
val statusBarColor = TangemTheme.colors.background.secondary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(color = statusBarColor)
|
||||
}
|
||||
TokensListScreen(
|
||||
modifier = Modifier.systemBarsPadding(),
|
||||
stateHolder = viewModel.uiState,
|
||||
)
|
||||
}
|
||||
}
|
||||
val statusBarColor = TangemTheme.colors.background.secondary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(color = statusBarColor)
|
||||
}
|
||||
TokensListScreen(
|
||||
modifier = Modifier.systemBarsPadding(),
|
||||
stateHolder = viewModel.uiState,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,6 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.features.tokens.impl.presentation.states.NetworkItemState
|
||||
import kotlinx.collections.immutable.ImmutableCollection
|
||||
|
|
@ -83,14 +82,14 @@ internal fun BriefNetworkItem(model: NetworkItemState, modifier: Modifier = Modi
|
|||
.align(Alignment.TopEnd)
|
||||
.size(TangemTheme.dimens.size7)
|
||||
.clip(CircleShape)
|
||||
.background(TangemColorPalette.White),
|
||||
.background(TangemTheme.colors.background.secondary),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size5)
|
||||
.clip(CircleShape)
|
||||
.background(TangemColorPalette.Meadow),
|
||||
.background(TangemTheme.colors.icon.accent),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import androidx.compose.ui.text.font.FontWeight
|
|||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.features.tokens.impl.presentation.states.NetworkItemState
|
||||
import com.tangem.tap.features.tokens.impl.presentation.states.TokenItemState
|
||||
|
|
@ -95,7 +94,10 @@ private fun DetailedNetworkItem(token: TokenItemState, network: NetworkItemState
|
|||
},
|
||||
modifier = Modifier.padding(start = TangemTheme.dimens.spacing16, end = TangemTheme.dimens.spacing8),
|
||||
colors = SwitchDefaults.colors(
|
||||
checkedThumbColor = TangemColorPalette.Meadow,
|
||||
checkedThumbColor = TangemTheme.colors.control.key,
|
||||
checkedTrackColor = TangemTheme.colors.icon.accent,
|
||||
uncheckedThumbColor = TangemTheme.colors.control.key,
|
||||
uncheckedTrackColor = TangemTheme.colors.icon.informative,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -112,7 +114,11 @@ private fun RowScope.NetworkTitle(model: NetworkItemState) {
|
|||
withStyle(
|
||||
style = SpanStyle(
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = if (model.isMainNetwork) TangemColorPalette.Meadow else TangemColorPalette.Dark2,
|
||||
color = if (model.isMainNetwork) {
|
||||
TangemTheme.colors.icon.accent
|
||||
} else {
|
||||
TangemTheme.colors.icon.secondary
|
||||
},
|
||||
),
|
||||
) {
|
||||
append(text = model.protocolName)
|
||||
|
|
@ -121,16 +127,16 @@ private fun RowScope.NetworkTitle(model: NetworkItemState) {
|
|||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 13.sp,
|
||||
color = if (model is NetworkItemState.ManageContent && model.isAdded.value) {
|
||||
TangemColorPalette.Black
|
||||
TangemTheme.colors.text.primary1
|
||||
} else {
|
||||
TangemColorPalette.Dark2
|
||||
TangemTheme.colors.text.secondary
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_DetailedNetworksList_ManageAccess() {
|
||||
private fun Preview_DetailedNetworksList_ManageAccess_Light() {
|
||||
TangemTheme {
|
||||
DetailedNetworksList(
|
||||
isExpanded = true,
|
||||
|
|
@ -142,7 +148,31 @@ private fun Preview_DetailedNetworksList_ManageAccess() {
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_DetailedNetworksList_ReadAccess() {
|
||||
private fun Preview_DetailedNetworksList_ManageAccess_Dark() {
|
||||
TangemTheme {
|
||||
DetailedNetworksList(
|
||||
isExpanded = true,
|
||||
token = TokenListPreviewData.createManageToken(),
|
||||
networks = TokenListPreviewData.createManageNetworksList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_DetailedNetworksList_ReadAccess_Light() {
|
||||
TangemTheme {
|
||||
DetailedNetworksList(
|
||||
isExpanded = true,
|
||||
token = TokenListPreviewData.createReadToken(),
|
||||
networks = TokenListPreviewData.createReadNetworksList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_DetailedNetworksList_ReadAccess_Dark() {
|
||||
TangemTheme {
|
||||
DetailedNetworksList(
|
||||
isExpanded = true,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
package com.tangem.tap.features.tokens.impl.presentation.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -45,8 +40,24 @@ internal fun NetworkItemArrow(itemHeight: Dp, isLastItem: Boolean) {
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_NetworkItemArrow_Column() {
|
||||
TangemTheme {
|
||||
private fun Preview_NetworkItemArrow_Column_Light() {
|
||||
TangemTheme(isDark = false) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(color = TangemTheme.colors.background.primary)
|
||||
.padding(start = TangemTheme.dimens.size36),
|
||||
) {
|
||||
NetworkItemArrow(itemHeight = TangemTheme.dimens.size62, isLastItem = false)
|
||||
NetworkItemArrow(itemHeight = TangemTheme.dimens.size62, isLastItem = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_NetworkItemArrow_Column_Dark() {
|
||||
TangemTheme(isDark = true) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
|
|||
|
|
@ -1,27 +1,18 @@
|
|||
package com.tangem.tap.features.tokens.impl.presentation.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.animation.expandVertically
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.scaleIn
|
||||
import androidx.compose.animation.scaleOut
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.animation.with
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
|
@ -29,6 +20,9 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.constraintlayout.compose.ConstraintLayout
|
||||
import androidx.constraintlayout.compose.Dimension
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.palette.graphics.Palette
|
||||
import coil.compose.SubcomposeAsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import com.tangem.core.ui.components.CurrencyPlaceholderIcon
|
||||
|
|
@ -40,13 +34,16 @@ import com.tangem.wallet.R
|
|||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
internal fun TokenItem(model: TokenItemState) {
|
||||
var isExpanded by rememberSaveable { mutableStateOf(value = false) }
|
||||
var iconBackgroundColor by remember { mutableStateOf(Color.Transparent) }
|
||||
|
||||
ConstraintLayout(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(color = TangemTheme.colors.background.secondary)
|
||||
.padding(top = TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
val (icon, title, availableNetworksText) = createRefs()
|
||||
|
|
@ -55,14 +52,24 @@ internal fun TokenItem(model: TokenItemState) {
|
|||
val spacing16 = TangemTheme.dimens.spacing16
|
||||
val spacing6 = TangemTheme.dimens.spacing6
|
||||
|
||||
Icon(
|
||||
name = model.fullName,
|
||||
iconUrl = model.iconUrl,
|
||||
modifier = Modifier.constrainAs(icon) {
|
||||
top.linkTo(parent.top)
|
||||
start.linkTo(anchor = parent.start, margin = spacing16)
|
||||
},
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.background(
|
||||
color = iconBackgroundColor,
|
||||
shape = TangemTheme.shapes.roundedCorners8,
|
||||
)
|
||||
.size(TangemTheme.dimens.size46)
|
||||
.constrainAs(icon) {
|
||||
top.linkTo(parent.top)
|
||||
start.linkTo(anchor = parent.start, margin = spacing16)
|
||||
},
|
||||
) {
|
||||
Icon(
|
||||
name = model.fullName,
|
||||
iconUrl = model.iconUrl,
|
||||
onContrastCalculate = { iconBackgroundColor = it },
|
||||
)
|
||||
}
|
||||
|
||||
Title(
|
||||
title = model.fullName,
|
||||
|
|
@ -119,8 +126,10 @@ internal fun TokenItem(model: TokenItemState) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun Icon(name: String, iconUrl: String, modifier: Modifier = Modifier) {
|
||||
private fun Icon(name: String, iconUrl: String, onContrastCalculate: (Color) -> Unit, modifier: Modifier = Modifier) {
|
||||
val iconModifier = modifier.size(size = TangemTheme.dimens.size46)
|
||||
val screenBackgroundColor = TangemTheme.colors.background.secondary.toArgb()
|
||||
val isDarkTheme = isSystemInDarkTheme()
|
||||
|
||||
SubcomposeAsyncImage(
|
||||
modifier = iconModifier,
|
||||
|
|
@ -128,6 +137,18 @@ private fun Icon(name: String, iconUrl: String, modifier: Modifier = Modifier) {
|
|||
.size(size = TangemTheme.dimens.size46.toPx().toInt())
|
||||
.data(data = iconUrl)
|
||||
.crossfade(enable = true)
|
||||
.allowHardware(false)
|
||||
.listener(
|
||||
onSuccess = { _, result ->
|
||||
if (isDarkTheme) {
|
||||
setContrastBackgroundIfNeeded(
|
||||
drawable = result.drawable,
|
||||
screenBackgroundColor = screenBackgroundColor,
|
||||
onContrastCalculate = onContrastCalculate,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
.build(),
|
||||
contentDescription = null,
|
||||
loading = { CurrencyPlaceholderIcon(id = name, modifier = iconModifier) },
|
||||
|
|
@ -135,6 +156,26 @@ private fun Icon(name: String, iconUrl: String, modifier: Modifier = Modifier) {
|
|||
)
|
||||
}
|
||||
|
||||
private fun setContrastBackgroundIfNeeded(
|
||||
drawable: Drawable,
|
||||
screenBackgroundColor: Int,
|
||||
onContrastCalculate: (Color) -> Unit,
|
||||
) {
|
||||
Palette.Builder(drawable.toBitmap()).generate { palette ->
|
||||
val color = palette?.getDominantColor(screenBackgroundColor) ?: screenBackgroundColor
|
||||
val contrast = ColorUtils.calculateContrast(color, screenBackgroundColor)
|
||||
val colorToSet = if (contrast > LOW_CONTRAST_RATIO) {
|
||||
Color.Transparent
|
||||
} else {
|
||||
Color.White
|
||||
}
|
||||
onContrastCalculate(colorToSet)
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
|
||||
private const val LOW_CONTRAST_RATIO = 1.5f
|
||||
|
||||
@Composable
|
||||
private fun Title(title: String, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
|
|
@ -183,18 +224,34 @@ private fun ChangeNetworksViewButton(isExpanded: Boolean, onClick: () -> Unit, m
|
|||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun Preview_TokenItem_ManageAccess() {
|
||||
TangemTheme {
|
||||
private fun Preview_TokenItem_ManageAccess_Light() {
|
||||
TangemTheme(isDark = false) {
|
||||
TokenItem(model = TokenListPreviewData.createManageToken())
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview()
|
||||
@Composable
|
||||
private fun Preview_TokenItem_ReadAccess() {
|
||||
TangemTheme {
|
||||
private fun Preview_TokenItem_ManageAccess_Dark() {
|
||||
TangemTheme(isDark = true) {
|
||||
TokenItem(model = TokenListPreviewData.createManageToken())
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun Preview_TokenItem_ReadAccess_Light() {
|
||||
TangemTheme(isDark = false) {
|
||||
TokenItem(model = TokenListPreviewData.createReadToken())
|
||||
}
|
||||
}
|
||||
|
||||
@Preview()
|
||||
@Composable
|
||||
private fun Preview_TokenItem_ReadAccess_Dark() {
|
||||
TangemTheme(isDark = true) {
|
||||
TokenItem(model = TokenListPreviewData.createReadToken())
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,8 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
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 androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.TextUnitType
|
||||
|
|
@ -70,6 +72,7 @@ internal fun TokensListScreen(stateHolder: TokensListStateHolder, modifier: Modi
|
|||
}
|
||||
},
|
||||
floatingActionButtonPosition = FabPosition.Center,
|
||||
backgroundColor = TangemTheme.colors.background.secondary,
|
||||
) { scaffoldPadding ->
|
||||
val tokens = stateHolder.tokens.collectAsLazyPagingItems()
|
||||
|
||||
|
|
@ -97,10 +100,10 @@ private fun LoadingContent() {
|
|||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(color = TangemColorPalette.White),
|
||||
.background(color = TangemTheme.colors.background.secondary),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
CircularProgressIndicator(color = TangemColorPalette.Meadow)
|
||||
CircularProgressIndicator(color = TangemTheme.colors.icon.accent)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,73 +181,71 @@ private fun SaveChangesButton(onClick: () -> Unit, modifier: Modifier = Modifier
|
|||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(showSystemUi = true)
|
||||
@Composable
|
||||
private fun Preview_TokensListScreen_Loading() {
|
||||
TangemTheme {
|
||||
TokensListScreen(
|
||||
stateHolder = TokensListStateHolder.ReadContent(
|
||||
toolbarState = TokensListToolbarState.Title.Manage(
|
||||
titleResId = R.string.main_manage_tokens,
|
||||
onBackButtonClick = {},
|
||||
onSearchButtonClick = {},
|
||||
onAddCustomTokenClick = {},
|
||||
),
|
||||
isLoading = true,
|
||||
isDifferentAddressesBlockVisible = false,
|
||||
tokens = emptyFlow(),
|
||||
onTokensLoadStateChanged = {},
|
||||
),
|
||||
)
|
||||
private fun Preview_TokensListScreen_Light(
|
||||
@PreviewParameter(TokensListScreenProvider::class) stateHolder: TokensListStateHolder,
|
||||
) {
|
||||
TangemTheme(isDark = false) {
|
||||
TokensListScreen(stateHolder)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(showSystemUi = true)
|
||||
@Composable
|
||||
private fun Preview_TokensListScreen_Manage() {
|
||||
TangemTheme {
|
||||
TokensListScreen(
|
||||
stateHolder = TokensListStateHolder.ManageContent(
|
||||
toolbarState = TokensListToolbarState.Title.Manage(
|
||||
titleResId = R.string.main_manage_tokens,
|
||||
onBackButtonClick = {},
|
||||
onSearchButtonClick = {},
|
||||
onAddCustomTokenClick = {},
|
||||
),
|
||||
isLoading = false,
|
||||
isDifferentAddressesBlockVisible = true,
|
||||
tokens = flowOf(
|
||||
PagingData.from(
|
||||
listOf(TokenListPreviewData.createManageToken()),
|
||||
),
|
||||
),
|
||||
onSaveButtonClick = {},
|
||||
onTokensLoadStateChanged = {},
|
||||
),
|
||||
)
|
||||
private fun Preview_TokensListScreen_Dark(
|
||||
@PreviewParameter(TokensListScreenProvider::class) stateHolder: TokensListStateHolder,
|
||||
) {
|
||||
TangemTheme(isDark = true) {
|
||||
TokensListScreen(stateHolder)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_TokensListScreen_Read() {
|
||||
TangemTheme {
|
||||
TokensListScreen(
|
||||
stateHolder = TokensListStateHolder.ReadContent(
|
||||
toolbarState = TokensListToolbarState.Title.Read(
|
||||
titleResId = R.string.common_search_tokens,
|
||||
onBackButtonClick = {},
|
||||
onSearchButtonClick = {},
|
||||
),
|
||||
isLoading = false,
|
||||
isDifferentAddressesBlockVisible = false,
|
||||
tokens = flowOf(
|
||||
PagingData.from(
|
||||
listOf(TokenListPreviewData.createManageToken()),
|
||||
),
|
||||
),
|
||||
onTokensLoadStateChanged = {},
|
||||
private class TokensListScreenProvider : CollectionPreviewParameterProvider<TokensListStateHolder>(
|
||||
collection = listOf(
|
||||
TokensListStateHolder.ReadContent(
|
||||
toolbarState = TokensListToolbarState.Title.Manage(
|
||||
titleResId = R.string.main_manage_tokens,
|
||||
onBackButtonClick = {},
|
||||
onSearchButtonClick = {},
|
||||
onAddCustomTokenClick = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
isLoading = true,
|
||||
isDifferentAddressesBlockVisible = false,
|
||||
tokens = emptyFlow(),
|
||||
onTokensLoadStateChanged = {},
|
||||
),
|
||||
TokensListStateHolder.ManageContent(
|
||||
toolbarState = TokensListToolbarState.Title.Manage(
|
||||
titleResId = R.string.main_manage_tokens,
|
||||
onBackButtonClick = {},
|
||||
onSearchButtonClick = {},
|
||||
onAddCustomTokenClick = {},
|
||||
),
|
||||
isLoading = false,
|
||||
isDifferentAddressesBlockVisible = true,
|
||||
tokens = flowOf(
|
||||
PagingData.from(
|
||||
listOf(TokenListPreviewData.createManageToken()),
|
||||
),
|
||||
),
|
||||
onSaveButtonClick = {},
|
||||
onTokensLoadStateChanged = {},
|
||||
),
|
||||
TokensListStateHolder.ReadContent(
|
||||
toolbarState = TokensListToolbarState.Title.Read(
|
||||
titleResId = R.string.common_search_tokens,
|
||||
onBackButtonClick = {},
|
||||
onSearchButtonClick = {},
|
||||
),
|
||||
isLoading = false,
|
||||
isDifferentAddressesBlockVisible = false,
|
||||
tokens = flowOf(
|
||||
PagingData.from(
|
||||
listOf(TokenListPreviewData.createManageToken()),
|
||||
),
|
||||
),
|
||||
onTokensLoadStateChanged = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -26,7 +26,6 @@ import androidx.compose.ui.text.input.ImeAction
|
|||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.features.tokens.impl.presentation.states.TokensListToolbarState
|
||||
import com.tangem.tap.features.tokens.impl.presentation.states.TokensListToolbarState.InputField
|
||||
|
|
@ -39,12 +38,15 @@ import kotlinx.coroutines.delay
|
|||
*/
|
||||
@Composable
|
||||
internal fun TokensListToolbar(state: TokensListToolbarState) {
|
||||
TopAppBar(backgroundColor = TangemTheme.colors.background.secondary) {
|
||||
TopAppBar(
|
||||
backgroundColor = TangemTheme.colors.background.secondary,
|
||||
elevation = TangemTheme.dimens.elevation0,
|
||||
) {
|
||||
IconButton(onClick = state.onBackButtonClick) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_back_24),
|
||||
contentDescription = "Go back",
|
||||
tint = TangemTheme.colors.icon.secondary,
|
||||
tint = TangemTheme.colors.icon.primary1,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +71,7 @@ private fun TitleContent(state: Title, modifier: Modifier = Modifier) {
|
|||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_search_24),
|
||||
contentDescription = "Search",
|
||||
tint = TangemTheme.colors.icon.secondary,
|
||||
tint = TangemTheme.colors.icon.primary1,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -78,7 +80,7 @@ private fun TitleContent(state: Title, modifier: Modifier = Modifier) {
|
|||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_plus_24),
|
||||
contentDescription = "Add custom token",
|
||||
tint = TangemTheme.colors.icon.secondary,
|
||||
tint = TangemTheme.colors.icon.primary1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -94,7 +96,10 @@ private fun InputContent(state: InputField, modifier: Modifier = Modifier) {
|
|||
value = state.value,
|
||||
onValueChange = state.onValueChange,
|
||||
modifier = modifier.focusRequester(focusRequester),
|
||||
textStyle = TangemTheme.typography.subtitle1.copy(fontWeight = FontWeight.Normal),
|
||||
textStyle = TangemTheme.typography.subtitle1.copy(
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
),
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text, imeAction = ImeAction.Search),
|
||||
keyboardActions = KeyboardActions(onSearch = { keyboardController?.hide() }),
|
||||
singleLine = true,
|
||||
|
|
@ -146,7 +151,7 @@ private fun Hint(value: String) {
|
|||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_search_24),
|
||||
contentDescription = null,
|
||||
tint = TangemColorPalette.Dark1,
|
||||
tint = TangemTheme.colors.icon.secondary,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.common_search),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue