mirror of
https://github.com/kickstarter/android-oss.git
synced 2026-03-13 09:11:01 +08:00
[MBL-2994] Show Featured badge (#2475)
* Wire Featured badge in KSRewardCard and AddOnViewHolder (same placement as Secret). Add Featured reward previews on KSRewardsCard. * Fix lint
This commit is contained in:
@@ -377,7 +377,8 @@ fun RewardCarouselScreen(
|
||||
} else null,
|
||||
addonsPillVisible = reward.hasAddons(),
|
||||
isCTAButtonVisible = project.isAllowedToPledge(),
|
||||
isSecret = reward.isSecretReward() == true
|
||||
isSecret = reward.isSecretReward() == true,
|
||||
isFeatured = reward.isFeatured() == true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,16 +20,19 @@ import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.zIndex
|
||||
import com.kickstarter.R
|
||||
import com.kickstarter.models.Photo
|
||||
import com.kickstarter.ui.compose.designsystem.KSFeaturedRewardBadge
|
||||
import com.kickstarter.ui.compose.designsystem.KSGreenBadge
|
||||
import com.kickstarter.ui.compose.designsystem.KSPrimaryGreenButton
|
||||
import com.kickstarter.ui.compose.designsystem.KSSecretRewardBadge
|
||||
@@ -94,6 +97,35 @@ fun KSRewardCardPreviewImageSelectedSecret() {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
fun KSRewardCardPreviewImageSelectedFeatured() {
|
||||
KSTheme {
|
||||
KSRewardCard(
|
||||
amount = "$20",
|
||||
conversion = "about $400",
|
||||
title = "Featured reward",
|
||||
backerCountBadgeText = "23 backers",
|
||||
image = Photo.builder().altText("").full("").build(),
|
||||
description = "this is a description",
|
||||
isCTAButtonEnabled = true,
|
||||
isSecret = false,
|
||||
isFeatured = true,
|
||||
estimatedDelivery = "June 10th, 2026",
|
||||
includes = listOf("1 Comic Book", "2 pins", "3 happy meals"),
|
||||
yourSelectionIsVisible = true,
|
||||
ctaButtonText = "Select",
|
||||
expirationDateText = "4 Days",
|
||||
shippingSummaryText = "Anywhere",
|
||||
addonsPillVisible = true,
|
||||
remainingText = "5 left",
|
||||
estimatedShippingCost = "About $10-$15",
|
||||
onRewardSelectClicked = { }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@@ -122,6 +154,35 @@ fun KSRewardCardPreviewImageNoSelectedSecret() {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
fun KSRewardCardPreviewImageNoSelectedFeatured() {
|
||||
KSTheme {
|
||||
KSRewardCard(
|
||||
amount = "$20",
|
||||
conversion = "about $400",
|
||||
title = "Featured reward",
|
||||
backerCountBadgeText = "23 backers",
|
||||
image = Photo.builder().altText("").full("").build(),
|
||||
description = "this is a description",
|
||||
isCTAButtonEnabled = true,
|
||||
isSecret = false,
|
||||
isFeatured = true,
|
||||
estimatedDelivery = "June 10th, 2026",
|
||||
includes = listOf("1 Comic Book", "2 pins", "3 happy meals"),
|
||||
yourSelectionIsVisible = false,
|
||||
ctaButtonText = "Select",
|
||||
expirationDateText = "4 Days",
|
||||
shippingSummaryText = "Anywhere",
|
||||
addonsPillVisible = true,
|
||||
remainingText = "5 left",
|
||||
estimatedShippingCost = "About $10-$15",
|
||||
onRewardSelectClicked = { }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@@ -177,6 +238,34 @@ fun KSRewardCardPreviewNoImageSelectedSecret() {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
fun KSRewardCardPreviewNoImageSelectedFeatured() {
|
||||
KSTheme {
|
||||
KSRewardCard(
|
||||
amount = "$20",
|
||||
conversion = "about $400",
|
||||
title = "Featured reward",
|
||||
backerCountBadgeText = "23 backers",
|
||||
description = "this is a description",
|
||||
isCTAButtonEnabled = true,
|
||||
isSecret = false,
|
||||
isFeatured = true,
|
||||
estimatedDelivery = "June 10th, 2026",
|
||||
includes = listOf("1 Comic Book", "2 pins", "3 happy meals"),
|
||||
yourSelectionIsVisible = true,
|
||||
ctaButtonText = "Select",
|
||||
expirationDateText = "4 Days",
|
||||
shippingSummaryText = "Anywhere",
|
||||
addonsPillVisible = true,
|
||||
remainingText = "5 left",
|
||||
estimatedShippingCost = "About $10-$15",
|
||||
onRewardSelectClicked = { }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@@ -237,6 +326,40 @@ fun KSRewardCardPreviewNoImageNoSelectedSecret() {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
fun KSRewardCardPreviewNoImageNoSelectedFeatured() {
|
||||
KSTheme {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(KSTheme.dimensions.cardWidth)
|
||||
.padding(KSTheme.dimensions.paddingMediumLarge)
|
||||
) {
|
||||
KSRewardCard(
|
||||
amount = "$20",
|
||||
conversion = "about $400",
|
||||
title = "Featured reward",
|
||||
backerCountBadgeText = "23 backers",
|
||||
description = "this is a description",
|
||||
isCTAButtonEnabled = true,
|
||||
isSecret = false,
|
||||
isFeatured = true,
|
||||
estimatedDelivery = "June 10th, 2026",
|
||||
includes = listOf("1 Comic Book", "2 pins", "3 happy meals"),
|
||||
yourSelectionIsVisible = false,
|
||||
ctaButtonText = "Select",
|
||||
expirationDateText = "4 Days",
|
||||
shippingSummaryText = "Anywhere",
|
||||
addonsPillVisible = true,
|
||||
remainingText = "5 left",
|
||||
estimatedShippingCost = "About $10-$15",
|
||||
onRewardSelectClicked = { }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@@ -288,27 +411,41 @@ fun KSRewardCard(
|
||||
estimatedShippingCost: String? = null,
|
||||
onRewardSelectClicked: () -> Unit,
|
||||
isSecret: Boolean = false,
|
||||
isFeatured: Boolean = false,
|
||||
) {
|
||||
Box(modifier = modifier.width(KSTheme.dimensions.cardWidth)) {
|
||||
if (isSecret && image == null && !yourSelectionIsVisible) {
|
||||
if ((isSecret || isFeatured) && image == null && !yourSelectionIsVisible) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.offset(x = dimensions.paddingMedium, y = -(dimensions.secretRewardBadgeOffsetY))
|
||||
.zIndex(1f)
|
||||
) {
|
||||
KSSecretRewardBadge()
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(dimensions.paddingSmall),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
if (isSecret) KSSecretRewardBadge()
|
||||
if (isFeatured) KSFeaturedRewardBadge()
|
||||
}
|
||||
}
|
||||
}
|
||||
val cardShape = RoundedCornerShape(KSTheme.dimensions.radiusMediumSmall)
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(KSTheme.dimensions.radiusMediumSmall),
|
||||
shape = cardShape,
|
||||
colors = CardDefaults.cardColors(containerColor = KSTheme.colors.kds_white),
|
||||
border = null,
|
||||
) {
|
||||
Column(modifier = Modifier.background(KSTheme.colors.kds_white)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clip(cardShape)
|
||||
.background(KSTheme.colors.kds_white)
|
||||
) {
|
||||
|
||||
Box {
|
||||
if (image != null) {
|
||||
KSRewardAsyncImage(image = image)
|
||||
if (isSecret) {
|
||||
if (isSecret || isFeatured) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomStart)
|
||||
@@ -317,14 +454,20 @@ fun KSRewardCard(
|
||||
y = dimensions.secretRewardBadgeOffsetY
|
||||
)
|
||||
) {
|
||||
KSSecretRewardBadge()
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(dimensions.paddingSmall),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
if (isSecret) KSSecretRewardBadge()
|
||||
if (isFeatured) KSFeaturedRewardBadge()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (yourSelectionIsVisible) {
|
||||
YourSelectionTag()
|
||||
if (isSecret && image == null) {
|
||||
if ((isSecret || isFeatured) && image == null) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomStart)
|
||||
@@ -333,7 +476,13 @@ fun KSRewardCard(
|
||||
top = dimensions.paddingXXXLarge
|
||||
)
|
||||
) {
|
||||
KSSecretRewardBadge()
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(dimensions.paddingSmall),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
if (isSecret) KSSecretRewardBadge()
|
||||
if (isFeatured) KSFeaturedRewardBadge()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,12 @@ package com.kickstarter.ui.viewholders
|
||||
|
||||
import android.util.Pair
|
||||
import android.view.View
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.view.isGone
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import coil.load
|
||||
@@ -14,6 +20,7 @@ import com.kickstarter.libs.utils.ViewUtils
|
||||
import com.kickstarter.libs.utils.extensions.addToDisposable
|
||||
import com.kickstarter.models.Reward
|
||||
import com.kickstarter.ui.adapters.RewardItemsAdapter
|
||||
import com.kickstarter.ui.compose.designsystem.KSFeaturedRewardBadge
|
||||
import com.kickstarter.ui.compose.designsystem.KSSecretRewardBadge
|
||||
import com.kickstarter.ui.compose.designsystem.KSTheme
|
||||
import com.kickstarter.ui.data.ProjectData
|
||||
@@ -154,14 +161,22 @@ class AddOnViewHolder(private val binding: ItemAddOnBinding) : KSViewHolder(bind
|
||||
val badgeOverImage = binding.secretBadgeComposeOverImage
|
||||
val badgeAboveCard = binding.secretBadgeComposeAboveCard
|
||||
|
||||
if (reward.isSecretReward() == true) {
|
||||
val showBadge = reward.isSecretReward() == true || reward.isFeatured() == true
|
||||
if (showBadge) {
|
||||
if (hasImage) {
|
||||
badgeOverImage.visibility = View.VISIBLE
|
||||
badgeAboveCard.visibility = View.GONE
|
||||
|
||||
badgeOverImage.setContent {
|
||||
KSTheme {
|
||||
KSSecretRewardBadge()
|
||||
Row(
|
||||
modifier = Modifier.wrapContentSize(),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
if (reward.isSecretReward() == true) KSSecretRewardBadge()
|
||||
if (reward.isFeatured() == true) KSFeaturedRewardBadge()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -170,7 +185,14 @@ class AddOnViewHolder(private val binding: ItemAddOnBinding) : KSViewHolder(bind
|
||||
|
||||
badgeAboveCard.setContent {
|
||||
KSTheme {
|
||||
KSSecretRewardBadge()
|
||||
Row(
|
||||
modifier = Modifier.wrapContentSize(),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
if (reward.isSecretReward() == true) KSSecretRewardBadge()
|
||||
if (reward.isFeatured() == true) KSFeaturedRewardBadge()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user