diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/list/RoundedListWithDividers.kt b/core/ui/src/main/java/com/tangem/core/ui/components/list/RoundedListWithDividers.kt index afa890cb01..adf160b367 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/list/RoundedListWithDividers.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/list/RoundedListWithDividers.kt @@ -15,7 +15,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview import com.tangem.core.ui.R -import com.tangem.core.ui.components.rows.CornersToRound import com.tangem.core.ui.components.rows.RoundableCornersRow import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.orMaskWithStars @@ -63,7 +62,8 @@ fun LazyListScope.roundedListWithDividersItems( InitialInfoContentRow( startText = row.startText.resolveReference(), endText = row.endText.orMaskWithStars(hideEndText && row.isEndTextHideable).resolveReference(), - cornersToRound = getCornersToRound(index, rows.size), + currentIndex = index, + lastIndex = rows.lastIndex, iconClick = row.iconClick, endTextColor = if (row.isEndTextHighlighted) { TangemTheme.colors.text.accent @@ -85,7 +85,8 @@ fun LazyListScope.roundedListWithDividersItems( private fun InitialInfoContentRow( startText: String, endText: String, - cornersToRound: CornersToRound, + currentIndex: Int, + lastIndex: Int, showDivider: Boolean, endTextColor: Color = TangemTheme.colors.text.tertiary, iconClick: (() -> Unit)? = null, @@ -98,7 +99,8 @@ private fun InitialInfoContentRow( endText = endText, endTextColor = endTextColor, endTextStyle = TangemTheme.typography.body2, - cornersToRound = cornersToRound, + currentIndex = currentIndex, + lastIndex = lastIndex, iconResId = R.drawable.ic_information_24, iconClick = iconClick, ) @@ -121,14 +123,6 @@ fun RoundedListDivider(modifier: Modifier = Modifier) { ) } -private fun getCornersToRound(currentIndex: Int, listSize: Int): CornersToRound { - return when (currentIndex) { - 0 -> CornersToRound.TOP_2 - listSize - 1 -> CornersToRound.BOTTOM_2 - else -> CornersToRound.ZERO - } -} - data class RoundedListWithDividersItemData( val id: Int, val startText: TextReference, diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/rows/RoundableCornersRow.kt b/core/ui/src/main/java/com/tangem/core/ui/components/rows/RoundableCornersRow.kt index 79b1cdb350..942e60deaf 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/rows/RoundableCornersRow.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/rows/RoundableCornersRow.kt @@ -5,7 +5,6 @@ import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon import androidx.compose.material3.Surface import androidx.compose.material3.Text @@ -20,9 +19,8 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp import com.tangem.core.ui.R +import com.tangem.core.ui.decorations.roundedShapeItemDecoration import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview @@ -35,12 +33,18 @@ fun RoundableCornersRow( endText: String, endTextColor: Color, endTextStyle: TextStyle, - cornersToRound: CornersToRound, + currentIndex: Int, + lastIndex: Int, iconResId: Int? = null, iconClick: (() -> Unit)? = null, ) { Surface( - shape = cornersToRound.getShape(), + modifier = Modifier + .roundedShapeItemDecoration( + currentIndex = currentIndex, + lastIndex = lastIndex, + addDefaultPadding = false, + ), color = TangemTheme.colors.background.action, ) { Row( @@ -86,26 +90,6 @@ fun RoundableCornersRow( } } -enum class CornersToRound { - - ALL_4, - TOP_2, - BOTTOM_2, - ZERO, - ; - - @Suppress("TopLevelComposableFunctions") - @Composable - fun getShape(radius: Dp = TangemTheme.dimens.radius12): RoundedCornerShape { - return when (this) { - ALL_4 -> RoundedCornerShape(radius) - TOP_2 -> RoundedCornerShape(topStart = radius, topEnd = radius) - BOTTOM_2 -> RoundedCornerShape(bottomStart = radius, bottomEnd = radius) - ZERO -> RoundedCornerShape(0.dp) - } - } -} - @Preview(widthDp = 360, showBackground = true) @Preview(widthDp = 360, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable @@ -121,7 +105,8 @@ private fun Preview_RoundableCornersRow( endText = previewData.endText, endTextColor = TangemTheme.colors.text.primary1, endTextStyle = TangemTheme.typography.subtitle2, - cornersToRound = previewData.cornersToRound, + currentIndex = previewData.currentIndex, + lastIndex = previewData.lastIndex, iconResId = previewData.iconResId, ) } @@ -131,7 +116,8 @@ private fun Preview_RoundableCornersRow( private data class RoundableCornersRowPreviewData( val startText: String, val endText: String, - val cornersToRound: CornersToRound, + val currentIndex: Int, + val lastIndex: Int, val iconResId: Int? = null, ) @@ -140,18 +126,20 @@ private class RoundableCornersRowDataProvider : override val values: Sequence get() = sequenceOf( - getPreviewData(cornersToRound = CornersToRound.ZERO), - getPreviewData(cornersToRound = CornersToRound.TOP_2), - getPreviewData(cornersToRound = CornersToRound.BOTTOM_2), - getPreviewData(cornersToRound = CornersToRound.ZERO, iconResId = R.drawable.ic_alert_24), - getPreviewData(cornersToRound = CornersToRound.TOP_2, iconResId = R.drawable.ic_alert_24), - getPreviewData(cornersToRound = CornersToRound.BOTTOM_2, iconResId = R.drawable.ic_alert_24), + getPreviewData(currentIndex = 1, lastIndex = 2), + getPreviewData(currentIndex = 0, lastIndex = 2), + getPreviewData(currentIndex = 2, lastIndex = 2), + getPreviewData(currentIndex = 1, lastIndex = 2, iconResId = R.drawable.ic_alert_24), + getPreviewData(currentIndex = 0, lastIndex = 2, iconResId = R.drawable.ic_alert_24), + getPreviewData(currentIndex = 2, lastIndex = 2, iconResId = R.drawable.ic_alert_24), ) - private fun getPreviewData(cornersToRound: CornersToRound, iconResId: Int? = null) = RoundableCornersRowPreviewData( - startText = "startText", - endText = "endText", - cornersToRound = cornersToRound, - iconResId = iconResId, - ) + private fun getPreviewData(currentIndex: Int, lastIndex: Int, iconResId: Int? = null) = + RoundableCornersRowPreviewData( + startText = "startText", + endText = "endText", + currentIndex = currentIndex, + lastIndex = lastIndex, + iconResId = iconResId, + ) } \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/TokenActionsBottomSheet.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/TokenActionsBottomSheet.kt index 7dc8517cd8..611315a24b 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/TokenActionsBottomSheet.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/TokenActionsBottomSheet.kt @@ -7,13 +7,12 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.tooling.preview.Preview import com.tangem.core.ui.components.SimpleSettingsRow import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetTitle -import com.tangem.core.ui.components.rows.CornersToRound +import com.tangem.core.ui.decorations.roundedShapeItemDecoration import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview @@ -43,15 +42,13 @@ private fun Content(content: TokenActionsBSContentUM) { ), ) { content.actions.forEachIndexed { index, action -> - val cornersToRound = when (index) { - 0 -> CornersToRound.TOP_2 - content.actions.lastIndex -> CornersToRound.BOTTOM_2 - else -> CornersToRound.ZERO - } - Box( modifier = Modifier - .clip(cornersToRound.getShape()) + .roundedShapeItemDecoration( + currentIndex = index, + lastIndex = content.actions.lastIndex, + addDefaultPadding = false, + ) .background(TangemTheme.colors.background.action), ) { SimpleSettingsRow( diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/MarketsListSortByBottomSheet.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/MarketsListSortByBottomSheet.kt index b5c0966102..61b289ff7e 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/MarketsListSortByBottomSheet.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/MarketsListSortByBottomSheet.kt @@ -8,13 +8,12 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.tooling.preview.Preview import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig import com.tangem.core.ui.components.inputrow.InputRowChecked import com.tangem.core.ui.components.inputrow.inner.DividerContainer -import com.tangem.core.ui.components.rows.CornersToRound +import com.tangem.core.ui.decorations.roundedShapeItemDecoration import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview @@ -43,15 +42,13 @@ private fun Content(content: SortByBottomSheetContentUM) { ), ) { SortByTypeUM.entries.forEachIndexed { index, type -> - val cornersToRound = when (index) { - 0 -> CornersToRound.TOP_2 - SortByTypeUM.entries.lastIndex -> CornersToRound.BOTTOM_2 - else -> CornersToRound.ZERO - } - DividerContainer( modifier = Modifier - .clip(cornersToRound.getShape()) + .roundedShapeItemDecoration( + currentIndex = index, + lastIndex = SortByTypeUM.entries.lastIndex, + addDefaultPadding = false, + ) .background(TangemTheme.colors.background.action) .clickable { content.onOptionClicked(type) }, showDivider = index != SortByTypeUM.entries.lastIndex, diff --git a/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ParticipateBottomBlock.kt b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ParticipateBottomBlock.kt index 01e2c4b3d1..300498f2e8 100644 --- a/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ParticipateBottomBlock.kt +++ b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ParticipateBottomBlock.kt @@ -26,7 +26,6 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider import androidx.core.content.ContextCompat.startActivity import com.tangem.core.ui.components.PrimaryButtonIconStart -import com.tangem.core.ui.components.rows.CornersToRound import com.tangem.core.ui.components.rows.RoundableCornersRow import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview @@ -69,21 +68,35 @@ internal fun ParticipateBottomBlock( } } +private const val INITIAL_VISIBLE_AWARDS_MAX_COUNT = 3 + @Composable private fun CounterAndAwards(purchasedWalletCount: Int, expectedAwards: ExpectedAwards?) { + val isExpanded = remember { mutableStateOf(false) } + + val overallItemsCount = calculateOverallItemsCount( + expectedAwards = expectedAwards, + isExpanded = isExpanded, + ) + Column { - Counter(purchasedWalletCount, expectedAwards) + Counter( + purchasedWalletCount = purchasedWalletCount, + overallItemsLastIndex = overallItemsCount - 1, + ) if (expectedAwards != null) { - Awards(expectedAwards) + Awards( + expectedAwards = expectedAwards, + overallItemsLastIndex = overallItemsCount - 1, + isExpanded = isExpanded, + ) } } } @Composable -private fun Counter(purchasedWalletCount: Int, expectedAwards: ExpectedAwards?) { - val isExpectedAwardsPresent = expectedAwards != null - +private fun Counter(purchasedWalletCount: Int, overallItemsLastIndex: Int) { RoundableCornersRow( startText = stringResource(id = R.string.referral_friends_bought_title), startTextColor = TangemTheme.colors.text.tertiary, @@ -95,20 +108,14 @@ private fun Counter(purchasedWalletCount: Int, expectedAwards: ExpectedAwards?) ), endTextColor = TangemTheme.colors.text.primary1, endTextStyle = TangemTheme.typography.body2, - cornersToRound = if (isExpectedAwardsPresent) { - CornersToRound.TOP_2 - } else { - CornersToRound.ALL_4 - }, + currentIndex = 0, + lastIndex = overallItemsLastIndex, ) } @Suppress("MagicNumber") @Composable -private fun Awards(expectedAwards: ExpectedAwards) { - val elementsCountToShowInLessMode = 3 - val isExpanded = remember { mutableStateOf(false) } - +private fun Awards(expectedAwards: ExpectedAwards, overallItemsLastIndex: Int, isExpanded: MutableState) { HorizontalDivider( thickness = TangemTheme.dimens.size0_5, color = TangemTheme.colors.stroke.primary, @@ -132,13 +139,14 @@ private fun Awards(expectedAwards: ExpectedAwards) { }, endTextColor = TangemTheme.colors.text.tertiary, endTextStyle = TangemTheme.typography.body2, - cornersToRound = CornersToRound.ZERO, + currentIndex = 1, + lastIndex = overallItemsLastIndex, ) - val initialItems = expectedAwards.expectedAwards.take(elementsCountToShowInLessMode) - val extraItems = expectedAwards.expectedAwards.drop(elementsCountToShowInLessMode) + val initialVisibleAwards = expectedAwards.expectedAwards.take(INITIAL_VISIBLE_AWARDS_MAX_COUNT) + val initialHiddenAwards = expectedAwards.expectedAwards.drop(INITIAL_VISIBLE_AWARDS_MAX_COUNT) - initialItems.forEachIndexed { index, expectedAward -> + initialVisibleAwards.forEachIndexed { index, expectedAward -> RoundableCornersRow( startText = expectedAward.paymentDate, startTextColor = TangemTheme.colors.text.primary1, @@ -146,11 +154,8 @@ private fun Awards(expectedAwards: ExpectedAwards) { endText = expectedAward.amount, endTextColor = TangemTheme.colors.text.primary1, endTextStyle = TangemTheme.typography.subtitle2, - cornersToRound = if (index == initialItems.size - 1 && extraItems.isEmpty()) { - CornersToRound.BOTTOM_2 - } else { - CornersToRound.ZERO - }, + currentIndex = index + 2, + lastIndex = overallItemsLastIndex, ) } @@ -159,10 +164,14 @@ private fun Awards(expectedAwards: ExpectedAwards) { enter = fadeIn() + expandVertically(), exit = shrinkVertically() + fadeOut(), ) { - ExtraItems(extraItems = extraItems) + ExtraItems( + extraItems = initialHiddenAwards, + overallItemsLastIndex = overallItemsLastIndex, + startIndex = initialVisibleAwards.size + 2, + ) } - if (expectedAwards.expectedAwards.size > elementsCountToShowInLessMode) { + if (initialHiddenAwards.isNotEmpty()) { LessMoreButton(isExpanded = isExpanded) } } @@ -217,9 +226,9 @@ private fun LessMoreButton(isExpanded: MutableState) { } @Composable -private fun ExtraItems(extraItems: List) { +private fun ExtraItems(extraItems: List, overallItemsLastIndex: Int, startIndex: Int) { Column { - extraItems.forEach { expectedAward -> + extraItems.forEachIndexed { index, expectedAward -> RoundableCornersRow( startText = expectedAward.paymentDate, startTextColor = TangemTheme.colors.text.primary1, @@ -227,7 +236,8 @@ private fun ExtraItems(extraItems: List) { endText = expectedAward.amount, endTextColor = TangemTheme.colors.text.primary1, endTextStyle = TangemTheme.typography.subtitle2, - cornersToRound = CornersToRound.ZERO, + currentIndex = index + startIndex, + lastIndex = overallItemsLastIndex, ) } } @@ -315,6 +325,22 @@ private fun AdditionalButtons( } } +private fun calculateOverallItemsCount(expectedAwards: ExpectedAwards?, isExpanded: MutableState): Int { + val totalItems = expectedAwards?.expectedAwards?.size ?: 0 + val initialItemsCount = minOf(totalItems, INITIAL_VISIBLE_AWARDS_MAX_COUNT) + val extraItemsCount = maxOf(0, totalItems - INITIAL_VISIBLE_AWARDS_MAX_COUNT) + + val awardItems = when { + expectedAwards == null -> 0 + extraItemsCount == 0 -> 1 + initialItemsCount + isExpanded.value -> 1 + initialItemsCount + extraItemsCount + 1 + else -> 1 + initialItemsCount + 1 + } + + val counterItems = 1 + return counterItems + awardItems +} + private fun Context.shareText(text: String) { val sendIntent: Intent = Intent().apply { action = Intent.ACTION_SEND diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt index de2cbafe46..c4b3d7e3f8 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.pullrefresh.PullRefreshIndicator @@ -40,7 +41,7 @@ import com.tangem.core.ui.components.SpacerH12 import com.tangem.core.ui.components.inputrow.InputRowDefault import com.tangem.core.ui.components.inputrow.InputRowImageInfo import com.tangem.core.ui.components.list.roundedListWithDividersItems -import com.tangem.core.ui.components.rows.CornersToRound +import com.tangem.core.ui.decorations.roundedShapeItemDecoration import com.tangem.core.ui.extensions.* import com.tangem.core.ui.pullToRefresh.PullToRefreshConfig import com.tangem.core.ui.res.TangemColorPalette @@ -151,8 +152,12 @@ private fun LazyListScope.activeStakingBlock( style = TangemTheme.typography.subtitle2, color = TangemTheme.colors.text.tertiary, modifier = Modifier + .roundedShapeItemDecoration( + currentIndex = 0, + lastIndex = 1 + state.yieldBalance.balance.lastIndex, + addDefaultPadding = false, + ) .fillMaxWidth() - .clip(CornersToRound.TOP_2.getShape()) .background(TangemTheme.colors.background.action) .padding( top = TangemTheme.dimens.spacing12, @@ -163,13 +168,13 @@ private fun LazyListScope.activeStakingBlock( ) } } - items( + itemsIndexed( items = state.yieldBalance.balance, - key = { + key = { _, balance -> // Staked balance does not have unique identifier. - it.toString() + balance.toString() }, - ) { balance -> + ) { index, balance -> ActiveStakingBlock( balance = balance, isBalanceHidden = isBalanceHidden, @@ -177,12 +182,10 @@ private fun LazyListScope.activeStakingBlock( onAnalytic = clickIntents::onActiveStakeAnalytic, modifier = Modifier .animateItem() - .then( - if (state.yieldBalance.balance.last() == balance) { - Modifier.clip(CornersToRound.BOTTOM_2.getShape()) - } else { - Modifier - }, + .roundedShapeItemDecoration( + currentIndex = index + 1, + lastIndex = state.yieldBalance.balance.lastIndex + 1, + addDefaultPadding = false, ), ) }