-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ANDROID-15405 -- PosterCard component (#398)
* dhonti/ANDROID-15405-postercard: First approach "PosterCard" component * dhonti/ANDROID-15405: Update approach in order to accept images * dhonti/ANDROID-15405-postercard: Fix viewing correctly lower custom content Composable and reorganizing current composables in package * dhonti/ANDROID-15405-postercard: Integration new "TopActions" attributos * dhonti/ANDROID-15405-postercard: Removing "Video" type from current "PosterCard" implementation. To be updated in future * dhonti/ANDROID-15405-postercard: Entry "PosterCard" creation in Mistica Catalog app * dhonti/ANDROID-15405-postercard: Add sample background * dhonti/ANDROID-15405-postercard: Update components "TopAction" components in order to fit clickable actions * dhonti/ANDROID-15405-postercard: Update some components * dhonti/ANDROID-15405-postercard: Update sample attributes * dhonti/NADROID-15405-postercard: - Added param in "TopAction" component to be able to receive a "testTag". - FIXED problem resize Image() * dhonti/ANDROID-15405-postercard: FIXED rescale when is provided an fixed aspect ratio and the height inner content is bigger than aspect ratio height. * dhonti/ANDROID-15405-postercard: Place correctly the PosterCardTopActions() subcomposable in order to be more visible * dhonti/ANDROID-15405-postercard: Remove unused import * dhonti/ANDROID-15405-postercard: Some code corrections * dhonti/ANDROID-15405-postercard: Create README.md file in "postercard" folder and linking with main README.md library * dhonti/ANDROID-15405-postercard: Fixed linking to "compose" folder * dhonti/ANDRID-15405-postercard: Update location "sample_background" * dhonti/ANDROID-15405-postercard: Update CONTRIBUTING.md * dhonti/ANDROID-15405-postercard: Update PosterCard README file * dhonti/ANDROID-15405-postercard: Applied some corrections proposed by @haynlo * dhonti/ANDROID-15405-postercard: Update modifier function in order to accept a clickable() and update param "contentDescription" * dhonti/ANDROID-15405-postercard: Update clickable() in modifier action * dhonti/ANDROID-15405-postercard: New way to manage top actions list processing * dhonti/ANDROID-15405-postercard: Update corresponding README.md postercard * dhonti/ANDROID-15405-postercard: Update use the "cardContentOverlay" in background shadow main content text * dhonti/ANDROID-15405-postercard: - Update TopAction components background according to Mistica color values and make them clickables * dhonti/ANDROID-15405-postercard: Update top actions management in code * dhonti/ANDROID-15405-postercard: Update resource to catalog and change format to WEBP * dhonti/ANDROID-15405-postercard: New preview reference with no images * dhont/ANDROID-15405-postercard: Update correct reference to resource in PosterCard() main component * dhonti/ANDROID-15405-postercard: Update R mistica Catalog module in PosterCards file * dhonti/ANDROID-15405-postercard: 1st approach for accesibility PosterCard * dhonti/ANDROID-15405-postercard: Remove unused imports * dhonti/ANDROID-15405-postercard: Change colors to support dark mode top actions * dhonti/ANDROID-15405-postercard: 2nd approach a11 postercard * dhonti/ANDROID-15405-postercard: First approach with a11 integrated * dhonti/ANDROID-15405-postercard: A11 approach using "Modifier.zIndex()" in corresponding components * dhonti/ANDROID-15405-postercard: Apply some corrections from PR @jeprubio
- Loading branch information
1 parent
300bada
commit 36a19aa
Showing
12 changed files
with
751 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
237 changes: 237 additions & 0 deletions
237
catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
package com.telefonica.mistica.catalog.ui.compose.components | ||
|
||
import androidx.annotation.AttrRes | ||
import androidx.compose.foundation.background | ||
import androidx.compose.foundation.border | ||
import androidx.compose.foundation.layout.Arrangement | ||
import androidx.compose.foundation.layout.Box | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.Row | ||
import androidx.compose.foundation.layout.fillMaxSize | ||
import androidx.compose.foundation.layout.fillMaxWidth | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.layout.size | ||
import androidx.compose.foundation.rememberScrollState | ||
import androidx.compose.foundation.verticalScroll | ||
import androidx.compose.material.Checkbox | ||
import androidx.compose.material.OutlinedTextField | ||
import androidx.compose.material.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.mutableIntStateOf | ||
import androidx.compose.runtime.mutableStateOf | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.runtime.setValue | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.graphics.Brush | ||
import androidx.compose.ui.graphics.Color | ||
import androidx.compose.ui.graphics.SolidColor | ||
import androidx.compose.ui.unit.dp | ||
import com.telefonica.mistica.catalog.R | ||
import com.telefonica.mistica.compose.card.postercard.PosterCard | ||
import com.telefonica.mistica.compose.card.postercard.PosterCardAspectRatio | ||
import com.telefonica.mistica.compose.card.postercard.PosterCardBackgroundType | ||
import com.telefonica.mistica.compose.card.postercard.TopActionData | ||
import com.telefonica.mistica.compose.input.DropDownInput | ||
import com.telefonica.mistica.compose.tag.Tag | ||
import com.telefonica.mistica.compose.theme.MisticaTheme | ||
import com.telefonica.mistica.tag.TagView | ||
import com.telefonica.mistica.tag.TagView.Companion.TYPE_PROMO | ||
|
||
@Composable | ||
fun PosterCards() { | ||
|
||
var tag: String by remember { mutableStateOf("Headline") } | ||
var tagType: Int by remember { mutableIntStateOf(TYPE_PROMO) } | ||
|
||
var aspectRatioType: PosterCardAspectRatio by remember { mutableStateOf(PosterCardAspectRatio.AR_AUTO) } | ||
|
||
var inverseDisplay: Boolean by remember { mutableStateOf(true) } | ||
var backgroundType: BackgroundType by remember { mutableStateOf(BackgroundType.IMAGE) } | ||
|
||
var topActionsType: TopActionsType by remember { mutableStateOf(TopActionsType.NONE) } | ||
|
||
var preTitle: String by remember { mutableStateOf("Pretitle") } | ||
var title: String by remember { mutableStateOf("Title") } | ||
var subtitle: String by remember { mutableStateOf("Subtitle") } | ||
var description: String by remember { mutableStateOf("Description") } | ||
|
||
var withAdditionalContent: Boolean by remember { mutableStateOf(false) } | ||
|
||
|
||
Column( | ||
modifier = Modifier | ||
.fillMaxSize() | ||
.padding(16.dp) | ||
.verticalScroll(rememberScrollState()), | ||
verticalArrangement = Arrangement.Center, | ||
horizontalAlignment = Alignment.CenterHorizontally, | ||
) { | ||
DropDownInput( | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.padding(top = 4.dp), | ||
items = PosterCardAspectRatio.entries.map { aspectRatioLabelsMaps[it].orEmpty() }, | ||
currentItemIndex = PosterCardAspectRatio.entries.indexOf(aspectRatioType), | ||
onItemSelected = { index -> aspectRatioType = PosterCardAspectRatio.entries.toTypedArray()[index] }, | ||
hint = "Aspect Ratio", | ||
) | ||
|
||
DropDownInput( | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.padding(top = 4.dp), | ||
items = BackgroundType.entries.map { backgroundTypeLabelsMap[it].orEmpty() }, | ||
currentItemIndex = BackgroundType.entries.indexOf(backgroundType), | ||
onItemSelected = { index -> backgroundType = BackgroundType.entries.toTypedArray()[index] }, | ||
hint = "Background type", | ||
) | ||
|
||
if (backgroundType != BackgroundType.IMAGE) { | ||
Row(verticalAlignment = Alignment.CenterVertically) { | ||
Text("Inverse display") | ||
Checkbox(checked = inverseDisplay, onCheckedChange = { | ||
inverseDisplay = !inverseDisplay | ||
backgroundType.backgroundValue.inverseDisplay = inverseDisplay | ||
}) | ||
} | ||
} | ||
|
||
DropDownInput( | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.padding(top = 4.dp), | ||
items = TopActionsType.entries.map { topActionsTypeLabelsMap[it].orEmpty() }, | ||
currentItemIndex = TopActionsType.entries.indexOf(topActionsType), | ||
onItemSelected = { index -> topActionsType = TopActionsType.entries.toTypedArray()[index] }, | ||
hint = "Top actions", | ||
) | ||
|
||
OutlinedTextField( | ||
modifier = Modifier.fillMaxWidth(), | ||
value = tag, | ||
onValueChange = { tag = it }, label = { Text("Tag label") } | ||
) | ||
|
||
DropDownInput( | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.padding(top = 4.dp), | ||
items = TagColorsValues.entries.map { it.name }, | ||
currentItemIndex = tagType, | ||
onItemSelected = { index -> tagType = index }, | ||
hint = "Tag style", | ||
) | ||
|
||
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = preTitle, onValueChange = { preTitle = it }, label = { Text("Pretitle") }) | ||
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = title, onValueChange = { title = it }, label = { Text("Title") }) | ||
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = subtitle, onValueChange = { subtitle = it }, label = { Text("Subtitle") }) | ||
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = description, onValueChange = { description = it }, label = { Text("Description") }) | ||
|
||
Row(verticalAlignment = Alignment.CenterVertically) { | ||
Text("With additional content") | ||
Checkbox(checked = withAdditionalContent, onCheckedChange = { withAdditionalContent = !withAdditionalContent }) | ||
} | ||
|
||
PosterCard( | ||
modifier = Modifier.fillMaxWidth(), | ||
aspectRatio = aspectRatioType, | ||
backgroundType = backgroundType.backgroundValue, | ||
headline = if (tag.isNotEmpty()) Tag(tag).withStyle(tagType) else null, | ||
preTitle = preTitle.getOrNullIfEmpty(), | ||
title = title.getOrNullIfEmpty(), | ||
subtitle = subtitle.getOrNullIfEmpty(), | ||
description = description.getOrNullIfEmpty(), | ||
firstTopAction = topActionsType.info?.firstTopAction, | ||
secondTopAction = topActionsType.info?.secondTopAction, | ||
customContent = { | ||
if (withAdditionalContent) { | ||
AdditionalContent() | ||
} | ||
} | ||
) | ||
} | ||
} | ||
|
||
private enum class TagColorsValues(@AttrRes val tagStyle: Int) { | ||
PROMO(TYPE_PROMO), | ||
ACTIVE(TagView.TYPE_ACTIVE), | ||
INACTIVE(TagView.TYPE_INACTIVE), | ||
SUCCESS(TagView.TYPE_SUCCESS), | ||
WARNING(TagView.TYPE_WARNING), | ||
ERROR(TagView.TYPE_ERROR), | ||
INVERSE(TagView.TYPE_INVERSE), | ||
} | ||
|
||
private val aspectRatioLabelsMaps = mapOf( | ||
PosterCardAspectRatio.AR_AUTO to "Auto", | ||
PosterCardAspectRatio.AR_1_1 to "1:1", | ||
PosterCardAspectRatio.AR_7_10 to "7:10", | ||
PosterCardAspectRatio.AR_9_10 to "9:10", | ||
PosterCardAspectRatio.AR_16_9 to "16:9" | ||
) | ||
|
||
private val backgroundTypeLabelsMap = mapOf( | ||
BackgroundType.SOLID_COLOR to "Solid color", | ||
BackgroundType.GRADIENT_COLOR to "Gradient color", | ||
BackgroundType.IMAGE to "Image" | ||
) | ||
|
||
private val topActionsTypeLabelsMap = mapOf( | ||
TopActionsType.NONE to "None", | ||
TopActionsType.ONE_ACTION_DISMISS to "One action (Dismiss)", | ||
TopActionsType.TWO_ACTIONS to "Two actions (View + Dismiss)" | ||
) | ||
|
||
private enum class BackgroundType(val backgroundValue: PosterCardBackgroundType) { | ||
IMAGE(PosterCardBackgroundType.Image(imageResource = R.drawable.sample_background, contentDescription = "Mística PosterCard")), | ||
SOLID_COLOR(PosterCardBackgroundType.Color(brush = SolidColor(Color.Red))), | ||
GRADIENT_COLOR(PosterCardBackgroundType.Color(brush = Brush.verticalGradient(colors = listOf(Color.Blue, Color.Cyan)))), | ||
} | ||
|
||
private enum class TopActionsType(val info: PosterCardTopActionInfo? = null) { | ||
NONE, | ||
ONE_ACTION_DISMISS( | ||
info = PosterCardTopActionInfo( | ||
firstTopAction = TopActionData(iconRes = R.drawable.ic_close_regular) | ||
) | ||
), | ||
TWO_ACTIONS( | ||
info = PosterCardTopActionInfo( | ||
firstTopAction = TopActionData( | ||
iconRes = R.drawable.icn_visibility, | ||
contentDescription = "PosterCard Visible top action" | ||
), | ||
secondTopAction = TopActionData( | ||
iconRes = R.drawable.ic_close_regular, | ||
contentDescription = "PosterCard Close top action" | ||
) | ||
) | ||
) | ||
} | ||
|
||
private data class PosterCardTopActionInfo( | ||
val firstTopAction: TopActionData? = null, | ||
val secondTopAction: TopActionData? = null | ||
) | ||
|
||
@Composable | ||
internal fun AdditionalContent() { | ||
Box( | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.size(150.dp) | ||
.background(color = MisticaTheme.colors.successHighInverse.copy(alpha = 0.5f)) | ||
.border(width = 1.dp, color = MisticaTheme.colors.success), | ||
contentAlignment = Alignment.Center | ||
) { | ||
Text( | ||
text = "Additional content", | ||
style = MisticaTheme.typography.preset2, | ||
color = MisticaTheme.colors.textPrimaryInverse | ||
) | ||
} | ||
} | ||
|
||
private fun String.getOrNullIfEmpty(): String? = this.ifEmpty { null } |
Binary file not shown.
96 changes: 96 additions & 0 deletions
96
library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package com.telefonica.mistica.compose.card.postercard | ||
|
||
import androidx.annotation.DrawableRes | ||
import androidx.compose.foundation.clickable | ||
import androidx.compose.foundation.layout.Arrangement | ||
import androidx.compose.foundation.layout.BoxWithConstraints | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.Spacer | ||
import androidx.compose.foundation.layout.height | ||
import androidx.compose.foundation.layout.heightIn | ||
import androidx.compose.foundation.layout.width | ||
import androidx.compose.foundation.shape.RoundedCornerShape | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.graphics.Brush | ||
import androidx.compose.ui.unit.Dp | ||
import androidx.compose.ui.unit.dp | ||
import androidx.compose.ui.zIndex | ||
import com.telefonica.mistica.compose.tag.Tag | ||
import com.telefonica.mistica.compose.theme.MisticaTheme | ||
|
||
@Composable | ||
fun PosterCard( | ||
aspectRatio: PosterCardAspectRatio, | ||
backgroundType: PosterCardBackgroundType, | ||
modifier: Modifier = Modifier, | ||
headline: Tag? = null, | ||
preTitle: String? = null, | ||
title: String? = null, | ||
subtitle: String? = null, | ||
description: String? = null, | ||
firstTopAction: TopActionData? = null, | ||
secondTopAction: TopActionData? = null, | ||
onClickAction: (() -> Unit)? = null, | ||
customContent: (@Composable () -> Unit)? = null, | ||
) { | ||
val anyTopActionsLoaded = firstTopAction != null || secondTopAction != null | ||
|
||
BoxWithConstraints(modifier = modifier) { | ||
androidx.compose.material.Card( | ||
elevation = 0.dp, | ||
shape = RoundedCornerShape(MisticaTheme.radius.containerBorderRadius), | ||
modifier = Modifier | ||
.width(maxWidth) | ||
.clickable(enabled = onClickAction != null) { | ||
onClickAction?.invoke() | ||
} | ||
.heightIn( | ||
min = maxWidth / aspectRatio.ratio, | ||
max = Dp.Infinity | ||
) | ||
) { | ||
PosterCardBackground(backgroundType = backgroundType) { | ||
Column( | ||
modifier = Modifier.align(alignment = Alignment.BottomCenter), | ||
verticalArrangement = Arrangement.Bottom | ||
) { | ||
if (anyTopActionsLoaded) { | ||
Spacer(modifier = Modifier.height(40.dp)) | ||
} | ||
PosterCardMainContent( | ||
backgroundType = backgroundType, | ||
tag = headline, | ||
preTitle = preTitle, | ||
title = title, | ||
description = description, | ||
subtitle = subtitle, | ||
customContent = customContent | ||
) | ||
} | ||
if (anyTopActionsLoaded) { | ||
PosterCardTopActions( | ||
modifier = Modifier.align(alignment = Alignment.TopCenter).zIndex(1f), | ||
firstTopAction = firstTopAction, | ||
secondTopAction = secondTopAction | ||
) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
enum class PosterCardAspectRatio(val ratio: Float) { | ||
AR_AUTO(ratio = Float.NaN), | ||
AR_1_1(ratio = 1f), | ||
AR_7_10(ratio = 0.7f), | ||
AR_9_10(ratio = 0.9f), | ||
AR_16_9(16 / 9f) | ||
} | ||
|
||
sealed class PosterCardBackgroundType(open var inverseDisplay: Boolean) { | ||
data class Image(@DrawableRes val imageResource: Int, val contentDescription: String = "") : PosterCardBackgroundType(inverseDisplay = true) | ||
data class Color(val brush: Brush, override var inverseDisplay: Boolean = true) : PosterCardBackgroundType(inverseDisplay = inverseDisplay) | ||
} | ||
|
Oops, something went wrong.