From adb61a788c26aaee311934d3f0e41f6dc93c2330 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Tue, 19 Nov 2024 15:43:29 +0100 Subject: [PATCH 01/39] dhonti/ANDROID-15405-postercard: First approach "PosterCard" component --- .../compose/card/postercard/PosterCard.kt | 74 +++++++++++++ .../card/postercard/PosterCardMainContent.kt | 103 +++++++++++++++++ .../card/postercard/PosterCardTextContent.kt | 104 ++++++++++++++++++ .../card/postercard/PosterCardTopContent.kt | 29 +++++ 4 files changed, 310 insertions(+) create mode 100644 library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt create mode 100644 library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt create mode 100644 library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt create mode 100644 library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopContent.kt diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt new file mode 100644 index 000000000..ef06c7748 --- /dev/null +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -0,0 +1,74 @@ +package com.telefonica.mistica.compose.card.postercard + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +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.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.telefonica.mistica.compose.tag.Tag +import com.telefonica.mistica.compose.theme.MisticaTheme +import com.telefonica.mistica.compose.theme.brand.TuBrand + +@Composable +fun PosterCard( + modifier: Modifier = Modifier, + aspectRatio: PosterCardAspectRatio, + backgroundType: PosterCardBackgroundType, + headline: Tag? = null, + preTitle: String? = null, + title: String? = null, + subtitle: String? = null, + description: String? = null, + customContent: @Composable () -> Unit = {}, + iconOrTopActions: @Composable (() -> Unit) ? = null, +) { + PosterCardMainContent( + modifier = modifier, + aspectRatio = aspectRatio, + backgroundType = backgroundType, + preTitle = preTitle, + title = title, + subtitle = subtitle, + description = description, + headline = headline, + customContent = customContent, + iconOrTopActions = iconOrTopActions + ) +} + +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 val inverseDisplay: Boolean) { + data class Image(val imageResource: Int, val contentDescription: String = "") : PosterCardBackgroundType(inverseDisplay = true) + data class Video(val videoContent: @Composable (() -> Unit)) : PosterCardBackgroundType(inverseDisplay = true) + data class Color(val brush: Brush, override val inverseDisplay: Boolean = true) : PosterCardBackgroundType(inverseDisplay = inverseDisplay) +} + +@Preview +@Composable +internal fun PosterCardSampleContent() { + MisticaTheme(brand = TuBrand) { + PosterCard( + modifier = Modifier.width(6000.dp).background(color = Color.Black), + iconOrTopActions = {}, + aspectRatio = PosterCardAspectRatio.AR_9_10, + backgroundType = PosterCardBackgroundType.Color(brush = SolidColor(Color.Red), inverseDisplay = false), + headline = Tag(content = "Headline"), + preTitle = "Pretitle", + title = "Title", + subtitle = "Subtitle", + description = "Description", + ) + } +} diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt new file mode 100644 index 000000000..e962691f6 --- /dev/null +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt @@ -0,0 +1,103 @@ +package com.telefonica.mistica.compose.card.postercard + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxSize +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.graphics.Color +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.unit.dp +import com.telefonica.mistica.compose.tag.Tag +import com.telefonica.mistica.compose.theme.MisticaTheme + +@Composable +internal fun PosterCardMainContent( + modifier: Modifier = Modifier, + aspectRatio: PosterCardAspectRatio = PosterCardAspectRatio.AR_7_10, + backgroundType: PosterCardBackgroundType, + headline: Tag? = null, + preTitle: String? = null, + title: String? = null, + subtitle: String? = null, + description: String? = null, + customContent: @Composable () -> Unit = {}, + iconOrTopActions: @Composable (() -> Unit)? = null, +) { + androidx.compose.material.Card( + elevation = 0.dp, + shape = RoundedCornerShape(MisticaTheme.radius.containerBorderRadius), + modifier = modifier.let { modifierValue -> + if (!aspectRatio.ratio.isNaN()) { + modifierValue.aspectRatio(aspectRatio.ratio) + } else { + modifierValue + } + }, + ) { + PosterCardBackground(backgroundType = backgroundType) { + Box(modifier = Modifier.fillMaxSize()) { + iconOrTopActions?.let { + PosterCardTopContent( + modifier = Modifier.align(alignment = Alignment.TopCenter), + ) + } + PosterCardTextContent( + modifier = Modifier.align(alignment = Alignment.BottomCenter), + backgroundType = backgroundType, + tag = headline, + preTitle = preTitle, + title = title, + description = description, + subtitle = subtitle + ) + customContent() + } + } + } +} + +@Composable +fun PosterCardBackground(backgroundType: PosterCardBackgroundType, content: @Composable () -> Unit) { + Box( + modifier = Modifier + .fillMaxSize() + .background( + brush = if (backgroundType is PosterCardBackgroundType.Color) { + backgroundType.brush + } else { + SolidColor(Color.Transparent) + } + ) + ) { + when (backgroundType) { + is PosterCardBackgroundType.Image -> { + //TODO: + } + + is PosterCardBackgroundType.Video -> { + //TODO: + } + + else -> {} + } + content() + } +} + +fun buildCardTextContentBackgroundBrush(backgroundType: PosterCardBackgroundType): Brush = + if (backgroundType is PosterCardBackgroundType.Color) { + SolidColor(Color.Transparent) + } else { + Brush.verticalGradient( + colorStops = arrayOf( + 0.0f to Color.Black.copy(alpha = 0f), + 0.3f to Color.Black.copy(alpha = 0.4f), + 1.0f to Color.Black.copy(alpha = 0.7f) + ) + ) + } \ No newline at end of file diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt new file mode 100644 index 000000000..05ea248ce --- /dev/null +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt @@ -0,0 +1,104 @@ +package com.telefonica.mistica.compose.card.postercard + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shadow +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.dp +import com.telefonica.mistica.compose.tag.Tag +import com.telefonica.mistica.compose.theme.MisticaTheme + +@Composable +internal fun PosterCardTextContent( + modifier: Modifier = Modifier, + backgroundType: PosterCardBackgroundType, + tag: Tag?, + preTitle: String?, + title: String?, + subtitle: String?, + description: String?, +) { + Column( + modifier = modifier + .fillMaxWidth() + .background(brush = buildCardTextContentBackgroundBrush(backgroundType = backgroundType)) + .padding( + top = 4.dp, + start = 16.dp, + end = 16.dp, + bottom = 24.dp, + ) + ) { + if (tag != null) { + Box(modifier = Modifier.padding(top = 8.dp, bottom = 8.dp)) { + tag.build() + } + } + + preTitle?.let { + PosterCardText( + modifier = Modifier.padding(top = 16.dp), + textValue = preTitle, + textStyle = MisticaTheme.typography.preset1, + inverseDisplay = backgroundType.inverseDisplay + ) + } + + title?.let { + PosterCardText( + modifier = Modifier.padding(top = 4.dp), + textValue = title, + textStyle = MisticaTheme.typography.presetCardTitle, + inverseDisplay = backgroundType.inverseDisplay + ) + } + subtitle?.let { + PosterCardText( + modifier = Modifier.padding(top = 4.dp), + textValue = subtitle, + textStyle = MisticaTheme.typography.preset2, + inverseDisplay = backgroundType.inverseDisplay + ) + } + description?.let { + PosterCardText( + modifier = Modifier.padding(top = 8.dp), + textValue = description, + textStyle = MisticaTheme.typography.preset2, + inverseDisplay = backgroundType.inverseDisplay + ) + } + } +} + +@Composable +internal fun PosterCardText(modifier: Modifier = Modifier, textValue: String, textStyle: TextStyle, inverseDisplay: Boolean) { + Text( + modifier = modifier, + text = textValue, + style = textStyle.apply { + if (inverseDisplay) { + copy(shadow = buildPosterCardShadow()) + } + }, + color = if (inverseDisplay) { + MisticaTheme.colors.textPrimaryInverse + } else { + MisticaTheme.colors.textPrimary + } + ) +} + +internal fun buildPosterCardShadow() = Shadow( + color = Color.Black.copy(alpha = 0.4f), + offset = Offset(x = 0f, y = 0f), + blurRadius = 15f +) \ No newline at end of file diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopContent.kt new file mode 100644 index 000000000..3cac8d546 --- /dev/null +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopContent.kt @@ -0,0 +1,29 @@ +package com.telefonica.mistica.compose.card.postercard + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp + +@Composable +fun PosterCardTopContent(modifier: Modifier = Modifier){ + Row( + modifier = modifier + .fillMaxWidth() + .background(color = Color.Gray) + .padding(top = 16.dp, start = 16.dp, end = 16.dp, bottom = 40.dp) + ) { + Spacer( + modifier = Modifier + .fillMaxWidth() + .background(color = Color.Green) + .height(30.dp) + ) + } +} \ No newline at end of file From e2c7a55d2c07c9473068b138a7dd69db08a24d79 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Tue, 19 Nov 2024 17:14:36 +0100 Subject: [PATCH 02/39] dhonti/ANDROID-15405: Update approach in order to accept images --- .../compose/card/postercard/PosterCard.kt | 9 +++++---- .../card/postercard/PosterCardMainContent.kt | 18 +++++++++++++----- .../card/postercard/PosterCardTextContent.kt | 15 +++++++++------ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index ef06c7748..92f8556d0 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -10,6 +10,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.telefonica.mistica.R import com.telefonica.mistica.compose.tag.Tag import com.telefonica.mistica.compose.theme.MisticaTheme import com.telefonica.mistica.compose.theme.brand.TuBrand @@ -55,15 +56,15 @@ sealed class PosterCardBackgroundType(open val inverseDisplay: Boolean) { data class Color(val brush: Brush, override val inverseDisplay: Boolean = true) : PosterCardBackgroundType(inverseDisplay = inverseDisplay) } -@Preview +@Preview(showSystemUi = true) @Composable internal fun PosterCardSampleContent() { MisticaTheme(brand = TuBrand) { PosterCard( - modifier = Modifier.width(6000.dp).background(color = Color.Black), - iconOrTopActions = {}, +// iconOrTopActions = {}, aspectRatio = PosterCardAspectRatio.AR_9_10, - backgroundType = PosterCardBackgroundType.Color(brush = SolidColor(Color.Red), inverseDisplay = false), +// backgroundType = PosterCardBackgroundType.Color(brush = SolidColor(Color.Red), inverseDisplay = true), + backgroundType = PosterCardBackgroundType.Image(imageResource = R.drawable.sample_background), headline = Tag(content = "Headline"), preTitle = "Pretitle", title = "Title", diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt index e962691f6..db025c553 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt @@ -1,5 +1,6 @@ package com.telefonica.mistica.compose.card.postercard +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.aspectRatio @@ -11,6 +12,8 @@ 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.layout.ContentScale +import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.telefonica.mistica.compose.tag.Tag import com.telefonica.mistica.compose.theme.MisticaTheme @@ -71,12 +74,17 @@ fun PosterCardBackground(backgroundType: PosterCardBackgroundType, content: @Com backgroundType.brush } else { SolidColor(Color.Transparent) - } + }, ) ) { when (backgroundType) { is PosterCardBackgroundType.Image -> { - //TODO: + Image( + modifier = Modifier.fillMaxSize(), + painter = painterResource(id = backgroundType.imageResource), + contentDescription = backgroundType.contentDescription, + contentScale = ContentScale.Crop + ) } is PosterCardBackgroundType.Video -> { @@ -90,9 +98,7 @@ fun PosterCardBackground(backgroundType: PosterCardBackgroundType, content: @Com } fun buildCardTextContentBackgroundBrush(backgroundType: PosterCardBackgroundType): Brush = - if (backgroundType is PosterCardBackgroundType.Color) { - SolidColor(Color.Transparent) - } else { + if( backgroundType.inverseDisplay ) { Brush.verticalGradient( colorStops = arrayOf( 0.0f to Color.Black.copy(alpha = 0f), @@ -100,4 +106,6 @@ fun buildCardTextContentBackgroundBrush(backgroundType: PosterCardBackgroundType 1.0f to Color.Black.copy(alpha = 0.7f) ) ) + } else { + SolidColor(Color.Transparent) } \ No newline at end of file diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt index 05ea248ce..1e7d1e288 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt @@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shadow import androidx.compose.ui.text.TextStyle @@ -80,13 +79,18 @@ internal fun PosterCardTextContent( } @Composable -internal fun PosterCardText(modifier: Modifier = Modifier, textValue: String, textStyle: TextStyle, inverseDisplay: Boolean) { +internal fun PosterCardText( + modifier: Modifier = Modifier, + textValue: String, + textStyle: TextStyle, + inverseDisplay: Boolean, +) { Text( modifier = modifier, text = textValue, - style = textStyle.apply { + style = textStyle.also { style -> if (inverseDisplay) { - copy(shadow = buildPosterCardShadow()) + style.copy(shadow = buildPosterCardTextShadow()) } }, color = if (inverseDisplay) { @@ -97,8 +101,7 @@ internal fun PosterCardText(modifier: Modifier = Modifier, textValue: String, te ) } -internal fun buildPosterCardShadow() = Shadow( +internal fun buildPosterCardTextShadow() = Shadow( color = Color.Black.copy(alpha = 0.4f), - offset = Offset(x = 0f, y = 0f), blurRadius = 15f ) \ No newline at end of file From 45088eac680f1e333db2a508a4f0fe4c0ba7c783 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Wed, 20 Nov 2024 09:48:56 +0100 Subject: [PATCH 03/39] dhonti/ANDROID-15405-postercard: Fix viewing correctly lower custom content Composable and reorganizing current composables in package --- .../compose/card/postercard/PosterCard.kt | 84 ++++++++-------- ...MainContent.kt => PosterCardBackground.kt} | 52 ---------- .../card/postercard/PosterCardPreviews.kt | 99 +++++++++++++++++++ .../card/postercard/PosterCardTextContent.kt | 12 ++- .../card/postercard/PosterCardTopContent.kt | 2 +- 5 files changed, 156 insertions(+), 93 deletions(-) rename library/src/main/java/com/telefonica/mistica/compose/card/postercard/{PosterCardMainContent.kt => PosterCardBackground.kt} (51%) create mode 100644 library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 92f8556d0..c28d772a6 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -1,19 +1,20 @@ package com.telefonica.mistica.compose.card.postercard -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.width +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +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.graphics.Color -import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.telefonica.mistica.R import com.telefonica.mistica.compose.tag.Tag import com.telefonica.mistica.compose.theme.MisticaTheme -import com.telefonica.mistica.compose.theme.brand.TuBrand @Composable fun PosterCard( @@ -25,21 +26,44 @@ fun PosterCard( title: String? = null, subtitle: String? = null, description: String? = null, - customContent: @Composable () -> Unit = {}, + customContent: (@Composable () -> Unit)? = null, iconOrTopActions: @Composable (() -> Unit) ? = null, ) { - PosterCardMainContent( - modifier = modifier, - aspectRatio = aspectRatio, - backgroundType = backgroundType, - preTitle = preTitle, - title = title, - subtitle = subtitle, - description = description, - headline = headline, - customContent = customContent, - iconOrTopActions = iconOrTopActions - ) + androidx.compose.material.Card( + elevation = 0.dp, + shape = RoundedCornerShape(MisticaTheme.radius.containerBorderRadius), + border = BorderStroke(width = 1.dp, color = MisticaTheme.colors.border), + modifier = modifier.let { modifierValue -> + if (!aspectRatio.ratio.isNaN()) { + modifierValue.aspectRatio(aspectRatio.ratio) + } else { + modifierValue + } + }, + ) { + PosterCardBackground(backgroundType = backgroundType) { + Box(modifier = Modifier.fillMaxSize()) { + iconOrTopActions?.let { + PosterCardTopContent(modifier = Modifier.align(alignment = Alignment.TopCenter)) + } + Column( + modifier = Modifier.align(alignment = Alignment.BottomCenter), + verticalArrangement = Arrangement.Bottom + ){ + PosterCardTextContent( + backgroundType = backgroundType, + tag = headline, + preTitle = preTitle, + title = title, + description = description, + subtitle = subtitle, + customContent = customContent + ) + + } + } + } + } } enum class PosterCardAspectRatio(val ratio: Float) { @@ -55,21 +79,3 @@ sealed class PosterCardBackgroundType(open val inverseDisplay: Boolean) { data class Video(val videoContent: @Composable (() -> Unit)) : PosterCardBackgroundType(inverseDisplay = true) data class Color(val brush: Brush, override val inverseDisplay: Boolean = true) : PosterCardBackgroundType(inverseDisplay = inverseDisplay) } - -@Preview(showSystemUi = true) -@Composable -internal fun PosterCardSampleContent() { - MisticaTheme(brand = TuBrand) { - PosterCard( -// iconOrTopActions = {}, - aspectRatio = PosterCardAspectRatio.AR_9_10, -// backgroundType = PosterCardBackgroundType.Color(brush = SolidColor(Color.Red), inverseDisplay = true), - backgroundType = PosterCardBackgroundType.Image(imageResource = R.drawable.sample_background), - headline = Tag(content = "Headline"), - preTitle = "Pretitle", - title = "Title", - subtitle = "Subtitle", - description = "Description", - ) - } -} diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt similarity index 51% rename from library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt rename to library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt index db025c553..597ec5af0 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt @@ -3,66 +3,14 @@ package com.telefonica.mistica.compose.card.postercard import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize -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.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp -import com.telefonica.mistica.compose.tag.Tag -import com.telefonica.mistica.compose.theme.MisticaTheme - -@Composable -internal fun PosterCardMainContent( - modifier: Modifier = Modifier, - aspectRatio: PosterCardAspectRatio = PosterCardAspectRatio.AR_7_10, - backgroundType: PosterCardBackgroundType, - headline: Tag? = null, - preTitle: String? = null, - title: String? = null, - subtitle: String? = null, - description: String? = null, - customContent: @Composable () -> Unit = {}, - iconOrTopActions: @Composable (() -> Unit)? = null, -) { - androidx.compose.material.Card( - elevation = 0.dp, - shape = RoundedCornerShape(MisticaTheme.radius.containerBorderRadius), - modifier = modifier.let { modifierValue -> - if (!aspectRatio.ratio.isNaN()) { - modifierValue.aspectRatio(aspectRatio.ratio) - } else { - modifierValue - } - }, - ) { - PosterCardBackground(backgroundType = backgroundType) { - Box(modifier = Modifier.fillMaxSize()) { - iconOrTopActions?.let { - PosterCardTopContent( - modifier = Modifier.align(alignment = Alignment.TopCenter), - ) - } - PosterCardTextContent( - modifier = Modifier.align(alignment = Alignment.BottomCenter), - backgroundType = backgroundType, - tag = headline, - preTitle = preTitle, - title = title, - description = description, - subtitle = subtitle - ) - customContent() - } - } - } -} @Composable fun PosterCardBackground(backgroundType: PosterCardBackgroundType, content: @Composable () -> Unit) { diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt new file mode 100644 index 000000000..d9dadce47 --- /dev/null +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt @@ -0,0 +1,99 @@ +package com.telefonica.mistica.compose.card.postercard + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +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.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.telefonica.mistica.R +import com.telefonica.mistica.compose.tag.Tag +import com.telefonica.mistica.compose.theme.MisticaTheme +import com.telefonica.mistica.compose.theme.brand.TuBrand + +@Preview +@Composable +internal fun PosterCardSolidColor() { + MisticaTheme(brand = TuBrand) { + PosterCard( +// iconOrTopActions = {}, + modifier = Modifier.width(300.dp), + aspectRatio = PosterCardAspectRatio.AR_1_1, + backgroundType = PosterCardBackgroundType.Color(brush = SolidColor(MisticaTheme.colors.background), inverseDisplay = false), + headline = Tag(content = TAG_HEADLINE_VALUE), + preTitle = PRE_TITLE_VALUE, + title = TITLE_VALUE, + subtitle = SUBTITLE_VALUE, + description = DESCRIPTION_VALUE, + ) + } +} + +@Preview +@Composable +internal fun PosterCardGradientColor() { + MisticaTheme(brand = TuBrand) { + PosterCard( +// iconOrTopActions = {}, + modifier = Modifier.width(300.dp), + aspectRatio = PosterCardAspectRatio.AR_1_1, + backgroundType = PosterCardBackgroundType.Color( + brush = Brush.verticalGradient(colors = listOf(Color.Blue, Color.LightGray)), inverseDisplay = + true + ), + headline = Tag(content = TAG_HEADLINE_VALUE), + preTitle = PRE_TITLE_VALUE, + title = TITLE_VALUE, + subtitle = SUBTITLE_VALUE, + description = DESCRIPTION_VALUE + ) + } +} + +@Preview +@Composable +internal fun PosterCardSampleContent() { + MisticaTheme(brand = TuBrand) { + PosterCard( +// iconOrTopActions = {}, + modifier = Modifier + .fillMaxWidth() + .height(300.dp), + aspectRatio = PosterCardAspectRatio.AR_AUTO, + backgroundType = PosterCardBackgroundType.Image(imageResource = R.drawable.sample_background), + headline = Tag(content = TAG_HEADLINE_VALUE), + preTitle = PRE_TITLE_VALUE, + title = TITLE_VALUE, + subtitle = SUBTITLE_VALUE, + description = DESCRIPTION_VALUE, + customContent = { + CustomLowerContent() + } + ) + } +} + +@Composable +internal fun CustomLowerContent() { + Spacer( + modifier = Modifier + .fillMaxWidth() + .size(30.dp) + .background(color = MisticaTheme.colors.successHighInverse.copy(alpha = 0.5f)) + .border(width = 1.dp, color = MisticaTheme.colors.success) + ) +} + +private const val TAG_HEADLINE_VALUE = "Headline" +private const val PRE_TITLE_VALUE = "Pretitle" +private const val TITLE_VALUE = "Title" +private const val SUBTITLE_VALUE = "Subtitle" +private const val DESCRIPTION_VALUE = "Description" \ No newline at end of file diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt index 1e7d1e288..7b6517a47 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt @@ -24,6 +24,7 @@ internal fun PosterCardTextContent( title: String?, subtitle: String?, description: String?, + customContent: (@Composable () -> Unit)? = null, ) { Column( modifier = modifier @@ -33,7 +34,11 @@ internal fun PosterCardTextContent( top = 4.dp, start = 16.dp, end = 16.dp, - bottom = 24.dp, + bottom = if (customContent != null) { + 0.dp + } else { + 24.dp + }, ) ) { if (tag != null) { @@ -75,6 +80,11 @@ internal fun PosterCardTextContent( inverseDisplay = backgroundType.inverseDisplay ) } + customContent?.let { + Box(modifier = Modifier.padding(top = 4.dp, bottom = 24.dp)) { + it() + } + } } } diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopContent.kt index 3cac8d546..d73eb9edb 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopContent.kt @@ -12,7 +12,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp @Composable -fun PosterCardTopContent(modifier: Modifier = Modifier){ +internal fun PosterCardTopContent(modifier: Modifier = Modifier){ Row( modifier = modifier .fillMaxWidth() From 4402233b5b0833339a9867c775230eec49be66fa Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Wed, 20 Nov 2024 17:08:23 +0100 Subject: [PATCH 04/39] dhonti/ANDROID-15405-postercard: Integration new "TopActions" attributos --- .../compose/card/postercard/PosterCard.kt | 51 +++++++++-------- .../card/postercard/PosterCardBackground.kt | 3 +- .../card/postercard/PosterCardPreviews.kt | 56 +++++++++++++------ .../card/postercard/PosterCardTextContent.kt | 4 +- .../card/postercard/PosterCardTopActions.kt | 46 +++++++++++++++ .../card/postercard/PosterCardTopContent.kt | 29 ---------- 6 files changed, 117 insertions(+), 72 deletions(-) create mode 100644 library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt delete mode 100644 library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopContent.kt diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index c28d772a6..63cf3de69 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -1,12 +1,10 @@ package com.telefonica.mistica.compose.card.postercard import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.aspectRatio -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -26,14 +24,19 @@ fun PosterCard( title: String? = null, subtitle: String? = null, description: String? = null, + onClickAction: (() -> Unit)? = null, customContent: (@Composable () -> Unit)? = null, - iconOrTopActions: @Composable (() -> Unit) ? = null, + firstTopAction: TopActionData? = null, + secondTopAction: TopActionData? = null, ) { androidx.compose.material.Card( elevation = 0.dp, shape = RoundedCornerShape(MisticaTheme.radius.containerBorderRadius), border = BorderStroke(width = 1.dp, color = MisticaTheme.colors.border), modifier = modifier.let { modifierValue -> + onClickAction?.let { + modifierValue.clickable { it.invoke() } + } if (!aspectRatio.ratio.isNaN()) { modifierValue.aspectRatio(aspectRatio.ratio) } else { @@ -42,25 +45,26 @@ fun PosterCard( }, ) { PosterCardBackground(backgroundType = backgroundType) { - Box(modifier = Modifier.fillMaxSize()) { - iconOrTopActions?.let { - PosterCardTopContent(modifier = Modifier.align(alignment = Alignment.TopCenter)) - } - Column( - modifier = Modifier.align(alignment = Alignment.BottomCenter), - verticalArrangement = Arrangement.Bottom - ){ - PosterCardTextContent( - backgroundType = backgroundType, - tag = headline, - preTitle = preTitle, - title = title, - description = description, - subtitle = subtitle, - customContent = customContent - ) - - } + if (firstTopAction != null || secondTopAction != null) { + PosterCardTopActions( + modifier = Modifier.align(alignment = Alignment.TopCenter), + firstTopAction = firstTopAction, + secondTopAction = secondTopAction + ) + } + Column( + modifier = Modifier.align(alignment = Alignment.BottomCenter), + verticalArrangement = Arrangement.Bottom + ) { + PosterCardTextContent( + backgroundType = backgroundType, + tag = headline, + preTitle = preTitle, + title = title, + description = description, + subtitle = subtitle, + customContent = customContent + ) } } } @@ -79,3 +83,4 @@ sealed class PosterCardBackgroundType(open val inverseDisplay: Boolean) { data class Video(val videoContent: @Composable (() -> Unit)) : PosterCardBackgroundType(inverseDisplay = true) data class Color(val brush: Brush, override val inverseDisplay: Boolean = true) : PosterCardBackgroundType(inverseDisplay = inverseDisplay) } + diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt index 597ec5af0..03158863a 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt @@ -3,6 +3,7 @@ package com.telefonica.mistica.compose.card.postercard import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -13,7 +14,7 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource @Composable -fun PosterCardBackground(backgroundType: PosterCardBackgroundType, content: @Composable () -> Unit) { +internal fun PosterCardBackground(backgroundType: PosterCardBackgroundType, content: @Composable BoxScope.() -> Unit) { Box( modifier = Modifier .fillMaxSize() diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt index d9dadce47..ee419117f 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt @@ -2,12 +2,13 @@ package com.telefonica.mistica.compose.card.postercard import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width +import androidx.compose.material.Text 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.graphics.Color @@ -15,6 +16,8 @@ import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.telefonica.mistica.R +import com.telefonica.mistica.compose.card.datacard.IconPainter +import com.telefonica.mistica.compose.card.datacard.IconType import com.telefonica.mistica.compose.tag.Tag import com.telefonica.mistica.compose.theme.MisticaTheme import com.telefonica.mistica.compose.theme.brand.TuBrand @@ -24,7 +27,6 @@ import com.telefonica.mistica.compose.theme.brand.TuBrand internal fun PosterCardSolidColor() { MisticaTheme(brand = TuBrand) { PosterCard( -// iconOrTopActions = {}, modifier = Modifier.width(300.dp), aspectRatio = PosterCardAspectRatio.AR_1_1, backgroundType = PosterCardBackgroundType.Color(brush = SolidColor(MisticaTheme.colors.background), inverseDisplay = false), @@ -42,9 +44,23 @@ internal fun PosterCardSolidColor() { internal fun PosterCardGradientColor() { MisticaTheme(brand = TuBrand) { PosterCard( -// iconOrTopActions = {}, - modifier = Modifier.width(300.dp), - aspectRatio = PosterCardAspectRatio.AR_1_1, + firstTopAction = TopActionData( + iconPainter = IconPainter.ResourceIconPainter( + iconRes = R.drawable.icn_visibility, + backgroundColor = MisticaTheme.colors.backgroundAlternative, + iconTint = MisticaTheme.colors.brand, + iconType = IconType.CIRCULAR_ASSET, + ) + ), + secondTopAction = TopActionData( + iconPainter = IconPainter.ResourceIconPainter( + iconRes = R.drawable.ic_close_regular, + backgroundColor = MisticaTheme.colors.backgroundAlternative, + iconTint = MisticaTheme.colors.brand, + iconType = IconType.CIRCULAR_ASSET, + ) + ), + aspectRatio = PosterCardAspectRatio.AR_16_9, backgroundType = PosterCardBackgroundType.Color( brush = Brush.verticalGradient(colors = listOf(Color.Blue, Color.LightGray)), inverseDisplay = true @@ -60,14 +76,11 @@ internal fun PosterCardGradientColor() { @Preview @Composable -internal fun PosterCardSampleContent() { +internal fun PosterCardImage() { MisticaTheme(brand = TuBrand) { PosterCard( -// iconOrTopActions = {}, - modifier = Modifier - .fillMaxWidth() - .height(300.dp), - aspectRatio = PosterCardAspectRatio.AR_AUTO, + modifier = Modifier.fillMaxWidth(), + aspectRatio = PosterCardAspectRatio.AR_7_10, backgroundType = PosterCardBackgroundType.Image(imageResource = R.drawable.sample_background), headline = Tag(content = TAG_HEADLINE_VALUE), preTitle = PRE_TITLE_VALUE, @@ -83,17 +96,26 @@ internal fun PosterCardSampleContent() { @Composable internal fun CustomLowerContent() { - Spacer( + Box( modifier = Modifier .fillMaxWidth() - .size(30.dp) + .size(40.dp) .background(color = MisticaTheme.colors.successHighInverse.copy(alpha = 0.5f)) - .border(width = 1.dp, color = MisticaTheme.colors.success) - ) + .border(width = 1.dp, color = MisticaTheme.colors.success), + contentAlignment = Alignment.Center + ) { + Text( + text = CUSTOM_SLOT_VALUE, + style = MisticaTheme.typography.preset2, + color = MisticaTheme.colors.textPrimaryInverse + ) + } } private const val TAG_HEADLINE_VALUE = "Headline" private const val PRE_TITLE_VALUE = "Pretitle" private const val TITLE_VALUE = "Title" private const val SUBTITLE_VALUE = "Subtitle" -private const val DESCRIPTION_VALUE = "Description" \ No newline at end of file +private const val DESCRIPTION_VALUE = "Description" + +private const val CUSTOM_SLOT_VALUE = "Custom slot" \ No newline at end of file diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt index 7b6517a47..899010a4a 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt @@ -42,14 +42,14 @@ internal fun PosterCardTextContent( ) ) { if (tag != null) { - Box(modifier = Modifier.padding(top = 8.dp, bottom = 8.dp)) { + Box(modifier = Modifier.padding(top = 8.dp, bottom = 20.dp)) { tag.build() } } preTitle?.let { PosterCardText( - modifier = Modifier.padding(top = 16.dp), + modifier = Modifier.padding(top = 4.dp), textValue = preTitle, textStyle = MisticaTheme.typography.preset1, inverseDisplay = backgroundType.inverseDisplay diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt new file mode 100644 index 000000000..696410d6f --- /dev/null +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -0,0 +1,46 @@ +package com.telefonica.mistica.compose.card.postercard + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.telefonica.mistica.compose.card.datacard.IconPainter + +@Composable +internal fun PosterCardTopActions(modifier: Modifier = Modifier, firstTopAction: TopActionData?, secondTopAction: TopActionData?) { + Row( + modifier = modifier + .fillMaxWidth() + .padding(top = 16.dp, start = 16.dp, end = 16.dp, bottom = 8.dp), + horizontalArrangement = Arrangement.End, + verticalAlignment = Alignment.CenterVertically + ) { + firstTopAction?.let { TopAction(topActionData = it) } + secondTopAction?.let { TopAction(topActionData = it) } + } +} + +@Composable +internal fun TopAction(modifier: Modifier = Modifier, topActionData: TopActionData) { + Box( + contentAlignment = Alignment.Center, + modifier = modifier + .padding(horizontal = 4.dp) + .clickable { + topActionData.onClick?.invoke() + } + ) { + topActionData.iconPainter.Paint() + } +} + +data class TopActionData( + val iconPainter: IconPainter = IconPainter.NoIconPainter, + val onClick: (() -> Unit)? = null, +) \ No newline at end of file diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopContent.kt deleted file mode 100644 index d73eb9edb..000000000 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopContent.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.telefonica.mistica.compose.card.postercard - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp - -@Composable -internal fun PosterCardTopContent(modifier: Modifier = Modifier){ - Row( - modifier = modifier - .fillMaxWidth() - .background(color = Color.Gray) - .padding(top = 16.dp, start = 16.dp, end = 16.dp, bottom = 40.dp) - ) { - Spacer( - modifier = Modifier - .fillMaxWidth() - .background(color = Color.Green) - .height(30.dp) - ) - } -} \ No newline at end of file From ff2a984bcb1de558d74af4b92c2152d3c83297ef Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Thu, 21 Nov 2024 09:40:40 +0100 Subject: [PATCH 05/39] dhonti/ANDROID-15405-postercard: Removing "Video" type from current "PosterCard" implementation. To be updated in future --- .../compose/card/postercard/PosterCard.kt | 1 - .../card/postercard/PosterCardBackground.kt | 24 +++++++------------ .../card/postercard/PosterCardPreviews.kt | 4 ++-- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 63cf3de69..955dec4b7 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -80,7 +80,6 @@ enum class PosterCardAspectRatio(val ratio: Float) { sealed class PosterCardBackgroundType(open val inverseDisplay: Boolean) { data class Image(val imageResource: Int, val contentDescription: String = "") : PosterCardBackgroundType(inverseDisplay = true) - data class Video(val videoContent: @Composable (() -> Unit)) : PosterCardBackgroundType(inverseDisplay = true) data class Color(val brush: Brush, override val inverseDisplay: Boolean = true) : PosterCardBackgroundType(inverseDisplay = inverseDisplay) } diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt index 03158863a..840fd1cae 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt @@ -26,28 +26,20 @@ internal fun PosterCardBackground(backgroundType: PosterCardBackgroundType, cont }, ) ) { - when (backgroundType) { - is PosterCardBackgroundType.Image -> { - Image( - modifier = Modifier.fillMaxSize(), - painter = painterResource(id = backgroundType.imageResource), - contentDescription = backgroundType.contentDescription, - contentScale = ContentScale.Crop - ) - } - - is PosterCardBackgroundType.Video -> { - //TODO: - } - - else -> {} + if (backgroundType is PosterCardBackgroundType.Image) { + Image( + modifier = Modifier.fillMaxSize(), + painter = painterResource(id = backgroundType.imageResource), + contentDescription = backgroundType.contentDescription, + contentScale = ContentScale.Crop + ) } content() } } fun buildCardTextContentBackgroundBrush(backgroundType: PosterCardBackgroundType): Brush = - if( backgroundType.inverseDisplay ) { + if (backgroundType.inverseDisplay) { Brush.verticalGradient( colorStops = arrayOf( 0.0f to Color.Black.copy(alpha = 0f), diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt index ee419117f..f8248330d 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt @@ -62,8 +62,8 @@ internal fun PosterCardGradientColor() { ), aspectRatio = PosterCardAspectRatio.AR_16_9, backgroundType = PosterCardBackgroundType.Color( - brush = Brush.verticalGradient(colors = listOf(Color.Blue, Color.LightGray)), inverseDisplay = - true + brush = Brush.verticalGradient(colors = listOf(Color.Blue, Color.LightGray)), + inverseDisplay = true ), headline = Tag(content = TAG_HEADLINE_VALUE), preTitle = PRE_TITLE_VALUE, From f43a07f898799ad721154f880af4231189b585ce Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Thu, 21 Nov 2024 12:46:36 +0100 Subject: [PATCH 06/39] dhonti/ANDROID-15405-postercard: Entry "PosterCard" creation in Mistica Catalog app --- .../mistica/catalog/ui/CatalogMainActivity.kt | 1 + .../catalog/ui/ComponentCatalogActivity.kt | 11 +- .../ui/compose/components/PosterCards.kt | 244 ++++++++++++++++++ 3 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/CatalogMainActivity.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/CatalogMainActivity.kt index fef4e1147..dcb2e5cf8 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/CatalogMainActivity.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/CatalogMainActivity.kt @@ -100,6 +100,7 @@ class CatalogMainActivity : AppCompatActivity() { SectionItem("Lists", R.drawable.ic_lists, Section.LISTS), SectionItem("Load Error Feedback", R.drawable.ic_load_feedback_error, Section.LOAD_ERROR_FEEDBACK), SectionItem("Media Card", R.drawable.ic_cards, Section.MEDIA_CARDS), + SectionItem("Poster Card", R.drawable.ic_cards, Section.POSTER_CARD), SectionItem("Filters", R.drawable.ic_filters, Section.FILTERS), SectionItem("PopOvers", R.drawable.ic_popovers, Section.POPOVERS), SectionItem("Scroll Content indicator", R.drawable.ic_feedbacks, Section.SCROLL_CONTENT_INDICATOR), diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/ComponentCatalogActivity.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/ComponentCatalogActivity.kt index 95805a8c8..d8891ab19 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/ComponentCatalogActivity.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/ComponentCatalogActivity.kt @@ -64,6 +64,7 @@ import com.telefonica.mistica.catalog.ui.compose.components.Lists import com.telefonica.mistica.catalog.ui.compose.components.LoadErrorFeedbacks import com.telefonica.mistica.catalog.ui.compose.components.MediaCards import com.telefonica.mistica.catalog.ui.compose.components.PopOvers +import com.telefonica.mistica.catalog.ui.compose.components.PosterCards import com.telefonica.mistica.catalog.ui.compose.components.Skeletons import com.telefonica.mistica.catalog.ui.compose.components.Steppers import com.telefonica.mistica.catalog.ui.compose.components.TabsCatalog @@ -128,7 +129,8 @@ class ComponentCatalogActivity : AppCompatActivity() { Section.CALLOUTS to ::setCalloutsCatalogFragment, Section.SHEET to ::setSheetCatalogFragment, Section.CAROUSEL to ::setCarouselFragment, - Section.SKELETON to ::setSkeletonFragment + Section.SKELETON to ::setSkeletonFragment, + Section.POSTER_CARD to ::setPosterCardFragment ) val section = intent.getSerializableExtra(EXTRA_SECTION) as? Section @@ -210,6 +212,12 @@ class ComponentCatalogActivity : AppCompatActivity() { composeComponent = { DataCards() }) } + private fun setPosterCardFragment() { + setPageAdapterWithTabs( + classicComponent = null, + composeComponent = { PosterCards() }) + } + private fun setMediaCardsFragment() { setPageAdapterWithTabs( classicComponent = MediaCardsFragment(), @@ -398,5 +406,6 @@ enum class Section { SHEET, CAROUSEL, SKELETON, + POSTER_CARD } diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt new file mode 100644 index 000000000..e66a87aa4 --- /dev/null +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt @@ -0,0 +1,244 @@ +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.R +import com.telefonica.mistica.compose.card.datacard.IconPainter +import com.telefonica.mistica.compose.card.datacard.IconType +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 backgroundType: BackgroundType by remember { mutableStateOf(BackgroundType.SOLID_COLOR) } + 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", + ) + + 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(), + customContent = { + if (withAdditionalContent) { + AdditionalContent() + } + }, + firstTopAction = topActionsType.info?.firstTopAction, + secondTopAction = topActionsType.info?.secondTopAction + ) + } +} + +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 color" +) + +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)), + SOLID_COLOR(PosterCardBackgroundType.Color(brush = SolidColor(Color.Red))), + GRADIENT_COLOR( + PosterCardBackgroundType.Color( + brush = Brush.verticalGradient(colors = listOf(Color.Blue, Color.LightGray)) + ) + ), +} + +private enum class TopActionsType(val info: PosterCardTopActionInfo? = null) { + NONE, + ONE_ACTION_DISMISS( + info = PosterCardTopActionInfo( + firstTopAction = TopActionData( + iconPainter = IconPainter.ResourceIconPainter( + iconRes = R.drawable.ic_close_regular, + backgroundColor = Color.White, + iconTint = Color.Gray, + iconType = IconType.CIRCULAR_ASSET + ) + ) + ) + ), + TWO_ACTIONS( + info = PosterCardTopActionInfo( + firstTopAction = TopActionData( + iconPainter = IconPainter.ResourceIconPainter( + iconRes = R.drawable.icn_visibility, + backgroundColor = Color.White, + iconTint = Color.Gray, + iconType = IconType.CIRCULAR_ASSET, + ) + ), + secondTopAction = TopActionData( + iconPainter = IconPainter.ResourceIconPainter( + iconRes = R.drawable.ic_close_regular, + backgroundColor = Color.White, + iconTint = Color.Gray, + iconType = IconType.CIRCULAR_ASSET, + ) + ), + ) + ) +} + +private data class PosterCardTopActionInfo( + val firstTopAction: TopActionData? = null, + val secondTopAction: TopActionData? = null, +) + +@Composable +internal fun AdditionalContent() { + Box( + modifier = Modifier + .fillMaxWidth() + .size(40.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 } \ No newline at end of file From 7eeef69f5cdf3eb8c5078ec656df5be43ad1c8b1 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Thu, 21 Nov 2024 12:47:17 +0100 Subject: [PATCH 07/39] dhonti/ANDROID-15405-postercard: Add sample background --- .../src/main/res/drawable/sample_background.jpg | Bin 0 -> 35151 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 library/src/main/res/drawable/sample_background.jpg diff --git a/library/src/main/res/drawable/sample_background.jpg b/library/src/main/res/drawable/sample_background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..95636a46bf64c7ac16f1a816970fde4b000ef4c8 GIT binary patch literal 35151 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

L_qr2} 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 literal 0 HcmV?d00001 From 8166136e4263a19324a8f167b89c770b344a82be Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Thu, 21 Nov 2024 18:02:37 +0100 Subject: [PATCH 08/39] dhonti/ANDROID-15405-postercard: Update components "TopAction" components in order to fit clickable actions --- .../ui/compose/components/PosterCards.kt | 53 +++++++++--------- .../compose/card/postercard/PosterCard.kt | 5 +- .../card/postercard/PosterCardPreviews.kt | 20 +++---- .../card/postercard/PosterCardTextContent.kt | 2 +- .../card/postercard/PosterCardTopActions.kt | 54 ++++++++++++++----- 5 files changed, 76 insertions(+), 58 deletions(-) diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt index e66a87aa4..9f7e5ce3a 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt @@ -29,8 +29,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.unit.dp import com.telefonica.mistica.R -import com.telefonica.mistica.compose.card.datacard.IconPainter -import com.telefonica.mistica.compose.card.datacard.IconType import com.telefonica.mistica.compose.card.postercard.PosterCard import com.telefonica.mistica.compose.card.postercard.PosterCardAspectRatio import com.telefonica.mistica.compose.card.postercard.PosterCardBackgroundType @@ -48,7 +46,10 @@ fun PosterCards() { 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.SOLID_COLOR) } + var topActionsType: TopActionsType by remember { mutableStateOf(TopActionsType.NONE) } var preTitle: String by remember { mutableStateOf("Pretitle") } @@ -58,6 +59,7 @@ fun PosterCards() { var withAdditionalContent: Boolean by remember { mutableStateOf(false) } + Column( modifier = Modifier .fillMaxSize() @@ -86,6 +88,16 @@ fun PosterCards() { 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() @@ -112,7 +124,7 @@ fun PosterCards() { hint = "Tag style", ) - OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = preTitle, onValueChange = { preTitle = it }, label = { Text("PreTitle") }) + 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") }) @@ -163,7 +175,7 @@ private val aspectRatioLabelsMaps = mapOf( private val backgroundTypeLabelsMap = mapOf( BackgroundType.SOLID_COLOR to "Solid color", BackgroundType.GRADIENT_COLOR to "Gradient color", - BackgroundType.IMAGE to "Image color" + BackgroundType.IMAGE to "Image" ) private val topActionsTypeLabelsMap = mapOf( @@ -175,11 +187,7 @@ private val topActionsTypeLabelsMap = mapOf( private enum class BackgroundType(val backgroundValue: PosterCardBackgroundType) { IMAGE(PosterCardBackgroundType.Image(imageResource = R.drawable.sample_background)), SOLID_COLOR(PosterCardBackgroundType.Color(brush = SolidColor(Color.Red))), - GRADIENT_COLOR( - PosterCardBackgroundType.Color( - brush = Brush.verticalGradient(colors = listOf(Color.Blue, Color.LightGray)) - ) - ), + GRADIENT_COLOR(PosterCardBackgroundType.Color(brush = Brush.verticalGradient(colors = listOf(Color.Blue, Color.LightGray)))), } private enum class TopActionsType(val info: PosterCardTopActionInfo? = null) { @@ -187,32 +195,23 @@ private enum class TopActionsType(val info: PosterCardTopActionInfo? = null) { ONE_ACTION_DISMISS( info = PosterCardTopActionInfo( firstTopAction = TopActionData( - iconPainter = IconPainter.ResourceIconPainter( - iconRes = R.drawable.ic_close_regular, - backgroundColor = Color.White, - iconTint = Color.Gray, - iconType = IconType.CIRCULAR_ASSET - ) + iconRes = R.drawable.ic_close_regular, + backgroundColor = Color.White, + iconTint = Color.Gray, ) ) ), TWO_ACTIONS( info = PosterCardTopActionInfo( firstTopAction = TopActionData( - iconPainter = IconPainter.ResourceIconPainter( - iconRes = R.drawable.icn_visibility, - backgroundColor = Color.White, - iconTint = Color.Gray, - iconType = IconType.CIRCULAR_ASSET, - ) + iconRes = R.drawable.icn_visibility, + backgroundColor = Color.White, + iconTint = Color.Gray ), secondTopAction = TopActionData( - iconPainter = IconPainter.ResourceIconPainter( - iconRes = R.drawable.ic_close_regular, - backgroundColor = Color.White, - iconTint = Color.Gray, - iconType = IconType.CIRCULAR_ASSET, - ) + iconRes = R.drawable.ic_close_regular, + backgroundColor = Color.White, + iconTint = Color.Gray ), ) ) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 955dec4b7..dd24a06f1 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -78,8 +79,8 @@ enum class PosterCardAspectRatio(val ratio: Float) { AR_16_9(16 / 9f) } -sealed class PosterCardBackgroundType(open val inverseDisplay: Boolean) { +sealed class PosterCardBackgroundType(open var inverseDisplay: Boolean) { data class Image(val imageResource: Int, val contentDescription: String = "") : PosterCardBackgroundType(inverseDisplay = true) - data class Color(val brush: Brush, override val inverseDisplay: Boolean = true) : PosterCardBackgroundType(inverseDisplay = inverseDisplay) + data class Color(val brush: Brush, override var inverseDisplay: Boolean = true) : PosterCardBackgroundType(inverseDisplay = inverseDisplay) } diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt index f8248330d..1b5bed866 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt @@ -16,8 +16,6 @@ import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.telefonica.mistica.R -import com.telefonica.mistica.compose.card.datacard.IconPainter -import com.telefonica.mistica.compose.card.datacard.IconType import com.telefonica.mistica.compose.tag.Tag import com.telefonica.mistica.compose.theme.MisticaTheme import com.telefonica.mistica.compose.theme.brand.TuBrand @@ -45,20 +43,14 @@ internal fun PosterCardGradientColor() { MisticaTheme(brand = TuBrand) { PosterCard( firstTopAction = TopActionData( - iconPainter = IconPainter.ResourceIconPainter( - iconRes = R.drawable.icn_visibility, - backgroundColor = MisticaTheme.colors.backgroundAlternative, - iconTint = MisticaTheme.colors.brand, - iconType = IconType.CIRCULAR_ASSET, - ) + iconRes = R.drawable.icn_visibility, + backgroundColor = MisticaTheme.colors.backgroundAlternative, + iconTint = MisticaTheme.colors.brand, ), secondTopAction = TopActionData( - iconPainter = IconPainter.ResourceIconPainter( - iconRes = R.drawable.ic_close_regular, - backgroundColor = MisticaTheme.colors.backgroundAlternative, - iconTint = MisticaTheme.colors.brand, - iconType = IconType.CIRCULAR_ASSET, - ) + iconRes = R.drawable.ic_close_regular, + backgroundColor = MisticaTheme.colors.backgroundAlternative, + iconTint = MisticaTheme.colors.brand, ), aspectRatio = PosterCardAspectRatio.AR_16_9, backgroundType = PosterCardBackgroundType.Color( diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt index 899010a4a..f2b612035 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt @@ -31,7 +31,7 @@ internal fun PosterCardTextContent( .fillMaxWidth() .background(brush = buildCardTextContentBackgroundBrush(backgroundType = backgroundType)) .padding( - top = 4.dp, + top = 16.dp, start = 16.dp, end = 16.dp, bottom = if (customContent != null) { diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index 696410d6f..41e2cf13e 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -1,16 +1,27 @@ package com.telefonica.mistica.compose.card.postercard +import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.shape.CircleShape 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.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp -import com.telefonica.mistica.compose.card.datacard.IconPainter @Composable internal fun PosterCardTopActions(modifier: Modifier = Modifier, firstTopAction: TopActionData?, secondTopAction: TopActionData?) { @@ -21,26 +32,41 @@ internal fun PosterCardTopActions(modifier: Modifier = Modifier, firstTopAction: horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically ) { - firstTopAction?.let { TopAction(topActionData = it) } - secondTopAction?.let { TopAction(topActionData = it) } + firstTopAction?.let { + TopAction(topActionData = it) + } + secondTopAction?.let { + Spacer(modifier = Modifier.width(16.dp)) + TopAction(topActionData = it) + } } } @Composable -internal fun TopAction(modifier: Modifier = Modifier, topActionData: TopActionData) { - Box( - contentAlignment = Alignment.Center, - modifier = modifier - .padding(horizontal = 4.dp) - .clickable { - topActionData.onClick?.invoke() - } - ) { - topActionData.iconPainter.Paint() +internal fun TopAction(topActionData: TopActionData) { + with(topActionData) { + Box( + modifier = Modifier + .size(40.dp) + .clip(CircleShape) + .background(color = backgroundColor) + .clickable { topActionData.onClick?.invoke() } + .wrapContentSize(align = Alignment.Center) + ) { + Image( + painter = painterResource(id = iconRes), + contentDescription = contentDescription, + colorFilter = iconTint?.let { ColorFilter.tint(iconTint) }, + contentScale = ContentScale.Crop + ) + } } } data class TopActionData( - val iconPainter: IconPainter = IconPainter.NoIconPainter, + val iconRes: Int, + val iconTint: Color?, + val backgroundColor: Color = Color.Transparent, + val contentDescription: String? = null, val onClick: (() -> Unit)? = null, ) \ No newline at end of file From c74285e7dd0900180a4ada571d56601e72f05598 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Fri, 22 Nov 2024 10:37:23 +0100 Subject: [PATCH 09/39] dhonti/ANDROID-15405-postercard: Update some components --- .../compose/card/postercard/PosterCard.kt | 5 ++--- ...extContent.kt => PosterCardMainContent.kt} | 2 +- .../main/res/drawable/sample_background.jpg | Bin 35151 -> 29995 bytes 3 files changed, 3 insertions(+), 4 deletions(-) rename library/src/main/java/com/telefonica/mistica/compose/card/postercard/{PosterCardTextContent.kt => PosterCardMainContent.kt} (99%) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index dd24a06f1..508bba81a 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -5,7 +5,6 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.aspectRatio -import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -32,7 +31,7 @@ fun PosterCard( ) { androidx.compose.material.Card( elevation = 0.dp, - shape = RoundedCornerShape(MisticaTheme.radius.containerBorderRadius), + shape = RoundedCornerShape(16.dp), border = BorderStroke(width = 1.dp, color = MisticaTheme.colors.border), modifier = modifier.let { modifierValue -> onClickAction?.let { @@ -57,7 +56,7 @@ fun PosterCard( modifier = Modifier.align(alignment = Alignment.BottomCenter), verticalArrangement = Arrangement.Bottom ) { - PosterCardTextContent( + PosterCardMainContent( backgroundType = backgroundType, tag = headline, preTitle = preTitle, diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt similarity index 99% rename from library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt rename to library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt index f2b612035..3b896b533 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTextContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt @@ -16,7 +16,7 @@ import com.telefonica.mistica.compose.tag.Tag import com.telefonica.mistica.compose.theme.MisticaTheme @Composable -internal fun PosterCardTextContent( +internal fun PosterCardMainContent( modifier: Modifier = Modifier, backgroundType: PosterCardBackgroundType, tag: Tag?, diff --git a/library/src/main/res/drawable/sample_background.jpg b/library/src/main/res/drawable/sample_background.jpg index 95636a46bf64c7ac16f1a816970fde4b000ef4c8..a425b181d7ee133e9b461277b5634d8c4dc66269 100644 GIT binary patch literal 29995 zcmb5VcRZE0Mv|BG>lYdUjZ%vprQJA0RQ)( zqNbreM|U24QsD|fO-)5h4balj08}*8|8A)nZ__YIs2bSQN_xIxzGIkMGki`h?kOEh zJGU1rkCe30rh5F`zlFgi|F`o0T^D@szlAS=Pl_=9?~>rs)ZpKB?%&0!7^!KPZcC`r zG8@>RW4Qw^o~vdUSF_oEHU%)yP=UWO4I`ie9Me+r*K`1dr~=XpyZ20Y1A1IrX8A%-G44}-S$z# zW`Egp+s&Ueii-_V`>uO@GMk$=ZHI1DH*4#Tp<*L9kAlPqM`^&r(*OM^mtS-!Oto5m z22kHP1IUGWxMYeOl}c@OfPPV`7#wljr0{^xU-&r^QBTmwv@&x%z4nZMYdJ?&=zCVHW^YrDRR*$Znjz z1r#0u)cLdL{?N_X-4}4OVH)%Jw#Y{j`?gZej8-8FZ-snU+%G%>CSr`&EQU{Q&j3=# z8BliyV3H&|4IX})OP^aljaD{n%Tv^zAmllH`Tk@>{kEbYsVJFtRhS_Bez)U@v-Avj zIfy>}TC7eY>y&izn{s`k7kcwZ(KW&19sEtRk4sj{Uckl43TFKnt!7CQ`9(HT9QKa- zA%4i&e=S;p-#3Ruz6gIM-Q>eVksw~^MA<;<_nCYkME9$7H#Q!S-bxVYIML7vjD7~S z4@4Z0P3Bc*0F-Vii6r*48(&`iQ z86aOPBWbsmiwdIK&_Mk?`tW+O(% zg#K!w@lkhgIsfoJ88u!fuW$yq*^z>Dmv}~RO+Vi#|LX)N?}qGjp8>^NDkoc~9CNFE z(BbuvmBce(sbOi^AcQ8pA^QN5{Vrtf3?NRqo#ykFRy|WT+(>!sGvrWDb@LWL4bZ)K z0O-Csnc&q9?cyontVX@mlj+h>n#R+;{M7n2vFOe1bH~_&_XFi78i1 zXY3LorBp7(Lr@`F^0}A^Id#-mLf|bra?*MfrlgHl&h|kYFMe3$*YSHpC{Oo?QzY*e zr-<+QRLE>t7{|h#Gw6W@v-K521Eo?{v9z;^hM9$nPbrK0$H5i_sHq5yFJa zFV=0VQGZ`SaBOo?B(hup7`L%?x<)>?Q9E3p7)7rJ$zBWgpe=MDku!NZz*yVSL5obk z=^b&~3*g1Et*%FUfyKjP;+=R0s^gH^qXiQ)fi=bG;dy(7YGe;Tr{}R}%we68LkGsS zc;1%rmt(4eYq6v-A9ci^m-R0rVQ5+6;((#e8~tmun6k+Cg*Y*qgbln@7PCz*Nr%Ac^m@a$n42T*I8boK4VuGz_mddl=W%mcz$E09t z77A>(m+`|IMakT5zelJZZ^HOM* zAfBon9^Z(i)L5rdPQ;&3)zXU}1u0B9ZohlKfgzN5eh0XMFrVkCJh_8=cCOds^Wh^H z@8{1KA0uZy!;qHbakqE6k{d0}5JVTt)X(EOjdGQ|Fi{+KktLBB9ML|B3r;PH{KflUC=JFCj%~w7-<*n^4FB0m9ItJ3 zm^$VXiyEBA>M7GXrv#%^Yo)Bb^UX7=Mn#mpyG+j5 z`AT9$rL@gTro(n0W#r*+bwy9q5&5rIBU{ZSOxM%#)Eb#dAL~q-(O~(-@uMqKndZ&# zW3;6BOlmYd%!`a1|CtK&5&2#Fac5M{v02lHUqJaQ`%YQNiX(>jfDHq~-TZY1JoOFW z9XO<)>$SFzCk93t?&ucO47m>~6m31xE#x1gHr!E1cyaz2ERfSenUP}jgr4=|*%tgE zI8%ob0#49`D47iP6GCCP{xl?&*N!?Kg}fvL*wSoHd2mV3XCEsI&DDqOsc_`y9{#

W#7hm0TP1>424aI8g^ zv28q%UXz>qQ1BU0k=%iAm|sq(yeb8>J7ZGjZ{B6^)BhZpw|4uuUFW|o0sue#MxB4i zX$l!SwWFonQNc0!0GVlO5^ys2HIp=6RXDB#{_gZMO~yh$15?h$Qf?+=m06(&0PX)m zjq-nD4^YVg>mbb`0Q|2Uf)#R~SK)3FMTGB4fjC6Rn5;MSSvc|`tFzayXsi0vbW^ru zBi!R&zfA;(fKVg`w(WF)X({47^!@>sM1CC;m{CajB+T5fPpk>`4XMn^GPPzQGBcFw ziGtzSZim0b2UCIPBw&RdcstVgSkH%bY090>Vmo!DiE;#MXVLuHW#4>h@{44Pb19#uUn%lR zAAIJwx7GeK{_JJ{l>LpAVFgBZu^()Q_V-%QYfy#T+Axz3&&hZGl#6NPC zo_Xlos19TJ3;TNnFN%f>c8K@EPCZf?f)th18$WuC4WLb_=>HSvGl3QTN_t%|>e47+ z_RL~s7x+wyRAk%GSno4t@8nnO)_sruEEYk++=k%j2YeUhG+O6%d^9qDsv}rP96iLg z+uZVCXm{0e`6ll_pY7dR@B1UEYvL8s7 zJcYL_w&h$*euf}EvkH3C3y?}FT=heblx<7c|8<<3;v+c&B&w{~5W6cE;XUl%NBU`d z$_`pP3ozJt2bLysb;Z5FZ==EnS&CY5mjaMB0qOu)a;dd1rg?`L;&emvXsGxdE>41# z^M3(*e)r!U)$Rj;Srh;+fTt%f0sU{?9yK!dchnp|UvH!)k$H%DR@DG32R89pIEE6M zp2yq&x~Ii9OtxY&SJE_o)3#{qokiOjP%^G#>#c53$op<3b~II6xmOI+=C;O*ml)cA zUm?(&t>07TS9Lo%Z_6ubLjw!POAkI8FeVkTy^YJ(OXf9WmZxiZQH%K~)qe&^6bH~- zgcQ{6oB>A<3za$L8y2oV>VsRu4A|W9TSq(o{Q8%qj!P$tmWBu6%t`6LM6-Vk%N_{s zZQMBGqING&EyB0M8a^BL?0%Yl!|^;!X*voXnw9vkutrbUiVt)yG%8KFy(i`z=WCc;S{-mi}M7JxYS~YO$JMEyG-V0v=E($0`0iPE#!pevRSkD ze0bV#p7jo6u1~?U8S@Dn1srSfq@fxD?J|2-ic6yoa{DWD6uc80T82WndTPN zF-G2ONna_v2YJbKRV*~#t*Vx(*tz;3R*leQ)isW z0K8VU;d#V2PR05FGC?ckn*;9wge8c~rjQBEw2%o1SaQB70|2!i7{RmvlMi%AFU5{p z@9#_d2n9Pn@>Tz}NJZ#$cqVO6M0%iIRvG{SXt8!m)8V9-w6g#ZtK$QmRQyESQ$Xyr zd({`UeaCUECDbw(tLDKzi`C;6U=$S|8n8Cd%BcBa?zS0ydUIZdwL;{fk+lk+5zJKN z>T0)ax}G2OM5;$ghAcZyi`D*q%092cCMp?{C8T_kEE<;e$G_Q-#DR6{B@}#LJlN&@ z^QXK)K|HhUhaX$Ca-}8A#CDwO1roAgEyz21pbwr`( z6e0hb9Kw!c5utDr)-a%kjWo@q)jg%W$W~=@*P5DT)(=w}%q>bUe)&Or?X+qF0!I0T zozY@7uzh9*eG!utPyiw5k8j{0EBZxpFi|#}x?2|-ZIQyaa{MAxnPQS z?A6a{ys?<6d?mfs`r|0Ql6d{{CHUeuWUDPe!nEzwHvWbUq@!Jg*24VSXywP%NQglN zFVrgGh@)4(M*b;gvA_dj>2N-IM_l zfTGL?HrIo!U(zd5kN#-ECiDCnYdbC$m6vR3L<=3#xm`-9Dwq+zD;F@ApzGdv^DeZE zC5p*+2SB|lWA8QFp@w&M*LNk-z_w}Jq6Qyv7qXQ)y zxcg+!mbm3m!gaCB9RkjuY`<>&{fnLZ)upGXm7eUPY|mdbibOwIo;0hN;o9J0DZ=%{ zr&&8zoB!tinxOsr9_`3nqvNs- zOS<*qov!p5f9PPXoN}0NPNnqEad`&x_q_nKh94En5> zzU1aa?OZh3uDg%khD=BlElr?oQi~2hEA~C((_ARx8(HANsx@_=wAp1mIRKZglO@bD z=R8e!e}&r7S{_2#IGrmnec`x1zy^VL_~z87c*Rq!J~4?*pk6mMUX@Mek;it?k`l3I z8LNdn&1)Q3?e_Xi;nc>N+y1Nq0a7z!w@CPc_e;EJ+@%=5nK%K(hRLiARY5$eydQkT zzg@tYC`E#oAcu*kVzV=y?!kNoA%_8|)2agYjh?|b?`CWnf1d$w!Ia7F5YU!U(oSei z3=cpI58e>#srSnpaacS9xbcgte}moguJO3v5X@pQ#A?O*VJ8vZ?LVi+?i&<1kq3A? zi`FEqNrCh0Y4#(kqiat9>`^H#{&1l6K)*nJpkkxRc2F(rd%8A=B@VnVWqc zKVU$2fLsQ=9AI;$qX690Xs|f|9siOA5Z_bo@XZCp`IC;{?125{8vqXR;54K+#2`VS zHp;oHSJ=aYwU=}w)>`Fx5~!WN_JqRFoqwP$Gx3iQJ?lHSc=2Lq087uS#sf0*dy{Zj z0#>o~ZVPn2B_1FN(ZfEj)mmX4z&!hkMYV7X%%5<|puR7eAzLDT_B(NB8(t14wPZ5S zc9=!FwjZi>i#*I(()QpHApuMw7NE6)J>0q|4Ie_e6T%lhQf zJ-4ToC4XH`yA!uK^|efE*cYUaS?g|$&+jQ_rA@-|c?ng?F)_AZPqb>{&Go7YRX5~* z;yKf-Q#OM7b_MiW)x|X1palJl^V?4|6PtHfYKmb;oES5IDZL%Co5>$ZZ>#T!W>UGi zETLgiV1nPlq-8;`FUPAbF?K0vB2x0Co^jas(f>P9)S~;ZrboFZ(oh}leY}$&ZZ30=TCe+WaC=NU>ozkATby3uH*65>C!V)o`9HP{tIdkOJjcaMTiV_ykx1W{ zekONJm==rzYdbmZ97kqWvpv9d=!&|k+NioW%s6C2Hz z>feowWHsgyLb3d3z~%gXo2#y_-SBG<_k!U!x6Xiz^|xEy!Mei>Ml>05T)5DEydg*V zJ*>=KtT**&>N5Lchko0~7QehFa*6f-RrM4|J^8*M%F3z!Yl$reUeziaX&|)*_92aC zT&md(%d2^^<&ve5Fbj#+lrQyDZXdU$De(#JORB~RBpNhif+0JB#|(^E03t|}ZW!`T z_Rug+QCzIpEJ;!2rFN0ftf5Iq78ow%)!rjc) zVU511$yW--N)x%%XyMLhqpVD-xZCMk6z2TXXN+~j(cuH*Z{E=E7oSTPUa3DMH3?7 zh<&3ecp{gVNYC$U^;Q=L~Xl^inS-~*D7CERw)*( zFhW1ny)nNjy#FWoTa|j}+WH^9 ztc)K#O>+kVZv1_6W8uzeK_)8auO&_1>tj8N{p(lPqjYLjp>1+!K@MHxa^L09!ZUl- zo;~&Nb;fv{6W`2L`2{geeuQ}MmPcQ{7n!+^Woq`*)}NPyf9r2-Xjvtz8@Xq^R+2rI zCXo@v?Oe(Bt;%X*Y|`+T{fajN?5`4hb8XImhLg9Kadgr%hbgEaj^##5$h8#g2{mcEx0k#&N2GWs_!6T_QG!89%HzZrlMI5PD92BOqfc0GscD zx`_YdH8~W65)TmcIK|WRbB%=+CAF<4vwd^HH)iJbUw_&5?U13=VYUM&mF{B+2QkrN z316=9pb@2cgExD}IF2&KPqZZFkJB~o-LJ6U&Ntt6;&LO(e2}%24{*y=6unmDj9~As zwf@v!_O@M+wro92u%K*JLc?B1oLCKiCDiuFVkP|MciD30YPZi^xi8~$u2M-<#$KzQ zlN>2_)WZ3RiZ1Oy5BDrrd6%(a_mVR4n;nAn6vRlLQEsulcIyZynukK2^mIYgb7CP# zN=j4kz}&Q7I&JQqZ|)^9K}wiA517rKr1XV+Q<{#*j6e6RGf0ryD0e+5Ha8k33Iq8( zn)jce3hbL#*LKgzj#J@>1t!obEScd|Y&|$oE;s@-QV>IX0sKDeuVjh(IT+XunK{>I zLhb>Skc)ll)`=fF-^;i`W@Pr!O=~OQ2N@Z<0Q;c+Xey_`Z?3 ze$wgk{ew1sjZaMn1_hX?_5E4 zB|ScjesPT(>UzrmIW&`UKaQ)~YGgxOGcE@PrhLSH+v^@sYYv{;@Q9@Q>$Bud?x}Bf z;)j!k0z@aX~a*XS?+7wQ(ya1PzI=9X2lPS z8rVekv^v>>1S(WQ55%1pE@0Wdpdxrm90RL1q3C){yq76FP3Mn{i!Kav^*~|Jbqb;_ zFFQi+y_m@LFuaB7PfJBk&67)Sg^sSOsU$j*30A>{8Or*N)#lI0F*f@W1lXt@QNJZ; zZkse#-H3538M#)Zdr!B-dr#zA^0JlsFV4~ekeBpvjbF164Q@5L;Tqy|_q}B4+pQ56 z|57L9E^BUSRmn(RNZfJmV^X-tp*MUkt8xxRSDZ@s4>rP zGUJ8z?F1f*;l+=51~fQMUA_*2R}J@q$C_#9LH_Ps8sfA(6isy;o>5l7Lsp5sfVu2N zh7AEc?O8)|_Q$Uz=d~2LEN^ww5HpiuXpw(YLFj)W4yYa! z*n?sZboFM2n04a#W^O@1s{67pm|vEzRaO#@b$nYf+0+^FH9Y|)qW-P>J2I9(r7ezpJC zaiX{9_Tu=5JNwtopa^mw*JxF#^eAOMV>+q8`}P|Sz8h~oq|V4i?JRdVOPNl|BDH0k zk_-|Kp2;_*dPY>Oh>vy!at&nEgh9%3C|lO{%9irWKVwoKzTdUyh3oVQZfyO0-WMgA z?J1Z2%X@)O>O~s*dX_@Jg2|)}pYtd<%XGwitFyV0KHlL-F6kT2aN!Wr%@zGPE^E>_ z!>!k%{JvebiPsv@>|;tHI9q*U5Q>%y;6ncQonYhmBHOOBF_{;&zcl=Pg z&FtI0p>&=1p?{)%MLRwJ9C2VDEU`{JEYgpNE`I{{^~}C%5?MsP6QsEkN;g8eYHapG zKrEy16y)0as;7@~QZFmjpbpP~VNl6Lh`Tg$;9O~xa^l@Ov6C-?;{USTTq@rEEQTwL zBE2d~FK|J5^^~(JURZrPk1VR-(Qs%UO;@$7qUvA#P2}uaADNxevlrugJST;eK_Bwn zyPqu6nAVsa=9kj`^f-Ox_-oUBEN4gCzQ+xZ_Jn}Aa%IPBHYB$skM?@6s-6r7$_NOr zuaT^+Lk{xt=a`x1Kl15h{j@ZOn1mWr#eqP+o}5rpUvj7TNI;OuY**;uB1Uf$YR+p4 z9il;t1N^>u_-EktX}X`Wxrg!=JF4#-iryYIx$$gRQR*NfGa^XO0yZh(Q!Yhhpo~Qp z_Gr+(u((+M;uC!tP>R<@3`2%t6J}5ap@Z9soTgVAOEmsblILS4^$5D*6ni$e__AG4 zsO48X?i-Q_`Hb<1lX*Z2gDNtCN)6p&GaaXoSc2-FUB^KL3Bpgv4FNi|JA5m@0+`Dl z)nKiM;Hq4C^(J0}RB?wfKw<(>Kd4{wJAO3#{>5>W-!5}zC}a1t$Sr15Nh^=!*!mRa zTnKLYm7KjKqLENgo-{LhQ60&vUtNuQi+YnatoX@M>{e{Vw0pbcuP;4(dWw~A&^l;M z1Yf~G(6?p-CUT&He99oyNHV>DT#MkXr4UnK(iS}^gQ)vpE1~E#Q-?7XlkONgevxby z$g@Y*5=)W0NgjL1{(1FophkVwFVof%3hFEFgV>F1ZUJX4X5(^lwurw(T7zl`7gWET$K@H)FvMs4;+I#=$)^2?B z)}i!Z*_J<#)zuevGK;!pLE@|=hF3BJaryW9tu39drNRkC*2;Va2W^tu2SSQ2<54FH zDzSGIsuP8Z=h7OSmJ*|rc$g8=c!4su8OO2$qIZZIrjy>ICX^&HSPjA)W2m{v2sq6u zM(M(+vXu2$Lo>sMfNcJ(Rq+qTaTH~RAvo&SqA^^<+m8}_cx%fbA=)OzF6#?xQ_ zb-s|%&OGAN^Yjjy;zdO>*(geVkacZ!wCJ1JE+JVyBh<|WU=aEo_wvURRpmJkWQGM$v{6S1q7g4XI4>T5vq*o?bv=LtAswc1XK&eC@ z5r#e|r<&MT`{3fgkL%mlCI?gtNcN(@^bl`vY~roor`;TnwL`Vz8Fs(2-QNWp5H619qpb=~idZZpzU z!%pGX(YAY{;{wGyE?E!*sqLztE+IF9%nGp+@g8A=mY9$=u{sg=-=Z?SA%)zEfoary84GvNGTaOM%pdRqyvuejxHg;>?O@%3l6?OocAt1JqnI^p!>V* zkEK5QwG$ypA7a~6?f`PhP3$`_G2;_Bp23j6oMhwldT96D1A(&|fw!9EmZoi=hYkyGRC zmS&+w^C7MzA@L0?=KhcaiUT%P`{GeS+M-|qnW={Eg{rz+)LPC_F2C=}%g;1Q)zKVl zfI|TlpiHL1)AYedld_m9#ho+R*$p)uepGL8vKqJG`xkHbg#;9q4z> ze8o*73pl63CU2j-e)dGcehTbBs50Wk$tbthF!%<6e~|QM`${$6Pk$fT-~A@D+zeog zFW+qsQ>r$L++{r#_M{pe2kJ~ zVy5jmp?$w!Kan9F=@vF=XFyE6WkBrKo!W)Eo{f35jALM%4pCNR>wM%>P`(LKD z|4<`=aVms~IxEjL%2EdEPfxmugb)MTN&_=9_PN1(r!E){O_FF#@ipvX&zHmr z?=3HfH0??)L(`I#v`&91&nU9Oz1FE^x2mCN7j`TkQhFuM8R!4oIWMD0P1sQUcltIi zq#Edc)cd_mCr4rm5LkJ1nL#rVCj8Ep z&gmPKpbWbOSbEoeq&4Qk@`W)86j}a$;$w?8xKR+ggf=)fwPe0nc*LL9Ckt!P$&(%pb};Xr@bV2Bz51(sSO~3sXUuKu;Eq9WQ;xo)>>vxE}zt{n(SRX9k8B7g1kl$?Bx4W;k~kgFD`*I;cxWlUVz{B zzHv0;eYZ5p6KzoBxgHzG*u<+rssRb2>Gg<0)hHIuvW7I9F2^Z%I>3nxy zj$%y^vGd!3$TBnBBBx?H@)Gev9h>y(Nxnp}sqXRQ4(Z)>KNVvRcmHY%U zsLKyZz>No>y9C49?4yr7zf1Lu>g1hoeHO-^=uSm5&lB;V&MER92w-V{^x<#tcK_ z<1(7a4ax~+D3``aMT}IO-lQayn*;4ovLcP-7TCM;dtquJ-Dv6Z%S5+Tp$^bz$Fnk|}NAD6!^TDQb{f6Ssum50HJs498IYC96&%iI|_cDIV zx-LwcAm!O=FnqW1BS#ZyIhLHI#iZY2Al7uGHK1r?plIf3QE{*;#aqy{#zugr;5^zh zw>p;|u!*#Ouj1HgEZ)CNu4rv9+id+BAn@_>Vntc5To9!5C?b|6(fr7@W$Oz`q_sP1 zh|2$K_5~UP%zQp@X-yRtv+cR-oLAd#Y}t6w z`tYi8GN=MZL|rYLl|S6ja1g}Fgra^IU4gHOLLIJudLtGLYo;}kX|L55j1$+hN$Zlc zScFx=H(DztbYi0IZ%8e^efU0|7jb9c$x-~%{0rD_zF{*1J_%3bTIBVH7a{*GZ2N9k z$Q-32VrUVnSks@uH;5$Llg) zA?iv~X|>qbbLU)S``e%iV{0`7?!yM}my&u2BRYxg!&h$NKUI$s9V`l1o?JT#?A`^A50W zb<+~*g&v2c{Fxt3sr+vJ+`=X-LA)s=GK8BuYKX0Ny zqC(kxII6Y)`%CvTn*9qmkHvwN>U41;j(ry(1x@e_v5ToxgRHTAgB?Hu_5IO!QbC6j z9)e+wNs-gonV`+uuz3rc(Ph?u3CqP*J+t~me*|R6Qj*AAxpMXhX<{xP?%S*T4YOi{ z3Y<1LYU|oW(1FIbWRI_w&9>D%&(7(Q!r_rXtJ^~Qhp2FfA?EK4QQ8&nD3 zdpnGlr1lXZ2l%SLPW@AP$~Qr~^h2;_odM@;>Q1kR43l})nataG8=Nv^pf-?FQ-t1M zN8I-`T3lzDj|;D%i@LEEvXS%onEcXBM{U+osXT*S7oM%qMu*^lHn@K$u4Fi4p490` z&hYeYXNnO#xRe!`HECTN-onvj*a|PcDq$u?*%z$1 zXDc<^99^bB+(`w={qOtqc`nApQw58u=S@RNR81r@;VcMrt^=?UGJuYHF zFRnRI#>D#@Vj@G!WMHE*s(s@=-%H;=_d&3Fsl7*-q!lE~UqY3<_w+%~R*vur+hWWE z+n$a%WS6~(iSvvRJgR+~?lWpwyI@hTlQqg%u_ZB7{&S`mr2Kh~AAWtPuJ?3ti*+d@ z&GR`XD<9cIsuk(V@M{df?IX{Lz&tV=2P&lVFj|jIb`>08hHAPli@#B#7fJrIAATKi z-%IQKVIZp9YIbwBzT|CEV$hI1sVnU5ONml0V_mH)RS9}ClNVHSxO^V&8r+uHhK-XF zoH%BDccni_8~ja@{+D7Q1Zi@?%8XM!h??AsB$+{j-Z9j$AHjh_*d(O~rk?lFPI7ZE7P1r#pSnQ$nFE*!Q!HL4O@=L!mc z`U=mB2Pyxnl@#Wn#mv4M?1K&v3r%}`bTy*G)j$Tkfw0u z%FbM{C`v1%yRkH+lk3n(C28L{BW!y-Yt`JH_nbieb;=rZ2GCGKCn^S}{Bu!Pu%hh| zpz9!M#oSWQbVCEwzOl-$_w4<}i5_tf9E1@i_6i3&vgv;3iHsHu$0Tv_;?MUV@cULq z?(3$2M!0M|myZtG#D5@SWHE`HL|l|0K*d2uD*h;TX&5?z;A1vbM;pJz;A4@!d=-=L z3&~^fyzfr^jn}W~?mDRK9x-kXoQjC)?+cmL1~bWRnVA_l*<^g5|8!NxG%C7KkNLc* zYn^W0K-)d4(z~1(Am~vJgQhL9544!HIT1 z`lPeQdu;~O7-Ha)mn;#?K~gK3%X zon8ZyrGD{Cat}udu_W&Y=i)FQuHDMkkHG_Tq}BZ+6I$qGWJq1f42zd)H z{v&^p>>TGyugzo$0?o2~rRk*t(wXI{s2xkcDyqa~OO`^u%I|wnMUnD<6d#(B|Ib~R z`OcHgzSs%XKlDx<*n+CM8Kiw>Yvy=ENB_2p+7wL zOFxm{Zt=)>_!i^4ruxjiSvlUWM-02|@1Vp)6G&f|(SgL2cW6_nH+CKU_ zKqqR4kGS-f+7YuztU(U}`uE9T7mdV|*`9`uTktJ`3GOQzrn$bO1#XFX_n~k0jxK0s zxVi!w6m3~})=zHBJss4oz}2TAY@f1is1537{7;~}q2PEtV<<8jEqlNNL4C7S$9#xK z*_Q3nl_yc8G2q^USG*50 zNBplcrP{{U@We^gn0Vt)5i?GmBn{5$qFRKUJ8iG%igR>Yp0%w(RTDz7roUn5^JryGn^p;#I#PI&;r1=zx?!|!HE|cVy%g{QSL<`sGcso@c>4=3PoiL3 zdwF7YinqN|65S-%ep#>8RJlMlON+})qr|p1=1tL&ss7v%{h(;|#IaMv_pzCu)A@%X zp3j2Hf*kpGL!OytJbq@Q)!!JPv)bYG*Iur#+$UO1WVnn_l~73A{Ouv-bfO^pZUbFY zPktEaFeOuJd|)@<<~u1CmygV_#^h|d$c6Yh0BVW&&Cnd(0;XHzI>?3R}ZqYe#B(-Lc; zyYAgao6ocU4$Q<|TLgx$77G&)@^%k1A9qbDFI=pTpRE)6kCk(U$=m@Kjr2Q~ec!N@ zS;n!n<2S`ce4dEqN4D|nA5>Td*fL~`y*NZWY_9eat8}*Zcl?5E`|5PU^7TxvBL40v zaBt^1V7^aZW}O8YbV+@=*0jLt$Y{)GBEll6+*6+hj=7H%7eC?2M4 ze2AYn_)B^o9dDy3q9_3}8|iq}=x8}71tBHjE13y}AyN#K(V`h{)M)`W2-?`(Be|d` z;d6+NBBkZ?Q0g}*dTEscI9f_PRx~1~EAvVw%N_CA^?h5<;$Zfl;e;gytG9J*>DK?V ztRs7$e8p9yefpfQ;TQli>^Q7x6`S9(a2MByXvF&aMTE|BiO^Mb>d6BdUzfQQKW|z$D~SDW`bLNd^lmR@ZfF&8OMl>KgD;rY8sPyB5K{N zYMnZvxI1u6u(}0D {)UDw2$EkhkLa4@Hcf6Lb3Euot*wFUl`(H(^sjI_LYeLZD ztm*qc2phi17F}r~OxojSBAb7f4oFcE>haE=GDM1ez-|-FLXW?TN>D(s?b+Sv)@^}@ za?X*W+gv8nHTKLc4s|_d%}p?^x-yCD;emHkWfD=HJoMKc$}EQr}|8+YFn zv-5`)JFMTTcPTjogrD4eS-(BGy*PEasnz}Sh0>$Ii%Cw-oBK-lJTKc{KefHz;(DxH zRNTjY20*z_RpxoWyY7xfY5(vSaUDNQ>XJKt4c7S^(jlFCV{4jcz+pn$SMaX>gS~6z zDC@p2#ewToz2~?k*Fj^Pd*X+I+~q^?c1okEz>dz=tvYC4KUsx9f~rfZS<5 zdv^8=u|2tCRn@wF>KsJs=P~OcgVSbpwz$QnX3A7B8hbMQtBa$lEH8m;`MmMzdABCn zPaLOo1vdBEKGN&o-itEB7B>7QXXz^BN}+(w~e2IDip(pi9{5o zKG~epSQ>-3X6CD{4@zXeQ2#O9sLZX3m(8fMnkN|mIH)nTstqhleh>PBZ`|x$RSMZw zs4DsNj)HdeO6}Mjd7hq*Psqsrxg%|3l=s1km)4Va?>}*9;)~-6Im^E@nm$dy-+f?n%<^alm332T0d285>EEl5U7YLn z3K82}*^YeU43$;iOt%{;FFtX^@bpF1bD|&YDR1+PdcsEM{5W|Vrm9h|Q|#9dKltVa zQy}|lpqDb19o#_$Wg*e{>wLrHz~5rk;oUJa_nANyIM4g4-2#cJ?&+#PFO&|0={Yj;bf234@99JX`? z8*uv`;*c5r=-df7*}lJEm8^#PGUA4*Q<|=YK7J%}>i~wV^nwn{yQR}VLQb^hJ&?x0 zfB4_g_dcSdq}sy6ETrY&kw_lm;hXGyUObeieR=)+;;Jr}d#Gkp%PX9z3%~E}24}g{PKL4^NeITbzV)LK2 zsL%`09Z*VBwaQuCSc35mXls*bwG!!A8bRr*k4Qn7*)!}Ooo66gr=cfBljIzkY9}J< zm-)ky*X3dB2(Att$T)3J>5N=%|K-=#coz-ngn&}Hm^6f4Q}-x_PyWT9=~jziHZg=} zcpzuj{SR*BB)J}Um5yzhqVWqvcZ%#0!x`YR*|Rc!csf_B3{7B0Du;nnCbv6lG5gRD z?ghF^fj^u_;r54*HCMX~!vpP9F7eewKM`URiQ9yXI$>Fnw?$-|O_A6M}C3(%$XE(w^ zt@Gs(d>?NSvz5MkY07>?r;JoFj9H>KBVqj7iE(_gnY~up27fhq;tObNu@85l=Ad)h ztsMt|dypKqyxix!Gdv$BZ(1R|o*zH=n3Jh0c@#zL9z0q+T?V&na?c^|*88rYK{ME; z6;bgxQek+iS;c|WG@g6r$C$`GUVd&n-*stZBXsze?;ydEQcp4raCB|qNNrH6AW)?$>2gn9oRlLejZnOD1> zMBmxYj_vJwtx3`tkPJ$gvVNmtJ-I!M7f_HQ{m#SKfYuGr)MpN}3n$DXhFqer#UsVx zp#R_AO2z^H)~hWwp&*lRaoTJ|^(3}Q7Xeym!5ttK)9?QfIp=Df+FvAtJ|olR?^vehov~lNI97DtUN%Ma z|10rr+iRQS761}@Qe+}MXG9$-gV@ygxJ@=}yT|PNm;MoG@D<%tbnx=m>48p~j_~57 z(nExL43qOY>PPR>ohk?Y4UosUlVdVve?Cum?z+>u4A1Um`J*5`YCyQ0cx@`AfEXU1w%G?E&&e0%0 zRi6PxQvovi$%_>tyvD=B7Zl8KBJW$Wtal?V5xlM=5+=rmPs-~{lErMMvS*t*(T2vR zKl$xnV^_GmvO?xw1jR^nTEHF~{?rcLxScg@9}_F17!>hyN`KvGzU6~Qb;a)sAXVdJ zxE3iyZJ9HLYkv_GF=H<|&uO!0_+~}3scZcuzs1@vU)tgil>@q(f2NHJzD)c0k>6B` zE*;maYAy9KKJn;n_~?+OqJIH%Fdm0agMULIPqdQT4l@2oK`5sk3LQ(B5VTRdbKDWpW>L4K@t&Xutt4G8Cw> z-YDnT!v>+Y_JXjM<$sj&_{lR8!W7|>7Q&u4d;%Sh`XrZl#T3lN+BeqTi=&eGLY zFg$~mXzfkhpzb5f4_r>NxdcVi-s78`wjaojo|^P_=fJn3InFzo=R zqaJa}s7<5NRr)Ucl@GKG4H`eioZW1~Jl-XzEG5UI;jg~u4L<{D(El9_lERrZB#fnf70^C^rUp-7aD>Rb#En^(250T11Rp68R()c z|7_xoY$H+gB#*YPX}U)N(L$Y^WiE&hyP!|<8HJko#2EDpVpODLwz*98V?gYDNJ5#{ z-ach+YA!hl`<&wSP2q`Nvo*ya{aue*pyJYnj<^^1>+GEF>UViYcz^Ol9Ek8`>!eLv z&$9_57p^(H1mXCe=Tc<0cLfJHov~|dQrC;wW5<>tBjJ1UMs%0uE=#M<(bFYalto!r zPIAtm$#tkt^2bmcl%5|7k;%eb4 zMNtn>*@YI!%Bf+-{-J4;q>5P1)7+H=J`J5g`q{MsgNu-qpkre`jDu)CNY%L7A;qpb zkj;0q&8qa!9amwDFz>MM(Hn00Wi}}}#wZ=ZQ>G6oyBOM6xzj=V%TWlL@ttablI;3K z=NGD0!g*rt&+Y}u()q791xSDQ)Q~*=i!KZg=ugjS5Hk|=nBg2z!?<{RrQ8GL4mKdD zC-Hscm}O74&`3wVkRIX&52B(B@_;?V`?Gt{P~mrKw(_>=&kwzuJS_U+cm;_y%hfx$_f-JJ zsWh|lW@r9x1t=cYvXNA~rqebtwb!_9mfy+GiO0a2@2Co?vW&lsfp^p+bO0y!Wms1{ zh`7>sqJhkk|5;mvQfL77dT#`N06|KHxB}=P?y2f0v^h?kf_kleM8JeyBwOrqrJ2DS z@6Q!fa1v#mYkd-08?MXOZvvWGG6s$Yy`<>lSHGFe31=@Ysd|9K5~g|5w*XK;xCrmY z*G)=G#An{EEX^BWNvzKK$G#x1SJai(43H*p(pX1BZdIkhs2`QWtbQcZt=SM)kQuY& ze`(@Eosd7+&^yI_P=5n|33QF8*WWuaN#6iiQZCn19q;LVhLe0p%l!@_{M|*>^3zzR zSur!uNVk4U3;Usd%#9hxvXp$AqcobT%I`g$rGoyOe_Lc*MCaTaW{P4gLFd+<3Hf4{ z&Fr4$Xh)1fqMONNX;cX|{LQuJ7mae8o{P2+(GvHcEiF)}`h}?;cMt`OaaQM36-d8U zh40^GE)HYKzB;&JsHK!4GXO^tCeb`Ne zNZna@{voVo9zQ^%#Re}pRUole-bnkSe#7uksK~DnoyokJ;=~ZDd!g3*WyHFcCGbEYlUlV z1wwmj_0n2t6Vs6t%Lc_C`=1|AuOATDvhQWc8aG4OKKxote~LplIsE6GAIgqHm8>e$ z{g!g(NUCD8Hd!_RYn{CYNbQ2I(7=0tSr4l5{8?PBM3ud2P7SjK!)E4@G$bK3!npRa zv4Qr=(JkR&IB4CgTogY}Ul`8Sh`@RG1W7<<0M38j6fCE+;{YS<89ShCD2;Vq-ht(xcv#1igL zbUc1vIvzEuPpwo6CfcYhM^65qp!}0wg5}s4I2ek!MA3tUO+(M**yo3iU~vr4-Myfj zH(KNjCl1E?&e_F&gOMeHU8ISX#!+jP1Wq^Y>7tChO|hv|Wpt2*UOQ zHRI_X3vet6E>s%k9DrJJnir$(srvTEafkY-ubzJ!T&3nfKC(35#$6{ZC$%q^h`aUk z-+Xj4wkDN)&d15@{NtjDG2@s^T3rsRFhU6*vn~F-TNAe3%6b|fLE5JJQX;%>kRyUT z$EJx|#0=T&j)7&$tIxiB(u=bPrHnzr-gt%N!}s&Y*;$vrSlX)h35~^HpKZUO|2E#g z=f<7|>-54wsp`!P>P?v1u)kzhXk~0V6CpFQA>!3z( z8WC+q#}}V?@yAC12Hp=~Y{Gev(=`X?pfNuJPx<$6#@dEkExx0o(E#ovI8@iWhYLP$!w8@F?U?)CQdT~e=}WcS$9%l(H^p? zNuSTRPv`OLG|tX8vdP(#!#L?puQ%KfvYz2-H!n>8gdQLA;?~?SNGucn0mp&-x;Y_0 z%rZ5{yXNY)B1Ds^M^zL68QfEUHq%iY;(ONq^jDMx49*)IxX@Ji7jtD2gQJ}^?61*< zSMIg4)F7>~gODkEqN?tjv}#2MUO};rCuMw2Jf5v$w#L0qsch!p6mTm%{%`4x_@3j5 zhO-J_LmN;P>!2|9{|hWD$x{fu4;uPq03Ib-wg#*WEZ=2pmcemLN3?bte5y(-?JWcf zvFla4XQ>lhd2?55cC>-p$rj=`(_di|a`{gXWhTPSsUdGuR+?lk7f;q|ex)60kF5&O zQVODdWVt0r)G}Ra?*ws(>}OI>3Ya=v0INL5SWT;Xgc}W2-+W(my{1iXszry^AOJ7G zQ8o-fnm_IrH5LN4eAqBqLRyqIJ$8EDJtVA(x5aFqyHmgPEI!skg|hY}zh`?)7)BbK zN9UDFmnKQoGWLTybkhGD#Hrfn_{|qXasPl0hzPnl#Wd{V+w}+PtW}ikEdHB8&6aBx zj+Iaqn03%I9b0$}nsYbp{WEKcY5dWc1OFwK3N;47;VQx8i@RG|r{k&K&8^^}(Qwf! zY4)G$KM_bFTQCM-khA8Y6u0=$*6dXb`k zr))Z&BufgGPDeLdA!mBnq&yVgV&oqekCfmPv3GjX!uJqy({ zhO!#e=?N6yST7dW%WfLpZ7T*sLBW{?U!3F=Gks*RJ$pBI4#T!$ZM-{GewFD^CgZ3z z^mohahR)SIXhmbqZ5GkPUwLFPmv^u!3 zPPKUSo5^S?xO(nQ(Xiyz%Asxd-SID*pO;darMh#=%B4!CQwYU|y|x>e@3Ag>-da2W zEA1Z>Frs0U;NLR4dji%kZ-C}^?4i}fg4PEArAs7{-%NvGmCN#A|C&xpkx|l)YEm3y zhPlJvr7*wkK?ledelzh)0~qzPZTNBW@_fs+OuX81z?K#;+{gyiXIv86$z+bo%JJqV zv?hPVRv)E)O1ZR5*7W}%B8NVvu|D=V0lKkj>07CAP9u2=B*A{XFQvBKb@ z^Je?aYc;+X?WHD_2E zGm~>N-X9e7xIYad1zBFGFH0^dWA^`k7Uib#x4tm5E6)MDA|3O`_$Oo@heLgkyxu7WNcfKy=d0zv9_IkG zu{LhvO(9Qlo4_cf5jpE{79YKxw}cVjvynw%1Zya@??!!`YiBp`l6r9Xd!vBYBbQ|t zTfz;!I#{0S2tVf~z63zA?;VO9BvH-g%XoC=cf* zu2vdWXMx&vkza6>+yzIW!tWVJ#f+AGfhci3>ry@D6GThj&m9)QjJcmQ_-3ZK@yn1Blp`3K>X3m@(9uz{# zU1Wa8=b~bNNs4jvf8Gh66L-6bm}(PJK&;>UYotg&f-md&Q&qzoloJ0n`MWSbB&wyr zvilVLt7MPjySr&#N#Q4d>@zd%KRwgXuX`5#*Ih^%lQ852_4b(~2wSReJJSA>(N|is ztq=hgEO>&z%rf}g<;|KQVgJlDVZFk{c!xDCxZWX%_ zoehf4e)y?;sF7)S1?!$BdXY5sOL<34Pk3ozH+(<&Ex+eo@o4Z-j53$M!$up@wqD za^`-(oq!>nLLN%6V)<`4`SH+tc>d5a=gj6_dT=n1VEtz5vM3nEdo1J>%0)wp z7+!pqgLzP?npI-P$~RKJNBLKV-vhHN@i&BmX21?3F#*^6X-&B+t?CK4a#0XS095`~ zU8m=bWm-!E7*hxGpJ}q)v}j1+@+T_rZhXw6U&qbl&5W4fcHEw09;Jnxc6_=AKs2}m zH|-D19C3WcTb1ftGcKVN>;m8V{;CdO&Z+qzx0lINeFW0%K3^cJiL85~v-lCtxQF0v z^1spzqB)%5MtiARCRw%12D3m!j)fpc?cX&^>K|K5_GJZj^xgF{h+4utkiMuxop@7#%K7H|n~5Y{DA_*xX~@T%hTIZBI|-^(_v-oqZ%R;$ zS8%-VSD-amVMvZOhEoW`RLwN-!*+Ueim~~Zq?B~^%%ndzPQj;ct354<7O01Etowy| zdj90^tn@zp!>2V_U{o(iDVj2~5wJ1zSIIbsU@5}&{EU0H$EM@GH>BY%kANH2A$cb9 zMkw#xr^*KnI!M#O1vWmUtu2(M;t zX_1znC46EE(Q!d7XOl2xUG-`iqa&*3wlGzPRGkL5=Ndh?YBiPP6uqplU)g8&& z_7e?ERqr$3^AdO2bLajns_3Q?J|6Z|IyCd0O+U=(z2B84mtM9`x-#V$T82;IyE>Z4 zvZplgESr1#fMet*nAULfkw&Kan9I2|%HLY1PAwKCC+Y71B}V!7REE7xa%C|IZ;-34 zkIH!)+-UFDg%z+LDXFh??MVVI&7C@8(PiJnN?U`MZnc;TyC)P}g~DAP6+i6q=(sjnP6jh zaOMX=(g>~FqG6QRVeF{9@MB-nQ=v=ci9Bv3C%`mO-lmTpPsw-ST3B!R13vA@xW}X??USHrqhmc^EoaA9;AIwsyABXaYO%uyd%YN3@aOSW3CI>K=zp# zeKqm@KPXeecFiAhFsw%}=kPQ6lfj>Bk1-=GWox1aO1J;?^uZ|F*E_|%Ny_0YfVsa= z)9r8!a0y%mDxN~6udk>$&vDsZ5#Qr)Kj;F(HJj_zx z?pF6JD;uEdcO_UL(LB(iK79XFdR*`>G_OoVTV`A4O=mn~7yp1iR6bE*dX($n(c5*m zXltJ!)t&b2A&b1D2?s%=27MXh`hVLYtGtJ51tpJGC_kk|&c3AOw#pFq_!X#UoRa4v zdUjPFr)~Q`$TR5PfRshfk<~1pT$7;4hGKjJdTAcGV)?if50a{sG%WaUiJ{jbF8S~m zvK6j?NlLo>`Y92N+s!Jb^4RfLz*Ie3akb=<-|BUHXu|u;M@;u1kfPz})UGtq286qW?Twk*Yde>v zq_bI!lSfU7CXvT(7Q<6m`_Uh|8)4VOwaQ5naqvICZ1a z#vHg7h-pjf0j?>U&!@CH7DCkgsE7Mu&z;OrfhGI~%Ewly?%kI43RvGAvlR`wjP;;~ zHu|A=&z8HUapuhI*nD!nlic;fyGF9H5dYRL1^erLD7tt*qZg~=y8&(aQ{~J+wq6Ys ztw9$u4GHTV`nbcA(iJ0YHa2*E*tM{_)lI9A+(6bhaY&~}@4o?fImlI%z^MRzLmAuH z{QHtR^^cA3KdqMjbw+9E@13wbATx0q=2=aAN1F$mmw%L^8eC)H$H1!`$_)>V^|hbi z#PY%!3W{-onr*&I*HYqXrvhoID-N;iE|>0mjM~ROx9{4PrAuFL=r`6>VGIK&bA=j4 z2M$#Wjm!Sqc(z{eHTc*`I|8G%LAF`99t867m*Si= zdJPlh#hUlLnD^NHi@()s)?IF!Ic#dq1XZD=$`qKSjC~e*JbKURH&Yuw|Fr|lT8NmK z#?gI)YS(L-vC*0~W(IymI-@3?F87iTCWih(T9F2YRT^<_Ra8r)f_`+IpQYD%f-XiR z(1OhcX&yIal?>&|D+OrE@uJ+Ym88N?ymfKG`$L0Ln8M(#zK&ID_WeOVg2>q@+Xsl` zQVX`L89`;GN|8MuzdTSEpP3uFm=-`|-3&o_Whq-sP^3k7WsEr{hJ>=Qg{97pt2#0; zebEN#z%2VCKh06%G3J0B$9;cLy9$&9w(K~1p4&tB*puMYipRpFbPN#xmZnuL994Xc zq)dM(eV?;rd2p908uVU3k5;rl{5n_3_UGg|UhtX4n9^vkAihiQm{9;GnMejZZ2$vw zevz_tNA~dwLxRy(^A_B~q@v{HAi*>LRz(i7H4NWrkTj9(cZ7f<0DQLll|q6!OR+w+ z>J)hQSQa+l`wa;Uj`%MoxCt9)>hL6tg|P^(Oap;jHA8HEeWSy%!5z1*rMi#XFGGu< z`UY#2$AHgRoO%dFr)Mwq6r00`#7Qg`nu|z2YUATt7W!$DbI-PB);%imKVD&dT!}>ylWQOV@!c7x`@Ql`x2bY28@UCs z5YP4?63lJ7rWZmq>en50p(0**oswRA8?b%5ks2_=&7kYV+eq4ZwX%A7wCl*Nk^2X^ z_4h6BWyjXdW=e7yi5~S9-lV}~2CViXiaYH65^UW}V~tXWZw}5zWSWTV0YIKMxoEEn z8VmV_&$D5!n&e-LAyRqhmNd|U1lm?Rdp+j zN4EanrH%*kRr!}vxg4MWoL`@wZFyzX!L2^RWVbyzp1Ms|tS6bI1!83Z??Voni5VC4 zYGG6yi!Z;=%Tzu)M+p#XDN|KyrZ1Te#HvueUO>ux6$~cZe=|j2UU5i2Xp$+U=IjYO zJXkCp7=Fewo)Fsg=?5muVCtCnSmeW@Ed%5M-rjlhy8>pQUW0(H1|zbXXC_sp(eg~g zaZ>)`F;>Iik4#;up=Pclq%l@Qrr4ODF|wf0b$tQGxP8goZmSK9P%@Wz!8k21!f!5j zMeerbYPp=(M|{Y7YX{NgD5We8p}N&{$}3u07lNrlQLDszJf7y8Zcw32e2b1A^35lz! ztk3Y}`W6YyagB!uQ+No)a6~l2ry((gubs2W>@!NvM^EOt6)t}pOo6vE4V={&5cw*NQN-e*f9 zP}`*WoB2}#ObpRi24kD`|q2&DlYgge1|jGq7=dO zBocRuU2qA^CYgYMY6YZxEo~v!*wei1(WJZuJCsi zb)I|UlyGYhqpTd@us{r-PH3|6i%2lq`pGXV&?J4Dc zwXHEeFrQH2FLYr^S`Gg*p}U&hfa)NwG~)2^CW&!nwpMfa`+(rS+X27HQJdGC@SaZ$ zHMG4m?#aa9Jjvg(kMasbdZP6u$&5w^$`iA&#QpiF3%{r=s(?ni zeSag*kPDc-`SQ#LO@UASCR1>EKaf4LDQk0Y3xBLe za_vb=OSL;X6Fu#^L$Z0ioCu)pVrk}>G`3o$5hXh-Mb3P)!cIxw*?!m zBjy@XRQzue10t-6Vvx`_Y+3F138V$MdRX8@jNb_1{g8pMWa@05Kv z*eK!2cUMeLS>nA<)5Z5}_^r&xHF2H`Pi~is-|)n}5iu$9Y804~){%j>Cw-Kix*!Ye zmqyLMd@#y9{x$}@K)95e=5H>P_Mw+#3umbNe>0*nxdPh{52Cmg3tN9#SXOy?STUrk z&yX!kj>=S~0A@3w*8x(dEAkLcu5b#Q!_QOx9K`(a+Z~3HbnCNo!adeX+F+r`2na+$ zW?ob045L+Ob(RN&zVgvtZC*;DSbn8Nu+y6D4gh1RtB6s5eI)N*bI}B%CTtp@o3c8` ziF`N~^2q5M>$qo~zz;9sD{Rn-sCh-j1-$RE- zwE1RqXh$s|Ih?De31YX(01TC*(fmc)_fXEHJe89RG1rKQiF3MRF#WoA@S;qh@fCY# zR28&F5q(a}!MG|{C+SsA#?$9)(>bW=TTNgU^s{H1M)Qk?K8#JLf=|q4n2DqbM+u>4 z)A77#4^Ng0+NBs8kX(-!6-Oy~#^r`eor1$}CEEs&lR9#&?}^}348H8Y@8m8b zsQyAzT9X;8v^VaFq|j<&F$bbMEp%cj+0XLv%|bD2fgZ%OLzE0S9`VXGsVth6enIM1 zp*Y!jrQ5idk|rd&!&)ODXYyeC^vlkJ zY@1pHO>2GV^U7}N__^y2PqVZPzNb&)tW+=$T>qMs>7ch^5(AM3w{Laqd16467uT_) zZ;yRbz-pGvHthVM`-?bR^B#6iYj7o}zTq+>01$3o;j@l3K;+yaP|c-)gsWU+Zr7?4 zidnPOTYo8BQT5`JMBhW#brbs9X1qIGvw&7CU}HfQDDSXzNR<1T{~BcCDVLOt7}eLX z^VJ8qQTQn7;_A0wPS2L9tF2^aSFwr7h@*tJ`f5RvQjN{Oo)gUL&^)>B>TWot2wf8G z!}MahcLNz(1l}Pr%hp~}*`MVRv6}1z?UYo}no`WQHgTC6pz%(++^#3)+RWY_UEOxo ztt>^CHpiRy9%Iqo0Je)|udP}OW#)dgYkEY|tE>$^-{}2i$CUtBooJ&rKDED`K~jZy z-9Xk*WMYhLly-q+C{G^&C^UznVSk*EZrV`fpu5K0%1m4Ir8S|jP97@vn6S5>boML0QI~?s9 z&|_h>{NiGW5C5@|(_5_lwZz?0jh6Gd<2mUqyH2fEP8r87XO53>P^nKE&F!Y)pAx@!xzFEwh?*Po3YpMnUVjnR4rf{C zxhg+z9*-z%d$MxfZn`=x!an&!rf@@O@<)B-<4lnFx2sQApBeE}?8CNQ0=9U=EcjB!vz#m<&oEK^tUu`^(u`CCml2k&Uq z$Nz?IUVCdgVdt5lUW7NKxZWiCL)meojr~BK z;My);AzZ(|3Qze#OGbuk%NLZEA#Jj{{TrV0B+d%OCgOYc=7u|elIGAxm{o8)5@;wsT z76L@}+gd|)#ur*1Z6cW{y6Z9@1M&l4wuCc84dO1LD`52gDCz{Rx9|dAr4TX44ATH! zVX3ceXNJGE^*hAEimb0UI=xhZtwjErdd7nH(YQMuUx75B7l1rbhnrazV{*wU(x3GW z*j+`H=-0_#M+(wYT;ddj=X1$^Fg1ttQ9}AeaYNhJ5{2}f1*x&0{CC#&!y~d;gpQMR z*TYU3uOBONzHi&?TJBhRKJO&S#sx~#4fp)^s`3gdJgxY2K~-gvv~WL~MaTGK!G6VT z4!7f{8iUU;2XyVYzMke?4Z{Ivf~byk780CQyUPm&BhsgAVHViL?eL$HNzool|S~&XAc(|NgxcC*X{DkGS*7EGy?fa=9HUpPpHdXT zC-C~lg-Nuk;=wF-A`8r8D={KF^Xl7bwb0}b)as()Cd6nbvcZxxT4pP67 zb+(DjMQH%#?M0JDf#RjBJ5|fuP=HK3iOIhO1ybfo;iSZhD$JRHu+wR?3vY=EPpO_u zP@&IPT%oy7#+F<=HbX`}^qJHgd|`_(k{7-`qyXMkO#Sw~7gqFviYyzoO;7 zQGFw4m{omX*M{;Rpw>wbCIcT_G!Swu|G5QU593n}j<>>Ru~yZ}y)m9q{doLg(?_JO zRLvjCmccKp7%kIESDuTjVc0w1(_O~J6Gm~OS=LQMyrOmkKOM6 zNA;Y4n_5%U`1b!YPPUBitYaasr~B!7Mu$p)ciHPcHJ?-5ZN(zM{F6-!9o4v*?USAx zdrIY;_H?fBss^`yP@(3z8+$1!%F47{Gk)v2@>av82d!U&TP7Ix z{sEf8dgD1Y#C@QbrVb@IaD^zQ`+sD)DHdlTw5{rFYxpc2OdpWF literal 35151 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

L_qr2} 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 From 78a3947b5062d845822b09895fea198c920c9e92 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Fri, 22 Nov 2024 10:54:07 +0100 Subject: [PATCH 10/39] dhonti/ANDROID-15405-postercard: Update sample attributes --- .../mistica/catalog/ui/compose/components/PosterCards.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt index 9f7e5ce3a..51887d61a 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt @@ -45,7 +45,7 @@ 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 aspectRatioType: PosterCardAspectRatio by remember { mutableStateOf(PosterCardAspectRatio.AR_16_9) } var inverseDisplay: Boolean by remember { mutableStateOf(true) } var backgroundType: BackgroundType by remember { mutableStateOf(BackgroundType.SOLID_COLOR) } @@ -187,7 +187,7 @@ private val topActionsTypeLabelsMap = mapOf( private enum class BackgroundType(val backgroundValue: PosterCardBackgroundType) { IMAGE(PosterCardBackgroundType.Image(imageResource = R.drawable.sample_background)), SOLID_COLOR(PosterCardBackgroundType.Color(brush = SolidColor(Color.Red))), - GRADIENT_COLOR(PosterCardBackgroundType.Color(brush = Brush.verticalGradient(colors = listOf(Color.Blue, Color.LightGray)))), + GRADIENT_COLOR(PosterCardBackgroundType.Color(brush = Brush.verticalGradient(colors = listOf(Color.Blue, Color.Cyan)))), } private enum class TopActionsType(val info: PosterCardTopActionInfo? = null) { @@ -197,7 +197,7 @@ private enum class TopActionsType(val info: PosterCardTopActionInfo? = null) { firstTopAction = TopActionData( iconRes = R.drawable.ic_close_regular, backgroundColor = Color.White, - iconTint = Color.Gray, + iconTint = Color.DarkGray, ) ) ), @@ -211,7 +211,7 @@ private enum class TopActionsType(val info: PosterCardTopActionInfo? = null) { secondTopAction = TopActionData( iconRes = R.drawable.ic_close_regular, backgroundColor = Color.White, - iconTint = Color.Gray + iconTint = Color.DarkGray ), ) ) From 85958e20694e849d2393242adf45aebe89c5a686 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Sun, 24 Nov 2024 23:07:47 +0100 Subject: [PATCH 11/39] dhonti/NADROID-15405-postercard: - Added param in "TopAction" component to be able to receive a "testTag". - FIXED problem resize Image() --- .../mistica/compose/card/postercard/PosterCard.kt | 12 ++++++------ .../compose/card/postercard/PosterCardBackground.kt | 9 +++++---- .../compose/card/postercard/PosterCardMainContent.kt | 2 +- .../compose/card/postercard/PosterCardTopActions.kt | 3 +++ 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 508bba81a..c16f373c8 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -24,10 +24,10 @@ fun PosterCard( title: String? = null, subtitle: String? = null, description: String? = null, - onClickAction: (() -> Unit)? = null, - customContent: (@Composable () -> Unit)? = null, firstTopAction: TopActionData? = null, secondTopAction: TopActionData? = null, + onClickAction: (() -> Unit)? = null, + customContent: (@Composable () -> Unit)? = null, ) { androidx.compose.material.Card( elevation = 0.dp, @@ -37,12 +37,12 @@ fun PosterCard( onClickAction?.let { modifierValue.clickable { it.invoke() } } - if (!aspectRatio.ratio.isNaN()) { - modifierValue.aspectRatio(aspectRatio.ratio) - } else { + if (aspectRatio == PosterCardAspectRatio.AR_AUTO) { modifierValue + } else { + modifierValue.aspectRatio(aspectRatio.ratio, matchHeightConstraintsFirst = true) } - }, + } ) { PosterCardBackground(backgroundType = backgroundType) { if (firstTopAction != null || secondTopAction != null) { diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt index 840fd1cae..04f1decf8 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt @@ -4,7 +4,6 @@ import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush @@ -14,10 +13,12 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource @Composable -internal fun PosterCardBackground(backgroundType: PosterCardBackgroundType, content: @Composable BoxScope.() -> Unit) { +internal fun PosterCardBackground( + backgroundType: PosterCardBackgroundType, + content: @Composable BoxScope.() -> Unit) +{ Box( modifier = Modifier - .fillMaxSize() .background( brush = if (backgroundType is PosterCardBackgroundType.Color) { backgroundType.brush @@ -28,7 +29,7 @@ internal fun PosterCardBackground(backgroundType: PosterCardBackgroundType, cont ) { if (backgroundType is PosterCardBackgroundType.Image) { Image( - modifier = Modifier.fillMaxSize(), + modifier = Modifier.matchParentSize(), painter = painterResource(id = backgroundType.imageResource), contentDescription = backgroundType.contentDescription, contentScale = ContentScale.Crop diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt index 3b896b533..cd7e9d4ea 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt @@ -42,7 +42,7 @@ internal fun PosterCardMainContent( ) ) { if (tag != null) { - Box(modifier = Modifier.padding(top = 8.dp, bottom = 20.dp)) { + Box(modifier = Modifier.padding(top = 16.dp, bottom = 20.dp)) { tag.build() } } diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index 41e2cf13e..bc6dfed4e 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp @@ -47,6 +48,7 @@ internal fun TopAction(topActionData: TopActionData) { with(topActionData) { Box( modifier = Modifier + .testTag(topActionData.testTag.orEmpty()) .size(40.dp) .clip(CircleShape) .background(color = backgroundColor) @@ -69,4 +71,5 @@ data class TopActionData( val backgroundColor: Color = Color.Transparent, val contentDescription: String? = null, val onClick: (() -> Unit)? = null, + val testTag: String? = null ) \ No newline at end of file From ad8a3ad0b153efe8c03a296be813e99e3e4c1322 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 25 Nov 2024 01:17:44 +0100 Subject: [PATCH 12/39] dhonti/ANDROID-15405-postercard: FIXED rescale when is provided an fixed aspect ratio and the height inner content is bigger than aspect ratio height. --- .../ui/compose/components/PosterCards.kt | 6 +- .../compose/card/postercard/PosterCard.kt | 83 ++++++++++--------- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt index 51887d61a..8276d9ea1 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt @@ -45,10 +45,10 @@ 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_16_9) } + var aspectRatioType: PosterCardAspectRatio by remember { mutableStateOf(PosterCardAspectRatio.AR_AUTO) } var inverseDisplay: Boolean by remember { mutableStateOf(true) } - var backgroundType: BackgroundType by remember { mutableStateOf(BackgroundType.SOLID_COLOR) } + var backgroundType: BackgroundType by remember { mutableStateOf(BackgroundType.IMAGE) } var topActionsType: TopActionsType by remember { mutableStateOf(TopActionsType.NONE) } @@ -227,7 +227,7 @@ internal fun AdditionalContent() { Box( modifier = Modifier .fillMaxWidth() - .size(40.dp) + .size(150.dp) .background(color = MisticaTheme.colors.successHighInverse.copy(alpha = 0.5f)) .border(width = 1.dp, color = MisticaTheme.colors.success), contentAlignment = Alignment.Center diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index c16f373c8..f13a5af81 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -3,13 +3,17 @@ package com.telefonica.mistica.compose.card.postercard import androidx.compose.foundation.BorderStroke 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.aspectRatio +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.graphics.Color +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.telefonica.mistica.compose.tag.Tag import com.telefonica.mistica.compose.theme.MisticaTheme @@ -29,45 +33,50 @@ fun PosterCard( onClickAction: (() -> Unit)? = null, customContent: (@Composable () -> Unit)? = null, ) { - androidx.compose.material.Card( - elevation = 0.dp, - shape = RoundedCornerShape(16.dp), - border = BorderStroke(width = 1.dp, color = MisticaTheme.colors.border), - modifier = modifier.let { modifierValue -> - onClickAction?.let { - modifierValue.clickable { it.invoke() } - } - if (aspectRatio == PosterCardAspectRatio.AR_AUTO) { - modifierValue - } else { - modifierValue.aspectRatio(aspectRatio.ratio, matchHeightConstraintsFirst = true) - } - } - ) { - PosterCardBackground(backgroundType = backgroundType) { - if (firstTopAction != null || secondTopAction != null) { - PosterCardTopActions( - modifier = Modifier.align(alignment = Alignment.TopCenter), - firstTopAction = firstTopAction, - secondTopAction = secondTopAction - ) - } - Column( - modifier = Modifier.align(alignment = Alignment.BottomCenter), - verticalArrangement = Arrangement.Bottom - ) { - PosterCardMainContent( - backgroundType = backgroundType, - tag = headline, - preTitle = preTitle, - title = title, - description = description, - subtitle = subtitle, - customContent = customContent - ) + BoxWithConstraints(modifier = modifier) { + androidx.compose.material.Card( + elevation = 0.dp, + backgroundColor = Color.Red, + shape = RoundedCornerShape(16.dp), + border = BorderStroke(width = 1.dp, color = MisticaTheme.colors.border), + modifier = Modifier + .width(maxWidth) + .let { modifierValue -> + onClickAction?.let { + modifierValue.clickable { it.invoke() } + } + modifierValue.heightIn( + min = maxWidth / aspectRatio.ratio, + max = Dp.Infinity + ) + } + ) { + PosterCardBackground(backgroundType = backgroundType) { + if (firstTopAction != null || secondTopAction != null) { + PosterCardTopActions( + modifier = Modifier.align(alignment = Alignment.TopCenter), + firstTopAction = firstTopAction, + secondTopAction = secondTopAction + ) + } + Column( + modifier = Modifier.align(alignment = Alignment.BottomCenter), + verticalArrangement = Arrangement.Bottom + ) { + PosterCardMainContent( + backgroundType = backgroundType, + tag = headline, + preTitle = preTitle, + title = title, + description = description, + subtitle = subtitle, + customContent = customContent + ) + } } } } + } enum class PosterCardAspectRatio(val ratio: Float) { From 7ffe1aabc7c2cb52fdcf48fdb2d3fc9952d16c1d Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 25 Nov 2024 01:25:43 +0100 Subject: [PATCH 13/39] dhonti/ANDROID-15405-postercard: Place correctly the PosterCardTopActions() subcomposable in order to be more visible --- .../mistica/compose/card/postercard/PosterCard.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index f13a5af81..c7c6f1dd3 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color 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 @@ -52,13 +53,6 @@ fun PosterCard( } ) { PosterCardBackground(backgroundType = backgroundType) { - if (firstTopAction != null || secondTopAction != null) { - PosterCardTopActions( - modifier = Modifier.align(alignment = Alignment.TopCenter), - firstTopAction = firstTopAction, - secondTopAction = secondTopAction - ) - } Column( modifier = Modifier.align(alignment = Alignment.BottomCenter), verticalArrangement = Arrangement.Bottom @@ -73,6 +67,13 @@ fun PosterCard( customContent = customContent ) } + if (firstTopAction != null || secondTopAction != null) { + PosterCardTopActions( + modifier = Modifier.align(alignment = Alignment.TopCenter), + firstTopAction = firstTopAction, + secondTopAction = secondTopAction + ) + } } } } From e775585c35c7f8859d22c93858cece2dfdc3556d Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 25 Nov 2024 01:26:22 +0100 Subject: [PATCH 14/39] dhonti/ANDROID-15405-postercard: Remove unused import --- .../com/telefonica/mistica/compose/card/postercard/PosterCard.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index c7c6f1dd3..9cd11b5f5 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -15,7 +15,6 @@ import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color 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 From 528c8cf7d8e401acc7548e91e508e1ad592c26ce Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 25 Nov 2024 08:01:13 +0100 Subject: [PATCH 15/39] dhonti/ANDROID-15405-postercard: Some code corrections --- .../card/postercard/PosterCardBackground.kt | 16 +--------------- .../card/postercard/PosterCardMainContent.kt | 19 +++++++++++++++++-- .../card/postercard/PosterCardPreviews.kt | 6 +++--- .../card/postercard/PosterCardTopActions.kt | 12 ++++++++---- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt index 04f1decf8..26512a909 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt @@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.runtime.Composable 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.layout.ContentScale @@ -18,8 +17,7 @@ internal fun PosterCardBackground( content: @Composable BoxScope.() -> Unit) { Box( - modifier = Modifier - .background( + modifier = Modifier.background( brush = if (backgroundType is PosterCardBackgroundType.Color) { backgroundType.brush } else { @@ -39,15 +37,3 @@ internal fun PosterCardBackground( } } -fun buildCardTextContentBackgroundBrush(backgroundType: PosterCardBackgroundType): Brush = - if (backgroundType.inverseDisplay) { - Brush.verticalGradient( - colorStops = arrayOf( - 0.0f to Color.Black.copy(alpha = 0f), - 0.3f to Color.Black.copy(alpha = 0.4f), - 1.0f to Color.Black.copy(alpha = 0.7f) - ) - ) - } else { - SolidColor(Color.Transparent) - } \ No newline at end of file diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt index cd7e9d4ea..f4e5b77c8 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt @@ -8,8 +8,10 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shadow +import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp import com.telefonica.mistica.compose.tag.Tag @@ -29,7 +31,7 @@ internal fun PosterCardMainContent( Column( modifier = modifier .fillMaxWidth() - .background(brush = buildCardTextContentBackgroundBrush(backgroundType = backgroundType)) + .background(brush = buildTextBackgroundGradientBrush(backgroundType = backgroundType)) .padding( top = 16.dp, start = 16.dp, @@ -114,4 +116,17 @@ internal fun PosterCardText( internal fun buildPosterCardTextShadow() = Shadow( color = Color.Black.copy(alpha = 0.4f), blurRadius = 15f -) \ No newline at end of file +) + +private fun buildTextBackgroundGradientBrush(backgroundType: PosterCardBackgroundType): Brush = + if (backgroundType.inverseDisplay) { + Brush.verticalGradient( + colorStops = arrayOf( + 0.0f to Color.Black.copy(alpha = 0f), + 0.3f to Color.Black.copy(alpha = 0.4f), + 1.0f to Color.Black.copy(alpha = 0.7f) + ) + ) + } else { + SolidColor(Color.Transparent) + } \ No newline at end of file diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt index 1b5bed866..e8d044568 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt @@ -54,7 +54,7 @@ internal fun PosterCardGradientColor() { ), aspectRatio = PosterCardAspectRatio.AR_16_9, backgroundType = PosterCardBackgroundType.Color( - brush = Brush.verticalGradient(colors = listOf(Color.Blue, Color.LightGray)), + brush = Brush.verticalGradient(colors = listOf(Color.Magenta, Color.Red)), inverseDisplay = true ), headline = Tag(content = TAG_HEADLINE_VALUE), @@ -72,7 +72,7 @@ internal fun PosterCardImage() { MisticaTheme(brand = TuBrand) { PosterCard( modifier = Modifier.fillMaxWidth(), - aspectRatio = PosterCardAspectRatio.AR_7_10, + aspectRatio = PosterCardAspectRatio.AR_16_9, backgroundType = PosterCardBackgroundType.Image(imageResource = R.drawable.sample_background), headline = Tag(content = TAG_HEADLINE_VALUE), preTitle = PRE_TITLE_VALUE, @@ -91,7 +91,7 @@ internal fun CustomLowerContent() { Box( modifier = Modifier .fillMaxWidth() - .size(40.dp) + .size(150.dp) .background(color = MisticaTheme.colors.successHighInverse.copy(alpha = 0.5f)) .border(width = 1.dp, color = MisticaTheme.colors.success), contentAlignment = Alignment.Center diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index bc6dfed4e..fd45a2221 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -52,13 +52,17 @@ internal fun TopAction(topActionData: TopActionData) { .size(40.dp) .clip(CircleShape) .background(color = backgroundColor) - .clickable { topActionData.onClick?.invoke() } .wrapContentSize(align = Alignment.Center) + .let { modifierValue -> + topActionData.onClick?.let { + modifierValue.clickable { it() } + } ?: modifierValue + } ) { Image( painter = painterResource(id = iconRes), contentDescription = contentDescription, - colorFilter = iconTint?.let { ColorFilter.tint(iconTint) }, + colorFilter = iconTint?.let { ColorFilter.tint(it) }, contentScale = ContentScale.Crop ) } @@ -67,9 +71,9 @@ internal fun TopAction(topActionData: TopActionData) { data class TopActionData( val iconRes: Int, - val iconTint: Color?, val backgroundColor: Color = Color.Transparent, + val iconTint: Color? = null, val contentDescription: String? = null, + val testTag: String? = null, val onClick: (() -> Unit)? = null, - val testTag: String? = null ) \ No newline at end of file From 2d4f90c7d95eb2264283b881802fd02eed06e67c Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 25 Nov 2024 08:32:58 +0100 Subject: [PATCH 16/39] dhonti/ANDROID-15405-postercard: Create README.md file in "postercard" folder and linking with main README.md library --- README.md | 1 + .../mistica/compose/card/postercard/README.md | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md diff --git a/README.md b/README.md index 94d36fb5b..1e643b6fc 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ Just set your App or any specific activity to use any of the following: * [Load Error Feedback](library/src/main/java/com/telefonica/mistica/feedback/error) * [Media Cards](library/src/main/java/com/telefonica/mistica/card/mediacard) * [Pop Overs](library/src/main/java/com/telefonica/mistica/feedback/popover) +* [Poster Card](library/src/main/java/com/telefonica/mistica/card/postercard) * [Screen Feedbacks](library/src/main/java/com/telefonica/mistica/feedback/screen) * [Scroll Content Indicator](library/src/main/java/com/telefonica/mistica/contentindicator) * [Sheet](library/src/main/java/com/telefonica/mistica/sheet) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md new file mode 100644 index 000000000..b83671a03 --- /dev/null +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md @@ -0,0 +1,11 @@ +# Poster Card + +This component allows you to display content organized by the following sections: +* Tag +* Pretitle +* Title +* Subtitle +* Description + +Whose background can be a color (solid or gradient) or an image. +In addition, up to a maximum of 2 actions can be defined, which will be displayed in the upper right corner inside. \ No newline at end of file From d877419653f2469e22e8b9e67018dbe4b8a64535 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 25 Nov 2024 08:36:12 +0100 Subject: [PATCH 17/39] dhonti/ANDROID-15405-postercard: Fixed linking to "compose" folder --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1e643b6fc..4f774d445 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ Just set your App or any specific activity to use any of the following: * [Load Error Feedback](library/src/main/java/com/telefonica/mistica/feedback/error) * [Media Cards](library/src/main/java/com/telefonica/mistica/card/mediacard) * [Pop Overs](library/src/main/java/com/telefonica/mistica/feedback/popover) -* [Poster Card](library/src/main/java/com/telefonica/mistica/card/postercard) +* [Poster Card](library/src/main/java/com/telefonica/mistica/compose/card/postercard) * [Screen Feedbacks](library/src/main/java/com/telefonica/mistica/feedback/screen) * [Scroll Content Indicator](library/src/main/java/com/telefonica/mistica/contentindicator) * [Sheet](library/src/main/java/com/telefonica/mistica/sheet) From af8fb308f1ca9bba5a8851d9429c997e1ebe3eba Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 25 Nov 2024 09:50:25 +0100 Subject: [PATCH 18/39] dhonti/ANDRID-15405-postercard: Update location "sample_background" --- .../sample_background.jpg | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename library/src/main/res/{drawable => drawable-nodpi}/sample_background.jpg (100%) diff --git a/library/src/main/res/drawable/sample_background.jpg b/library/src/main/res/drawable-nodpi/sample_background.jpg similarity index 100% rename from library/src/main/res/drawable/sample_background.jpg rename to library/src/main/res/drawable-nodpi/sample_background.jpg From cea0eb5b3ffbdebe25fdf50cf1940081419b827a Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 25 Nov 2024 10:07:35 +0100 Subject: [PATCH 19/39] dhonti/ANDROID-15405-postercard: Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eba2dd5a4..0bc497fbc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,6 +11,8 @@ Don't hesitate to ask any questions and share your ideas We would love to accept your Pull Requests but please, before starting your development, [create an issue](https://github.com/Telefonica/mistica-android/issues/new/choose). +Include someone from **Telefonica/mistica-design** team as reviewer. + ## Bug reports If something is broken or not working as expected, let us know! From 6c1f09ad03d76b7be023c7c1a84f4088a93d89b4 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 25 Nov 2024 10:20:10 +0100 Subject: [PATCH 20/39] dhonti/ANDROID-15405-postercard: Update PosterCard README file --- .../mistica/compose/card/postercard/README.md | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md index b83671a03..16f14aa90 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md @@ -8,4 +8,26 @@ This component allows you to display content organized by the following sections * Description Whose background can be a color (solid or gradient) or an image. -In addition, up to a maximum of 2 actions can be defined, which will be displayed in the upper right corner inside. \ No newline at end of file +In addition, up to a maximum of 2 actions can be defined, which will be displayed in the upper right corner inside. + +```kotlin +PosterCard( + firstTopAction = TopActionData( + iconRes = R.drawable.icn_visibility, + backgroundColor = MisticaTheme.colors.backgroundAlternative, + iconTint = MisticaTheme.colors.brand, + ), + secondTopAction = TopActionData( + iconRes = R.drawable.ic_close_regular, + backgroundColor = MisticaTheme.colors.backgroundAlternative, + iconTint = MisticaTheme.colors.brand, + ), + aspectRatio = PosterCardAspectRatio.AR_16_9, + backgroundType = PosterCardBackgroundType.Color(brush = SolidColor(MisticaTheme.colors.background), inverseDisplay = false), + headline = Tag(content = "Headline"), + preTitle = "Pretitle", + title = "Title", + subtitle = "Subtitle", + description = "Description" +) +``` \ No newline at end of file From e1fbfc49ce46300eecc5e3b35508d5a3eb0aedc0 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 25 Nov 2024 18:47:18 +0100 Subject: [PATCH 21/39] dhonti/ANDROID-15405-postercard: Applied some corrections proposed by @haynlo --- .../mistica/compose/card/postercard/PosterCard.kt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 9cd11b5f5..83f708fcf 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -1,6 +1,5 @@ package com.telefonica.mistica.compose.card.postercard -import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.BoxWithConstraints @@ -12,7 +11,6 @@ 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.graphics.Color import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.telefonica.mistica.compose.tag.Tag @@ -36,9 +34,7 @@ fun PosterCard( BoxWithConstraints(modifier = modifier) { androidx.compose.material.Card( elevation = 0.dp, - backgroundColor = Color.Red, - shape = RoundedCornerShape(16.dp), - border = BorderStroke(width = 1.dp, color = MisticaTheme.colors.border), + shape = RoundedCornerShape(MisticaTheme.radius.containerBorderRadius), modifier = Modifier .width(maxWidth) .let { modifierValue -> From 91ca8546f3096629afe6e6c50d3c82ae7a6b7377 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 25 Nov 2024 22:30:05 +0100 Subject: [PATCH 22/39] dhonti/ANDROID-15405-postercard: Update modifier function in order to accept a clickable() and update param "contentDescription" --- .../mistica/compose/card/postercard/PosterCard.kt | 14 ++++++-------- .../card/postercard/PosterCardTopActions.kt | 11 +++++------ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 83f708fcf..703f41a11 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -37,15 +37,13 @@ fun PosterCard( shape = RoundedCornerShape(MisticaTheme.radius.containerBorderRadius), modifier = Modifier .width(maxWidth) - .let { modifierValue -> - onClickAction?.let { - modifierValue.clickable { it.invoke() } - } - modifierValue.heightIn( - min = maxWidth / aspectRatio.ratio, - max = Dp.Infinity - ) + .clickable(enabled = onClickAction != null) { + onClickAction?.invoke() } + .heightIn( + min = maxWidth / aspectRatio.ratio, + max = Dp.Infinity + ) ) { PosterCardBackground(backgroundType = backgroundType) { Column( diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index fd45a2221..57128d83e 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -51,13 +51,12 @@ internal fun TopAction(topActionData: TopActionData) { .testTag(topActionData.testTag.orEmpty()) .size(40.dp) .clip(CircleShape) + .clickable(enabled = topActionData.onClick != null) { + topActionData.onClick?.invoke() + } .background(color = backgroundColor) .wrapContentSize(align = Alignment.Center) - .let { modifierValue -> - topActionData.onClick?.let { - modifierValue.clickable { it() } - } ?: modifierValue - } + ) { Image( painter = painterResource(id = iconRes), @@ -72,8 +71,8 @@ internal fun TopAction(topActionData: TopActionData) { data class TopActionData( val iconRes: Int, val backgroundColor: Color = Color.Transparent, + val contentDescription: String = "", val iconTint: Color? = null, - val contentDescription: String? = null, val testTag: String? = null, val onClick: (() -> Unit)? = null, ) \ No newline at end of file From 97a3b6921d31ffe3f9bf6304fd878824a9821f28 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 25 Nov 2024 22:33:50 +0100 Subject: [PATCH 23/39] dhonti/ANDROID-15405-postercard: Update clickable() in modifier action --- .../mistica/compose/card/postercard/PosterCardTopActions.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index 57128d83e..5aeee4df0 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -48,11 +48,11 @@ internal fun TopAction(topActionData: TopActionData) { with(topActionData) { Box( modifier = Modifier - .testTag(topActionData.testTag.orEmpty()) + .testTag(testTag.orEmpty()) .size(40.dp) .clip(CircleShape) - .clickable(enabled = topActionData.onClick != null) { - topActionData.onClick?.invoke() + .clickable(enabled = onClick != null) { + onClick?.invoke() } .background(color = backgroundColor) .wrapContentSize(align = Alignment.Center) From 3586a3619766976126a880f192d1e7a0d9889750 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Tue, 26 Nov 2024 09:24:37 +0100 Subject: [PATCH 24/39] dhonti/ANDROID-15405-postercard: New way to manage top actions list processing --- .../ui/compose/components/PosterCards.kt | 38 ++++++++++--------- .../compose/card/postercard/PosterCard.kt | 17 ++++++--- .../card/postercard/PosterCardPreviews.kt | 20 +++++----- .../card/postercard/PosterCardTopActions.kt | 13 +++---- 4 files changed, 48 insertions(+), 40 deletions(-) diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt index 8276d9ea1..47a582fdf 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt @@ -148,8 +148,7 @@ fun PosterCards() { AdditionalContent() } }, - firstTopAction = topActionsType.info?.firstTopAction, - secondTopAction = topActionsType.info?.secondTopAction + topActionsList = topActionsType.info?.topActionsList ) } } @@ -194,32 +193,35 @@ private enum class TopActionsType(val info: PosterCardTopActionInfo? = null) { NONE, ONE_ACTION_DISMISS( info = PosterCardTopActionInfo( - firstTopAction = TopActionData( - iconRes = R.drawable.ic_close_regular, - backgroundColor = Color.White, - iconTint = Color.DarkGray, + topActionsList = listOf( + TopActionData( + iconRes = R.drawable.ic_close_regular, + backgroundColor = Color.White, + iconTint = Color.DarkGray, + ) ) ) ), TWO_ACTIONS( info = PosterCardTopActionInfo( - firstTopAction = TopActionData( - iconRes = R.drawable.icn_visibility, - backgroundColor = Color.White, - iconTint = Color.Gray - ), - secondTopAction = TopActionData( - iconRes = R.drawable.ic_close_regular, - backgroundColor = Color.White, - iconTint = Color.DarkGray - ), + topActionsList = listOf( + TopActionData( + iconRes = R.drawable.icn_visibility, + backgroundColor = Color.White, + iconTint = Color.Gray + ), + TopActionData( + iconRes = R.drawable.ic_close_regular, + backgroundColor = Color.White, + iconTint = Color.DarkGray + ) + ) ) ) } private data class PosterCardTopActionInfo( - val firstTopAction: TopActionData? = null, - val secondTopAction: TopActionData? = null, + val topActionsList: List? = null, ) @Composable diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 703f41a11..436b7d89b 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -4,6 +4,8 @@ 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 @@ -26,8 +28,7 @@ fun PosterCard( title: String? = null, subtitle: String? = null, description: String? = null, - firstTopAction: TopActionData? = null, - secondTopAction: TopActionData? = null, + topActionsList: List? = null, onClickAction: (() -> Unit)? = null, customContent: (@Composable () -> Unit)? = null, ) { @@ -50,6 +51,9 @@ fun PosterCard( modifier = Modifier.align(alignment = Alignment.BottomCenter), verticalArrangement = Arrangement.Bottom ) { + if (topActionsList.areLoaded()) { + Spacer(modifier = Modifier.height(40.dp)) + } PosterCardMainContent( backgroundType = backgroundType, tag = headline, @@ -60,19 +64,20 @@ fun PosterCard( customContent = customContent ) } - if (firstTopAction != null || secondTopAction != null) { + if (topActionsList.areLoaded()) { PosterCardTopActions( modifier = Modifier.align(alignment = Alignment.TopCenter), - firstTopAction = firstTopAction, - secondTopAction = secondTopAction + topActionsList = topActionsList!! ) } } } } - } +private fun List?.areLoaded(): Boolean = + !this.isNullOrEmpty() && size <= 2 + enum class PosterCardAspectRatio(val ratio: Float) { AR_AUTO(ratio = Float.NaN), AR_1_1(ratio = 1f), diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt index e8d044568..27dd836e7 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt @@ -42,15 +42,17 @@ internal fun PosterCardSolidColor() { internal fun PosterCardGradientColor() { MisticaTheme(brand = TuBrand) { PosterCard( - firstTopAction = TopActionData( - iconRes = R.drawable.icn_visibility, - backgroundColor = MisticaTheme.colors.backgroundAlternative, - iconTint = MisticaTheme.colors.brand, - ), - secondTopAction = TopActionData( - iconRes = R.drawable.ic_close_regular, - backgroundColor = MisticaTheme.colors.backgroundAlternative, - iconTint = MisticaTheme.colors.brand, + topActionsList = listOf( + TopActionData( + iconRes = R.drawable.icn_visibility, + backgroundColor = MisticaTheme.colors.backgroundAlternative, + iconTint = MisticaTheme.colors.brand, + ), + TopActionData( + iconRes = R.drawable.ic_close_regular, + backgroundColor = MisticaTheme.colors.backgroundAlternative, + iconTint = MisticaTheme.colors.brand, + ) ), aspectRatio = PosterCardAspectRatio.AR_16_9, backgroundType = PosterCardBackgroundType.Color( diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index 5aeee4df0..0e795822c 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -25,7 +25,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp @Composable -internal fun PosterCardTopActions(modifier: Modifier = Modifier, firstTopAction: TopActionData?, secondTopAction: TopActionData?) { +internal fun PosterCardTopActions(modifier: Modifier = Modifier, topActionsList: List) { Row( modifier = modifier .fillMaxWidth() @@ -33,12 +33,11 @@ internal fun PosterCardTopActions(modifier: Modifier = Modifier, firstTopAction: horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically ) { - firstTopAction?.let { - TopAction(topActionData = it) - } - secondTopAction?.let { - Spacer(modifier = Modifier.width(16.dp)) - TopAction(topActionData = it) + topActionsList.forEachIndexed { index, topActionData -> + TopAction(topActionData = topActionData) + if( index!=topActionsList.lastIndex ){ + Spacer(modifier = Modifier.width(16.dp)) + } } } } From 573a30407122cdfae327b48a93fb953fbcd0a9c3 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Tue, 26 Nov 2024 09:58:12 +0100 Subject: [PATCH 25/39] dhonti/ANDROID-15405-postercard: Update corresponding README.md postercard --- .../mistica/compose/card/postercard/README.md | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md index 16f14aa90..11526276a 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md @@ -12,15 +12,17 @@ In addition, up to a maximum of 2 actions can be defined, which will be displaye ```kotlin PosterCard( - firstTopAction = TopActionData( - iconRes = R.drawable.icn_visibility, - backgroundColor = MisticaTheme.colors.backgroundAlternative, - iconTint = MisticaTheme.colors.brand, - ), - secondTopAction = TopActionData( - iconRes = R.drawable.ic_close_regular, - backgroundColor = MisticaTheme.colors.backgroundAlternative, - iconTint = MisticaTheme.colors.brand, + topActionsList = listOf( + TopActionData( + iconRes = R.drawable.icn_visibility, + backgroundColor = MisticaTheme.colors.backgroundAlternative, + iconTint = MisticaTheme.colors.brand, + ), + TopActionData( + iconRes = R.drawable.ic_close_regular, + backgroundColor = MisticaTheme.colors.backgroundAlternative, + iconTint = MisticaTheme.colors.brand, + ) ), aspectRatio = PosterCardAspectRatio.AR_16_9, backgroundType = PosterCardBackgroundType.Color(brush = SolidColor(MisticaTheme.colors.background), inverseDisplay = false), From faf034f9b6957d29d7f73a0168d2e01dc649c81f Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Wed, 27 Nov 2024 08:30:46 +0100 Subject: [PATCH 26/39] dhonti/ANDROID-15405-postercard: Update use the "cardContentOverlay" in background shadow main content text --- .../card/postercard/PosterCardMainContent.kt | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt index f4e5b77c8..662202052 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt @@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shadow import androidx.compose.ui.graphics.SolidColor @@ -31,7 +30,13 @@ internal fun PosterCardMainContent( Column( modifier = modifier .fillMaxWidth() - .background(brush = buildTextBackgroundGradientBrush(backgroundType = backgroundType)) + .background( + brush = if (backgroundType.inverseDisplay) { + MisticaTheme.brushes.cardContentOverlay + } else { + SolidColor(Color.Transparent) + } + ) .padding( top = 16.dp, start = 16.dp, @@ -117,16 +122,3 @@ internal fun buildPosterCardTextShadow() = Shadow( color = Color.Black.copy(alpha = 0.4f), blurRadius = 15f ) - -private fun buildTextBackgroundGradientBrush(backgroundType: PosterCardBackgroundType): Brush = - if (backgroundType.inverseDisplay) { - Brush.verticalGradient( - colorStops = arrayOf( - 0.0f to Color.Black.copy(alpha = 0f), - 0.3f to Color.Black.copy(alpha = 0.4f), - 1.0f to Color.Black.copy(alpha = 0.7f) - ) - ) - } else { - SolidColor(Color.Transparent) - } \ No newline at end of file From ef9ca70dbd89b026ba3901740da2e7e1ebde242e Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Wed, 27 Nov 2024 11:30:43 +0100 Subject: [PATCH 27/39] dhonti/ANDROID-15405-postercard: - Update TopAction components background according to Mistica color values and make them clickables --- .../ui/compose/components/PosterCards.kt | 18 ++---------- .../compose/card/postercard/PosterCard.kt | 2 +- .../card/postercard/PosterCardPreviews.kt | 12 ++------ .../card/postercard/PosterCardTopActions.kt | 29 +++++++++++++------ 4 files changed, 26 insertions(+), 35 deletions(-) diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt index 47a582fdf..615421def 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt @@ -194,27 +194,15 @@ private enum class TopActionsType(val info: PosterCardTopActionInfo? = null) { ONE_ACTION_DISMISS( info = PosterCardTopActionInfo( topActionsList = listOf( - TopActionData( - iconRes = R.drawable.ic_close_regular, - backgroundColor = Color.White, - iconTint = Color.DarkGray, - ) + TopActionData(iconRes = R.drawable.ic_close_regular) ) ) ), TWO_ACTIONS( info = PosterCardTopActionInfo( topActionsList = listOf( - TopActionData( - iconRes = R.drawable.icn_visibility, - backgroundColor = Color.White, - iconTint = Color.Gray - ), - TopActionData( - iconRes = R.drawable.ic_close_regular, - backgroundColor = Color.White, - iconTint = Color.DarkGray - ) + TopActionData(iconRes = R.drawable.icn_visibility), + TopActionData(iconRes = R.drawable.ic_close_regular) ) ) ) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 436b7d89b..1c1c2e293 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -38,7 +38,7 @@ fun PosterCard( shape = RoundedCornerShape(MisticaTheme.radius.containerBorderRadius), modifier = Modifier .width(maxWidth) - .clickable(enabled = onClickAction != null) { + .clickable(enabled = onClickAction!=null) { onClickAction?.invoke() } .heightIn( diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt index 27dd836e7..922cca3a0 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt @@ -43,16 +43,8 @@ internal fun PosterCardGradientColor() { MisticaTheme(brand = TuBrand) { PosterCard( topActionsList = listOf( - TopActionData( - iconRes = R.drawable.icn_visibility, - backgroundColor = MisticaTheme.colors.backgroundAlternative, - iconTint = MisticaTheme.colors.brand, - ), - TopActionData( - iconRes = R.drawable.ic_close_regular, - backgroundColor = MisticaTheme.colors.backgroundAlternative, - iconTint = MisticaTheme.colors.brand, - ) + TopActionData(iconRes = R.drawable.icn_visibility), + TopActionData(iconRes = R.drawable.ic_close_regular) ), aspectRatio = PosterCardAspectRatio.AR_16_9, backgroundType = PosterCardBackgroundType.Color( diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index 0e795822c..ea950ed79 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp +import com.telefonica.mistica.compose.theme.MisticaTheme @Composable internal fun PosterCardTopActions(modifier: Modifier = Modifier, topActionsList: List) { @@ -35,7 +36,7 @@ internal fun PosterCardTopActions(modifier: Modifier = Modifier, topActionsList: ) { topActionsList.forEachIndexed { index, topActionData -> TopAction(topActionData = topActionData) - if( index!=topActionsList.lastIndex ){ + if (index != topActionsList.lastIndex) { Spacer(modifier = Modifier.width(16.dp)) } } @@ -50,17 +51,27 @@ internal fun TopAction(topActionData: TopActionData) { .testTag(testTag.orEmpty()) .size(40.dp) .clip(CircleShape) - .clickable(enabled = onClick != null) { - onClick?.invoke() - } - .background(color = backgroundColor) + .clickable { onClick() } + .background( + color = when { + isInverse -> Color.Transparent + withBackground -> MisticaTheme.colors.inverse.copy(alpha = 0.8f) + else -> Color.Transparent + } + ) .wrapContentSize(align = Alignment.Center) ) { Image( painter = painterResource(id = iconRes), contentDescription = contentDescription, - colorFilter = iconTint?.let { ColorFilter.tint(it) }, + colorFilter = ColorFilter.tint( + if (isInverse) { + MisticaTheme.colors.inverse + } else { + MisticaTheme.colors.neutralHigh + } + ), contentScale = ContentScale.Crop ) } @@ -69,9 +80,9 @@ internal fun TopAction(topActionData: TopActionData) { data class TopActionData( val iconRes: Int, - val backgroundColor: Color = Color.Transparent, val contentDescription: String = "", - val iconTint: Color? = null, val testTag: String? = null, - val onClick: (() -> Unit)? = null, + val withBackground: Boolean = true, + val isInverse: Boolean = false, + val onClick: () -> Unit = {}, ) \ No newline at end of file From f1f1d21c7e7760b07d35c19df2b70df84537f464 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Wed, 27 Nov 2024 12:29:20 +0100 Subject: [PATCH 28/39] dhonti/ANDROID-15405-postercard: Update top actions management in code --- .../ui/compose/components/PosterCards.kt | 18 ++++++++---------- .../compose/card/postercard/PosterCard.kt | 15 ++++++++------- .../card/postercard/PosterCardPreviews.kt | 7 +++---- .../card/postercard/PosterCardTopActions.kt | 15 +++++++++++---- .../mistica/compose/card/postercard/README.md | 14 ++------------ 5 files changed, 32 insertions(+), 37 deletions(-) diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt index 615421def..74994342c 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt @@ -143,12 +143,13 @@ fun PosterCards() { title = title.getOrNullIfEmpty(), subtitle = subtitle.getOrNullIfEmpty(), description = description.getOrNullIfEmpty(), + firstTopAction = topActionsType.info?.firstTopAction, + secondTopAction = topActionsType.info?.secondTopAction, customContent = { if (withAdditionalContent) { AdditionalContent() } - }, - topActionsList = topActionsType.info?.topActionsList + } ) } } @@ -193,23 +194,20 @@ private enum class TopActionsType(val info: PosterCardTopActionInfo? = null) { NONE, ONE_ACTION_DISMISS( info = PosterCardTopActionInfo( - topActionsList = listOf( - TopActionData(iconRes = R.drawable.ic_close_regular) - ) + firstTopAction = TopActionData(iconRes = R.drawable.ic_close_regular) ) ), TWO_ACTIONS( info = PosterCardTopActionInfo( - topActionsList = listOf( - TopActionData(iconRes = R.drawable.icn_visibility), - TopActionData(iconRes = R.drawable.ic_close_regular) - ) + firstTopAction = TopActionData(iconRes = R.drawable.icn_visibility), + secondTopAction = TopActionData(iconRes = R.drawable.ic_close_regular) ) ) } private data class PosterCardTopActionInfo( - val topActionsList: List? = null, + val firstTopAction: TopActionData? = null, + val secondTopAction: TopActionData? = null ) @Composable diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 1c1c2e293..444409540 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -28,10 +28,13 @@ fun PosterCard( title: String? = null, subtitle: String? = null, description: String? = null, - topActionsList: List? = 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, @@ -51,7 +54,7 @@ fun PosterCard( modifier = Modifier.align(alignment = Alignment.BottomCenter), verticalArrangement = Arrangement.Bottom ) { - if (topActionsList.areLoaded()) { + if (anyTopActionsLoaded) { Spacer(modifier = Modifier.height(40.dp)) } PosterCardMainContent( @@ -64,10 +67,11 @@ fun PosterCard( customContent = customContent ) } - if (topActionsList.areLoaded()) { + if (anyTopActionsLoaded) { PosterCardTopActions( modifier = Modifier.align(alignment = Alignment.TopCenter), - topActionsList = topActionsList!! + firstTopAction = firstTopAction, + secondTopAction = secondTopAction ) } } @@ -75,9 +79,6 @@ fun PosterCard( } } -private fun List?.areLoaded(): Boolean = - !this.isNullOrEmpty() && size <= 2 - enum class PosterCardAspectRatio(val ratio: Float) { AR_AUTO(ratio = Float.NaN), AR_1_1(ratio = 1f), diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt index 922cca3a0..b8cf7a4e1 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt @@ -42,10 +42,8 @@ internal fun PosterCardSolidColor() { internal fun PosterCardGradientColor() { MisticaTheme(brand = TuBrand) { PosterCard( - topActionsList = listOf( - TopActionData(iconRes = R.drawable.icn_visibility), - TopActionData(iconRes = R.drawable.ic_close_regular) - ), + firstTopAction = TopActionData(iconRes = R.drawable.icn_visibility), + secondTopAction = TopActionData(iconRes = R.drawable.ic_close_regular), aspectRatio = PosterCardAspectRatio.AR_16_9, backgroundType = PosterCardBackgroundType.Color( brush = Brush.verticalGradient(colors = listOf(Color.Magenta, Color.Red)), @@ -65,6 +63,7 @@ internal fun PosterCardGradientColor() { internal fun PosterCardImage() { MisticaTheme(brand = TuBrand) { PosterCard( + firstTopAction = TopActionData(iconRes = R.drawable.icn_visibility), modifier = Modifier.fillMaxWidth(), aspectRatio = PosterCardAspectRatio.AR_16_9, backgroundType = PosterCardBackgroundType.Image(imageResource = R.drawable.sample_background), diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index ea950ed79..066e6c917 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -26,7 +26,11 @@ import androidx.compose.ui.unit.dp import com.telefonica.mistica.compose.theme.MisticaTheme @Composable -internal fun PosterCardTopActions(modifier: Modifier = Modifier, topActionsList: List) { +internal fun PosterCardTopActions( + modifier: Modifier = Modifier, + firstTopAction: TopActionData?, + secondTopAction: TopActionData? +) { Row( modifier = modifier .fillMaxWidth() @@ -34,11 +38,14 @@ internal fun PosterCardTopActions(modifier: Modifier = Modifier, topActionsList: horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically ) { - topActionsList.forEachIndexed { index, topActionData -> - TopAction(topActionData = topActionData) - if (index != topActionsList.lastIndex) { + firstTopAction?.let { + TopAction(topActionData = it) + } + secondTopAction?.let { + if (firstTopAction != null) { Spacer(modifier = Modifier.width(16.dp)) } + TopAction(topActionData = it) } } } diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md index 11526276a..3a166775b 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/README.md @@ -12,18 +12,8 @@ In addition, up to a maximum of 2 actions can be defined, which will be displaye ```kotlin PosterCard( - topActionsList = listOf( - TopActionData( - iconRes = R.drawable.icn_visibility, - backgroundColor = MisticaTheme.colors.backgroundAlternative, - iconTint = MisticaTheme.colors.brand, - ), - TopActionData( - iconRes = R.drawable.ic_close_regular, - backgroundColor = MisticaTheme.colors.backgroundAlternative, - iconTint = MisticaTheme.colors.brand, - ) - ), + firstTopAction = TopActionData(iconRes = R.drawable.icn_visibility), + secondTopAction = TopActionData(iconRes = R.drawable.ic_close_regular), aspectRatio = PosterCardAspectRatio.AR_16_9, backgroundType = PosterCardBackgroundType.Color(brush = SolidColor(MisticaTheme.colors.background), inverseDisplay = false), headline = Tag(content = "Headline"), From 2d4ce56a8a873a5127542872ed114ca4ee253670 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Thu, 28 Nov 2024 15:42:18 +0100 Subject: [PATCH 29/39] dhonti/ANDROID-15405-postercard: Update resource to catalog and change format to WEBP --- .../res/drawable-nodpi/sample_background.webp | Bin 0 -> 21422 bytes .../res/drawable-nodpi/sample_background.jpg | Bin 29995 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 catalog/src/main/res/drawable-nodpi/sample_background.webp delete mode 100644 library/src/main/res/drawable-nodpi/sample_background.jpg diff --git a/catalog/src/main/res/drawable-nodpi/sample_background.webp b/catalog/src/main/res/drawable-nodpi/sample_background.webp new file mode 100644 index 0000000000000000000000000000000000000000..70dcdc96ba19ac9751379132ce6e73b54bb560e1 GIT binary patch literal 21422 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 MjU#ge1gxY0032Hqz5oCK literal 0 HcmV?d00001 diff --git a/library/src/main/res/drawable-nodpi/sample_background.jpg b/library/src/main/res/drawable-nodpi/sample_background.jpg deleted file mode 100644 index a425b181d7ee133e9b461277b5634d8c4dc66269..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29995 zcmb5VcRZE0Mv|BG>lYdUjZ%vprQJA0RQ)( zqNbreM|U24QsD|fO-)5h4balj08}*8|8A)nZ__YIs2bSQN_xIxzGIkMGki`h?kOEh zJGU1rkCe30rh5F`zlFgi|F`o0T^D@szlAS=Pl_=9?~>rs)ZpKB?%&0!7^!KPZcC`r zG8@>RW4Qw^o~vdUSF_oEHU%)yP=UWO4I`ie9Me+r*K`1dr~=XpyZ20Y1A1IrX8A%-G44}-S$z# zW`Egp+s&Ueii-_V`>uO@GMk$=ZHI1DH*4#Tp<*L9kAlPqM`^&r(*OM^mtS-!Oto5m z22kHP1IUGWxMYeOl}c@OfPPV`7#wljr0{^xU-&r^QBTmwv@&x%z4nZMYdJ?&=zCVHW^YrDRR*$Znjz z1r#0u)cLdL{?N_X-4}4OVH)%Jw#Y{j`?gZej8-8FZ-snU+%G%>CSr`&EQU{Q&j3=# z8BliyV3H&|4IX})OP^aljaD{n%Tv^zAmllH`Tk@>{kEbYsVJFtRhS_Bez)U@v-Avj zIfy>}TC7eY>y&izn{s`k7kcwZ(KW&19sEtRk4sj{Uckl43TFKnt!7CQ`9(HT9QKa- zA%4i&e=S;p-#3Ruz6gIM-Q>eVksw~^MA<;<_nCYkME9$7H#Q!S-bxVYIML7vjD7~S z4@4Z0P3Bc*0F-Vii6r*48(&`iQ z86aOPBWbsmiwdIK&_Mk?`tW+O(% zg#K!w@lkhgIsfoJ88u!fuW$yq*^z>Dmv}~RO+Vi#|LX)N?}qGjp8>^NDkoc~9CNFE z(BbuvmBce(sbOi^AcQ8pA^QN5{Vrtf3?NRqo#ykFRy|WT+(>!sGvrWDb@LWL4bZ)K z0O-Csnc&q9?cyontVX@mlj+h>n#R+;{M7n2vFOe1bH~_&_XFi78i1 zXY3LorBp7(Lr@`F^0}A^Id#-mLf|bra?*MfrlgHl&h|kYFMe3$*YSHpC{Oo?QzY*e zr-<+QRLE>t7{|h#Gw6W@v-K521Eo?{v9z;^hM9$nPbrK0$H5i_sHq5yFJa zFV=0VQGZ`SaBOo?B(hup7`L%?x<)>?Q9E3p7)7rJ$zBWgpe=MDku!NZz*yVSL5obk z=^b&~3*g1Et*%FUfyKjP;+=R0s^gH^qXiQ)fi=bG;dy(7YGe;Tr{}R}%we68LkGsS zc;1%rmt(4eYq6v-A9ci^m-R0rVQ5+6;((#e8~tmun6k+Cg*Y*qgbln@7PCz*Nr%Ac^m@a$n42T*I8boK4VuGz_mddl=W%mcz$E09t z77A>(m+`|IMakT5zelJZZ^HOM* zAfBon9^Z(i)L5rdPQ;&3)zXU}1u0B9ZohlKfgzN5eh0XMFrVkCJh_8=cCOds^Wh^H z@8{1KA0uZy!;qHbakqE6k{d0}5JVTt)X(EOjdGQ|Fi{+KktLBB9ML|B3r;PH{KflUC=JFCj%~w7-<*n^4FB0m9ItJ3 zm^$VXiyEBA>M7GXrv#%^Yo)Bb^UX7=Mn#mpyG+j5 z`AT9$rL@gTro(n0W#r*+bwy9q5&5rIBU{ZSOxM%#)Eb#dAL~q-(O~(-@uMqKndZ&# zW3;6BOlmYd%!`a1|CtK&5&2#Fac5M{v02lHUqJaQ`%YQNiX(>jfDHq~-TZY1JoOFW z9XO<)>$SFzCk93t?&ucO47m>~6m31xE#x1gHr!E1cyaz2ERfSenUP}jgr4=|*%tgE zI8%ob0#49`D47iP6GCCP{xl?&*N!?Kg}fvL*wSoHd2mV3XCEsI&DDqOsc_`y9{#

W#7hm0TP1>424aI8g^ zv28q%UXz>qQ1BU0k=%iAm|sq(yeb8>J7ZGjZ{B6^)BhZpw|4uuUFW|o0sue#MxB4i zX$l!SwWFonQNc0!0GVlO5^ys2HIp=6RXDB#{_gZMO~yh$15?h$Qf?+=m06(&0PX)m zjq-nD4^YVg>mbb`0Q|2Uf)#R~SK)3FMTGB4fjC6Rn5;MSSvc|`tFzayXsi0vbW^ru zBi!R&zfA;(fKVg`w(WF)X({47^!@>sM1CC;m{CajB+T5fPpk>`4XMn^GPPzQGBcFw ziGtzSZim0b2UCIPBw&RdcstVgSkH%bY090>Vmo!DiE;#MXVLuHW#4>h@{44Pb19#uUn%lR zAAIJwx7GeK{_JJ{l>LpAVFgBZu^()Q_V-%QYfy#T+Axz3&&hZGl#6NPC zo_Xlos19TJ3;TNnFN%f>c8K@EPCZf?f)th18$WuC4WLb_=>HSvGl3QTN_t%|>e47+ z_RL~s7x+wyRAk%GSno4t@8nnO)_sruEEYk++=k%j2YeUhG+O6%d^9qDsv}rP96iLg z+uZVCXm{0e`6ll_pY7dR@B1UEYvL8s7 zJcYL_w&h$*euf}EvkH3C3y?}FT=heblx<7c|8<<3;v+c&B&w{~5W6cE;XUl%NBU`d z$_`pP3ozJt2bLysb;Z5FZ==EnS&CY5mjaMB0qOu)a;dd1rg?`L;&emvXsGxdE>41# z^M3(*e)r!U)$Rj;Srh;+fTt%f0sU{?9yK!dchnp|UvH!)k$H%DR@DG32R89pIEE6M zp2yq&x~Ii9OtxY&SJE_o)3#{qokiOjP%^G#>#c53$op<3b~II6xmOI+=C;O*ml)cA zUm?(&t>07TS9Lo%Z_6ubLjw!POAkI8FeVkTy^YJ(OXf9WmZxiZQH%K~)qe&^6bH~- zgcQ{6oB>A<3za$L8y2oV>VsRu4A|W9TSq(o{Q8%qj!P$tmWBu6%t`6LM6-Vk%N_{s zZQMBGqING&EyB0M8a^BL?0%Yl!|^;!X*voXnw9vkutrbUiVt)yG%8KFy(i`z=WCc;S{-mi}M7JxYS~YO$JMEyG-V0v=E($0`0iPE#!pevRSkD ze0bV#p7jo6u1~?U8S@Dn1srSfq@fxD?J|2-ic6yoa{DWD6uc80T82WndTPN zF-G2ONna_v2YJbKRV*~#t*Vx(*tz;3R*leQ)isW z0K8VU;d#V2PR05FGC?ckn*;9wge8c~rjQBEw2%o1SaQB70|2!i7{RmvlMi%AFU5{p z@9#_d2n9Pn@>Tz}NJZ#$cqVO6M0%iIRvG{SXt8!m)8V9-w6g#ZtK$QmRQyESQ$Xyr zd({`UeaCUECDbw(tLDKzi`C;6U=$S|8n8Cd%BcBa?zS0ydUIZdwL;{fk+lk+5zJKN z>T0)ax}G2OM5;$ghAcZyi`D*q%092cCMp?{C8T_kEE<;e$G_Q-#DR6{B@}#LJlN&@ z^QXK)K|HhUhaX$Ca-}8A#CDwO1roAgEyz21pbwr`( z6e0hb9Kw!c5utDr)-a%kjWo@q)jg%W$W~=@*P5DT)(=w}%q>bUe)&Or?X+qF0!I0T zozY@7uzh9*eG!utPyiw5k8j{0EBZxpFi|#}x?2|-ZIQyaa{MAxnPQS z?A6a{ys?<6d?mfs`r|0Ql6d{{CHUeuWUDPe!nEzwHvWbUq@!Jg*24VSXywP%NQglN zFVrgGh@)4(M*b;gvA_dj>2N-IM_l zfTGL?HrIo!U(zd5kN#-ECiDCnYdbC$m6vR3L<=3#xm`-9Dwq+zD;F@ApzGdv^DeZE zC5p*+2SB|lWA8QFp@w&M*LNk-z_w}Jq6Qyv7qXQ)y zxcg+!mbm3m!gaCB9RkjuY`<>&{fnLZ)upGXm7eUPY|mdbibOwIo;0hN;o9J0DZ=%{ zr&&8zoB!tinxOsr9_`3nqvNs- zOS<*qov!p5f9PPXoN}0NPNnqEad`&x_q_nKh94En5> zzU1aa?OZh3uDg%khD=BlElr?oQi~2hEA~C((_ARx8(HANsx@_=wAp1mIRKZglO@bD z=R8e!e}&r7S{_2#IGrmnec`x1zy^VL_~z87c*Rq!J~4?*pk6mMUX@Mek;it?k`l3I z8LNdn&1)Q3?e_Xi;nc>N+y1Nq0a7z!w@CPc_e;EJ+@%=5nK%K(hRLiARY5$eydQkT zzg@tYC`E#oAcu*kVzV=y?!kNoA%_8|)2agYjh?|b?`CWnf1d$w!Ia7F5YU!U(oSei z3=cpI58e>#srSnpaacS9xbcgte}moguJO3v5X@pQ#A?O*VJ8vZ?LVi+?i&<1kq3A? zi`FEqNrCh0Y4#(kqiat9>`^H#{&1l6K)*nJpkkxRc2F(rd%8A=B@VnVWqc zKVU$2fLsQ=9AI;$qX690Xs|f|9siOA5Z_bo@XZCp`IC;{?125{8vqXR;54K+#2`VS zHp;oHSJ=aYwU=}w)>`Fx5~!WN_JqRFoqwP$Gx3iQJ?lHSc=2Lq087uS#sf0*dy{Zj z0#>o~ZVPn2B_1FN(ZfEj)mmX4z&!hkMYV7X%%5<|puR7eAzLDT_B(NB8(t14wPZ5S zc9=!FwjZi>i#*I(()QpHApuMw7NE6)J>0q|4Ie_e6T%lhQf zJ-4ToC4XH`yA!uK^|efE*cYUaS?g|$&+jQ_rA@-|c?ng?F)_AZPqb>{&Go7YRX5~* z;yKf-Q#OM7b_MiW)x|X1palJl^V?4|6PtHfYKmb;oES5IDZL%Co5>$ZZ>#T!W>UGi zETLgiV1nPlq-8;`FUPAbF?K0vB2x0Co^jas(f>P9)S~;ZrboFZ(oh}leY}$&ZZ30=TCe+WaC=NU>ozkATby3uH*65>C!V)o`9HP{tIdkOJjcaMTiV_ykx1W{ zekONJm==rzYdbmZ97kqWvpv9d=!&|k+NioW%s6C2Hz z>feowWHsgyLb3d3z~%gXo2#y_-SBG<_k!U!x6Xiz^|xEy!Mei>Ml>05T)5DEydg*V zJ*>=KtT**&>N5Lchko0~7QehFa*6f-RrM4|J^8*M%F3z!Yl$reUeziaX&|)*_92aC zT&md(%d2^^<&ve5Fbj#+lrQyDZXdU$De(#JORB~RBpNhif+0JB#|(^E03t|}ZW!`T z_Rug+QCzIpEJ;!2rFN0ftf5Iq78ow%)!rjc) zVU511$yW--N)x%%XyMLhqpVD-xZCMk6z2TXXN+~j(cuH*Z{E=E7oSTPUa3DMH3?7 zh<&3ecp{gVNYC$U^;Q=L~Xl^inS-~*D7CERw)*( zFhW1ny)nNjy#FWoTa|j}+WH^9 ztc)K#O>+kVZv1_6W8uzeK_)8auO&_1>tj8N{p(lPqjYLjp>1+!K@MHxa^L09!ZUl- zo;~&Nb;fv{6W`2L`2{geeuQ}MmPcQ{7n!+^Woq`*)}NPyf9r2-Xjvtz8@Xq^R+2rI zCXo@v?Oe(Bt;%X*Y|`+T{fajN?5`4hb8XImhLg9Kadgr%hbgEaj^##5$h8#g2{mcEx0k#&N2GWs_!6T_QG!89%HzZrlMI5PD92BOqfc0GscD zx`_YdH8~W65)TmcIK|WRbB%=+CAF<4vwd^HH)iJbUw_&5?U13=VYUM&mF{B+2QkrN z316=9pb@2cgExD}IF2&KPqZZFkJB~o-LJ6U&Ntt6;&LO(e2}%24{*y=6unmDj9~As zwf@v!_O@M+wro92u%K*JLc?B1oLCKiCDiuFVkP|MciD30YPZi^xi8~$u2M-<#$KzQ zlN>2_)WZ3RiZ1Oy5BDrrd6%(a_mVR4n;nAn6vRlLQEsulcIyZynukK2^mIYgb7CP# zN=j4kz}&Q7I&JQqZ|)^9K}wiA517rKr1XV+Q<{#*j6e6RGf0ryD0e+5Ha8k33Iq8( zn)jce3hbL#*LKgzj#J@>1t!obEScd|Y&|$oE;s@-QV>IX0sKDeuVjh(IT+XunK{>I zLhb>Skc)ll)`=fF-^;i`W@Pr!O=~OQ2N@Z<0Q;c+Xey_`Z?3 ze$wgk{ew1sjZaMn1_hX?_5E4 zB|ScjesPT(>UzrmIW&`UKaQ)~YGgxOGcE@PrhLSH+v^@sYYv{;@Q9@Q>$Bud?x}Bf z;)j!k0z@aX~a*XS?+7wQ(ya1PzI=9X2lPS z8rVekv^v>>1S(WQ55%1pE@0Wdpdxrm90RL1q3C){yq76FP3Mn{i!Kav^*~|Jbqb;_ zFFQi+y_m@LFuaB7PfJBk&67)Sg^sSOsU$j*30A>{8Or*N)#lI0F*f@W1lXt@QNJZ; zZkse#-H3538M#)Zdr!B-dr#zA^0JlsFV4~ekeBpvjbF164Q@5L;Tqy|_q}B4+pQ56 z|57L9E^BUSRmn(RNZfJmV^X-tp*MUkt8xxRSDZ@s4>rP zGUJ8z?F1f*;l+=51~fQMUA_*2R}J@q$C_#9LH_Ps8sfA(6isy;o>5l7Lsp5sfVu2N zh7AEc?O8)|_Q$Uz=d~2LEN^ww5HpiuXpw(YLFj)W4yYa! z*n?sZboFM2n04a#W^O@1s{67pm|vEzRaO#@b$nYf+0+^FH9Y|)qW-P>J2I9(r7ezpJC zaiX{9_Tu=5JNwtopa^mw*JxF#^eAOMV>+q8`}P|Sz8h~oq|V4i?JRdVOPNl|BDH0k zk_-|Kp2;_*dPY>Oh>vy!at&nEgh9%3C|lO{%9irWKVwoKzTdUyh3oVQZfyO0-WMgA z?J1Z2%X@)O>O~s*dX_@Jg2|)}pYtd<%XGwitFyV0KHlL-F6kT2aN!Wr%@zGPE^E>_ z!>!k%{JvebiPsv@>|;tHI9q*U5Q>%y;6ncQonYhmBHOOBF_{;&zcl=Pg z&FtI0p>&=1p?{)%MLRwJ9C2VDEU`{JEYgpNE`I{{^~}C%5?MsP6QsEkN;g8eYHapG zKrEy16y)0as;7@~QZFmjpbpP~VNl6Lh`Tg$;9O~xa^l@Ov6C-?;{USTTq@rEEQTwL zBE2d~FK|J5^^~(JURZrPk1VR-(Qs%UO;@$7qUvA#P2}uaADNxevlrugJST;eK_Bwn zyPqu6nAVsa=9kj`^f-Ox_-oUBEN4gCzQ+xZ_Jn}Aa%IPBHYB$skM?@6s-6r7$_NOr zuaT^+Lk{xt=a`x1Kl15h{j@ZOn1mWr#eqP+o}5rpUvj7TNI;OuY**;uB1Uf$YR+p4 z9il;t1N^>u_-EktX}X`Wxrg!=JF4#-iryYIx$$gRQR*NfGa^XO0yZh(Q!Yhhpo~Qp z_Gr+(u((+M;uC!tP>R<@3`2%t6J}5ap@Z9soTgVAOEmsblILS4^$5D*6ni$e__AG4 zsO48X?i-Q_`Hb<1lX*Z2gDNtCN)6p&GaaXoSc2-FUB^KL3Bpgv4FNi|JA5m@0+`Dl z)nKiM;Hq4C^(J0}RB?wfKw<(>Kd4{wJAO3#{>5>W-!5}zC}a1t$Sr15Nh^=!*!mRa zTnKLYm7KjKqLENgo-{LhQ60&vUtNuQi+YnatoX@M>{e{Vw0pbcuP;4(dWw~A&^l;M z1Yf~G(6?p-CUT&He99oyNHV>DT#MkXr4UnK(iS}^gQ)vpE1~E#Q-?7XlkONgevxby z$g@Y*5=)W0NgjL1{(1FophkVwFVof%3hFEFgV>F1ZUJX4X5(^lwurw(T7zl`7gWET$K@H)FvMs4;+I#=$)^2?B z)}i!Z*_J<#)zuevGK;!pLE@|=hF3BJaryW9tu39drNRkC*2;Va2W^tu2SSQ2<54FH zDzSGIsuP8Z=h7OSmJ*|rc$g8=c!4su8OO2$qIZZIrjy>ICX^&HSPjA)W2m{v2sq6u zM(M(+vXu2$Lo>sMfNcJ(Rq+qTaTH~RAvo&SqA^^<+m8}_cx%fbA=)OzF6#?xQ_ zb-s|%&OGAN^Yjjy;zdO>*(geVkacZ!wCJ1JE+JVyBh<|WU=aEo_wvURRpmJkWQGM$v{6S1q7g4XI4>T5vq*o?bv=LtAswc1XK&eC@ z5r#e|r<&MT`{3fgkL%mlCI?gtNcN(@^bl`vY~roor`;TnwL`Vz8Fs(2-QNWp5H619qpb=~idZZpzU z!%pGX(YAY{;{wGyE?E!*sqLztE+IF9%nGp+@g8A=mY9$=u{sg=-=Z?SA%)zEfoary84GvNGTaOM%pdRqyvuejxHg;>?O@%3l6?OocAt1JqnI^p!>V* zkEK5QwG$ypA7a~6?f`PhP3$`_G2;_Bp23j6oMhwldT96D1A(&|fw!9EmZoi=hYkyGRC zmS&+w^C7MzA@L0?=KhcaiUT%P`{GeS+M-|qnW={Eg{rz+)LPC_F2C=}%g;1Q)zKVl zfI|TlpiHL1)AYedld_m9#ho+R*$p)uepGL8vKqJG`xkHbg#;9q4z> ze8o*73pl63CU2j-e)dGcehTbBs50Wk$tbthF!%<6e~|QM`${$6Pk$fT-~A@D+zeog zFW+qsQ>r$L++{r#_M{pe2kJ~ zVy5jmp?$w!Kan9F=@vF=XFyE6WkBrKo!W)Eo{f35jALM%4pCNR>wM%>P`(LKD z|4<`=aVms~IxEjL%2EdEPfxmugb)MTN&_=9_PN1(r!E){O_FF#@ipvX&zHmr z?=3HfH0??)L(`I#v`&91&nU9Oz1FE^x2mCN7j`TkQhFuM8R!4oIWMD0P1sQUcltIi zq#Edc)cd_mCr4rm5LkJ1nL#rVCj8Ep z&gmPKpbWbOSbEoeq&4Qk@`W)86j}a$;$w?8xKR+ggf=)fwPe0nc*LL9Ckt!P$&(%pb};Xr@bV2Bz51(sSO~3sXUuKu;Eq9WQ;xo)>>vxE}zt{n(SRX9k8B7g1kl$?Bx4W;k~kgFD`*I;cxWlUVz{B zzHv0;eYZ5p6KzoBxgHzG*u<+rssRb2>Gg<0)hHIuvW7I9F2^Z%I>3nxy zj$%y^vGd!3$TBnBBBx?H@)Gev9h>y(Nxnp}sqXRQ4(Z)>KNVvRcmHY%U zsLKyZz>No>y9C49?4yr7zf1Lu>g1hoeHO-^=uSm5&lB;V&MER92w-V{^x<#tcK_ z<1(7a4ax~+D3``aMT}IO-lQayn*;4ovLcP-7TCM;dtquJ-Dv6Z%S5+Tp$^bz$Fnk|}NAD6!^TDQb{f6Ssum50HJs498IYC96&%iI|_cDIV zx-LwcAm!O=FnqW1BS#ZyIhLHI#iZY2Al7uGHK1r?plIf3QE{*;#aqy{#zugr;5^zh zw>p;|u!*#Ouj1HgEZ)CNu4rv9+id+BAn@_>Vntc5To9!5C?b|6(fr7@W$Oz`q_sP1 zh|2$K_5~UP%zQp@X-yRtv+cR-oLAd#Y}t6w z`tYi8GN=MZL|rYLl|S6ja1g}Fgra^IU4gHOLLIJudLtGLYo;}kX|L55j1$+hN$Zlc zScFx=H(DztbYi0IZ%8e^efU0|7jb9c$x-~%{0rD_zF{*1J_%3bTIBVH7a{*GZ2N9k z$Q-32VrUVnSks@uH;5$Llg) zA?iv~X|>qbbLU)S``e%iV{0`7?!yM}my&u2BRYxg!&h$NKUI$s9V`l1o?JT#?A`^A50W zb<+~*g&v2c{Fxt3sr+vJ+`=X-LA)s=GK8BuYKX0Ny zqC(kxII6Y)`%CvTn*9qmkHvwN>U41;j(ry(1x@e_v5ToxgRHTAgB?Hu_5IO!QbC6j z9)e+wNs-gonV`+uuz3rc(Ph?u3CqP*J+t~me*|R6Qj*AAxpMXhX<{xP?%S*T4YOi{ z3Y<1LYU|oW(1FIbWRI_w&9>D%&(7(Q!r_rXtJ^~Qhp2FfA?EK4QQ8&nD3 zdpnGlr1lXZ2l%SLPW@AP$~Qr~^h2;_odM@;>Q1kR43l})nataG8=Nv^pf-?FQ-t1M zN8I-`T3lzDj|;D%i@LEEvXS%onEcXBM{U+osXT*S7oM%qMu*^lHn@K$u4Fi4p490` z&hYeYXNnO#xRe!`HECTN-onvj*a|PcDq$u?*%z$1 zXDc<^99^bB+(`w={qOtqc`nApQw58u=S@RNR81r@;VcMrt^=?UGJuYHF zFRnRI#>D#@Vj@G!WMHE*s(s@=-%H;=_d&3Fsl7*-q!lE~UqY3<_w+%~R*vur+hWWE z+n$a%WS6~(iSvvRJgR+~?lWpwyI@hTlQqg%u_ZB7{&S`mr2Kh~AAWtPuJ?3ti*+d@ z&GR`XD<9cIsuk(V@M{df?IX{Lz&tV=2P&lVFj|jIb`>08hHAPli@#B#7fJrIAATKi z-%IQKVIZp9YIbwBzT|CEV$hI1sVnU5ONml0V_mH)RS9}ClNVHSxO^V&8r+uHhK-XF zoH%BDccni_8~ja@{+D7Q1Zi@?%8XM!h??AsB$+{j-Z9j$AHjh_*d(O~rk?lFPI7ZE7P1r#pSnQ$nFE*!Q!HL4O@=L!mc z`U=mB2Pyxnl@#Wn#mv4M?1K&v3r%}`bTy*G)j$Tkfw0u z%FbM{C`v1%yRkH+lk3n(C28L{BW!y-Yt`JH_nbieb;=rZ2GCGKCn^S}{Bu!Pu%hh| zpz9!M#oSWQbVCEwzOl-$_w4<}i5_tf9E1@i_6i3&vgv;3iHsHu$0Tv_;?MUV@cULq z?(3$2M!0M|myZtG#D5@SWHE`HL|l|0K*d2uD*h;TX&5?z;A1vbM;pJz;A4@!d=-=L z3&~^fyzfr^jn}W~?mDRK9x-kXoQjC)?+cmL1~bWRnVA_l*<^g5|8!NxG%C7KkNLc* zYn^W0K-)d4(z~1(Am~vJgQhL9544!HIT1 z`lPeQdu;~O7-Ha)mn;#?K~gK3%X zon8ZyrGD{Cat}udu_W&Y=i)FQuHDMkkHG_Tq}BZ+6I$qGWJq1f42zd)H z{v&^p>>TGyugzo$0?o2~rRk*t(wXI{s2xkcDyqa~OO`^u%I|wnMUnD<6d#(B|Ib~R z`OcHgzSs%XKlDx<*n+CM8Kiw>Yvy=ENB_2p+7wL zOFxm{Zt=)>_!i^4ruxjiSvlUWM-02|@1Vp)6G&f|(SgL2cW6_nH+CKU_ zKqqR4kGS-f+7YuztU(U}`uE9T7mdV|*`9`uTktJ`3GOQzrn$bO1#XFX_n~k0jxK0s zxVi!w6m3~})=zHBJss4oz}2TAY@f1is1537{7;~}q2PEtV<<8jEqlNNL4C7S$9#xK z*_Q3nl_yc8G2q^USG*50 zNBplcrP{{U@We^gn0Vt)5i?GmBn{5$qFRKUJ8iG%igR>Yp0%w(RTDz7roUn5^JryGn^p;#I#PI&;r1=zx?!|!HE|cVy%g{QSL<`sGcso@c>4=3PoiL3 zdwF7YinqN|65S-%ep#>8RJlMlON+})qr|p1=1tL&ss7v%{h(;|#IaMv_pzCu)A@%X zp3j2Hf*kpGL!OytJbq@Q)!!JPv)bYG*Iur#+$UO1WVnn_l~73A{Ouv-bfO^pZUbFY zPktEaFeOuJd|)@<<~u1CmygV_#^h|d$c6Yh0BVW&&Cnd(0;XHzI>?3R}ZqYe#B(-Lc; zyYAgao6ocU4$Q<|TLgx$77G&)@^%k1A9qbDFI=pTpRE)6kCk(U$=m@Kjr2Q~ec!N@ zS;n!n<2S`ce4dEqN4D|nA5>Td*fL~`y*NZWY_9eat8}*Zcl?5E`|5PU^7TxvBL40v zaBt^1V7^aZW}O8YbV+@=*0jLt$Y{)GBEll6+*6+hj=7H%7eC?2M4 ze2AYn_)B^o9dDy3q9_3}8|iq}=x8}71tBHjE13y}AyN#K(V`h{)M)`W2-?`(Be|d` z;d6+NBBkZ?Q0g}*dTEscI9f_PRx~1~EAvVw%N_CA^?h5<;$Zfl;e;gytG9J*>DK?V ztRs7$e8p9yefpfQ;TQli>^Q7x6`S9(a2MByXvF&aMTE|BiO^Mb>d6BdUzfQQKW|z$D~SDW`bLNd^lmR@ZfF&8OMl>KgD;rY8sPyB5K{N zYMnZvxI1u6u(}0D {)UDw2$EkhkLa4@Hcf6Lb3Euot*wFUl`(H(^sjI_LYeLZD ztm*qc2phi17F}r~OxojSBAb7f4oFcE>haE=GDM1ez-|-FLXW?TN>D(s?b+Sv)@^}@ za?X*W+gv8nHTKLc4s|_d%}p?^x-yCD;emHkWfD=HJoMKc$}EQr}|8+YFn zv-5`)JFMTTcPTjogrD4eS-(BGy*PEasnz}Sh0>$Ii%Cw-oBK-lJTKc{KefHz;(DxH zRNTjY20*z_RpxoWyY7xfY5(vSaUDNQ>XJKt4c7S^(jlFCV{4jcz+pn$SMaX>gS~6z zDC@p2#ewToz2~?k*Fj^Pd*X+I+~q^?c1okEz>dz=tvYC4KUsx9f~rfZS<5 zdv^8=u|2tCRn@wF>KsJs=P~OcgVSbpwz$QnX3A7B8hbMQtBa$lEH8m;`MmMzdABCn zPaLOo1vdBEKGN&o-itEB7B>7QXXz^BN}+(w~e2IDip(pi9{5o zKG~epSQ>-3X6CD{4@zXeQ2#O9sLZX3m(8fMnkN|mIH)nTstqhleh>PBZ`|x$RSMZw zs4DsNj)HdeO6}Mjd7hq*Psqsrxg%|3l=s1km)4Va?>}*9;)~-6Im^E@nm$dy-+f?n%<^alm332T0d285>EEl5U7YLn z3K82}*^YeU43$;iOt%{;FFtX^@bpF1bD|&YDR1+PdcsEM{5W|Vrm9h|Q|#9dKltVa zQy}|lpqDb19o#_$Wg*e{>wLrHz~5rk;oUJa_nANyIM4g4-2#cJ?&+#PFO&|0={Yj;bf234@99JX`? z8*uv`;*c5r=-df7*}lJEm8^#PGUA4*Q<|=YK7J%}>i~wV^nwn{yQR}VLQb^hJ&?x0 zfB4_g_dcSdq}sy6ETrY&kw_lm;hXGyUObeieR=)+;;Jr}d#Gkp%PX9z3%~E}24}g{PKL4^NeITbzV)LK2 zsL%`09Z*VBwaQuCSc35mXls*bwG!!A8bRr*k4Qn7*)!}Ooo66gr=cfBljIzkY9}J< zm-)ky*X3dB2(Att$T)3J>5N=%|K-=#coz-ngn&}Hm^6f4Q}-x_PyWT9=~jziHZg=} zcpzuj{SR*BB)J}Um5yzhqVWqvcZ%#0!x`YR*|Rc!csf_B3{7B0Du;nnCbv6lG5gRD z?ghF^fj^u_;r54*HCMX~!vpP9F7eewKM`URiQ9yXI$>Fnw?$-|O_A6M}C3(%$XE(w^ zt@Gs(d>?NSvz5MkY07>?r;JoFj9H>KBVqj7iE(_gnY~up27fhq;tObNu@85l=Ad)h ztsMt|dypKqyxix!Gdv$BZ(1R|o*zH=n3Jh0c@#zL9z0q+T?V&na?c^|*88rYK{ME; z6;bgxQek+iS;c|WG@g6r$C$`GUVd&n-*stZBXsze?;ydEQcp4raCB|qNNrH6AW)?$>2gn9oRlLejZnOD1> zMBmxYj_vJwtx3`tkPJ$gvVNmtJ-I!M7f_HQ{m#SKfYuGr)MpN}3n$DXhFqer#UsVx zp#R_AO2z^H)~hWwp&*lRaoTJ|^(3}Q7Xeym!5ttK)9?QfIp=Df+FvAtJ|olR?^vehov~lNI97DtUN%Ma z|10rr+iRQS761}@Qe+}MXG9$-gV@ygxJ@=}yT|PNm;MoG@D<%tbnx=m>48p~j_~57 z(nExL43qOY>PPR>ohk?Y4UosUlVdVve?Cum?z+>u4A1Um`J*5`YCyQ0cx@`AfEXU1w%G?E&&e0%0 zRi6PxQvovi$%_>tyvD=B7Zl8KBJW$Wtal?V5xlM=5+=rmPs-~{lErMMvS*t*(T2vR zKl$xnV^_GmvO?xw1jR^nTEHF~{?rcLxScg@9}_F17!>hyN`KvGzU6~Qb;a)sAXVdJ zxE3iyZJ9HLYkv_GF=H<|&uO!0_+~}3scZcuzs1@vU)tgil>@q(f2NHJzD)c0k>6B` zE*;maYAy9KKJn;n_~?+OqJIH%Fdm0agMULIPqdQT4l@2oK`5sk3LQ(B5VTRdbKDWpW>L4K@t&Xutt4G8Cw> z-YDnT!v>+Y_JXjM<$sj&_{lR8!W7|>7Q&u4d;%Sh`XrZl#T3lN+BeqTi=&eGLY zFg$~mXzfkhpzb5f4_r>NxdcVi-s78`wjaojo|^P_=fJn3InFzo=R zqaJa}s7<5NRr)Ucl@GKG4H`eioZW1~Jl-XzEG5UI;jg~u4L<{D(El9_lERrZB#fnf70^C^rUp-7aD>Rb#En^(250T11Rp68R()c z|7_xoY$H+gB#*YPX}U)N(L$Y^WiE&hyP!|<8HJko#2EDpVpODLwz*98V?gYDNJ5#{ z-ach+YA!hl`<&wSP2q`Nvo*ya{aue*pyJYnj<^^1>+GEF>UViYcz^Ol9Ek8`>!eLv z&$9_57p^(H1mXCe=Tc<0cLfJHov~|dQrC;wW5<>tBjJ1UMs%0uE=#M<(bFYalto!r zPIAtm$#tkt^2bmcl%5|7k;%eb4 zMNtn>*@YI!%Bf+-{-J4;q>5P1)7+H=J`J5g`q{MsgNu-qpkre`jDu)CNY%L7A;qpb zkj;0q&8qa!9amwDFz>MM(Hn00Wi}}}#wZ=ZQ>G6oyBOM6xzj=V%TWlL@ttablI;3K z=NGD0!g*rt&+Y}u()q791xSDQ)Q~*=i!KZg=ugjS5Hk|=nBg2z!?<{RrQ8GL4mKdD zC-Hscm}O74&`3wVkRIX&52B(B@_;?V`?Gt{P~mrKw(_>=&kwzuJS_U+cm;_y%hfx$_f-JJ zsWh|lW@r9x1t=cYvXNA~rqebtwb!_9mfy+GiO0a2@2Co?vW&lsfp^p+bO0y!Wms1{ zh`7>sqJhkk|5;mvQfL77dT#`N06|KHxB}=P?y2f0v^h?kf_kleM8JeyBwOrqrJ2DS z@6Q!fa1v#mYkd-08?MXOZvvWGG6s$Yy`<>lSHGFe31=@Ysd|9K5~g|5w*XK;xCrmY z*G)=G#An{EEX^BWNvzKK$G#x1SJai(43H*p(pX1BZdIkhs2`QWtbQcZt=SM)kQuY& ze`(@Eosd7+&^yI_P=5n|33QF8*WWuaN#6iiQZCn19q;LVhLe0p%l!@_{M|*>^3zzR zSur!uNVk4U3;Usd%#9hxvXp$AqcobT%I`g$rGoyOe_Lc*MCaTaW{P4gLFd+<3Hf4{ z&Fr4$Xh)1fqMONNX;cX|{LQuJ7mae8o{P2+(GvHcEiF)}`h}?;cMt`OaaQM36-d8U zh40^GE)HYKzB;&JsHK!4GXO^tCeb`Ne zNZna@{voVo9zQ^%#Re}pRUole-bnkSe#7uksK~DnoyokJ;=~ZDd!g3*WyHFcCGbEYlUlV z1wwmj_0n2t6Vs6t%Lc_C`=1|AuOATDvhQWc8aG4OKKxote~LplIsE6GAIgqHm8>e$ z{g!g(NUCD8Hd!_RYn{CYNbQ2I(7=0tSr4l5{8?PBM3ud2P7SjK!)E4@G$bK3!npRa zv4Qr=(JkR&IB4CgTogY}Ul`8Sh`@RG1W7<<0M38j6fCE+;{YS<89ShCD2;Vq-ht(xcv#1igL zbUc1vIvzEuPpwo6CfcYhM^65qp!}0wg5}s4I2ek!MA3tUO+(M**yo3iU~vr4-Myfj zH(KNjCl1E?&e_F&gOMeHU8ISX#!+jP1Wq^Y>7tChO|hv|Wpt2*UOQ zHRI_X3vet6E>s%k9DrJJnir$(srvTEafkY-ubzJ!T&3nfKC(35#$6{ZC$%q^h`aUk z-+Xj4wkDN)&d15@{NtjDG2@s^T3rsRFhU6*vn~F-TNAe3%6b|fLE5JJQX;%>kRyUT z$EJx|#0=T&j)7&$tIxiB(u=bPrHnzr-gt%N!}s&Y*;$vrSlX)h35~^HpKZUO|2E#g z=f<7|>-54wsp`!P>P?v1u)kzhXk~0V6CpFQA>!3z( z8WC+q#}}V?@yAC12Hp=~Y{Gev(=`X?pfNuJPx<$6#@dEkExx0o(E#ovI8@iWhYLP$!w8@F?U?)CQdT~e=}WcS$9%l(H^p? zNuSTRPv`OLG|tX8vdP(#!#L?puQ%KfvYz2-H!n>8gdQLA;?~?SNGucn0mp&-x;Y_0 z%rZ5{yXNY)B1Ds^M^zL68QfEUHq%iY;(ONq^jDMx49*)IxX@Ji7jtD2gQJ}^?61*< zSMIg4)F7>~gODkEqN?tjv}#2MUO};rCuMw2Jf5v$w#L0qsch!p6mTm%{%`4x_@3j5 zhO-J_LmN;P>!2|9{|hWD$x{fu4;uPq03Ib-wg#*WEZ=2pmcemLN3?bte5y(-?JWcf zvFla4XQ>lhd2?55cC>-p$rj=`(_di|a`{gXWhTPSsUdGuR+?lk7f;q|ex)60kF5&O zQVODdWVt0r)G}Ra?*ws(>}OI>3Ya=v0INL5SWT;Xgc}W2-+W(my{1iXszry^AOJ7G zQ8o-fnm_IrH5LN4eAqBqLRyqIJ$8EDJtVA(x5aFqyHmgPEI!skg|hY}zh`?)7)BbK zN9UDFmnKQoGWLTybkhGD#Hrfn_{|qXasPl0hzPnl#Wd{V+w}+PtW}ikEdHB8&6aBx zj+Iaqn03%I9b0$}nsYbp{WEKcY5dWc1OFwK3N;47;VQx8i@RG|r{k&K&8^^}(Qwf! zY4)G$KM_bFTQCM-khA8Y6u0=$*6dXb`k zr))Z&BufgGPDeLdA!mBnq&yVgV&oqekCfmPv3GjX!uJqy({ zhO!#e=?N6yST7dW%WfLpZ7T*sLBW{?U!3F=Gks*RJ$pBI4#T!$ZM-{GewFD^CgZ3z z^mohahR)SIXhmbqZ5GkPUwLFPmv^u!3 zPPKUSo5^S?xO(nQ(Xiyz%Asxd-SID*pO;darMh#=%B4!CQwYU|y|x>e@3Ag>-da2W zEA1Z>Frs0U;NLR4dji%kZ-C}^?4i}fg4PEArAs7{-%NvGmCN#A|C&xpkx|l)YEm3y zhPlJvr7*wkK?ledelzh)0~qzPZTNBW@_fs+OuX81z?K#;+{gyiXIv86$z+bo%JJqV zv?hPVRv)E)O1ZR5*7W}%B8NVvu|D=V0lKkj>07CAP9u2=B*A{XFQvBKb@ z^Je?aYc;+X?WHD_2E zGm~>N-X9e7xIYad1zBFGFH0^dWA^`k7Uib#x4tm5E6)MDA|3O`_$Oo@heLgkyxu7WNcfKy=d0zv9_IkG zu{LhvO(9Qlo4_cf5jpE{79YKxw}cVjvynw%1Zya@??!!`YiBp`l6r9Xd!vBYBbQ|t zTfz;!I#{0S2tVf~z63zA?;VO9BvH-g%XoC=cf* zu2vdWXMx&vkza6>+yzIW!tWVJ#f+AGfhci3>ry@D6GThj&m9)QjJcmQ_-3ZK@yn1Blp`3K>X3m@(9uz{# zU1Wa8=b~bNNs4jvf8Gh66L-6bm}(PJK&;>UYotg&f-md&Q&qzoloJ0n`MWSbB&wyr zvilVLt7MPjySr&#N#Q4d>@zd%KRwgXuX`5#*Ih^%lQ852_4b(~2wSReJJSA>(N|is ztq=hgEO>&z%rf}g<;|KQVgJlDVZFk{c!xDCxZWX%_ zoehf4e)y?;sF7)S1?!$BdXY5sOL<34Pk3ozH+(<&Ex+eo@o4Z-j53$M!$up@wqD za^`-(oq!>nLLN%6V)<`4`SH+tc>d5a=gj6_dT=n1VEtz5vM3nEdo1J>%0)wp z7+!pqgLzP?npI-P$~RKJNBLKV-vhHN@i&BmX21?3F#*^6X-&B+t?CK4a#0XS095`~ zU8m=bWm-!E7*hxGpJ}q)v}j1+@+T_rZhXw6U&qbl&5W4fcHEw09;Jnxc6_=AKs2}m zH|-D19C3WcTb1ftGcKVN>;m8V{;CdO&Z+qzx0lINeFW0%K3^cJiL85~v-lCtxQF0v z^1spzqB)%5MtiARCRw%12D3m!j)fpc?cX&^>K|K5_GJZj^xgF{h+4utkiMuxop@7#%K7H|n~5Y{DA_*xX~@T%hTIZBI|-^(_v-oqZ%R;$ zS8%-VSD-amVMvZOhEoW`RLwN-!*+Ueim~~Zq?B~^%%ndzPQj;ct354<7O01Etowy| zdj90^tn@zp!>2V_U{o(iDVj2~5wJ1zSIIbsU@5}&{EU0H$EM@GH>BY%kANH2A$cb9 zMkw#xr^*KnI!M#O1vWmUtu2(M;t zX_1znC46EE(Q!d7XOl2xUG-`iqa&*3wlGzPRGkL5=Ndh?YBiPP6uqplU)g8&& z_7e?ERqr$3^AdO2bLajns_3Q?J|6Z|IyCd0O+U=(z2B84mtM9`x-#V$T82;IyE>Z4 zvZplgESr1#fMet*nAULfkw&Kan9I2|%HLY1PAwKCC+Y71B}V!7REE7xa%C|IZ;-34 zkIH!)+-UFDg%z+LDXFh??MVVI&7C@8(PiJnN?U`MZnc;TyC)P}g~DAP6+i6q=(sjnP6jh zaOMX=(g>~FqG6QRVeF{9@MB-nQ=v=ci9Bv3C%`mO-lmTpPsw-ST3B!R13vA@xW}X??USHrqhmc^EoaA9;AIwsyABXaYO%uyd%YN3@aOSW3CI>K=zp# zeKqm@KPXeecFiAhFsw%}=kPQ6lfj>Bk1-=GWox1aO1J;?^uZ|F*E_|%Ny_0YfVsa= z)9r8!a0y%mDxN~6udk>$&vDsZ5#Qr)Kj;F(HJj_zx z?pF6JD;uEdcO_UL(LB(iK79XFdR*`>G_OoVTV`A4O=mn~7yp1iR6bE*dX($n(c5*m zXltJ!)t&b2A&b1D2?s%=27MXh`hVLYtGtJ51tpJGC_kk|&c3AOw#pFq_!X#UoRa4v zdUjPFr)~Q`$TR5PfRshfk<~1pT$7;4hGKjJdTAcGV)?if50a{sG%WaUiJ{jbF8S~m zvK6j?NlLo>`Y92N+s!Jb^4RfLz*Ie3akb=<-|BUHXu|u;M@;u1kfPz})UGtq286qW?Twk*Yde>v zq_bI!lSfU7CXvT(7Q<6m`_Uh|8)4VOwaQ5naqvICZ1a z#vHg7h-pjf0j?>U&!@CH7DCkgsE7Mu&z;OrfhGI~%Ewly?%kI43RvGAvlR`wjP;;~ zHu|A=&z8HUapuhI*nD!nlic;fyGF9H5dYRL1^erLD7tt*qZg~=y8&(aQ{~J+wq6Ys ztw9$u4GHTV`nbcA(iJ0YHa2*E*tM{_)lI9A+(6bhaY&~}@4o?fImlI%z^MRzLmAuH z{QHtR^^cA3KdqMjbw+9E@13wbATx0q=2=aAN1F$mmw%L^8eC)H$H1!`$_)>V^|hbi z#PY%!3W{-onr*&I*HYqXrvhoID-N;iE|>0mjM~ROx9{4PrAuFL=r`6>VGIK&bA=j4 z2M$#Wjm!Sqc(z{eHTc*`I|8G%LAF`99t867m*Si= zdJPlh#hUlLnD^NHi@()s)?IF!Ic#dq1XZD=$`qKSjC~e*JbKURH&Yuw|Fr|lT8NmK z#?gI)YS(L-vC*0~W(IymI-@3?F87iTCWih(T9F2YRT^<_Ra8r)f_`+IpQYD%f-XiR z(1OhcX&yIal?>&|D+OrE@uJ+Ym88N?ymfKG`$L0Ln8M(#zK&ID_WeOVg2>q@+Xsl` zQVX`L89`;GN|8MuzdTSEpP3uFm=-`|-3&o_Whq-sP^3k7WsEr{hJ>=Qg{97pt2#0; zebEN#z%2VCKh06%G3J0B$9;cLy9$&9w(K~1p4&tB*puMYipRpFbPN#xmZnuL994Xc zq)dM(eV?;rd2p908uVU3k5;rl{5n_3_UGg|UhtX4n9^vkAihiQm{9;GnMejZZ2$vw zevz_tNA~dwLxRy(^A_B~q@v{HAi*>LRz(i7H4NWrkTj9(cZ7f<0DQLll|q6!OR+w+ z>J)hQSQa+l`wa;Uj`%MoxCt9)>hL6tg|P^(Oap;jHA8HEeWSy%!5z1*rMi#XFGGu< z`UY#2$AHgRoO%dFr)Mwq6r00`#7Qg`nu|z2YUATt7W!$DbI-PB);%imKVD&dT!}>ylWQOV@!c7x`@Ql`x2bY28@UCs z5YP4?63lJ7rWZmq>en50p(0**oswRA8?b%5ks2_=&7kYV+eq4ZwX%A7wCl*Nk^2X^ z_4h6BWyjXdW=e7yi5~S9-lV}~2CViXiaYH65^UW}V~tXWZw}5zWSWTV0YIKMxoEEn z8VmV_&$D5!n&e-LAyRqhmNd|U1lm?Rdp+j zN4EanrH%*kRr!}vxg4MWoL`@wZFyzX!L2^RWVbyzp1Ms|tS6bI1!83Z??Voni5VC4 zYGG6yi!Z;=%Tzu)M+p#XDN|KyrZ1Te#HvueUO>ux6$~cZe=|j2UU5i2Xp$+U=IjYO zJXkCp7=Fewo)Fsg=?5muVCtCnSmeW@Ed%5M-rjlhy8>pQUW0(H1|zbXXC_sp(eg~g zaZ>)`F;>Iik4#;up=Pclq%l@Qrr4ODF|wf0b$tQGxP8goZmSK9P%@Wz!8k21!f!5j zMeerbYPp=(M|{Y7YX{NgD5We8p}N&{$}3u07lNrlQLDszJf7y8Zcw32e2b1A^35lz! ztk3Y}`W6YyagB!uQ+No)a6~l2ry((gubs2W>@!NvM^EOt6)t}pOo6vE4V={&5cw*NQN-e*f9 zP}`*WoB2}#ObpRi24kD`|q2&DlYgge1|jGq7=dO zBocRuU2qA^CYgYMY6YZxEo~v!*wei1(WJZuJCsi zb)I|UlyGYhqpTd@us{r-PH3|6i%2lq`pGXV&?J4Dc zwXHEeFrQH2FLYr^S`Gg*p}U&hfa)NwG~)2^CW&!nwpMfa`+(rS+X27HQJdGC@SaZ$ zHMG4m?#aa9Jjvg(kMasbdZP6u$&5w^$`iA&#QpiF3%{r=s(?ni zeSag*kPDc-`SQ#LO@UASCR1>EKaf4LDQk0Y3xBLe za_vb=OSL;X6Fu#^L$Z0ioCu)pVrk}>G`3o$5hXh-Mb3P)!cIxw*?!m zBjy@XRQzue10t-6Vvx`_Y+3F138V$MdRX8@jNb_1{g8pMWa@05Kv z*eK!2cUMeLS>nA<)5Z5}_^r&xHF2H`Pi~is-|)n}5iu$9Y804~){%j>Cw-Kix*!Ye zmqyLMd@#y9{x$}@K)95e=5H>P_Mw+#3umbNe>0*nxdPh{52Cmg3tN9#SXOy?STUrk z&yX!kj>=S~0A@3w*8x(dEAkLcu5b#Q!_QOx9K`(a+Z~3HbnCNo!adeX+F+r`2na+$ zW?ob045L+Ob(RN&zVgvtZC*;DSbn8Nu+y6D4gh1RtB6s5eI)N*bI}B%CTtp@o3c8` ziF`N~^2q5M>$qo~zz;9sD{Rn-sCh-j1-$RE- zwE1RqXh$s|Ih?De31YX(01TC*(fmc)_fXEHJe89RG1rKQiF3MRF#WoA@S;qh@fCY# zR28&F5q(a}!MG|{C+SsA#?$9)(>bW=TTNgU^s{H1M)Qk?K8#JLf=|q4n2DqbM+u>4 z)A77#4^Ng0+NBs8kX(-!6-Oy~#^r`eor1$}CEEs&lR9#&?}^}348H8Y@8m8b zsQyAzT9X;8v^VaFq|j<&F$bbMEp%cj+0XLv%|bD2fgZ%OLzE0S9`VXGsVth6enIM1 zp*Y!jrQ5idk|rd&!&)ODXYyeC^vlkJ zY@1pHO>2GV^U7}N__^y2PqVZPzNb&)tW+=$T>qMs>7ch^5(AM3w{Laqd16467uT_) zZ;yRbz-pGvHthVM`-?bR^B#6iYj7o}zTq+>01$3o;j@l3K;+yaP|c-)gsWU+Zr7?4 zidnPOTYo8BQT5`JMBhW#brbs9X1qIGvw&7CU}HfQDDSXzNR<1T{~BcCDVLOt7}eLX z^VJ8qQTQn7;_A0wPS2L9tF2^aSFwr7h@*tJ`f5RvQjN{Oo)gUL&^)>B>TWot2wf8G z!}MahcLNz(1l}Pr%hp~}*`MVRv6}1z?UYo}no`WQHgTC6pz%(++^#3)+RWY_UEOxo ztt>^CHpiRy9%Iqo0Je)|udP}OW#)dgYkEY|tE>$^-{}2i$CUtBooJ&rKDED`K~jZy z-9Xk*WMYhLly-q+C{G^&C^UznVSk*EZrV`fpu5K0%1m4Ir8S|jP97@vn6S5>boML0QI~?s9 z&|_h>{NiGW5C5@|(_5_lwZz?0jh6Gd<2mUqyH2fEP8r87XO53>P^nKE&F!Y)pAx@!xzFEwh?*Po3YpMnUVjnR4rf{C zxhg+z9*-z%d$MxfZn`=x!an&!rf@@O@<)B-<4lnFx2sQApBeE}?8CNQ0=9U=EcjB!vz#m<&oEK^tUu`^(u`CCml2k&Uq z$Nz?IUVCdgVdt5lUW7NKxZWiCL)meojr~BK z;My);AzZ(|3Qze#OGbuk%NLZEA#Jj{{TrV0B+d%OCgOYc=7u|elIGAxm{o8)5@;wsT z76L@}+gd|)#ur*1Z6cW{y6Z9@1M&l4wuCc84dO1LD`52gDCz{Rx9|dAr4TX44ATH! zVX3ceXNJGE^*hAEimb0UI=xhZtwjErdd7nH(YQMuUx75B7l1rbhnrazV{*wU(x3GW z*j+`H=-0_#M+(wYT;ddj=X1$^Fg1ttQ9}AeaYNhJ5{2}f1*x&0{CC#&!y~d;gpQMR z*TYU3uOBONzHi&?TJBhRKJO&S#sx~#4fp)^s`3gdJgxY2K~-gvv~WL~MaTGK!G6VT z4!7f{8iUU;2XyVYzMke?4Z{Ivf~byk780CQyUPm&BhsgAVHViL?eL$HNzool|S~&XAc(|NgxcC*X{DkGS*7EGy?fa=9HUpPpHdXT zC-C~lg-Nuk;=wF-A`8r8D={KF^Xl7bwb0}b)as()Cd6nbvcZxxT4pP67 zb+(DjMQH%#?M0JDf#RjBJ5|fuP=HK3iOIhO1ybfo;iSZhD$JRHu+wR?3vY=EPpO_u zP@&IPT%oy7#+F<=HbX`}^qJHgd|`_(k{7-`qyXMkO#Sw~7gqFviYyzoO;7 zQGFw4m{omX*M{;Rpw>wbCIcT_G!Swu|G5QU593n}j<>>Ru~yZ}y)m9q{doLg(?_JO zRLvjCmccKp7%kIESDuTjVc0w1(_O~J6Gm~OS=LQMyrOmkKOM6 zNA;Y4n_5%U`1b!YPPUBitYaasr~B!7Mu$p)ciHPcHJ?-5ZN(zM{F6-!9o4v*?USAx zdrIY;_H?fBss^`yP@(3z8+$1!%F47{Gk)v2@>av82d!U&TP7Ix z{sEf8dgD1Y#C@QbrVb@IaD^zQ`+sD)DHdlTw5{rFYxpc2OdpWF From 6b3637aeb51daa86ed68e6b88a54ad282ff85772 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Thu, 28 Nov 2024 15:50:42 +0100 Subject: [PATCH 30/39] dhonti/ANDROID-15405-postercard: New preview reference with no images --- .../mistica/compose/card/postercard/PosterCardPreviews.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt index b8cf7a4e1..9ae386f01 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt @@ -66,7 +66,7 @@ internal fun PosterCardImage() { firstTopAction = TopActionData(iconRes = R.drawable.icn_visibility), modifier = Modifier.fillMaxWidth(), aspectRatio = PosterCardAspectRatio.AR_16_9, - backgroundType = PosterCardBackgroundType.Image(imageResource = R.drawable.sample_background), + backgroundType = PosterCardBackgroundType.Color(brush = SolidColor(MisticaTheme.colors.successLow)), headline = Tag(content = TAG_HEADLINE_VALUE), preTitle = PRE_TITLE_VALUE, title = TITLE_VALUE, From 4c400f5ed9527933d7a4e51a345db3ea9970e574 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Thu, 28 Nov 2024 16:13:10 +0100 Subject: [PATCH 31/39] dhont/ANDROID-15405-postercard: Update correct reference to resource in PosterCard() main component --- .../mistica/compose/card/postercard/PosterCard.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 444409540..68c661fe0 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -1,5 +1,6 @@ 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 @@ -13,6 +14,8 @@ 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.semantics.focused +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.telefonica.mistica.compose.tag.Tag @@ -48,6 +51,9 @@ fun PosterCard( min = maxWidth / aspectRatio.ratio, max = Dp.Infinity ) + .semantics { + focused = true + } ) { PosterCardBackground(backgroundType = backgroundType) { Column( @@ -88,7 +94,7 @@ enum class PosterCardAspectRatio(val ratio: Float) { } sealed class PosterCardBackgroundType(open var inverseDisplay: Boolean) { - data class Image(val imageResource: Int, val contentDescription: String = "") : PosterCardBackgroundType(inverseDisplay = true) + 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) } From f73ec022d5b0b6363911954ea25b245d1a4fc3bb Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Thu, 28 Nov 2024 16:47:46 +0100 Subject: [PATCH 32/39] dhonti/ANDROID-15405-postercard: Update R mistica Catalog module in PosterCards file --- .../mistica/catalog/ui/compose/components/PosterCards.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt index 74994342c..0f0bc6cad 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt @@ -28,7 +28,7 @@ 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.R +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 From 2c4477996af01e699314e5c0ca3a4c2c4418663f Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Fri, 29 Nov 2024 09:42:16 +0100 Subject: [PATCH 33/39] dhonti/ANDROID-15405-postercard: 1st approach for accesibility PosterCard --- .../compose/card/postercard/PosterCard.kt | 13 +++--- .../card/postercard/PosterCardMainContent.kt | 42 ++++++++++++++++--- .../card/postercard/PosterCardTopActions.kt | 15 +++++-- 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 68c661fe0..520ec2cc6 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -14,7 +14,6 @@ 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.semantics.focused import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -36,7 +35,7 @@ fun PosterCard( onClickAction: (() -> Unit)? = null, customContent: (@Composable () -> Unit)? = null, ) { - val anyTopActionsLoaded = firstTopAction!=null || secondTopAction!=null + val anyTopActionsLoaded = firstTopAction != null || secondTopAction != null BoxWithConstraints(modifier = modifier) { androidx.compose.material.Card( @@ -44,18 +43,18 @@ fun PosterCard( shape = RoundedCornerShape(MisticaTheme.radius.containerBorderRadius), modifier = Modifier .width(maxWidth) - .clickable(enabled = onClickAction!=null) { + .clickable(enabled = onClickAction != null) { onClickAction?.invoke() } .heightIn( min = maxWidth / aspectRatio.ratio, max = Dp.Infinity ) - .semantics { - focused = true - } + .semantics(mergeDescendants = true) {} ) { - PosterCardBackground(backgroundType = backgroundType) { + PosterCardBackground( + backgroundType = backgroundType + ) { Column( modifier = Modifier.align(alignment = Alignment.BottomCenter), verticalArrangement = Arrangement.Bottom diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt index 662202052..5a32c0202 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt @@ -11,6 +11,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shadow import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.semantics.heading +import androidx.compose.ui.semantics.isTraversalGroup +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.traversalIndex import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp import com.telefonica.mistica.compose.tag.Tag @@ -47,16 +51,25 @@ internal fun PosterCardMainContent( 24.dp }, ) + .semantics { isTraversalGroup = true }, ) { if (tag != null) { - Box(modifier = Modifier.padding(top = 16.dp, bottom = 20.dp)) { + Box(modifier = Modifier + .padding(top = 16.dp, bottom = 20.dp) + .semantics { + traversalIndex = 2f + }) { tag.build() } } preTitle?.let { PosterCardText( - modifier = Modifier.padding(top = 4.dp), + modifier = Modifier + .padding(top = 4.dp) + .semantics { + traversalIndex = 3f + }, textValue = preTitle, textStyle = MisticaTheme.typography.preset1, inverseDisplay = backgroundType.inverseDisplay @@ -65,7 +78,12 @@ internal fun PosterCardMainContent( title?.let { PosterCardText( - modifier = Modifier.padding(top = 4.dp), + modifier = Modifier + .padding(top = 4.dp) + .semantics { + heading() + traversalIndex = 1f + }, textValue = title, textStyle = MisticaTheme.typography.presetCardTitle, inverseDisplay = backgroundType.inverseDisplay @@ -73,7 +91,11 @@ internal fun PosterCardMainContent( } subtitle?.let { PosterCardText( - modifier = Modifier.padding(top = 4.dp), + modifier = Modifier + .padding(top = 4.dp) + .semantics { + traversalIndex = 4f + }, textValue = subtitle, textStyle = MisticaTheme.typography.preset2, inverseDisplay = backgroundType.inverseDisplay @@ -81,14 +103,22 @@ internal fun PosterCardMainContent( } description?.let { PosterCardText( - modifier = Modifier.padding(top = 8.dp), + modifier = Modifier + .padding(top = 8.dp) + .semantics { + traversalIndex = 5f + }, textValue = description, textStyle = MisticaTheme.typography.preset2, inverseDisplay = backgroundType.inverseDisplay ) } customContent?.let { - Box(modifier = Modifier.padding(top = 4.dp, bottom = 24.dp)) { + Box(modifier = Modifier + .padding(top = 4.dp, bottom = 24.dp) + .semantics { + traversalIndex = 6f + }) { it() } } diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index 066e6c917..82f458cd0 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -22,6 +22,9 @@ import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource +import androidx.compose.ui.semantics.focused +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.traversalIndex import androidx.compose.ui.unit.dp import com.telefonica.mistica.compose.theme.MisticaTheme @@ -39,22 +42,26 @@ internal fun PosterCardTopActions( verticalAlignment = Alignment.CenterVertically ) { firstTopAction?.let { - TopAction(topActionData = it) + TopAction(topActionData = it, modifier = Modifier.semantics { + traversalIndex = 8f + }) } secondTopAction?.let { if (firstTopAction != null) { Spacer(modifier = Modifier.width(16.dp)) } - TopAction(topActionData = it) + TopAction(topActionData = it, modifier = Modifier.semantics { + traversalIndex = 9f + }) } } } @Composable -internal fun TopAction(topActionData: TopActionData) { +internal fun TopAction(modifier: Modifier, topActionData: TopActionData) { with(topActionData) { Box( - modifier = Modifier + modifier = modifier .testTag(testTag.orEmpty()) .size(40.dp) .clip(CircleShape) From bdea242555783b56b0977f7535c0c613104849ed Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Fri, 29 Nov 2024 09:50:56 +0100 Subject: [PATCH 34/39] dhonti/ANDROID-15405-postercard: Remove unused imports --- .../mistica/compose/card/postercard/PosterCardTopActions.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index 82f458cd0..bbe6596fd 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -22,7 +22,6 @@ import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource -import androidx.compose.ui.semantics.focused import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.traversalIndex import androidx.compose.ui.unit.dp From a3f85e6cd8fda89bfd8884ba53390e9c12e40257 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Fri, 29 Nov 2024 10:21:06 +0100 Subject: [PATCH 35/39] dhonti/ANDROID-15405-postercard: Change colors to support dark mode top actions --- .../compose/card/postercard/PosterCardPreviews.kt | 3 ++- .../compose/card/postercard/PosterCardTopActions.kt | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt index 9ae386f01..8bf9b59aa 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardPreviews.kt @@ -1,5 +1,6 @@ package com.telefonica.mistica.compose.card.postercard +import android.content.res.Configuration import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.Box @@ -37,7 +38,7 @@ internal fun PosterCardSolidColor() { } } -@Preview +@Preview(name = "Dark Mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true) @Composable internal fun PosterCardGradientColor() { MisticaTheme(brand = TuBrand) { diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index bbe6596fd..6eceecb16 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -36,7 +36,7 @@ internal fun PosterCardTopActions( Row( modifier = modifier .fillMaxWidth() - .padding(top = 16.dp, start = 16.dp, end = 16.dp, bottom = 8.dp), + .padding(8.dp), horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically ) { @@ -47,7 +47,7 @@ internal fun PosterCardTopActions( } secondTopAction?.let { if (firstTopAction != null) { - Spacer(modifier = Modifier.width(16.dp)) + Spacer(modifier = Modifier.width(4.dp)) } TopAction(topActionData = it, modifier = Modifier.semantics { traversalIndex = 9f @@ -62,13 +62,14 @@ internal fun TopAction(modifier: Modifier, topActionData: TopActionData) { Box( modifier = modifier .testTag(testTag.orEmpty()) - .size(40.dp) + .size(48.dp) + .padding(4.dp) .clip(CircleShape) .clickable { onClick() } .background( color = when { isInverse -> Color.Transparent - withBackground -> MisticaTheme.colors.inverse.copy(alpha = 0.8f) + withBackground -> MisticaTheme.colors.controlInverse.copy(alpha = 0.8f) else -> Color.Transparent } ) From 1d90eb7f92afa967ac327e52f4c0a23caa620c2f Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Fri, 29 Nov 2024 12:41:46 +0100 Subject: [PATCH 36/39] dhonti/ANDROID-15405-postercard: 2nd approach a11 postercard --- .../catalog/ui/compose/components/PosterCards.kt | 14 ++++++++++---- .../mistica/compose/card/postercard/PosterCard.kt | 15 ++++++++++----- .../card/postercard/PosterCardBackground.kt | 7 +++++-- .../card/postercard/PosterCardMainContent.kt | 2 +- .../card/postercard/PosterCardTopActions.kt | 7 +++---- 5 files changed, 29 insertions(+), 16 deletions(-) diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt index 0f0bc6cad..89ab8389d 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt @@ -50,7 +50,7 @@ fun PosterCards() { var inverseDisplay: Boolean by remember { mutableStateOf(true) } var backgroundType: BackgroundType by remember { mutableStateOf(BackgroundType.IMAGE) } - var topActionsType: TopActionsType by remember { mutableStateOf(TopActionsType.NONE) } + var topActionsType: TopActionsType by remember { mutableStateOf(TopActionsType.TWO_ACTIONS) } var preTitle: String by remember { mutableStateOf("Pretitle") } var title: String by remember { mutableStateOf("Title") } @@ -185,7 +185,7 @@ private val topActionsTypeLabelsMap = mapOf( ) private enum class BackgroundType(val backgroundValue: PosterCardBackgroundType) { - IMAGE(PosterCardBackgroundType.Image(imageResource = R.drawable.sample_background)), + 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)))), } @@ -199,8 +199,14 @@ private enum class TopActionsType(val info: PosterCardTopActionInfo? = null) { ), TWO_ACTIONS( info = PosterCardTopActionInfo( - firstTopAction = TopActionData(iconRes = R.drawable.icn_visibility), - secondTopAction = TopActionData(iconRes = R.drawable.ic_close_regular) + 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" + ) ) ) } diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 520ec2cc6..dacb0d112 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -14,6 +14,7 @@ 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.semantics.isTraversalGroup import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -37,7 +38,7 @@ fun PosterCard( ) { val anyTopActionsLoaded = firstTopAction != null || secondTopAction != null - BoxWithConstraints(modifier = modifier) { + BoxWithConstraints(modifier = modifier.semantics(mergeDescendants = true) { }) { androidx.compose.material.Card( elevation = 0.dp, shape = RoundedCornerShape(MisticaTheme.radius.containerBorderRadius), @@ -50,11 +51,13 @@ fun PosterCard( min = maxWidth / aspectRatio.ratio, max = Dp.Infinity ) - .semantics(mergeDescendants = true) {} + .semantics { isTraversalGroup = true } +// .semantics(mergeDescendants = true) { +// focused = true +// } ) { - PosterCardBackground( - backgroundType = backgroundType - ) { + PosterCardBackground(//modifier = Modifier.semantics { isTraversalGroup = true }, + backgroundType = backgroundType) { Column( modifier = Modifier.align(alignment = Alignment.BottomCenter), verticalArrangement = Arrangement.Bottom @@ -63,6 +66,7 @@ fun PosterCard( Spacer(modifier = Modifier.height(40.dp)) } PosterCardMainContent( +// modifier = Modifier.semantics { isTraversalGroup = true }, backgroundType = backgroundType, tag = headline, preTitle = preTitle, @@ -75,6 +79,7 @@ fun PosterCard( if (anyTopActionsLoaded) { PosterCardTopActions( modifier = Modifier.align(alignment = Alignment.TopCenter), +// .semantics { isTraversalGroup = true }, firstTopAction = firstTopAction, secondTopAction = secondTopAction ) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt index 26512a909..1bc4589f3 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt @@ -10,14 +10,17 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.traversalIndex @Composable internal fun PosterCardBackground( + modifier: Modifier = Modifier, backgroundType: PosterCardBackgroundType, content: @Composable BoxScope.() -> Unit) { Box( - modifier = Modifier.background( + modifier = modifier.background( brush = if (backgroundType is PosterCardBackgroundType.Color) { backgroundType.brush } else { @@ -27,7 +30,7 @@ internal fun PosterCardBackground( ) { if (backgroundType is PosterCardBackgroundType.Image) { Image( - modifier = Modifier.matchParentSize(), + modifier = Modifier.matchParentSize().semantics { traversalIndex = 0f }, painter = painterResource(id = backgroundType.imageResource), contentDescription = backgroundType.contentDescription, contentScale = ContentScale.Crop diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt index 5a32c0202..e9452a4a8 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt @@ -51,7 +51,7 @@ internal fun PosterCardMainContent( 24.dp }, ) - .semantics { isTraversalGroup = true }, + .semantics { isTraversalGroup = true } ) { if (tag != null) { Box(modifier = Modifier diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index 6eceecb16..7c43686a0 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -36,7 +36,7 @@ internal fun PosterCardTopActions( Row( modifier = modifier .fillMaxWidth() - .padding(8.dp), + .padding(16.dp), horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically ) { @@ -47,7 +47,7 @@ internal fun PosterCardTopActions( } secondTopAction?.let { if (firstTopAction != null) { - Spacer(modifier = Modifier.width(4.dp)) + Spacer(modifier = Modifier.width(16.dp)) } TopAction(topActionData = it, modifier = Modifier.semantics { traversalIndex = 9f @@ -62,8 +62,7 @@ internal fun TopAction(modifier: Modifier, topActionData: TopActionData) { Box( modifier = modifier .testTag(testTag.orEmpty()) - .size(48.dp) - .padding(4.dp) + .size(40.dp) .clip(CircleShape) .clickable { onClick() } .background( From 52bb0b9a3219e60af56f28cc3eab8ce0911a3e94 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 2 Dec 2024 08:59:04 +0100 Subject: [PATCH 37/39] dhonti/ANDROID-15405-postercard: First approach with a11 integrated --- .../ui/compose/components/PosterCards.kt | 2 +- .../compose/card/postercard/PosterCard.kt | 19 ++++------- .../card/postercard/PosterCardBackground.kt | 12 +++---- .../card/postercard/PosterCardMainContent.kt | 33 +++++-------------- .../card/postercard/PosterCardTopActions.kt | 19 +++++------ 5 files changed, 31 insertions(+), 54 deletions(-) diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt index 89ab8389d..95da4ba73 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt @@ -57,7 +57,7 @@ fun PosterCards() { var subtitle: String by remember { mutableStateOf("Subtitle") } var description: String by remember { mutableStateOf("Description") } - var withAdditionalContent: Boolean by remember { mutableStateOf(false) } + var withAdditionalContent: Boolean by remember { mutableStateOf(true) } Column( diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index dacb0d112..9ce0c8fe0 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -38,26 +38,23 @@ fun PosterCard( ) { val anyTopActionsLoaded = firstTopAction != null || secondTopAction != null - BoxWithConstraints(modifier = modifier.semantics(mergeDescendants = true) { }) { + BoxWithConstraints(modifier = modifier.semantics { isTraversalGroup = true }) { androidx.compose.material.Card( elevation = 0.dp, shape = RoundedCornerShape(MisticaTheme.radius.containerBorderRadius), modifier = Modifier .width(maxWidth) - .clickable(enabled = onClickAction != null) { - onClickAction?.invoke() - } +// .clickable(enabled = onClickAction != null) { +// onClickAction?.invoke() +// } .heightIn( min = maxWidth / aspectRatio.ratio, max = Dp.Infinity ) - .semantics { isTraversalGroup = true } -// .semantics(mergeDescendants = true) { -// focused = true -// } ) { - PosterCardBackground(//modifier = Modifier.semantics { isTraversalGroup = true }, - backgroundType = backgroundType) { + PosterCardBackground( + backgroundType = backgroundType + ) { Column( modifier = Modifier.align(alignment = Alignment.BottomCenter), verticalArrangement = Arrangement.Bottom @@ -66,7 +63,6 @@ fun PosterCard( Spacer(modifier = Modifier.height(40.dp)) } PosterCardMainContent( -// modifier = Modifier.semantics { isTraversalGroup = true }, backgroundType = backgroundType, tag = headline, preTitle = preTitle, @@ -79,7 +75,6 @@ fun PosterCard( if (anyTopActionsLoaded) { PosterCardTopActions( modifier = Modifier.align(alignment = Alignment.TopCenter), -// .semantics { isTraversalGroup = true }, firstTopAction = firstTopAction, secondTopAction = secondTopAction ) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt index 1bc4589f3..6692fb4c5 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt @@ -10,27 +10,27 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.semantics.traversalIndex @Composable internal fun PosterCardBackground( modifier: Modifier = Modifier, backgroundType: PosterCardBackgroundType, - content: @Composable BoxScope.() -> Unit) -{ + content: @Composable BoxScope.() -> Unit +) { Box( - modifier = modifier.background( + modifier = Modifier + .background( brush = if (backgroundType is PosterCardBackgroundType.Color) { backgroundType.brush } else { SolidColor(Color.Transparent) }, ) + .then(modifier) ) { if (backgroundType is PosterCardBackgroundType.Image) { Image( - modifier = Modifier.matchParentSize().semantics { traversalIndex = 0f }, + modifier = Modifier.matchParentSize(), painter = painterResource(id = backgroundType.imageResource), contentDescription = backgroundType.contentDescription, contentScale = ContentScale.Crop diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt index e9452a4a8..00fb71c34 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt @@ -11,8 +11,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shadow import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.semantics.heading -import androidx.compose.ui.semantics.isTraversalGroup import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.traversalIndex import androidx.compose.ui.text.TextStyle @@ -51,15 +49,10 @@ internal fun PosterCardMainContent( 24.dp }, ) - .semantics { isTraversalGroup = true } ) { if (tag != null) { - Box(modifier = Modifier - .padding(top = 16.dp, bottom = 20.dp) - .semantics { - traversalIndex = 2f - }) { - tag.build() + Box(modifier = Modifier.padding(top = 16.dp, bottom = 20.dp)) { + tag.withModifier(modifier = Modifier.semantics { traversalIndex = 2f }).build() } } @@ -67,9 +60,7 @@ internal fun PosterCardMainContent( PosterCardText( modifier = Modifier .padding(top = 4.dp) - .semantics { - traversalIndex = 3f - }, + .semantics { traversalIndex = 3f }, textValue = preTitle, textStyle = MisticaTheme.typography.preset1, inverseDisplay = backgroundType.inverseDisplay @@ -80,10 +71,7 @@ internal fun PosterCardMainContent( PosterCardText( modifier = Modifier .padding(top = 4.dp) - .semantics { - heading() - traversalIndex = 1f - }, + .semantics { traversalIndex = 1f }, textValue = title, textStyle = MisticaTheme.typography.presetCardTitle, inverseDisplay = backgroundType.inverseDisplay @@ -93,9 +81,7 @@ internal fun PosterCardMainContent( PosterCardText( modifier = Modifier .padding(top = 4.dp) - .semantics { - traversalIndex = 4f - }, + .semantics { traversalIndex = 4f }, textValue = subtitle, textStyle = MisticaTheme.typography.preset2, inverseDisplay = backgroundType.inverseDisplay @@ -105,9 +91,7 @@ internal fun PosterCardMainContent( PosterCardText( modifier = Modifier .padding(top = 8.dp) - .semantics { - traversalIndex = 5f - }, + .semantics { traversalIndex = 5f }, textValue = description, textStyle = MisticaTheme.typography.preset2, inverseDisplay = backgroundType.inverseDisplay @@ -116,9 +100,8 @@ internal fun PosterCardMainContent( customContent?.let { Box(modifier = Modifier .padding(top = 4.dp, bottom = 24.dp) - .semantics { - traversalIndex = 6f - }) { + .semantics { traversalIndex = 6f } + ) { it() } } diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index 7c43686a0..06277b18c 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -31,7 +31,7 @@ import com.telefonica.mistica.compose.theme.MisticaTheme internal fun PosterCardTopActions( modifier: Modifier = Modifier, firstTopAction: TopActionData?, - secondTopAction: TopActionData? + secondTopAction: TopActionData?, ) { Row( modifier = modifier @@ -41,26 +41,25 @@ internal fun PosterCardTopActions( verticalAlignment = Alignment.CenterVertically ) { firstTopAction?.let { - TopAction(topActionData = it, modifier = Modifier.semantics { - traversalIndex = 8f - }) + TopAction(topActionData = it, modifier = Modifier.semantics { traversalIndex = 7f }) } secondTopAction?.let { if (firstTopAction != null) { Spacer(modifier = Modifier.width(16.dp)) } - TopAction(topActionData = it, modifier = Modifier.semantics { - traversalIndex = 9f - }) + TopAction(topActionData = it, modifier = Modifier.semantics { traversalIndex = 8f }) } } } @Composable -internal fun TopAction(modifier: Modifier, topActionData: TopActionData) { +internal fun TopAction( + modifier: Modifier = Modifier, + topActionData: TopActionData +) { with(topActionData) { Box( - modifier = modifier + modifier = Modifier .testTag(testTag.orEmpty()) .size(40.dp) .clip(CircleShape) @@ -73,7 +72,7 @@ internal fun TopAction(modifier: Modifier, topActionData: TopActionData) { } ) .wrapContentSize(align = Alignment.Center) - + .then(modifier) ) { Image( painter = painterResource(id = iconRes), From 3ada235f64d32ec692c0dbfb8cf90a37ea2ce468 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 2 Dec 2024 16:19:20 +0100 Subject: [PATCH 38/39] dhonti/ANDROID-15405-postercard: A11 approach using "Modifier.zIndex()" in corresponding components --- .../compose/card/postercard/PosterCard.kt | 13 +++++------ .../card/postercard/PosterCardMainContent.kt | 23 ++++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 9ce0c8fe0..004823e9f 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -14,10 +14,9 @@ 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.semantics.isTraversalGroup -import androidx.compose.ui.semantics.semantics 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 @@ -38,15 +37,15 @@ fun PosterCard( ) { val anyTopActionsLoaded = firstTopAction != null || secondTopAction != null - BoxWithConstraints(modifier = modifier.semantics { isTraversalGroup = true }) { + 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() -// } + .clickable(enabled = onClickAction != null) { + onClickAction?.invoke() + } .heightIn( min = maxWidth / aspectRatio.ratio, max = Dp.Infinity @@ -74,7 +73,7 @@ fun PosterCard( } if (anyTopActionsLoaded) { PosterCardTopActions( - modifier = Modifier.align(alignment = Alignment.TopCenter), + modifier = Modifier.align(alignment = Alignment.TopCenter).zIndex(1f), firstTopAction = firstTopAction, secondTopAction = secondTopAction ) diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt index 00fb71c34..38719496a 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardMainContent.kt @@ -11,10 +11,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shadow import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.semantics.traversalIndex import androidx.compose.ui.text.TextStyle 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 @@ -51,8 +50,8 @@ internal fun PosterCardMainContent( ) ) { if (tag != null) { - Box(modifier = Modifier.padding(top = 16.dp, bottom = 20.dp)) { - tag.withModifier(modifier = Modifier.semantics { traversalIndex = 2f }).build() + Box(modifier = Modifier.padding(top = 16.dp, bottom = 20.dp).zIndex(2f)) { + tag.build() } } @@ -60,7 +59,7 @@ internal fun PosterCardMainContent( PosterCardText( modifier = Modifier .padding(top = 4.dp) - .semantics { traversalIndex = 3f }, + .zIndex(2f), textValue = preTitle, textStyle = MisticaTheme.typography.preset1, inverseDisplay = backgroundType.inverseDisplay @@ -71,7 +70,7 @@ internal fun PosterCardMainContent( PosterCardText( modifier = Modifier .padding(top = 4.dp) - .semantics { traversalIndex = 1f }, + .zIndex(0f), textValue = title, textStyle = MisticaTheme.typography.presetCardTitle, inverseDisplay = backgroundType.inverseDisplay @@ -81,7 +80,7 @@ internal fun PosterCardMainContent( PosterCardText( modifier = Modifier .padding(top = 4.dp) - .semantics { traversalIndex = 4f }, + .zIndex(4f), textValue = subtitle, textStyle = MisticaTheme.typography.preset2, inverseDisplay = backgroundType.inverseDisplay @@ -91,16 +90,18 @@ internal fun PosterCardMainContent( PosterCardText( modifier = Modifier .padding(top = 8.dp) - .semantics { traversalIndex = 5f }, + .zIndex(5f), textValue = description, textStyle = MisticaTheme.typography.preset2, inverseDisplay = backgroundType.inverseDisplay ) } + customContent?.let { - Box(modifier = Modifier - .padding(top = 4.dp, bottom = 24.dp) - .semantics { traversalIndex = 6f } + Box( + modifier = Modifier + .padding(top = 4.dp, bottom = 24.dp) + .zIndex(6f), ) { it() } From f78acfa1ee55caf098306648144a1e7c59b5e348 Mon Sep 17 00:00:00 2001 From: David Hontiveros Gordo Date: Mon, 2 Dec 2024 17:04:53 +0100 Subject: [PATCH 39/39] dhonti/ANDROID-15405-postercard: Apply some corrections from PR @jeprubio --- .../catalog/ui/compose/components/PosterCards.kt | 4 ++-- .../mistica/compose/card/postercard/PosterCard.kt | 6 ++---- .../compose/card/postercard/PosterCardBackground.kt | 2 -- .../compose/card/postercard/PosterCardTopActions.kt | 12 +++--------- 4 files changed, 7 insertions(+), 17 deletions(-) diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt index 95da4ba73..2faeef6ca 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/PosterCards.kt @@ -50,14 +50,14 @@ fun PosterCards() { var inverseDisplay: Boolean by remember { mutableStateOf(true) } var backgroundType: BackgroundType by remember { mutableStateOf(BackgroundType.IMAGE) } - var topActionsType: TopActionsType by remember { mutableStateOf(TopActionsType.TWO_ACTIONS) } + 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(true) } + var withAdditionalContent: Boolean by remember { mutableStateOf(false) } Column( diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt index 004823e9f..5bfb683c7 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCard.kt @@ -22,9 +22,9 @@ import com.telefonica.mistica.compose.theme.MisticaTheme @Composable fun PosterCard( - modifier: Modifier = Modifier, aspectRatio: PosterCardAspectRatio, backgroundType: PosterCardBackgroundType, + modifier: Modifier = Modifier, headline: Tag? = null, preTitle: String? = null, title: String? = null, @@ -51,9 +51,7 @@ fun PosterCard( max = Dp.Infinity ) ) { - PosterCardBackground( - backgroundType = backgroundType - ) { + PosterCardBackground(backgroundType = backgroundType) { Column( modifier = Modifier.align(alignment = Alignment.BottomCenter), verticalArrangement = Arrangement.Bottom diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt index 6692fb4c5..29552eca1 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardBackground.kt @@ -13,7 +13,6 @@ import androidx.compose.ui.res.painterResource @Composable internal fun PosterCardBackground( - modifier: Modifier = Modifier, backgroundType: PosterCardBackgroundType, content: @Composable BoxScope.() -> Unit ) { @@ -26,7 +25,6 @@ internal fun PosterCardBackground( SolidColor(Color.Transparent) }, ) - .then(modifier) ) { if (backgroundType is PosterCardBackgroundType.Image) { Image( diff --git a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt index 06277b18c..e6e495b27 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/card/postercard/PosterCardTopActions.kt @@ -22,8 +22,6 @@ import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.semantics.traversalIndex import androidx.compose.ui.unit.dp import com.telefonica.mistica.compose.theme.MisticaTheme @@ -41,22 +39,19 @@ internal fun PosterCardTopActions( verticalAlignment = Alignment.CenterVertically ) { firstTopAction?.let { - TopAction(topActionData = it, modifier = Modifier.semantics { traversalIndex = 7f }) + TopAction(topActionData = it) } secondTopAction?.let { if (firstTopAction != null) { Spacer(modifier = Modifier.width(16.dp)) } - TopAction(topActionData = it, modifier = Modifier.semantics { traversalIndex = 8f }) + TopAction(topActionData = it) } } } @Composable -internal fun TopAction( - modifier: Modifier = Modifier, - topActionData: TopActionData -) { +internal fun TopAction(topActionData: TopActionData) { with(topActionData) { Box( modifier = Modifier @@ -72,7 +67,6 @@ internal fun TopAction( } ) .wrapContentSize(align = Alignment.Center) - .then(modifier) ) { Image( painter = painterResource(id = iconRes),