Skip to content

Commit d906eba

Browse files
authored
update samples, add kmp compose android host app (#84) [skip ci]
* update samples, add kmp compose android host app * spotless and detekt
1 parent 8a188e6 commit d906eba

File tree

19 files changed

+271
-45
lines changed

19 files changed

+271
-45
lines changed

.github/workflows/sample.yml

+6-1
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,9 @@ jobs:
5959
run: chmod +x ./gradlew
6060

6161
- name: Build
62-
run: ./gradlew :sample:standalone-androidApp:assembleDebug :sample:standalone-composeMultiplatform:desktopApp:packageDistributionForCurrentOS --stacktrace
62+
run: |
63+
./gradlew \
64+
:sample:standalone-androidApp:assembleDebug \
65+
:sample:standalone-composeMultiplatform:desktopApp:packageDistributionForCurrentOS \
66+
:sample:standalone-composeMultiplatform:androidApp:assembleDebug \
67+
--stacktrace

.idea/deploymentTargetSelector.xml

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

channel-event-bus/gradle.properties

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
POM_NAME=kotlin-channel-event-bus
1+
POM_NAME=KotlinChannelEventBus
22
POM_ARTIFACT_ID=channel-event-bus
3-
POM_DESCRIPTION=Multi-keys, multi-producers, single-consumer event bus backed by Kotlinx Coroutines Channels
3+
POM_DESCRIPTION=Kotlin Channel EventBus. Multi-keys, multi-producers, single-consumer event bus backed by Kotlinx Coroutines Channels.

gradle/libs.versions.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ jetbrains-compose = "1.6.11"
2828
touchlab-stately = "2.0.7"
2929
napier = "2.7.1"
3030
flowExt = "1.0.0-RC"
31-
koin-core = "3.5.6"
32-
koin-compose = "1.1.5"
31+
koin-core = "4.0.0-RC1"
32+
koin-compose = "4.0.0-RC1"
3333
coil = "2.7.0"
3434
compose-rules-detekt = "0.4.11"
3535

sample/standalone-androidApp/build.gradle.kts

+10-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ android {
3737
}
3838
}
3939

40+
kotlin {
41+
jvmToolchain {
42+
languageVersion = JavaLanguageVersion.of(libs.versions.java.toolchain.get())
43+
vendor = JvmVendorSpec.AZUL
44+
}
45+
}
46+
4047
dependencies {
4148
implementation(project(":channel-event-bus"))
4249

@@ -63,7 +70,9 @@ dependencies {
6370
}
6471

6572
composeCompiler {
66-
enableStrongSkippingMode = true
73+
featureFlags.addAll(
74+
org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag.OptimizeNonSkippingGroups,
75+
)
6776

6877
val composeCompilerDir = layout.buildDirectory.dir("compose_compiler")
6978
if (project.findProperty("composeCompilerReports") == "true") {

sample/standalone-androidApp/src/main/java/com/hoc081098/channeleventbus/sample/android/ui/register/contract.kt

+19-8
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ package com.hoc081098.channeleventbus.sample.android.ui.register
22

33
import androidx.compose.runtime.Immutable
44
import androidx.compose.runtime.Stable
5-
import com.hoc081098.kmp.viewmodel.InternalKmpViewModelApi
65
import com.hoc081098.kmp.viewmodel.safe.NullableSavedStateHandleKey
6+
import com.hoc081098.kmp.viewmodel.safe.serializable
77
import com.hoc081098.kmp.viewmodel.safe.string
8+
import com.hoc081098.kmp.viewmodel.serializable.JvmSerializable
89
import kotlin.LazyThreadSafetyMode.PUBLICATION
910

1011
@Immutable
11-
internal enum class Gender {
12+
internal enum class Gender : JvmSerializable {
1213
MALE,
1314
FEMALE,
1415
}
@@ -51,11 +52,21 @@ internal fun RegisterUiState.Companion.from(
5152
RegisterUiState.Unfilled
5253
}
5354

54-
internal val FirstNameKey by lazy(PUBLICATION) { NullableSavedStateHandleKey.string("first_name", null) }
55-
internal val LastNameKey by lazy(PUBLICATION) { NullableSavedStateHandleKey.string("last_name", null) }
55+
internal val FirstNameKey by lazy(PUBLICATION) {
56+
NullableSavedStateHandleKey.string(
57+
key = "first_name",
58+
defaultValue = null,
59+
)
60+
}
61+
internal val LastNameKey by lazy(PUBLICATION) {
62+
NullableSavedStateHandleKey.string(
63+
key = "last_name",
64+
defaultValue = null,
65+
)
66+
}
5667
internal val GenderKey by lazy(PUBLICATION) {
57-
// TODO: When Serializable is supported, remove the below workaround
58-
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
59-
@OptIn(InternalKmpViewModelApi::class)
60-
NullableSavedStateHandleKey<Gender>("gender", null)
68+
NullableSavedStateHandleKey.serializable<Gender>(
69+
key = "gender",
70+
defaultValue = null,
71+
)
6172
}

sample/standalone-androidApp/src/main/java/com/hoc081098/channeleventbus/sample/android/ui/register/steptwo/RegisterStepTwoScreen.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ fun RegisterStepTwoScreen(
4848
GenderSection(
4949
modifier = Modifier.fillMaxWidth(),
5050
selectedGender = selectedGender,
51-
onGenderChanged = remember { vm::onGenderChanged },
51+
onGenderChange = remember { vm::onGenderChanged },
5252
)
5353

5454
Spacer(modifier = Modifier.weight(1f))
@@ -64,12 +64,12 @@ fun RegisterStepTwoScreen(
6464
@Composable
6565
private fun GenderSection(
6666
selectedGender: Gender?,
67-
onGenderChanged: (Gender) -> Unit,
67+
onGenderChange: (Gender) -> Unit,
6868
modifier: Modifier = Modifier,
6969
) {
7070
Column(modifier = modifier) {
7171
Gender.entries.forEach { item ->
72-
val onClick = { onGenderChanged(item) }
72+
val onClick = { onGenderChange(item) }
7373
val selected = selectedGender == item
7474

7575
Row(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
@Suppress("DSL_SCOPE_VIOLATION")
2+
plugins {
3+
alias(libs.plugins.android.app)
4+
alias(libs.plugins.kotlin.android)
5+
alias(libs.plugins.jetbrains.compose)
6+
alias(libs.plugins.kotlin.compose)
7+
}
8+
9+
android {
10+
namespace = "com.hoc081098.channeleventbus.sample.kmp.compose.android"
11+
compileSdk = libs.versions.sample.android.compile.get().toInt()
12+
defaultConfig {
13+
applicationId = "com.hoc081098.channeleventbus.sample.kmp.compose.android"
14+
minSdk = libs.versions.android.min.get().toInt()
15+
targetSdk = libs.versions.sample.android.target.get().toInt()
16+
versionCode = 1
17+
versionName = "1.0"
18+
}
19+
buildFeatures {
20+
buildConfig = true
21+
}
22+
packaging {
23+
resources {
24+
excludes += "/META-INF/{AL2.0,LGPL2.1}"
25+
}
26+
}
27+
buildTypes {
28+
getByName("release") {
29+
isMinifyEnabled = false
30+
}
31+
}
32+
compileOptions {
33+
sourceCompatibility = JavaVersion.toVersion(libs.versions.java.target.get())
34+
targetCompatibility = JavaVersion.toVersion(libs.versions.java.target.get())
35+
}
36+
kotlinOptions {
37+
jvmTarget = JavaVersion.toVersion(libs.versions.java.target.get()).toString()
38+
}
39+
}
40+
41+
kotlin {
42+
jvmToolchain {
43+
languageVersion = JavaLanguageVersion.of(libs.versions.java.toolchain.get())
44+
vendor = JvmVendorSpec.AZUL
45+
}
46+
}
47+
48+
dependencies {
49+
// Compose app
50+
implementation(projects.sample.standaloneComposeMultiplatform.composeApp)
51+
52+
implementation(libs.androidx.activity.compose)
53+
implementation(libs.koin.androidx.compose)
54+
55+
implementation(libs.flowExt)
56+
57+
implementation(libs.timber)
58+
}
59+
60+
composeCompiler {
61+
featureFlags.addAll(
62+
org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag.OptimizeNonSkippingGroups,
63+
)
64+
65+
val composeCompilerDir = layout.buildDirectory.dir("compose_compiler")
66+
if (project.findProperty("composeCompilerReports") == "true") {
67+
reportsDestination = composeCompilerDir
68+
}
69+
if (project.findProperty("composeCompilerMetrics") == "true") {
70+
metricsDestination = composeCompilerDir
71+
}
72+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<uses-permission android:name="android.permission.INTERNET" />
5+
6+
<application
7+
android:name=".MyApp"
8+
android:allowBackup="false"
9+
android:supportsRtl="true"
10+
android:theme="@style/AppTheme">
11+
<activity
12+
android:name=".MainActivity"
13+
android:exported="true">
14+
<intent-filter>
15+
<action android:name="android.intent.action.MAIN" />
16+
<category android:name="android.intent.category.LAUNCHER" />
17+
</intent-filter>
18+
</activity>
19+
</application>
20+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.hoc081098.channeleventbus.sample.kmp.compose.android
2+
3+
import android.os.Bundle
4+
import androidx.activity.ComponentActivity
5+
import androidx.activity.compose.setContent
6+
import com.hoc081098.channeleventbus.sample.kmp.compose.ChannelEventBusSampleApp
7+
import org.koin.androidx.compose.KoinAndroidContext
8+
9+
class MainActivity : ComponentActivity() {
10+
override fun onCreate(savedInstanceState: Bundle?) {
11+
super.onCreate(savedInstanceState)
12+
13+
setContent {
14+
KoinAndroidContext {
15+
ChannelEventBusSampleApp()
16+
}
17+
}
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.hoc081098.channeleventbus.sample.kmp.compose.android
2+
3+
import android.app.Application
4+
import com.hoc081098.channeleventbus.sample.kmp.compose.setupNapier
5+
import com.hoc081098.channeleventbus.sample.kmp.compose.startKoinCommon
6+
import org.koin.android.ext.koin.androidContext
7+
import org.koin.android.ext.koin.androidLogger
8+
import org.koin.core.logger.Level
9+
10+
class MyApp : Application() {
11+
override fun onCreate() {
12+
super.onCreate()
13+
14+
setupNapier()
15+
startKoinCommon {
16+
androidContext(this@MyApp)
17+
androidLogger(
18+
if (BuildConfig.DEBUG) {
19+
Level.DEBUG
20+
} else {
21+
Level.ERROR
22+
},
23+
)
24+
}
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<resources>
2+
<style name="AppTheme" parent="android:Theme.Material.NoActionBar"/>
3+
</resources>

sample/standalone-composeMultiplatform/composeApp/build.gradle.kts

+25-9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2+
13
plugins {
24
alias(libs.plugins.kotlin.multiplatform)
35
alias(libs.plugins.jetbrains.compose)
@@ -8,22 +10,26 @@ plugins {
810

911
kotlin {
1012
jvmToolchain {
11-
languageVersion = JavaLanguageVersion.of(21)
13+
languageVersion = JavaLanguageVersion.of(libs.versions.java.toolchain.get())
1214
vendor = JvmVendorSpec.AZUL
1315
}
1416

1517
androidTarget {
16-
compilations.all {
17-
kotlinOptions {
18-
jvmTarget = "11"
18+
compilations.configureEach {
19+
compileTaskProvider.configure {
20+
compilerOptions {
21+
jvmTarget = JvmTarget.fromTarget(libs.versions.java.target.get())
22+
}
1923
}
2024
}
2125
}
2226

2327
jvm("desktop") {
24-
compilations.all {
25-
kotlinOptions {
26-
jvmTarget = "11"
28+
compilations.configureEach {
29+
compileTaskProvider.configure {
30+
compilerOptions {
31+
jvmTarget = JvmTarget.fromTarget(libs.versions.java.target.get())
32+
}
2733
}
2834
}
2935
}
@@ -41,7 +47,7 @@ kotlin {
4147
}
4248
commonMain.dependencies {
4349
// Channel event bus
44-
implementation(project(":channel-event-bus"))
50+
implementation(projects.channelEventBus)
4551

4652
implementation(compose.runtime)
4753
implementation(compose.foundation)
@@ -110,5 +116,15 @@ android {
110116
}
111117

112118
composeCompiler {
113-
enableStrongSkippingMode = true
119+
featureFlags.addAll(
120+
org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag.OptimizeNonSkippingGroups,
121+
)
122+
123+
val composeCompilerDir = layout.buildDirectory.dir("compose_compiler")
124+
if (project.findProperty("composeCompilerReports") == "true") {
125+
reportsDestination = composeCompilerDir
126+
}
127+
if (project.findProperty("composeCompilerMetrics") == "true") {
128+
metricsDestination = composeCompilerDir
129+
}
114130
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.hoc081098.channeleventbus.sample.kmp.compose.common
2+
3+
import com.hoc081098.channeleventbus.sample.kmp.compose.BuildConfig
4+
5+
actual fun isBuildDebug(): Boolean = BuildConfig.DEBUG
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.hoc081098.channeleventbus.sample.kmp.compose.common
2+
3+
internal actual fun Any?.identityHashCode(): Int = System.identityHashCode(this)

sample/standalone-composeMultiplatform/composeApp/src/commonMain/kotlin/com/hoc081098/channeleventbus/sample/kmp/compose/ui/register/contract.kt

+19-8
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ package com.hoc081098.channeleventbus.sample.kmp.compose.ui.register
22

33
import androidx.compose.runtime.Immutable
44
import androidx.compose.runtime.Stable
5-
import com.hoc081098.kmp.viewmodel.InternalKmpViewModelApi
65
import com.hoc081098.kmp.viewmodel.safe.NullableSavedStateHandleKey
6+
import com.hoc081098.kmp.viewmodel.safe.serializable
77
import com.hoc081098.kmp.viewmodel.safe.string
8+
import com.hoc081098.kmp.viewmodel.serializable.JvmSerializable
89
import kotlin.LazyThreadSafetyMode.PUBLICATION
910

1011
@Immutable
11-
internal enum class Gender {
12+
internal enum class Gender : JvmSerializable {
1213
MALE,
1314
FEMALE,
1415
}
@@ -51,11 +52,21 @@ internal fun RegisterUiState.Companion.from(
5152
RegisterUiState.Unfilled
5253
}
5354

54-
internal val FirstNameKey by lazy(PUBLICATION) { NullableSavedStateHandleKey.string("first_name", null) }
55-
internal val LastNameKey by lazy(PUBLICATION) { NullableSavedStateHandleKey.string("last_name", null) }
55+
internal val FirstNameKey by lazy(PUBLICATION) {
56+
NullableSavedStateHandleKey.string(
57+
key = "first_name",
58+
defaultValue = null,
59+
)
60+
}
61+
internal val LastNameKey by lazy(PUBLICATION) {
62+
NullableSavedStateHandleKey.string(
63+
key = "last_name",
64+
defaultValue = null,
65+
)
66+
}
5667
internal val GenderKey by lazy(PUBLICATION) {
57-
// TODO: When Serializable is supported, remove the below workaround
58-
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
59-
@OptIn(InternalKmpViewModelApi::class)
60-
NullableSavedStateHandleKey<Gender>("gender", null)
68+
NullableSavedStateHandleKey.serializable<Gender>(
69+
key = "gender",
70+
defaultValue = null,
71+
)
6172
}

0 commit comments

Comments
 (0)