Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

ANDROID-13941 Implement Callout Image/Avatar #317

Merged
merged 15 commits into from
Dec 1, 2023

Conversation

fjquileze
Copy link
Contributor

🥅 What's the goal?

We need to add the image/avatar to callout element as it's specified here: Callout Component Specs

Currently we only have icons

🚧 How do we do it?

  • Add an image and avatar (circular image) to CalloutView
  • Add the imageRes and imageConfig params to the Callout composable maintaining the old iconRes for retrocompatibility purposes

☑️ Checks

  • I updated the documentation, including readmes and wikis. If this is a breaking change, update UPGRADING.md to inform users how to proceed. If no updates are necessary, indicate so.
  • Tested with dark mode.
  • Tested with API 23.

🧪 How can I test this?

  • 🖼️ Screenshots/Video
Screen_recording_20231110_184246.mp4
  • Mistica App QR or download link
  • Reviewed by Mistica design team

@fjquileze fjquileze requested review from DevPabloGarcia, a team and jeslat and removed request for a team November 10, 2023 17:45
Copy link

📱 New catalog for testing generated: Download

Copy link
Contributor

@DevPabloGarcia DevPabloGarcia left a comment

Choose a reason for hiding this comment

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

Thanks! check comments please

/>

<ImageView
android:id="@+id/callout_image"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Set visibility default as: GONE

android:visibility="gone"
app:shapeAppearance="@style/CircleImageView"
tools:src="@tools:sample/avatars"
tools:visibility="gone"
Copy link
Contributor

Choose a reason for hiding this comment

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

as we have android:visibility="gone", tools:visibility="gone" is not needed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nice catch! I'm going to remove it

@@ -322,6 +389,11 @@ class CalloutView @JvmOverloads constructor(
const val BUTTONS_CONFIG_SECONDARY_LINK = 4
const val BUTTONS_CONFIG_LINK = 5

const val IMAGE_CONFIG_NONE = -1
Copy link
Contributor

Choose a reason for hiding this comment

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

Question, why not use a enum class?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was just following the code that was here before but I can make an enum

@@ -31,6 +38,8 @@ fun Callout(
description: String?,
buttonConfig: CalloutButtonConfig,
@DrawableRes iconRes: Int? = null,
Copy link
Contributor

Choose a reason for hiding this comment

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

IMHO instead of having one attribute to icon an other to imageRes we can simplify it, and just have iconRes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you're right, I'm gonna change it!

@@ -56,13 +65,43 @@ fun Callout(
modifier = Modifier.padding(16.dp),
verticalAlignment = Alignment.Top,
) {
iconRes?.let {

if (iconRes != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand this logic, first we check if iconRes is not null to create an Image, but bellow if imageConfig is IMAGE_CONFIG_ICON we create the same object?

I think we can check first the imageConfig and then create the image:

`when (imageConfig) {
CalloutView.IMAGE_CONFIG_ICON -> // create icon
CalloutView.IMAGE_CONFIG_SQUARE -> // create square image
CalloutView.IMAGE_CONFIG_CIRCULAR -> //create circular image

}
`

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed!

Copy link

📱 New catalog for testing generated: Download

@fjquileze fjquileze requested review from DevPabloGarcia, a team and yceballost and removed request for a team November 15, 2023 11:11
Comment on lines 43 to 52
BindingMethod(
type = CalloutView::class,
attribute = "calloutImage",
method = "setImage",
),
BindingMethod(
type = CalloutView::class,
attribute = "calloutCircularImage",
method = "setCircularImage",
),
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the API would be easier to use if you follow the same approach that we use in ListRowView or DataCardView. Instead of having one method per image type, which can be confusing for the user because he has to know which types of images support this component, have two methods:

  • setAsset
  • setAssetType

If we have more asset types in the future, will be easier to add them.

I'm not sure if maintaining the retro compatibility in this case is worth it. We could remove the setIcon method and migrate its uses (it should be easy).

Copy link
Contributor

Choose a reason for hiding this comment

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

It would be the same that you have done in the Compose version

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, I'm going to change it

}
CalloutViewImageConfig.IMAGE_CONFIG_SQUARE -> {
resourceIconPainter(
iconRes = iconRes, iconType = IconType.SQUARE_IMAGE,
Copy link
Contributor

Choose a reason for hiding this comment

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

Move the iconType to the next line

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

modifier = Modifier.padding(end = 16.dp)
)
}
else -> noIcon()
Copy link
Contributor

Choose a reason for hiding this comment

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

I would not use the else, if in the future you add a new type, the compiler won't tell you anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good point! changed

colorFilter = ColorFilter.tint(MisticaTheme.colors.neutralHigh)
)

if (iconRes != null) {
Copy link
Contributor

@jeslat jeslat Nov 16, 2023

Choose a reason for hiding this comment

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

I would extract the icon logic to a new private composable:

if (iconRes != null) {
                Icon(imageConfig, iconRes)
            }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

Copy link

📱 New catalog for testing generated: Download

@fjquileze fjquileze requested a review from jeslat November 21, 2023 08:26
@@ -272,7 +272,6 @@
<declare-styleable name="CalloutView">
<attr name="calloutTitle" format="string"/>
<attr name="calloutDescription" format="string"/>
<attr name="calloutIcon" format="reference"/>
Copy link
Contributor

Choose a reason for hiding this comment

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

As this is a breaking change, remember to deploy a major release and add a new section in the migrations document https://github.com/Telefonica/mistica-android/blob/main/UPGRADING.md

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

@@ -37,7 +38,12 @@ import com.telefonica.mistica.util.getThemeColor
BindingMethod(
type = CalloutView::class,
attribute = "calloutIcon",
Copy link
Contributor

Choose a reason for hiding this comment

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

These attributes have to have the same name as defined in attrs_components

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

Comment on lines +239 to +240
image.visibility = GONE
circularImage.visibility = GONE
Copy link
Contributor

Choose a reason for hiding this comment

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

I would move these visibility changes inside setIcon method. The same with setImage and setCircularImage

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done 👍

Comment on lines 372 to 393
CalloutViewImageConfig.IMAGE_CONFIG_NONE -> {
icon.visibility = GONE
image.visibility = GONE
circularImage.visibility = GONE
}

CalloutViewImageConfig.IMAGE_CONFIG_ICON -> {
icon.visibility = VISIBLE
image.visibility = GONE
circularImage.visibility = GONE
}

CalloutViewImageConfig.IMAGE_CONFIG_SQUARE -> {
icon.visibility = GONE
image.visibility = VISIBLE
circularImage.visibility = GONE
}

CalloutViewImageConfig.IMAGE_CONFIG_CIRCULAR -> {
icon.visibility = GONE
image.visibility = GONE
circularImage.visibility = VISIBLE
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you are doing these visibility changes two times, I would remove this method

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed!

@@ -153,3 +184,9 @@ fun Callouts() {
}
}

private enum class ImageTypes(val iconType: CalloutViewImageConfig) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I found we have 3 enums for the same reason: Image Type, I think we can simplify it only using CalloutViewImageConfig.

To show the name in callout catalog we can make a function or extension function to obtain the name

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree, I'm gonna refactor it

}
setAssetType(imageConfig)
Copy link
Contributor

Choose a reason for hiding this comment

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

If the imageConfig is NONE we call this function twice, we can avoid this moving this line to each condition

Suggested change
setAssetType(imageConfig)
when (imageConfig) {
CalloutViewImageConfig.IMAGE_CONFIG_NONE -> {
setAssetType(imageConfig)
}
CalloutViewImageConfig.IMAGE_CONFIG_ICON -> {
setAsset(R.drawable.ic_callout)
setAssetType(imageConfig)
}
CalloutViewImageConfig.IMAGE_CONFIG_SQUARE,
CalloutViewImageConfig.IMAGE_CONFIG_CIRCULAR -> {
setAsset(R.drawable.media_card_sample_image)
setAssetType(imageConfig)
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

@@ -95,4 +119,11 @@ class CalloutsCatalogFragment : Fragment() {
SECONDARY_AND_LINK(CalloutView.BUTTONS_CONFIG_SECONDARY_LINK),
LINK(CalloutView.BUTTONS_CONFIG_LINK),
}

private enum class CalloutImageConfig(val imageConfig: CalloutViewImageConfig) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Se next comment, we are declaring 3 enums to store the same value

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed!

icon.setImageResource(iconRes)
icon.visibility = VISIBLE
fun setAsset(@DrawableRes assetRes: Int?) {
asset = assetRes
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
asset = assetRes
when (assetType) {
null,
CalloutViewImageConfig.IMAGE_CONFIG_NONE -> noAsset()
CalloutViewImageConfig.IMAGE_CONFIG_ICON -> setIcon(assetRes)
CalloutViewImageConfig.IMAGE_CONFIG_SQUARE -> setImage(assetRes)
CalloutViewImageConfig.IMAGE_CONFIG_CIRCULAR -> setCircularImage(assetRes)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't get this change, can you explain it a little more?

Copy link
Contributor

@yceballost yceballost Nov 21, 2023

Choose a reason for hiding this comment

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

image
this left padding is not correct when the image is "none" (in classic)

An example in web
https://tinyurl.com/ykhg3dk8

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed!

Copy link
Contributor

Choose a reason for hiding this comment

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

Image is not using border radius token

This screenshot is in Vivo new for example:
image

Image component has to use mediaSmall
https://github.com/Telefonica/mistica-design/blob/5542488dfa4d6e6555b63129cc33e2ea502e9c39/tokens/movistar.json#L1118

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed! 👍

Copy link

📱 New catalog for testing generated: Download

Copy link

📱 New catalog for testing generated: Download

Copy link

📱 New catalog for testing generated: Download

Copy link

📱 New catalog for testing generated: Download

BUTTONS_CONFIG_NONE -> {}
}
}

private fun setImageConfig(imageConfig: CalloutViewImageConfig) {
Copy link
Contributor

Choose a reason for hiding this comment

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

You are not using this method

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm using it at the CalloutCatalogFragment to set the type

Copy link
Contributor

Choose a reason for hiding this comment

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

No, you are not, you are using setButtonsConfig. This method is private, it's impossible that you are using it out of this class

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh! you're right, I was thinking in the setAssetType method. I'm gonna delete this one

Comment on lines 153 to 158
imageConfig = when (iconType) {
CalloutViewImageConfig.NONE -> CalloutViewImageConfig.NONE
CalloutViewImageConfig.ICON -> CalloutViewImageConfig.ICON
CalloutViewImageConfig.SQUARE_IMAGE -> CalloutViewImageConfig.SQUARE_IMAGE
CalloutViewImageConfig.CIRCULAR_IMAGE -> CalloutViewImageConfig.CIRCULAR_IMAGE
},
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need the when, both types are the same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤦‍♂️ fixed!

Copy link

📱 New catalog for testing generated: Download

Copy link
Contributor

@jeslat jeslat left a comment

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

@DevPabloGarcia DevPabloGarcia left a comment

Choose a reason for hiding this comment

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

Nice !

@nimeacuerdo
Copy link
Contributor

Hi @yceballost! anything left on your side to approve this?

Copy link

github-actions bot commented Dec 1, 2023

📱 New catalog for testing generated: Download

Copy link
Contributor

@yceballost yceballost left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks!

@fjquileze fjquileze merged commit 05f5567 into main Dec 1, 2023
5 checks passed
@fjquileze fjquileze deleted the task/android-13941-implement-callout-image-avatar branch December 1, 2023 10:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants