From 68817bfd768927d26852bf8ba1d35fea43da71ea Mon Sep 17 00:00:00 2001 From: skydoves Date: Tue, 16 Aug 2022 14:57:26 +0900 Subject: [PATCH 1/4] Add compose compiler matrix analyser --- build.gradle.kts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 5b2e25a..fee5eda 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,6 +25,16 @@ subprojects { "-Xopt-in=androidx.compose.material3.ExperimentalMaterial3Api", "-Xopt-in=androidx.lifecycle.compose.ExperimentalLifecycleComposeApi" ) + kotlinOptions.freeCompilerArgs += listOf( + "-P", + "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + + project.buildDir.absolutePath + "/compose_metrics" + ) + kotlinOptions.freeCompilerArgs += listOf( + "-P", + "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + + project.buildDir.absolutePath + "/compose_metrics" + ) kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString() } } From 4d36530bd3a0ae2f7fc21a5eb6aa889c800fec89 Mon Sep 17 00:00:00 2001 From: skydoves Date: Tue, 16 Aug 2022 14:58:01 +0900 Subject: [PATCH 2/4] Implement core-uistate module and generates restartable and skippable UI states --- core-data/build.gradle.kts | 12 ------ core-designsystem/build.gradle.kts | 7 ---- core-model/build.gradle.kts | 1 + core-uistate/.gitignore | 1 + core-uistate/build.gradle.kts | 42 +++++++++++++++++++ core-uistate/src/main/AndroidManifest.xml | 2 + .../whatsappclone/uistate}/UiState.kt | 9 +++- .../uistate}/WhatsAppUserExtensive.kt | 6 ++- feature-calls/build.gradle.kts | 8 +--- .../whatsappclone/calls/WhatsAppCalls.kt | 2 +- .../calls/WhatsAppCallsViewModel.kt | 5 +-- feature-camera/build.gradle.kts | 7 ---- feature-chats/build.gradle.kts | 8 +--- .../chats/messages/WhatsAppMessageTopBar.kt | 2 +- .../messages/WhatsAppMessagesViewModel.kt | 2 +- feature-status/build.gradle.kts | 7 ---- settings.gradle.kts | 1 + 17 files changed, 66 insertions(+), 56 deletions(-) create mode 100644 core-uistate/.gitignore create mode 100644 core-uistate/build.gradle.kts create mode 100644 core-uistate/src/main/AndroidManifest.xml rename {core-data/src/main/kotlin/io/getstream/whatsappclone/data/model => core-uistate/src/main/kotlin/io/getstream/whatsappclone/uistate}/UiState.kt (82%) rename {core-model/src/main/kotlin/io/getstream/whatsappclone/model => core-uistate/src/main/kotlin/io/getstream/whatsappclone/uistate}/WhatsAppUserExtensive.kt (82%) diff --git a/core-data/build.gradle.kts b/core-data/build.gradle.kts index bdf72a5..d1cdf5b 100644 --- a/core-data/build.gradle.kts +++ b/core-data/build.gradle.kts @@ -3,7 +3,6 @@ plugins { id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.plugin.serialization") id("kotlin-kapt") - id("com.google.devtools.ksp") id("dagger.hilt.android.plugin") } @@ -21,24 +20,13 @@ android { } } -kotlin { - sourceSets.configureEach { - kotlin.srcDir("$buildDir/generated/ksp/$name/kotlin/") - } -} - dependencies { api(project(":core-model")) api(project(":core-network")) api(project(":core-database")) - api(Dependencies.streamClient) - api(Dependencies.coroutines) api(Dependencies.hiltAndroid) kapt(Dependencies.hiltCompiler) - - implementation(Dependencies.sealedXCore) - ksp(Dependencies.sealedXProcessor) } diff --git a/core-designsystem/build.gradle.kts b/core-designsystem/build.gradle.kts index b9176b3..e4f2a94 100644 --- a/core-designsystem/build.gradle.kts +++ b/core-designsystem/build.gradle.kts @@ -24,13 +24,6 @@ android { composeOptions { kotlinCompilerExtensionVersion = Versions.COMPOSE_COMPILER } - - packagingOptions { - resources.excludes.add("META-INF/LICENSE.txt") - resources.excludes.add("META-INF/NOTICE.txt") - resources.excludes.add("LICENSE.txt") - resources.excludes.add("/META-INF/{AL2.0,LGPL2.1}") - } } dependencies { diff --git a/core-model/build.gradle.kts b/core-model/build.gradle.kts index 7531077..b13bac3 100644 --- a/core-model/build.gradle.kts +++ b/core-model/build.gradle.kts @@ -20,5 +20,6 @@ android { } dependencies { + api(Dependencies.streamClient) api(Dependencies.kotlinSerializationJson) } diff --git a/core-uistate/.gitignore b/core-uistate/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/core-uistate/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/core-uistate/build.gradle.kts b/core-uistate/build.gradle.kts new file mode 100644 index 0000000..4fba40d --- /dev/null +++ b/core-uistate/build.gradle.kts @@ -0,0 +1,42 @@ +plugins { + id("com.android.library") + id("org.jetbrains.kotlin.android") + id("com.google.devtools.ksp") +} + +android { + compileSdk = Configurations.compileSdk + + defaultConfig { + minSdk = Configurations.minSdk + targetSdk = Configurations.targetSdk + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + buildFeatures { + compose = true + } + + composeOptions { + kotlinCompilerExtensionVersion = Versions.COMPOSE_COMPILER + } +} + +kotlin { + sourceSets.configureEach { + kotlin.srcDir("$buildDir/generated/ksp/$name/kotlin/") + } +} + +dependencies { + implementation(project(":core-model")) + + implementation(Dependencies.composeRuntime) + + implementation(Dependencies.sealedXCore) + ksp(Dependencies.sealedXProcessor) +} diff --git a/core-uistate/src/main/AndroidManifest.xml b/core-uistate/src/main/AndroidManifest.xml new file mode 100644 index 0000000..6ec53da --- /dev/null +++ b/core-uistate/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/core-data/src/main/kotlin/io/getstream/whatsappclone/data/model/UiState.kt b/core-uistate/src/main/kotlin/io/getstream/whatsappclone/uistate/UiState.kt similarity index 82% rename from core-data/src/main/kotlin/io/getstream/whatsappclone/data/model/UiState.kt rename to core-uistate/src/main/kotlin/io/getstream/whatsappclone/uistate/UiState.kt index 65d6d94..088dac7 100644 --- a/core-data/src/main/kotlin/io/getstream/whatsappclone/data/model/UiState.kt +++ b/core-uistate/src/main/kotlin/io/getstream/whatsappclone/uistate/UiState.kt @@ -14,20 +14,25 @@ * limitations under the License. */ -package io.getstream.whatsappclone.data.model +package io.getstream.whatsappclone.uistate +import androidx.compose.runtime.Immutable import com.skydoves.sealedx.core.Extensive import com.skydoves.sealedx.core.annotations.ExtensiveModel import com.skydoves.sealedx.core.annotations.ExtensiveSealed import io.getstream.chat.android.client.models.Channel -import io.getstream.whatsappclone.model.WhatsAppUserExtensive +/** + * Generates restartable and skippable UI states based on KSP and extensive models. + * @see (SealedX)[https://github.com/skydoves/sealedx] + */ @ExtensiveSealed( models = [ ExtensiveModel(type = Channel::class, name = "WhatsAppMessage"), ExtensiveModel(type = WhatsAppUserExtensive::class, name = "WhatsAppUser") ] ) +@Immutable sealed interface UiState { data class Success(val data: Extensive) : UiState object Loading : UiState diff --git a/core-model/src/main/kotlin/io/getstream/whatsappclone/model/WhatsAppUserExtensive.kt b/core-uistate/src/main/kotlin/io/getstream/whatsappclone/uistate/WhatsAppUserExtensive.kt similarity index 82% rename from core-model/src/main/kotlin/io/getstream/whatsappclone/model/WhatsAppUserExtensive.kt rename to core-uistate/src/main/kotlin/io/getstream/whatsappclone/uistate/WhatsAppUserExtensive.kt index 24cc119..442d9b8 100644 --- a/core-model/src/main/kotlin/io/getstream/whatsappclone/model/WhatsAppUserExtensive.kt +++ b/core-uistate/src/main/kotlin/io/getstream/whatsappclone/uistate/WhatsAppUserExtensive.kt @@ -14,8 +14,12 @@ * limitations under the License. */ -package io.getstream.whatsappclone.model +package io.getstream.whatsappclone.uistate +import androidx.compose.runtime.Immutable +import io.getstream.whatsappclone.model.WhatsAppUser + +@Immutable data class WhatsAppUserExtensive( val whatsappUserList: List ) diff --git a/feature-calls/build.gradle.kts b/feature-calls/build.gradle.kts index bf701ff..071d75a 100644 --- a/feature-calls/build.gradle.kts +++ b/feature-calls/build.gradle.kts @@ -30,19 +30,13 @@ android { lint { abortOnError = false } - - packagingOptions { - resources.excludes.add("META-INF/LICENSE.txt") - resources.excludes.add("META-INF/NOTICE.txt") - resources.excludes.add("LICENSE.txt") - resources.excludes.add("/META-INF/{AL2.0,LGPL2.1}") - } } dependencies { // core modules implementation(project(":core-designsystem")) implementation(project(":core-navigation")) + implementation(project(":core-uistate")) implementation(project(":core-data")) implementation(Dependencies.composeLifecycle) diff --git a/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCalls.kt b/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCalls.kt index cc21da0..3688539 100644 --- a/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCalls.kt +++ b/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCalls.kt @@ -21,11 +21,11 @@ import androidx.compose.foundation.lazy.items import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.lifecycle.compose.collectAsStateWithLifecycle -import io.getstream.whatsappclone.data.model.WhatsAppUserUiState import io.getstream.whatsappclone.designsystem.component.WhatsAppError import io.getstream.whatsappclone.designsystem.component.WhatsAppLoadingColumn import io.getstream.whatsappclone.navigation.AppComposeNavigator import io.getstream.whatsappclone.navigation.WhatsAppScreens +import io.getstream.whatsappclone.uistate.WhatsAppUserUiState @Composable fun WhatsAppCalls( diff --git a/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt b/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt index b8e6315..a84b881 100644 --- a/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt +++ b/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt @@ -19,9 +19,8 @@ package io.getstream.whatsappclone.calls import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import io.getstream.whatsappclone.data.model.WhatsAppUserUiState import io.getstream.whatsappclone.data.repository.CallHistoryRepository -import io.getstream.whatsappclone.model.WhatsAppUserExtensive +import io.getstream.whatsappclone.uistate.WhatsAppUserUiState import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.flatMapLatest @@ -40,7 +39,7 @@ class WhatsAppCallsViewModel @Inject constructor( if (it.isSuccess) { flowOf( WhatsAppUserUiState.Success( - WhatsAppUserExtensive(it.getOrThrow()) + io.getstream.whatsappclone.uistate.WhatsAppUserExtensive(it.getOrThrow()) ) ) } else { diff --git a/feature-camera/build.gradle.kts b/feature-camera/build.gradle.kts index 005be40..31f4654 100644 --- a/feature-camera/build.gradle.kts +++ b/feature-camera/build.gradle.kts @@ -27,13 +27,6 @@ android { lint { abortOnError = false } - - packagingOptions { - resources.excludes.add("META-INF/LICENSE.txt") - resources.excludes.add("META-INF/NOTICE.txt") - resources.excludes.add("LICENSE.txt") - resources.excludes.add("/META-INF/{AL2.0,LGPL2.1}") - } } dependencies { diff --git a/feature-chats/build.gradle.kts b/feature-chats/build.gradle.kts index c9aec48..fc6acb3 100644 --- a/feature-chats/build.gradle.kts +++ b/feature-chats/build.gradle.kts @@ -29,13 +29,6 @@ android { lint { abortOnError = false } - - packagingOptions { - resources.excludes.add("META-INF/LICENSE.txt") - resources.excludes.add("META-INF/NOTICE.txt") - resources.excludes.add("LICENSE.txt") - resources.excludes.add("/META-INF/{AL2.0,LGPL2.1}") - } } dependencies { @@ -43,6 +36,7 @@ dependencies { implementation(project(":core-designsystem")) implementation(project(":core-navigation")) implementation(project(":core-network")) + implementation(project(":core-uistate")) implementation(project(":core-data")) // Stream chat Compose diff --git a/feature-chats/src/main/kotlin/io/getstream/whatsappclone/chats/messages/WhatsAppMessageTopBar.kt b/feature-chats/src/main/kotlin/io/getstream/whatsappclone/chats/messages/WhatsAppMessageTopBar.kt index d681a0b..416837d 100644 --- a/feature-chats/src/main/kotlin/io/getstream/whatsappclone/chats/messages/WhatsAppMessageTopBar.kt +++ b/feature-chats/src/main/kotlin/io/getstream/whatsappclone/chats/messages/WhatsAppMessageTopBar.kt @@ -39,12 +39,12 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.skydoves.landscapist.glide.GlideImage import io.getstream.chat.android.client.ChatClient -import io.getstream.whatsappclone.data.model.WhatsAppMessageUiState import io.getstream.whatsappclone.designsystem.component.WhatsAppLoadingIndicator import io.getstream.whatsappclone.designsystem.icon.WhatsAppIcons import io.getstream.whatsappclone.designsystem.theme.WhatsAppCloneComposeTheme import io.getstream.whatsappclone.navigation.AppComposeNavigator import io.getstream.whatsappclone.navigation.WhatsAppCloneComposeNavigator +import io.getstream.whatsappclone.uistate.WhatsAppMessageUiState import kotlinx.coroutines.Dispatchers @Composable diff --git a/feature-chats/src/main/kotlin/io/getstream/whatsappclone/chats/messages/WhatsAppMessagesViewModel.kt b/feature-chats/src/main/kotlin/io/getstream/whatsappclone/chats/messages/WhatsAppMessagesViewModel.kt index 44abc02..725daa9 100644 --- a/feature-chats/src/main/kotlin/io/getstream/whatsappclone/chats/messages/WhatsAppMessagesViewModel.kt +++ b/feature-chats/src/main/kotlin/io/getstream/whatsappclone/chats/messages/WhatsAppMessagesViewModel.kt @@ -22,9 +22,9 @@ import dagger.hilt.android.lifecycle.HiltViewModel import io.getstream.chat.android.client.ChatClient import io.getstream.chat.android.client.utils.onError import io.getstream.chat.android.client.utils.onSuccess -import io.getstream.whatsappclone.data.model.WhatsAppMessageUiState import io.getstream.whatsappclone.network.Dispatcher import io.getstream.whatsappclone.network.WhatsAppDispatchers +import io.getstream.whatsappclone.uistate.WhatsAppMessageUiState import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow diff --git a/feature-status/build.gradle.kts b/feature-status/build.gradle.kts index e0bbf73..90b56ae 100644 --- a/feature-status/build.gradle.kts +++ b/feature-status/build.gradle.kts @@ -27,13 +27,6 @@ android { lint { abortOnError = false } - - packagingOptions { - resources.excludes.add("META-INF/LICENSE.txt") - resources.excludes.add("META-INF/NOTICE.txt") - resources.excludes.add("LICENSE.txt") - resources.excludes.add("/META-INF/{AL2.0,LGPL2.1}") - } } dependencies { diff --git a/settings.gradle.kts b/settings.gradle.kts index a772e59..bffbbb5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,6 +24,7 @@ include(":core-model") include(":core-network") include(":core-database") include(":core-data") +include(":core-uistate") include(":feature-camera") include(":feature-chats") include(":feature-status") From 9a1772f95001b8203d7444b5703e162c92d1b6c5 Mon Sep 17 00:00:00 2001 From: skydoves Date: Tue, 16 Aug 2022 14:59:52 +0900 Subject: [PATCH 3/4] Rename with simple name --- .../getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt b/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt index a84b881..9fe984b 100644 --- a/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt +++ b/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt @@ -20,13 +20,14 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import io.getstream.whatsappclone.data.repository.CallHistoryRepository +import io.getstream.whatsappclone.uistate.WhatsAppUserExtensive import io.getstream.whatsappclone.uistate.WhatsAppUserUiState +import javax.inject.Inject import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.stateIn -import javax.inject.Inject @HiltViewModel class WhatsAppCallsViewModel @Inject constructor( @@ -39,7 +40,7 @@ class WhatsAppCallsViewModel @Inject constructor( if (it.isSuccess) { flowOf( WhatsAppUserUiState.Success( - io.getstream.whatsappclone.uistate.WhatsAppUserExtensive(it.getOrThrow()) + WhatsAppUserExtensive(it.getOrThrow()) ) ) } else { From 4f47ac16e33af86ff6e32057532e4136bebb6504 Mon Sep 17 00:00:00 2001 From: skydoves Date: Tue, 16 Aug 2022 15:07:44 +0900 Subject: [PATCH 4/4] Apply spotless --- .../io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt b/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt index 9fe984b..8f04482 100644 --- a/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt +++ b/feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt @@ -22,12 +22,12 @@ import dagger.hilt.android.lifecycle.HiltViewModel import io.getstream.whatsappclone.data.repository.CallHistoryRepository import io.getstream.whatsappclone.uistate.WhatsAppUserExtensive import io.getstream.whatsappclone.uistate.WhatsAppUserUiState -import javax.inject.Inject import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.stateIn +import javax.inject.Inject @HiltViewModel class WhatsAppCallsViewModel @Inject constructor(