Updated on 2026-08-14
This commit is contained in:
parent
799d797fb5
commit
50a384f13d
16 changed files with 61 additions and 78 deletions
|
|
@ -108,7 +108,7 @@ fun PortfolioSelectRowV2(
|
||||||
modifier = Modifier.padding(end = TangemTheme.dimens2.x3),
|
modifier = Modifier.padding(end = TangemTheme.dimens2.x3),
|
||||||
name = state.name,
|
name = state.name,
|
||||||
icon = state.icon,
|
icon = state.icon,
|
||||||
size = AccountIconSize.RedesignedDefault,
|
size = AccountIconSize.Default,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if (state.imageState != null) {
|
} else if (state.imageState != null) {
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,6 @@ enum class AccountIconSize {
|
||||||
Medium,
|
Medium,
|
||||||
Small,
|
Small,
|
||||||
ExtraSmall,
|
ExtraSmall,
|
||||||
RedesignedDefault,
|
|
||||||
RedesignExtraSmall,
|
|
||||||
ContactLarge,
|
ContactLarge,
|
||||||
ContactDefault,
|
ContactDefault,
|
||||||
}
|
}
|
||||||
|
|
@ -133,13 +131,11 @@ fun AccountCharIcon(char: Char, color: Color, size: AccountIconSize, modifier: M
|
||||||
animationSpec = animation(),
|
animationSpec = animation(),
|
||||||
)
|
)
|
||||||
val textStyle = when (size) {
|
val textStyle = when (size) {
|
||||||
AccountIconSize.Default -> TangemTheme.typography.h3
|
AccountIconSize.Default -> TangemTheme.typography2.headingSemibold28
|
||||||
AccountIconSize.Large -> TangemTheme.typography.h1
|
AccountIconSize.Large -> TangemTheme.typography.h1
|
||||||
AccountIconSize.Medium -> TangemTheme.typography.subtitle1
|
AccountIconSize.Medium -> TangemTheme.typography.subtitle1
|
||||||
AccountIconSize.Small -> TangemTheme.typography.subtitle2
|
AccountIconSize.Small -> TangemTheme.typography.subtitle2
|
||||||
AccountIconSize.ExtraSmall -> TangemTheme.typography.caption1
|
AccountIconSize.ExtraSmall -> TangemTheme.typography2.captionMedium11
|
||||||
AccountIconSize.RedesignedDefault -> TangemTheme.typography2.headingSemibold28
|
|
||||||
AccountIconSize.RedesignExtraSmall -> TangemTheme.typography2.captionMedium11
|
|
||||||
AccountIconSize.ContactLarge -> TangemTheme.typography3.heading.medium
|
AccountIconSize.ContactLarge -> TangemTheme.typography3.heading.medium
|
||||||
AccountIconSize.ContactDefault -> TangemTheme.typography3.body.medium
|
AccountIconSize.ContactDefault -> TangemTheme.typography3.body.medium
|
||||||
}
|
}
|
||||||
|
|
@ -174,32 +170,26 @@ private fun AccountIconSize.iconSizeInDp(): Dp = when (this) {
|
||||||
AccountIconSize.Medium -> 16.dp
|
AccountIconSize.Medium -> 16.dp
|
||||||
AccountIconSize.Small -> 12.dp
|
AccountIconSize.Small -> 12.dp
|
||||||
AccountIconSize.ExtraSmall -> 8.dp
|
AccountIconSize.ExtraSmall -> 8.dp
|
||||||
AccountIconSize.RedesignedDefault -> 20.dp
|
|
||||||
AccountIconSize.RedesignExtraSmall -> 8.dp
|
|
||||||
AccountIconSize.ContactLarge -> 32.dp
|
AccountIconSize.ContactLarge -> 32.dp
|
||||||
AccountIconSize.ContactDefault -> 20.dp
|
AccountIconSize.ContactDefault -> 20.dp
|
||||||
}
|
}
|
||||||
|
|
||||||
fun AccountIconSize.toBoxSize(): Dp = when (this) {
|
fun AccountIconSize.toBoxSize(): Dp = when (this) {
|
||||||
AccountIconSize.Default -> 36.dp
|
AccountIconSize.Default -> 40.dp
|
||||||
AccountIconSize.Large -> 88.dp
|
AccountIconSize.Large -> 88.dp
|
||||||
AccountIconSize.Medium -> 28.dp
|
AccountIconSize.Medium -> 28.dp
|
||||||
AccountIconSize.Small -> 20.dp
|
AccountIconSize.Small -> 20.dp
|
||||||
AccountIconSize.ExtraSmall -> 14.dp
|
AccountIconSize.ExtraSmall -> 16.dp
|
||||||
AccountIconSize.RedesignedDefault -> 40.dp
|
|
||||||
AccountIconSize.RedesignExtraSmall -> 16.dp
|
|
||||||
AccountIconSize.ContactLarge -> 80.dp
|
AccountIconSize.ContactLarge -> 80.dp
|
||||||
AccountIconSize.ContactDefault -> 40.dp
|
AccountIconSize.ContactDefault -> 40.dp
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun AccountIconSize.boxShapeSizeInDp(): Dp = when (this) {
|
private fun AccountIconSize.boxShapeSizeInDp(): Dp = when (this) {
|
||||||
AccountIconSize.Default -> 10.dp
|
AccountIconSize.Default -> 12.dp
|
||||||
AccountIconSize.Large -> 24.dp
|
AccountIconSize.Large -> 24.dp
|
||||||
AccountIconSize.Medium -> 8.dp
|
AccountIconSize.Medium -> 8.dp
|
||||||
AccountIconSize.Small -> 6.dp
|
AccountIconSize.Small -> 6.dp
|
||||||
AccountIconSize.ExtraSmall -> 4.dp
|
AccountIconSize.ExtraSmall -> 6.dp
|
||||||
AccountIconSize.RedesignedDefault -> 12.dp
|
|
||||||
AccountIconSize.RedesignExtraSmall -> 6.dp
|
|
||||||
AccountIconSize.ContactLarge -> 80.dp
|
AccountIconSize.ContactLarge -> 80.dp
|
||||||
AccountIconSize.ContactDefault -> 100.dp
|
AccountIconSize.ContactDefault -> 100.dp
|
||||||
}
|
}
|
||||||
|
|
@ -242,9 +232,7 @@ private fun Sample() {
|
||||||
AccountIconSize.Large -> AccountIconSize.Medium
|
AccountIconSize.Large -> AccountIconSize.Medium
|
||||||
AccountIconSize.Medium -> AccountIconSize.Small
|
AccountIconSize.Medium -> AccountIconSize.Small
|
||||||
AccountIconSize.Small -> AccountIconSize.ExtraSmall
|
AccountIconSize.Small -> AccountIconSize.ExtraSmall
|
||||||
AccountIconSize.ExtraSmall -> AccountIconSize.RedesignedDefault
|
AccountIconSize.ExtraSmall -> AccountIconSize.ContactLarge
|
||||||
AccountIconSize.RedesignedDefault -> AccountIconSize.RedesignExtraSmall
|
|
||||||
AccountIconSize.RedesignExtraSmall -> AccountIconSize.ContactLarge
|
|
||||||
AccountIconSize.ContactLarge -> AccountIconSize.ContactDefault
|
AccountIconSize.ContactLarge -> AccountIconSize.ContactDefault
|
||||||
AccountIconSize.ContactDefault -> AccountIconSize.Default
|
AccountIconSize.ContactDefault -> AccountIconSize.Default
|
||||||
}
|
}
|
||||||
|
|
@ -264,6 +252,5 @@ private fun Sample() {
|
||||||
AccountCharIcon(char = 'M', color = Color.Magenta, size = AccountIconSize.Medium)
|
AccountCharIcon(char = 'M', color = Color.Magenta, size = AccountIconSize.Medium)
|
||||||
AccountCharIcon(char = 'S', color = Color.DarkGray, size = AccountIconSize.Small)
|
AccountCharIcon(char = 'S', color = Color.DarkGray, size = AccountIconSize.Small)
|
||||||
AccountCharIcon(char = 'E', color = Color.Green, size = AccountIconSize.ExtraSmall)
|
AccountCharIcon(char = 'E', color = Color.Green, size = AccountIconSize.ExtraSmall)
|
||||||
AccountCharIcon(char = 'D', color = Color.LightGray, size = AccountIconSize.RedesignExtraSmall)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +50,7 @@ fun TangemCurrencyIcon(state: CurrencyIconState, modifier: Modifier = Modifier,
|
||||||
modifier = iconModifier,
|
modifier = iconModifier,
|
||||||
shouldShowTopBadge = shouldDisplayNetwork,
|
shouldShowTopBadge = shouldDisplayNetwork,
|
||||||
networkBadgeSize = 14.dp,
|
networkBadgeSize = 14.dp,
|
||||||
networkBadgeBackground = TangemTheme.colors2.surface.level1,
|
networkBadgeBackground = TangemTheme.colors3.bg.secondary,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +72,7 @@ fun CurrencyIcon(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
shouldDisplayNetwork: Boolean = true,
|
shouldDisplayNetwork: Boolean = true,
|
||||||
networkBadgeSize: Dp = 14.dp,
|
networkBadgeSize: Dp = 14.dp,
|
||||||
networkBadgeBackground: Color = TangemTheme.colors.background.primary,
|
networkBadgeBackground: Color = TangemTheme.colors3.bg.secondary,
|
||||||
withFixedSize: Boolean = true,
|
withFixedSize: Boolean = true,
|
||||||
iconSize: Dp = 36.dp,
|
iconSize: Dp = 36.dp,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package com.tangem.domain.earn.usecase
|
package com.tangem.domain.earn.usecase
|
||||||
|
|
||||||
import arrow.core.Either
|
|
||||||
import com.tangem.domain.account.models.AccountList
|
import com.tangem.domain.account.models.AccountList
|
||||||
import com.tangem.domain.account.supplier.MultiAccountListSupplier
|
import com.tangem.domain.account.supplier.MultiAccountListSupplier
|
||||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||||
|
|
@ -26,7 +25,8 @@ class GetEarnNetworksUseCase(
|
||||||
private val userWalletsListRepository: UserWalletsListRepository,
|
private val userWalletsListRepository: UserWalletsListRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
operator fun invoke(): Flow<EarnNetworks> {
|
/** Emits `null` until the networks are loaded, so callers can tell it apart from a loaded empty list */
|
||||||
|
operator fun invoke(): Flow<EarnNetworks?> {
|
||||||
return combine(
|
return combine(
|
||||||
earnRepository.observeEarnNetworks(),
|
earnRepository.observeEarnNetworks(),
|
||||||
observeMyNetworkIds(),
|
observeMyNetworkIds(),
|
||||||
|
|
@ -35,7 +35,7 @@ class GetEarnNetworksUseCase(
|
||||||
earnNetworks.map { network ->
|
earnNetworks.map { network ->
|
||||||
network.copy(isAdded = network.networkId in myNetworkIds)
|
network.copy(isAdded = network.networkId in myNetworkIds)
|
||||||
}
|
}
|
||||||
} ?: Either.Right(emptyList())
|
}
|
||||||
}.distinctUntilChanged()
|
}.distinctUntilChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -535,9 +535,9 @@ private fun AccountRow(
|
||||||
AccountRowComposables(
|
AccountRowComposables(
|
||||||
icon = { iconModifier ->
|
icon = { iconModifier ->
|
||||||
val iconSize = if (isExpandedState) {
|
val iconSize = if (isExpandedState) {
|
||||||
AccountIconSize.RedesignExtraSmall
|
AccountIconSize.ExtraSmall
|
||||||
} else {
|
} else {
|
||||||
AccountIconSize.RedesignedDefault
|
AccountIconSize.Default
|
||||||
}
|
}
|
||||||
val sizedIcon = when (val icon = tokenRowUM.headIconUM) {
|
val sizedIcon = when (val icon = tokenRowUM.headIconUM) {
|
||||||
is TangemIconUM.Currency -> icon.copy(
|
is TangemIconUM.Currency -> icon.copy(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.tangem.features.feed.model.earn
|
package com.tangem.features.feed.model.earn
|
||||||
|
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import arrow.core.Either
|
|
||||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||||
import com.arkivanov.decompose.router.slot.activate
|
import com.arkivanov.decompose.router.slot.activate
|
||||||
import com.arkivanov.decompose.router.slot.dismiss
|
import com.arkivanov.decompose.router.slot.dismiss
|
||||||
|
|
@ -68,7 +67,7 @@ internal class EarnModel @Inject constructor(
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
||||||
private val params = paramsContainer.require<DefaultEarnComponent.Params>()
|
private val params = paramsContainer.require<DefaultEarnComponent.Params>()
|
||||||
private val earnNetworks = MutableStateFlow<EarnNetworks>(Either.Right(emptyList()))
|
private val earnNetworks = MutableStateFlow<EarnNetworks?>(null)
|
||||||
private val earnListConfigProvider = Provider {
|
private val earnListConfigProvider = Provider {
|
||||||
createEarnTokensListConfig(
|
createEarnTokensListConfig(
|
||||||
selectedTypeFilter = stateController.value.earnFilterUM.selectedTypeFilter,
|
selectedTypeFilter = stateController.value.earnFilterUM.selectedTypeFilter,
|
||||||
|
|
@ -131,10 +130,10 @@ internal class EarnModel @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun EarnFilter.resolveAgainst(networks: EarnNetworks): EarnFilter {
|
private fun EarnFilter.resolveAgainst(networks: EarnNetworks?): EarnFilter {
|
||||||
val specific = earnFilterNetwork as? EarnFilterNetwork.Specific ?: return this
|
val specific = earnFilterNetwork as? EarnFilterNetwork.Specific ?: return this
|
||||||
if (specific.symbol.isNotEmpty()) return this
|
if (specific.symbol.isNotEmpty()) return this
|
||||||
val loaded = networks.getOrNull()?.takeIf { it.isNotEmpty() } ?: return this
|
val loaded = networks?.getOrNull()?.takeIf { it.isNotEmpty() } ?: return this
|
||||||
val match = loaded.firstOrNull { it.networkId.equals(specific.id, ignoreCase = true) }
|
val match = loaded.firstOrNull { it.networkId.equals(specific.id, ignoreCase = true) }
|
||||||
return copy(
|
return copy(
|
||||||
earnFilterNetwork = match?.let { earnNetwork ->
|
earnFilterNetwork = match?.let { earnNetwork ->
|
||||||
|
|
@ -230,7 +229,7 @@ internal class EarnModel @Inject constructor(
|
||||||
|
|
||||||
private fun reloadEarnNetworks() {
|
private fun reloadEarnNetworks() {
|
||||||
modelScope.launch(dispatchers.default) {
|
modelScope.launch(dispatchers.default) {
|
||||||
if (earnNetworks.value.isLeft()) {
|
if (earnNetworks.value?.isLeft() != false) {
|
||||||
fetchEarnNetworks()
|
fetchEarnNetworks()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -275,7 +274,7 @@ internal class EarnModel @Inject constructor(
|
||||||
isSelected = selectedFilter is EarnFilterNetworkUM.MyNetworks,
|
isSelected = selectedFilter is EarnFilterNetworkUM.MyNetworks,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
earnNetworks.value.onRight { networks ->
|
earnNetworks.value?.onRight { networks ->
|
||||||
networks.mapTo(this) { network ->
|
networks.mapTo(this) { network ->
|
||||||
EarnFilterNetwork.Specific(
|
EarnFilterNetwork.Specific(
|
||||||
id = network.networkId,
|
id = network.networkId,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import com.tangem.features.feed.ui.earn.state.EarnFilterTypeUM
|
||||||
internal fun createEarnTokensListConfig(
|
internal fun createEarnTokensListConfig(
|
||||||
selectedTypeFilter: EarnFilterTypeUM,
|
selectedTypeFilter: EarnFilterTypeUM,
|
||||||
selectedNetworkFilter: EarnFilterNetworkUM,
|
selectedNetworkFilter: EarnFilterNetworkUM,
|
||||||
earnNetworks: EarnNetworks,
|
earnNetworks: EarnNetworks?,
|
||||||
isForEarn: Boolean = false,
|
isForEarn: Boolean = false,
|
||||||
): EarnTokensListConfig {
|
): EarnTokensListConfig {
|
||||||
val type = when (selectedTypeFilter) {
|
val type = when (selectedTypeFilter) {
|
||||||
|
|
@ -19,8 +19,9 @@ internal fun createEarnTokensListConfig(
|
||||||
}
|
}
|
||||||
val networks = when (selectedNetworkFilter) {
|
val networks = when (selectedNetworkFilter) {
|
||||||
is EarnFilterNetworkUM.AllNetworks -> null
|
is EarnFilterNetworkUM.AllNetworks -> null
|
||||||
is EarnFilterNetworkUM.MyNetworks -> {
|
is EarnFilterNetworkUM.MyNetworks -> when (earnNetworks) {
|
||||||
earnNetworks.fold(
|
null -> listOf(NO_ONE_NETWORK)
|
||||||
|
else -> earnNetworks.fold(
|
||||||
ifLeft = { null },
|
ifLeft = { null },
|
||||||
ifRight = { networks ->
|
ifRight = { networks ->
|
||||||
networks.filter(EarnNetwork::isAdded)
|
networks.filter(EarnNetwork::isAdded)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import com.tangem.features.feed.ui.earn.state.EarnFilterTypeUM
|
||||||
import com.tangem.features.feed.ui.earn.state.EarnUM
|
import com.tangem.features.feed.ui.earn.state.EarnUM
|
||||||
|
|
||||||
internal class EarnFilterSelectedStateTransformer(
|
internal class EarnFilterSelectedStateTransformer(
|
||||||
private val earnNetworks: EarnNetworks,
|
private val earnNetworks: EarnNetworks?,
|
||||||
private val filterType: EarnFilterTypeUM,
|
private val filterType: EarnFilterTypeUM,
|
||||||
private val filterNetwork: EarnFilterNetworkUM,
|
private val filterNetwork: EarnFilterNetworkUM,
|
||||||
) : EarnUMTransformer {
|
) : EarnUMTransformer {
|
||||||
|
|
@ -16,7 +16,7 @@ internal class EarnFilterSelectedStateTransformer(
|
||||||
earnFilterUM = prevState.earnFilterUM.copy(
|
earnFilterUM = prevState.earnFilterUM.copy(
|
||||||
selectedTypeFilter = filterType,
|
selectedTypeFilter = filterType,
|
||||||
selectedNetworkFilter = filterNetwork,
|
selectedNetworkFilter = filterNetwork,
|
||||||
isNetworkFilterEnabled = earnNetworks.isRight { networks -> networks.isNotEmpty() },
|
isNetworkFilterEnabled = earnNetworks?.isRight { networks -> networks.isNotEmpty() } == true,
|
||||||
isTypeFilterEnabled = true,
|
isTypeFilterEnabled = true,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,9 @@ internal class EarnListBatchFlowManager(
|
||||||
private val modelScope: CoroutineScope,
|
private val modelScope: CoroutineScope,
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
) {
|
) {
|
||||||
private val actionsFlow = MutableSharedFlow<BatchAction<Int, EarnTokensListConfig, Nothing>>()
|
// `replay = 1` because the batch source subscribes asynchronously, so an action emitted before
|
||||||
|
// that would be dropped silently.
|
||||||
|
private val actionsFlow = MutableSharedFlow<BatchAction<Int, EarnTokensListConfig, Nothing>>(replay = 1)
|
||||||
private val converter = EarnTokenWithCurrencyToListItemUMConverter(
|
private val converter = EarnTokenWithCurrencyToListItemUMConverter(
|
||||||
onItemClick = { onItemClick(it, EarnSource.BEST_OPPORTUNITIES_SOURCE) },
|
onItemClick = { onItemClick(it, EarnSource.BEST_OPPORTUNITIES_SOURCE) },
|
||||||
)
|
)
|
||||||
|
|
@ -38,8 +40,10 @@ internal class EarnListBatchFlowManager(
|
||||||
batchSize = DEFAULT_BATCH_SIZE,
|
batchSize = DEFAULT_BATCH_SIZE,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val batchState = batchFlow.state.filterNot { it.status is PaginationStatus.None }
|
||||||
|
|
||||||
val uiItems: StateFlow<ImmutableList<EarnListItemUM>> =
|
val uiItems: StateFlow<ImmutableList<EarnListItemUM>> =
|
||||||
batchFlow.state
|
batchState
|
||||||
.scan(persistentListOf<EarnListItemUM>() to -1) { (accItems, lastProcessedBatchIndex), newState ->
|
.scan(persistentListOf<EarnListItemUM>() to -1) { (accItems, lastProcessedBatchIndex), newState ->
|
||||||
if (newState.data.size <= lastProcessedBatchIndex) {
|
if (newState.data.size <= lastProcessedBatchIndex) {
|
||||||
val newItems = newState.data
|
val newItems = newState.data
|
||||||
|
|
@ -63,7 +67,7 @@ internal class EarnListBatchFlowManager(
|
||||||
initialValue = persistentListOf(),
|
initialValue = persistentListOf(),
|
||||||
)
|
)
|
||||||
|
|
||||||
val initialLoadingError: StateFlow<Throwable?> = batchFlow.state
|
val initialLoadingError: StateFlow<Throwable?> = batchState
|
||||||
.map { state ->
|
.map { state ->
|
||||||
val status = state.status
|
val status = state.status
|
||||||
if (status is PaginationStatus.InitialLoadingError) {
|
if (status is PaginationStatus.InitialLoadingError) {
|
||||||
|
|
@ -79,7 +83,7 @@ internal class EarnListBatchFlowManager(
|
||||||
initialValue = null,
|
initialValue = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
val paginationStatus: StateFlow<PaginationStatus<List<EarnTokenWithCurrency>>> = batchFlow.state
|
val paginationStatus: StateFlow<PaginationStatus<List<EarnTokenWithCurrency>>> = batchState
|
||||||
.map { it.status }
|
.map { it.status }
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.stateIn(
|
.stateIn(
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ internal class ForYouEarnOpportunitiesPotentialRewardsConverter(
|
||||||
return TangemTokenRowUM.Content(
|
return TangemTokenRowUM.Content(
|
||||||
id = account.accountId.value,
|
id = account.accountId.value,
|
||||||
headIconUM = TangemIconUM.Currency(
|
headIconUM = TangemIconUM.Currency(
|
||||||
currencyIconState = AccountIconItemStateConverter(size = AccountIconSize.RedesignedDefault)
|
currencyIconState = AccountIconItemStateConverter(size = AccountIconSize.Default)
|
||||||
.convert(account),
|
.convert(account),
|
||||||
),
|
),
|
||||||
titleUM = TangemTokenRowUM.TitleUM.Content(
|
titleUM = TangemTokenRowUM.TitleUM.Content(
|
||||||
|
|
|
||||||
|
|
@ -187,9 +187,9 @@ private fun PortfolioSharedAssetIcon(
|
||||||
|
|
||||||
if (headIcon is TangemIconUM.Currency) {
|
if (headIcon is TangemIconUM.Currency) {
|
||||||
val size = if (isExpandedWrapped) {
|
val size = if (isExpandedWrapped) {
|
||||||
AccountIconSize.RedesignExtraSmall
|
AccountIconSize.ExtraSmall
|
||||||
} else {
|
} else {
|
||||||
AccountIconSize.RedesignedDefault
|
AccountIconSize.Default
|
||||||
}
|
}
|
||||||
val currencyIconState = when (val currencyIconState = headIcon.currencyIconState) {
|
val currencyIconState = when (val currencyIconState = headIcon.currencyIconState) {
|
||||||
is CurrencyIconState.CryptoPortfolio.Icon -> currencyIconState.copy(size = size)
|
is CurrencyIconState.CryptoPortfolio.Icon -> currencyIconState.copy(size = size)
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ import com.tangem.core.ui.extensions.stringResourceSafe
|
||||||
import com.tangem.core.ui.haptic.TangemHapticEffect
|
import com.tangem.core.ui.haptic.TangemHapticEffect
|
||||||
import com.tangem.core.ui.res.LocalHapticManager
|
import com.tangem.core.ui.res.LocalHapticManager
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||||
import com.tangem.core.ui.test.ManageTokensScreenTestTags
|
import com.tangem.core.ui.test.ManageTokensScreenTestTags
|
||||||
import com.tangem.core.ui.utils.WindowInsetsZero
|
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||||
import com.tangem.core.ui.utils.rememberHideKeyboardNestedScrollConnection
|
import com.tangem.core.ui.utils.rememberHideKeyboardNestedScrollConnection
|
||||||
|
|
@ -78,13 +78,13 @@ internal fun ManageTokensScreen(state: ManageTokensUM, modifier: Modifier = Modi
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = modifier.nestedScroll(nestedScrollConnection),
|
modifier = modifier.nestedScroll(nestedScrollConnection),
|
||||||
containerColor = TangemTheme.colors.background.primary,
|
containerColor = TangemTheme.colors3.bg.primary,
|
||||||
contentWindowInsets = WindowInsetsZero,
|
contentWindowInsets = WindowInsetsZero,
|
||||||
topBar = {
|
topBar = {
|
||||||
ManageTokensTopBar(
|
ManageTokensTopBar(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.statusBarsPadding()
|
.statusBarsPadding()
|
||||||
.background(TangemTheme.colors.background.primary),
|
.background(TangemTheme.colors3.bg.primary),
|
||||||
topBar = state.topBar,
|
topBar = state.topBar,
|
||||||
search = state.search,
|
search = state.search,
|
||||||
)
|
)
|
||||||
|
|
@ -93,6 +93,7 @@ internal fun ManageTokensScreen(state: ManageTokensUM, modifier: Modifier = Modi
|
||||||
Content(
|
Content(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
|
.padding(horizontal = 8.dp)
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
state = state,
|
state = state,
|
||||||
)
|
)
|
||||||
|
|
@ -245,7 +246,7 @@ fun SearchNothingFoundText(modifier: Modifier = Modifier) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResourceSafe(R.string.markets_search_token_no_result_title),
|
text = stringResourceSafe(R.string.markets_search_token_no_result_title),
|
||||||
style = TangemTheme.typography.caption1,
|
style = TangemTheme.typography.caption1,
|
||||||
color = TangemTheme.colors.text.tertiary,
|
color = TangemTheme.colors3.text.tertiary,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -253,10 +254,10 @@ fun SearchNothingFoundText(modifier: Modifier = Modifier) {
|
||||||
@Composable
|
@Composable
|
||||||
fun ProgressIndicator(modifier: Modifier = Modifier) {
|
fun ProgressIndicator(modifier: Modifier = Modifier) {
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier.background(color = TangemTheme.colors.background.primary),
|
modifier = modifier.background(color = TangemTheme.colors3.bg.primary),
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
CircularProgressIndicator(color = TangemTheme.colors.icon.informative)
|
CircularProgressIndicator(color = TangemTheme.colors3.icon.tertiary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -339,7 +340,7 @@ private fun BasicCurrencyItem(item: CurrencyItemUM.Basic, isEditable: Boolean, m
|
||||||
.rotate(rotation)
|
.rotate(rotation)
|
||||||
.size(TangemTheme.dimens.size24),
|
.size(TangemTheme.dimens.size24),
|
||||||
painter = painterResource(id = R.drawable.ic_chevron_24),
|
painter = painterResource(id = R.drawable.ic_chevron_24),
|
||||||
tint = TangemTheme.colors.icon.informative,
|
tint = TangemTheme.colors3.icon.tertiary,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -434,7 +435,7 @@ private fun NetworksList(
|
||||||
private fun Preview_ManageTokens(
|
private fun Preview_ManageTokens(
|
||||||
@PreviewParameter(PreviewManageTokensComponentProvider::class) component: ManageTokensComponent,
|
@PreviewParameter(PreviewManageTokensComponentProvider::class) component: ManageTokensComponent,
|
||||||
) {
|
) {
|
||||||
TangemThemePreview {
|
TangemThemePreviewRedesign {
|
||||||
component.Content(Modifier.fillMaxWidth())
|
component.Content(Modifier.fillMaxWidth())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@ private fun TokenDetailsTitle(titleState: TitleState) {
|
||||||
AccountIcon(
|
AccountIcon(
|
||||||
name = titleState.accountName,
|
name = titleState.accountName,
|
||||||
icon = titleState.accountIconUM,
|
icon = titleState.accountIconUM,
|
||||||
size = AccountIconSize.RedesignExtraSmall,
|
size = AccountIconSize.ExtraSmall,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ private fun VirtualAccountMainContent(
|
||||||
AccountIcon(
|
AccountIcon(
|
||||||
name = TextReference.EMPTY,
|
name = TextReference.EMPTY,
|
||||||
icon = AccountIconUM.Virtual,
|
icon = AccountIconUM.Virtual,
|
||||||
size = AccountIconSize.RedesignedDefault,
|
size = AccountIconSize.Default,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.layoutId(TangemRowLayoutId.HEAD)
|
.layoutId(TangemRowLayoutId.HEAD)
|
||||||
.padding(end = TangemTheme.dimens2.x2),
|
.padding(end = TangemTheme.dimens2.x2),
|
||||||
|
|
@ -139,7 +139,7 @@ private fun VirtualAccountStateRow(
|
||||||
AccountIcon(
|
AccountIcon(
|
||||||
name = TextReference.EMPTY,
|
name = TextReference.EMPTY,
|
||||||
icon = AccountIconUM.Virtual,
|
icon = AccountIconUM.Virtual,
|
||||||
size = AccountIconSize.RedesignedDefault,
|
size = AccountIconSize.Default,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.layoutId(TangemRowLayoutId.HEAD)
|
.layoutId(TangemRowLayoutId.HEAD)
|
||||||
.padding(end = TangemTheme.dimens2.x2),
|
.padding(end = TangemTheme.dimens2.x2),
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,7 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetType
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetType
|
||||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation
|
||||||
import com.tangem.core.ui.ds.topbar.TangemTopBar
|
|
||||||
import com.tangem.core.ui.ds.topbar.TangemTopBarType
|
|
||||||
import com.tangem.core.ui.ds2.button.TangemButton
|
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
|
|
@ -47,19 +44,13 @@ internal fun AddAndManageBottomSheetContent(
|
||||||
content = TangemBottomSheetConfigContent.Empty,
|
content = TangemBottomSheetConfigContent.Empty,
|
||||||
),
|
),
|
||||||
type = TangemBottomSheetType.Modal,
|
type = TangemBottomSheetType.Modal,
|
||||||
containerColor = TangemTheme.colors2.surface.level2,
|
containerColor = TangemTheme.colors3.bg.tertiary,
|
||||||
title = {
|
title = {
|
||||||
TangemTopBar(
|
TangemTopNavigation(
|
||||||
title = resourceReference(R.string.main_add_and_manage_tokens),
|
title = resourceReference(R.string.main_add_and_manage_tokens),
|
||||||
type = TangemTopBarType.BottomSheet,
|
contentAlign = TangemTopNavigation.ContentAlign.Center,
|
||||||
endContent = {
|
blurBackground = false,
|
||||||
TangemButton(
|
onClose = onDismiss,
|
||||||
iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_24),
|
|
||||||
onClick = onDismiss,
|
|
||||||
size = TangemButton.Size.X11,
|
|
||||||
variant = TangemButton.Variant.Material,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
content = {
|
content = {
|
||||||
|
|
@ -119,8 +110,8 @@ private fun AddAndManageRow(
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clip(RoundedCornerShape(20.dp))
|
.clip(RoundedCornerShape(20.dp))
|
||||||
.clickable(onClick = onClick)
|
.clickable(onClick = onClick)
|
||||||
.background(TangemTheme.colors2.surface.level3)
|
.background(TangemTheme.colors3.bg.tertiary)
|
||||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
.padding(16.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
|
|
@ -128,12 +119,12 @@ private fun AddAndManageRow(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(40.dp)
|
.size(40.dp)
|
||||||
.clip(CircleShape)
|
.clip(CircleShape)
|
||||||
.background(TangemTheme.colors2.graphic.status.accent.copy(alpha = 0.1f)),
|
.background(TangemTheme.colors3.icon.brand.copy(alpha = 0.1f)),
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
modifier = Modifier.size(20.dp),
|
modifier = Modifier.size(20.dp),
|
||||||
imageVector = ImageVector.vectorResource(id = iconRes),
|
imageVector = ImageVector.vectorResource(id = iconRes),
|
||||||
tint = TangemTheme.colors2.markers.iconBlue,
|
tint = TangemTheme.colors3.icon.brand,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +147,7 @@ private fun AddAndManageRow(
|
||||||
SpacerW(8.dp)
|
SpacerW(8.dp)
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.ic_chevron_right_24,
|
imageVector = Icons.ic_chevron_right_24,
|
||||||
tint = TangemTheme.colors2.graphic.neutral.tertiaryConstant,
|
tint = TangemTheme.colors3.icon.secondary,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ internal class OrganizeAccountItemConverter(
|
||||||
headerRowUM = TangemHeaderRowUM(
|
headerRowUM = TangemHeaderRowUM(
|
||||||
id = value.accountId.value,
|
id = value.accountId.value,
|
||||||
startIconUM = TangemIconUM.Currency(
|
startIconUM = TangemIconUM.Currency(
|
||||||
currencyIconState = AccountIconItemStateConverter(size = AccountIconSize.RedesignExtraSmall)
|
currencyIconState = AccountIconItemStateConverter(size = AccountIconSize.ExtraSmall)
|
||||||
.convert(value.account),
|
.convert(value.account),
|
||||||
),
|
),
|
||||||
title = value.account.accountName.toUM().value,
|
title = value.account.accountName.toUM().value,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue