Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MBL-2069 Add images on rewards UI #2224

Merged
merged 9 commits into from
Feb 13, 2025
2 changes: 2 additions & 0 deletions app/src/main/graphql/fragments.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ fragment backing on Backing {
items {
... rewardItems
}
...rewardImage
}
backer {
... user
Expand All @@ -194,6 +195,7 @@ fragment backing on Backing {
items {
... rewardItems
}
...rewardImage
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -758,11 +758,13 @@ fun backingTransformer(backingGr: com.kickstarter.fragment.Backing?): Backing {
val projectId = decodeRelayId(backingGr?.project?.project?.id) ?: -1
val shippingAmount = backingGr?.shippingAmount
val items = backingGr?.reward?.items
val rewardImage = backingGr?.reward?.rewardImage
val reward = backingGr?.reward?.reward?.let { reward ->
return@let rewardTransformer(
reward,
allowedAddons = reward.allowedAddons.isNotNull(),
rewardItems = complexRewardItemsTransformer(items?.rewardItems)
rewardItems = complexRewardItemsTransformer(items?.rewardItems),
rewardImage = rewardImage
)
}

Expand Down Expand Up @@ -833,7 +835,7 @@ fun backingTransformer(backingGr: com.kickstarter.fragment.Backing?): Backing {
*/
fun getAddOnsList(addOns: com.kickstarter.fragment.Backing.AddOns): List<Reward> {
val rewardsList = addOns.nodes?.mapNotNull { node ->
node?.let { rewardTransformer(it.reward) }
node?.let { rewardTransformer(it.reward, rewardImage = it.rewardImage) }
}

val mapHolder = mutableMapOf<Long, Reward>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
Expand All @@ -23,9 +24,15 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.kickstarter.R
import com.kickstarter.models.Photo
import com.kickstarter.ui.compose.designsystem.KSCoralBadge
import com.kickstarter.ui.compose.designsystem.KSDividerLineGrey
import com.kickstarter.ui.compose.designsystem.KSPrimaryBlackButton
Expand Down Expand Up @@ -61,6 +68,7 @@ private fun AddOnsContainerPreview() {
@Composable
fun AddOnsContainer(
rewardId: Long = 0,
image: Photo? = null,
title: String,
amount: String,
conversionAmount: String? = null,
Expand All @@ -85,152 +93,169 @@ fun AddOnsContainer(
Column(
modifier = Modifier
.fillMaxWidth()
.padding(dimensions.paddingMediumLarge)
) {
if (image != null) {
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(image.full())
.crossfade(true)
.build(),
contentDescription = image.altText(),
modifier = Modifier
.fillMaxWidth()
.aspectRatio(dimensions.cardImageAspectRatio),
placeholder = ColorPainter(color = colors.backgroundDisabled),
contentScale = ContentScale.Crop
)
}
Column(
modifier = Modifier.padding(dimensions.paddingMediumLarge)
) {
Copy link
Contributor Author

@ycheng-kickstarter ycheng-kickstarter Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please ignore everything after this line. Only relevant changes in this file are up to here. The diff just did a terrible job of detecting actual differences.


Text(text = title, style = typographyV2.title2Bold, color = colors.kds_black)

Text(text = title, style = typographyV2.title2Bold, color = colors.kds_black)
Spacer(modifier = Modifier.height(dimensions.paddingXSmall))

Spacer(modifier = Modifier.height(dimensions.paddingXSmall))
Row {
Text(text = amount, style = typographyV2.bodyLG, color = colors.textAccentGreen)

Row {
Text(text = amount, style = typographyV2.bodyLG, color = colors.textAccentGreen)
if (!shippingAmount.isNullOrEmpty()) {
Text(
text = shippingAmount,
style = typographyV2.bodyLG,
color = colors.textAccentGreen
)
}
}

if (!shippingAmount.isNullOrEmpty()) {
if (!conversionAmount.isNullOrEmpty()) {
Text(
text = shippingAmount,
style = typographyV2.bodyLG,
color = colors.textAccentGreen
modifier = Modifier.padding(top = dimensions.paddingXSmall),
text = conversionAmount,
style = typographyV2.footNoteMedium,
color = colors.textSecondary
)
}
}

if (!conversionAmount.isNullOrEmpty()) {
Text(
modifier = Modifier.padding(top = dimensions.paddingXSmall),
text = conversionAmount,
style = typographyV2.footNoteMedium,
color = colors.textSecondary
)
}
Spacer(modifier = Modifier.height(dimensions.paddingMediumLarge))

Spacer(modifier = Modifier.height(dimensions.paddingMediumLarge))
Text(text = description, style = typographyV2.bodyMD, color = colors.textPrimary)

Text(text = description, style = typographyV2.bodyMD, color = colors.textPrimary)
Spacer(modifier = Modifier.height(dimensions.paddingMedium))

Spacer(modifier = Modifier.height(dimensions.paddingMedium))
KSDividerLineGrey()

KSDividerLineGrey()
Spacer(modifier = Modifier.height(dimensions.paddingMedium))

Spacer(modifier = Modifier.height(dimensions.paddingMedium))
if (includesList.isNotEmpty()) {
Text(
text = stringResource(id = R.string.project_view_pledge_includes),
style = typographyV2.headingLG,
color = colors.textSecondary
)

if (includesList.isNotEmpty()) {
Text(
text = stringResource(id = R.string.project_view_pledge_includes),
style = typographyV2.headingLG,
color = colors.textSecondary
)
includesList.forEachIndexed { index, itemDescription ->
Row(verticalAlignment = Alignment.CenterVertically) {
Spacer(modifier = Modifier.width(dimensions.paddingMediumSmall))

includesList.forEachIndexed { index, itemDescription ->
Row(verticalAlignment = Alignment.CenterVertically) {
Spacer(modifier = Modifier.width(dimensions.paddingMediumSmall))
Box(
modifier = Modifier
.padding(end = dimensions.paddingSmall)
.size(dimensions.dottedListDotSize)
.background(color = colors.textPrimary, shape = CircleShape),
)

Box(
modifier = Modifier
.padding(end = dimensions.paddingSmall)
.size(dimensions.dottedListDotSize)
.background(color = colors.textPrimary, shape = CircleShape),
)
Text(
modifier = Modifier.padding(
top = dimensions.paddingXSmall,
bottom = dimensions.paddingXSmall
),
text = itemDescription,
style = typographyV2.bodyMD,
color = colors.textPrimary
)

Text(
modifier = Modifier.padding(
top = dimensions.paddingXSmall,
bottom = dimensions.paddingXSmall
),
text = itemDescription,
style = typographyV2.bodyMD,
color = colors.textPrimary
)
Spacer(modifier = Modifier.width(dimensions.paddingMediumSmall))
}

Spacer(modifier = Modifier.width(dimensions.paddingMediumSmall))
if (index != includesList.lastIndex) KSDividerLineGrey()
}

if (index != includesList.lastIndex) KSDividerLineGrey()
}
}

if (!estimatedShippingCost.isNullOrEmpty()) {
Spacer(modifier = Modifier.height(dimensions.paddingMediumLarge))
Text(
text = stringResource(id = R.string.Estimated_Shipping),
color = colors.kds_support_400,
style = typographyV2.headingLG
)

Text(
modifier = Modifier.padding(top = dimensions.radiusSmall),
text = estimatedShippingCost,
color = colors.kds_support_700,
style = typographyV2.bodyMD
)
}

if (limit > 0) {
Spacer(Modifier.height(dimensions.paddingMedium))
KSCoralBadge(text = "Limit $limit")
}
if (!estimatedShippingCost.isNullOrEmpty()) {
Spacer(modifier = Modifier.height(dimensions.paddingMediumLarge))
Text(
text = stringResource(id = R.string.Estimated_Shipping),
color = colors.kds_support_400,
style = typographyV2.headingLG
)

Spacer(Modifier.height(dimensions.paddingLarge))

when (count) {
0 -> {
KSPrimaryBlackButton(
onClickAction = {
count++
onItemAddedOrRemoved(count, rewardId)
},
text = buttonText,
isEnabled = buttonEnabled
Text(
modifier = Modifier.padding(top = dimensions.radiusSmall),
text = estimatedShippingCost,
color = colors.kds_support_700,
style = typographyV2.bodyMD
)
}

else -> {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
KSStepper(
onPlusClicked = {
if (limit > 0) {
Spacer(Modifier.height(dimensions.paddingMedium))
KSCoralBadge(text = "Limit $limit")
}

Spacer(Modifier.height(dimensions.paddingLarge))

when (count) {
0 -> {
KSPrimaryBlackButton(
onClickAction = {
count++
onItemAddedOrRemoved(count, rewardId)
},
isPlusEnabled = count < limit,
onMinusClicked = {
count--
onItemAddedOrRemoved(count, rewardId)
},
isMinusEnabled = true
text = buttonText,
isEnabled = buttonEnabled
)
}

Box(
modifier = Modifier
.border(
width = dimensions.dividerThickness,
color = colors.textSecondary,
shape = shapes.small
)
.padding(
top = dimensions.paddingSmall,
bottom = dimensions.paddingSmall,
start = dimensions.paddingMedium,
end = dimensions.paddingMedium
)
else -> {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = "$count",
style = typographyV2.bodyLG,
color = colors.textPrimary
KSStepper(
onPlusClicked = {
count++
onItemAddedOrRemoved(count, rewardId)
},
isPlusEnabled = count < limit,
onMinusClicked = {
count--
onItemAddedOrRemoved(count, rewardId)
},
isMinusEnabled = true
)

Box(
modifier = Modifier
.border(
width = dimensions.dividerThickness,
color = colors.textSecondary,
shape = shapes.small
)
.padding(
top = dimensions.paddingSmall,
bottom = dimensions.paddingSmall,
start = dimensions.paddingMedium,
end = dimensions.paddingMedium
)
) {
Text(
text = "$count",
style = typographyV2.bodyLG,
color = colors.textPrimary
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ fun AddOnsScreen(

AddOnsContainer(
rewardId = reward.id(),
image = reward.image(),
title = reward.title() ?: "",
amount = environment.ksCurrency()?.format(
reward.minimum(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ fun RewardCarouselScreen(
)
}
},
image = reward.image(),
isCTAButtonEnabled = ctaButtonEnabled,
includes = if (RewardUtils.isItemized(reward) && !reward.rewardsItems()
.isNullOrEmpty() && environment.ksString().isNotNull()
Expand Down
Loading