Skip to content

Commit

Permalink
Merge pull request #6 from javierpe/task/large-screens
Browse files Browse the repository at this point in the history
KSP processor
  • Loading branch information
javierpe authored Nov 2, 2022
2 parents 168471e + 27518c8 commit 0f087e2
Show file tree
Hide file tree
Showing 126 changed files with 18,424 additions and 1,177 deletions.
57 changes: 15 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
- [x] Compose navigation
- [x] Render process mechanism
- [x] Package refactor and naming
- [x] Unit test
- [x] Macrobenchmark test
- [x] Android CI
- [x] KSP processor to avoid boilerplate code
- [x] Unit test, Macrobenchmark and Android CI

Art Gallery is based on Server Driven UI, only provide a JSON with a UI definition.
Expand Down Expand Up @@ -42,48 +46,17 @@
}
```

To complete this magic, now we should register the component and follow the next steps:

### DynamicListAdapterFactory
1. We need to add new component name to RenderType enum.
2. We need to create a factory class that extends DynamicListAdapterFactory, this class must implement some functions:
* ###### ...renders: List<RenderType>
* This define what renders will be created in current factory
* ###### ...CreateComponent(...)
* This function will create a component, put compose view inside this.
* ###### ...CreateSkeleton()
* This is a copy of you compose component view, this allow show the component when screen is loading

### DynamicListRender
1. We need create a render class to extends DynamicListRender
2. This class is in charge of processing the JSON model and converting it into a Kotlin object, we need to pass it a generic type which it will return after processing it.
3. This class allows you to define data processing logic before the component is displayed.
* ###### ...renders: List<RenderType>
* This define what renders will be created in current render
* ###### ...resolve(...)
* This returns the previously defined model in the class

### Hilt

Hilt helps us to inject these renders and factories when the back end responds, to show this component we need add it to:

* ###### DynamicListFactoriesModule
```java
@Binds
@IntoSet
abstract fun bindFactory(
factory: MyCustomFactory
): DynamicListAdapterFactory
```

* ###### DynamicListRendersModule
```java
@Binds
@IntoSet
abstract fun bindRender(
render: MyCustomRender
): DynamicListRender<*>
```
### Magic annotations

With KSP we extend the functionality to annotations to avoid boilerplate code. Only follow this:

1. Your data class should have @RenderClass annotation and provide it the render type like RenderType.BANNER or whatever you need.

2. If you want transform that model when the resource is available you can add a render factory class that extends of DynamicListRender<BannerCarouselModel> and provide @RenderFactory annotation with a model class as parameter like BannerCarouselModel::class. This process transform your model before UI use it.

3. Finaly, you should have a factory that will be used to create the UI for that single component, should extends of DynamicListFactory and provide @AdapterFactory annotation.

Note: _ComponentModel_ is a data class that contains your element definition, _render_, _index_ and _resource_

And thats it...

Expand Down
1 change: 1 addition & 0 deletions app/benchmark/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ android {
}

targetProjectPath = ":app"
namespace 'com.nucu.benchmark'
experimentalProperties["android.experimental.self-instrumenting"] = true
}

Expand Down
3 changes: 1 addition & 2 deletions app/benchmark/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nucu.benchmark">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<queries>
<package android:name="com.nucu.dynamiclistcompose" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.nucu.benchmark

import androidx.benchmark.macro.ExperimentalBaselineProfilesApi
import androidx.benchmark.macro.junit4.BaselineProfileRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@ExperimentalBaselineProfilesApi
@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {

@get:Rule
val baselineProfileRule = BaselineProfileRule()

@Test
fun startup() =
baselineProfileRule.collectBaselineProfile(packageName = PACKAGE_NAME) {
pressHome()
// This block defines the app's critical user journey. Here we are interested in
// optimizing for app startup. But you can also navigate and scroll
// through your most important UI.
startActivityAndWait()
}
}
58 changes: 37 additions & 21 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,28 @@ plugins {
}

android {
signingConfigs {
release {
storeFile file('release_app')
storePassword 'j35u5777'
keyAlias 'ArtGallery'
keyPassword 'j35u5777'
}
}
compileSdk 33

defaultConfig {
applicationId "com.nucu.dynamiclistcompose"
minSdk 26
targetSdk 33
versionCode 5
versionName "1.0.4"
versionCode 6
versionName "1.1.0"

testInstrumentationRunner = "com.nucu.dynamiclistcompose.HiltTestRunner"
vectorDrawables {
useSupportLibrary true
}
signingConfig signingConfigs.release
}

lint {
Expand All @@ -28,7 +37,9 @@ android {

buildTypes {
release {
minifyEnabled false
debuggable false
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
benchmark {
Expand Down Expand Up @@ -82,38 +93,40 @@ android {
}
}

hilt {
enableTransformForLocalTests = true
}

dependencies {

// Navigation
implementation(project(":navigation:api"))
implementation(project(":navigation:impl"))
implementation(project(":navigation:wiring"))

// Render processor
implementation(project(":render-processor"))
ksp(project(":render-processor"))

// Pager
implementation "com.google.accompanist:accompanist-pager:0.26.2-beta"
implementation "com.google.accompanist:accompanist-pager-indicators:0.19.0"

// Coil (Bad performance)
//implementation("io.coil-kt:coil-compose:2.2.0")

implementation "com.github.skydoves:landscapist-glide:1.6.1"
implementation("io.coil-kt:coil-compose:2.2.2")

// Gson
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
implementation "com.squareup.moshi:moshi-kotlin:1.14.0"
implementation "com.squareup.moshi:moshi-adapters:1.13.0"
ksp 'com.squareup.moshi:moshi-kotlin-codegen:1.14.0'

// Hilt
implementation("com.google.dagger:hilt-android:2.43.2")
implementation 'androidx.constraintlayout:constraintlayout-core:1.0.4'
kapt("com.google.dagger:hilt-android-compiler:2.43.2")

// Navigation
implementation("androidx.hilt:hilt-navigation-compose:1.0.0")
implementation 'io.github.raamcosta.compose-destinations:core:1.7.16-beta'
implementation 'io.github.raamcosta.compose-destinations:animations-core:1.7.16-beta'
ksp 'io.github.raamcosta.compose-destinations:ksp:1.7.16-beta'
implementation 'io.github.raamcosta.compose-destinations:core:1.7.22-beta'
implementation 'io.github.raamcosta.compose-destinations:animations-core:1.7.22-beta'
ksp 'io.github.raamcosta.compose-destinations:ksp:1.7.22-beta'

// Lottie
implementation "com.airbnb.android:lottie-compose:5.2.0"
Expand All @@ -122,9 +135,11 @@ dependencies {
implementation "androidx.datastore:datastore-preferences:1.0.0"

// Alpha
implementation "androidx.compose.material3:material3-window-size-class:1.0.0-beta01"
implementation "androidx.compose.material3:material3:1.0.0-beta01"
// Pagination: implementation "androidx.paging:paging-compose:1.0.0-alpha14"
implementation "androidx.compose.material3:material3-window-size-class:1.0.0-rc01"
implementation "androidx.compose.material3:material3:1.0.0-rc01"

// Pagination:
//implementation "androidx.paging:paging-compose:1.0.0-alpha16"

// Room
implementation "androidx.room:room-rxjava3:2.4.3"
Expand All @@ -133,13 +148,14 @@ dependencies {

// Compose
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:1.3.0-beta01"
implementation "androidx.compose.material:material:1.3.0-rc01"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.activity:activity-compose:1.5.1'
implementation 'androidx.activity:activity-compose:1.6.0'
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"

implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation 'androidx.core:core-ktx:1.8.0'
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$compose_lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-compose:$compose_lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$compose_lifecycle_version"
implementation 'androidx.core:core-ktx:1.9.0'

// Test
testImplementation 'app.cash.turbine:turbine:0.9.0'
Expand Down
4 changes: 3 additions & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#-renamesourcefileattribute SourceFile

-keep class com.nucu.dynamiclistcompose.presentation.components.** { *; }
20 changes: 20 additions & 0 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.nucu.dynamiclistcompose",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 5,
"versionName": "1.0.4",
"outputFile": "app-release.apk"
}
],
"elementType": "File"
}
Binary file added app/release_app
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import androidx.compose.ui.test.onNodeWithTag
import com.nucu.dynamiclistcompose.MainActivity
import com.nucu.dynamiclistcompose.data.models.ComponentInfo
import com.nucu.dynamiclistcompose.data.models.ComponentItemModel
import com.nucu.dynamiclistcompose.data.renders.base.RenderType
import com.javi.render.processor.data.enums.RenderType
import com.nucu.dynamiclistcompose.presentation.components.bannerCarousel.BannerCarouselModel
import com.nucu.dynamiclistcompose.presentation.ui.components.showCase.rememberShowCaseState
import dagger.hilt.android.testing.HiltAndroidRule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import androidx.compose.ui.test.onNodeWithTag
import com.nucu.dynamiclistcompose.MainActivity
import com.nucu.dynamiclistcompose.data.models.ComponentInfo
import com.nucu.dynamiclistcompose.data.models.ComponentItemModel
import com.nucu.dynamiclistcompose.data.renders.base.RenderType
import com.javi.render.processor.data.enums.RenderType
import com.nucu.dynamiclistcompose.presentation.components.banner.BannerModel
import com.nucu.dynamiclistcompose.presentation.ui.components.showCase.rememberShowCaseState
import dagger.hilt.android.testing.HiltAndroidRule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import androidx.compose.ui.test.onNodeWithTag
import com.nucu.dynamiclistcompose.MainActivity
import com.nucu.dynamiclistcompose.data.models.ComponentInfo
import com.nucu.dynamiclistcompose.data.models.ComponentItemModel
import com.nucu.dynamiclistcompose.data.renders.base.RenderType
import com.javi.render.processor.data.enums.RenderType
import com.nucu.dynamiclistcompose.presentation.components.card.CardsModel
import com.nucu.dynamiclistcompose.presentation.ui.components.showCase.rememberShowCaseState
import dagger.hilt.android.testing.HiltAndroidRule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import androidx.compose.ui.test.onNodeWithTag
import com.nucu.dynamiclistcompose.MainActivity
import com.nucu.dynamiclistcompose.data.models.ComponentInfo
import com.nucu.dynamiclistcompose.data.models.ComponentItemModel
import com.nucu.dynamiclistcompose.data.renders.base.RenderType
import com.javi.render.processor.data.enums.RenderType
import com.nucu.dynamiclistcompose.presentation.components.faces.FacesModel
import com.nucu.dynamiclistcompose.presentation.ui.components.showCase.rememberShowCaseState
import dagger.hilt.android.testing.HiltAndroidRule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import androidx.compose.ui.test.onNodeWithTag
import com.nucu.dynamiclistcompose.MainActivity
import com.nucu.dynamiclistcompose.data.models.ComponentInfo
import com.nucu.dynamiclistcompose.data.models.ComponentItemModel
import com.nucu.dynamiclistcompose.data.renders.base.RenderType
import com.nucu.dynamiclistcompose.presentation.components.filters.FiltersModel
import com.javi.render.processor.data.enums.RenderType
import com.nucu.dynamiclistcompose.presentation.components.filters.Filters
import com.nucu.dynamiclistcompose.presentation.ui.components.showCase.rememberShowCaseState
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
Expand All @@ -34,7 +34,7 @@ class FiltersFactoryTest {
ComponentItemModel(
render = RenderType.FILTERS.name,
index = 0,
resource = FiltersModel(
resource = Filters(
items = emptyList()
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import androidx.compose.ui.test.onNodeWithTag
import com.nucu.dynamiclistcompose.MainActivity
import com.nucu.dynamiclistcompose.data.models.ComponentInfo
import com.nucu.dynamiclistcompose.data.models.ComponentItemModel
import com.nucu.dynamiclistcompose.data.renders.base.RenderType
import com.javi.render.processor.data.enums.RenderType
import com.nucu.dynamiclistcompose.presentation.components.message.MessageModel
import com.nucu.dynamiclistcompose.presentation.ui.components.showCase.rememberShowCaseState
import dagger.hilt.android.testing.HiltAndroidRule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import androidx.compose.ui.test.onNodeWithTag
import com.nucu.dynamiclistcompose.MainActivity
import com.nucu.dynamiclistcompose.data.models.ComponentInfo
import com.nucu.dynamiclistcompose.data.models.ComponentItemModel
import com.nucu.dynamiclistcompose.data.renders.base.RenderType
import com.javi.render.processor.data.enums.RenderType
import com.nucu.dynamiclistcompose.presentation.components.text.TextModel
import com.nucu.dynamiclistcompose.presentation.ui.components.showCase.rememberShowCaseState
import dagger.hilt.android.testing.HiltAndroidRule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.nucu.dynamiclistcompose.domain.database
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.nucu.dynamiclistcompose.data.renders.base.RenderType
import com.javi.render.processor.data.enums.RenderType
import com.nucu.dynamiclistcompose.domain.database.skeletons.SkeletonsDao
import com.nucu.dynamiclistcompose.domain.database.skeletons.SkeletonsEntity
import org.junit.After
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.nucu.dynamiclistcompose">
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />

Expand Down
Loading

0 comments on commit 0f087e2

Please sign in to comment.