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

Add support for Custom Preview Annotations #263

Conversation

oas004
Copy link
Contributor

@oas004 oas004 commented Sep 9, 2022

Add support for CustomMultiPreviewAnnotations in Showkase.

This is the third PR in a series to add support for Custom MultiPreview Annotations. Referencing as a followup on #259 and #255.

By completing this should solve #233

What do I mean by Custom MultiPreview Annotations?

This is an annotation in the form

@Preview(name = "Custom Preview One First", group = "Custom Previews")
@Preview(name = "Custom Preview One Second", group = "Custom Previews")
annotation class CustomPreview

this can be used to annotate a composable function like you would do any other preview function in Compose like this:

@CustomPreview
@Composable
fun CustomAnnotationPreview() {
}

This can also be combined like this:

@Preview(name = "Custom Preview One First", group = "Custom Previews")
@Preview(name = "Custom Preview One Second", group = "Custom Previews")
annotation class CustomPreviewOne


@Preview(name = "Custom Preview Two First", group = "Custom Previews")
@Preview(name = "Custom Preview Two Second", group = "Custom Previews")
annotation class CustomPreviewTwo

@CustomPreviewOne
@CustomPreviewTwo
@Composable
fun CustomAnnotationPreviewCombined() {
}

They should be able to have the custom annotations and the use of them in different modules in a project.

For more information, please see docs on tooling in compose here

Goal

The goal is to add support for this in Showkase. We would like showkase to act like the tooling in Android Studio does. That means that when Android Studio Preview would have generated a Preview, showkase should also generate a ShowkaseMetadata function.

Testing

Sample App

In the sample app I have introduced Shapes. This is to showkase different shapes in Showkase.

Here I have made two internal (in same module) and one external (in submodule) annotations

Internals:

@Preview(name = "Square 200 by 200", group = "Shape", widthDp = 200, heightDp = 200)
@Preview(name = "Square 400 by 400", group = "Shape", widthDp = 400, heightDp = 400)
annotation class ShapePreview

@Preview(
    name = "Phone 200 by 200",
    group = "Shape",
    widthDp = 200,
    heightDp = 200,
    device = Devices.PHONE
)
@Preview(
    name = "Tablet 400 by 400",
    group = "Shape",
    widthDp = 400,
    heightDp = 400,
    device = Devices.TABLET
)
annotation class DevicePreview

Eksternal

@Preview(name = "Circle 150 by 150", group = "Shape", widthDp = 150, heightDp = 150)
@Preview(name = "Circle 200 by 200", group = "Shape", widthDp = 200, heightDp = 200)
annotation class CircleShapePreview

This is annotating different Composables in the shapes domain. Here is an overview of the Composables that are annotated.

ElementName Comined Scope
CirclePreview No External
RoundRectanglePreview Yes Both
SquarePreview No Internal

The RoundRectanglePreview here is also annotated with a singular Preview annotation to check that the combination works. Since It is annotated with two annotations that has two preview annotations this should generate 2 + 2 + 1 previews in Showkase.

Please check out the app with the useKsp=true and click on the shapes tab to see the samples.

Browser Test

For the UI tests I have currently made two custom annotations. One internal (same module) and one external(submodule)

Internal

@Preview(
    name = "Custom Text Light",
    group = "Button",
    uiMode = Configuration.UI_MODE_NIGHT_NO,
)
@Preview(
    name = "Custom Text Dark",
    group = "Button",
    uiMode = Configuration.UI_MODE_NIGHT_YES,
)
annotation class CustomButtonPreview

External

@Preview(name = "CustomPreview one", group = "CustomExternalPreview")
@Preview(name = "CustomPreview two", group = "CustomExternalPreview")
annotation class CustomPreviewAnnotation

These are annotating different Composables. Here I have tried to combine them as well with each other and with singular ones.

Added tests for the different cases and checked that they are generating individual Composables in their respective group.
This should be the same as what is generated in the Sample application just with different names.

Processor Test

In the processor tests, I have made tests that make sure all the correct metadata objects are created and that we are creating the files to store the custom annotations that the processor has registered. You can check these tests in showcase-processor-testing module.

What is left

This is very much still a work in progress. I have tried to list up what I have left under to get an overview.

- [ ] Add docs about how to support your custom preview annotations. - This should be done in a different PR that can be merged just before release so that it does not cause confusion.

  • Make custom multi preview annotations work for annotations that are in the same module as the showkase preview.
  • Make custom multi preview annotations work for annotations that are in a different module as the showkase preview and is imported into the file that has the showkase preview.
  • Add processor tests for the different cases.

- [ ] Add processor testing submodule so that I can test that the annotation being in a different library module will generate a showkaseMetadata object. - Not possible because testing library does not support this

  • Add Browser tests for the singular module case.
  • Add Browser tests for the multi module case.
  • Add processor test for combining custom annotations.
  • Make combining multiple custom annotations generate multiple showkaseMetadata objects.
  • Add Browser tests for combining multiple custom annotations.

sample-submodule/build.gradle Outdated Show resolved Hide resolved
@oas004 oas004 force-pushed the feature/add-support-for-custom-preview-annotations branch 3 times, most recently from 111b43d to 5fc4bef Compare September 19, 2022 20:04
sample/build.gradle Outdated Show resolved Hide resolved
@oas004 oas004 force-pushed the feature/add-support-for-custom-preview-annotations branch 3 times, most recently from db752cf to 5d8ba7e Compare September 19, 2022 20:10
@oas004 oas004 force-pushed the feature/add-support-for-custom-preview-annotations branch 2 times, most recently from 7b0419c to ea3e4c7 Compare September 22, 2022 16:11
@oas004 oas004 force-pushed the feature/add-support-for-custom-preview-annotations branch 2 times, most recently from e6646de to aad61a6 Compare September 28, 2022 19:50
@oas004 oas004 changed the title [WIP] Add support for Custom Preview Annotations Add support for Custom Preview Annotations Sep 28, 2022
@oas004 oas004 marked this pull request as ready for review September 28, 2022 21:24
@oas004 oas004 force-pushed the feature/add-support-for-custom-preview-annotations branch 3 times, most recently from a32b305 to f46bef0 Compare September 29, 2022 15:22
@oas004 oas004 requested a review from vinaygaba September 29, 2022 16:08
@oas004 oas004 force-pushed the feature/add-support-for-custom-preview-annotations branch from 9e6d946 to 6cd4a89 Compare October 30, 2022 13:27
return (showkaseComposablesMetadata + previewComposablesMetadata)

// This is for getting custom annotations from class path
val customAnnotationMetadataFromClassPath =
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why are we picking from the classpath here? Why not do it at the same place where we do it for @Preview and @ShowkaseComposable annotations

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 think the reason I have to split this up into two methods, is that the processCustomAnnotation method only uses the supported annotations type qualified name and was meant for KAPT to work. But the processCustomAnnotationFromClassPath was meant to get the stored annotation metadata from each round and based on that check if we had any qualified names we could search for. The reason we have to split them up is that we are using some of the other properties from the stored metadata that we store on each round I believe. Maybe I can remove the processCustomAnnotation and merge that into the processCustomAnnotationFromClassPath but I think that might risk it becoming very messy? And I kinda don't know how to handle that we get preview name and such from the stored metadata and not from the supported compile option name thingy 🤔

@polivmi1
Copy link

Is this still planned in near future? Is any help needed?

@oas004
Copy link
Contributor Author

oas004 commented Jan 18, 2023

Is this still planned in near future? Is any help needed?

With this PR it should work for KSP. We had to do some changes for KAPT. I think I will have to make another PR because there is to much conflicts and we have to change the approach a bit after some of the changes that has been merged. I have not gotten around to it quite yet because of other things. If you want to help and check this out, you are more than welcome to :)

@anhanh11001
Copy link

Hi @oas004 , thanks for the work!

My team’s work is dependent on this custom preview annotation in order to support Paparazzi screenshot testing. Can I ask if there are estimated timeline on having this released (only KSP is already great to us)?

I’d love to help if I can do anything but I’m really new to annotation processing programming so maybe guides are needed

@oas004
Copy link
Contributor Author

oas004 commented Jan 30, 2023

Hi @oas004 , thanks for the work!

My team’s work is dependent on this custom preview annotation in order to support Paparazzi screenshot testing. Can I ask if there are estimated timeline on having this released (only KSP is already great to us)?

I’d love to help if I can do anything but I’m really new to annotation processing programming so maybe guides are needed

Hey @anhanh11001. Sorry for blocking you. Had a bit to much on my plate at work, so this has been a bit down prioritised. I will try my best to get some work in on this this week. Since we have released #255, it should at least not throw at compile time, it will just be bypassed from Showkase point of view.

I think the stuff in this PR should be enough for it to work with KSP at least. It has to be changed along with this #284

@oas004
Copy link
Contributor Author

oas004 commented Feb 12, 2023

Closing this in favour of #303

@oas004 oas004 closed this Feb 12, 2023
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.

4 participants