diff --git a/build.gradle.kts b/build.gradle.kts
index fef4f83..c7d87c7 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,6 +1,7 @@
plugins {
alias(libs.plugins.kotlin.multiplatform) apply false
alias(libs.plugins.kotlin.compose) apply false
+ alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.android.application) apply false
alias(libs.plugins.compose) apply false
}
\ No newline at end of file
diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts
index d092629..c2a6a75 100644
--- a/composeApp/build.gradle.kts
+++ b/composeApp/build.gradle.kts
@@ -25,6 +25,12 @@ private val gitCommitsCount: Int by lazy {
}
kotlin {
+ androidTarget {
+ @OptIn(ExperimentalKotlinGradlePluginApi::class)
+ compilerOptions {
+ jvmTarget.set(JvmTarget.JVM_11)
+ }
+ }
js {
moduleName = "composeApp"
browser {
@@ -51,12 +57,6 @@ kotlin {
}
binaries.executable()
}
- androidTarget {
- @OptIn(ExperimentalKotlinGradlePluginApi::class)
- compilerOptions {
- jvmTarget.set(JvmTarget.JVM_11)
- }
- }
jvm()
listOf(
iosX64(),
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 388a8ac..2de863c 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -3,11 +3,15 @@ min-sdk = "31"
compile-sdk = "35"
target-sdk = "35"
agp = "8.7.2"
+
androidx-activity = "1.9.3"
androidx-core-splashscreen = "1.0.1"
androidx-lifecycle = "2.8.4"
+wearCompose = "1.4.0"
+composeUiTooling = "1.4.0"
google-material = "1.12.0"
+google-horologist = "0.6.20"
jetbrains-compose = "1.7.1"
jetbrains-androidx-navigation-compose = "2.8.0-alpha10"
@@ -36,6 +40,7 @@ kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
google-material = { module = "com.google.android.material:material", version.ref = "google-material" }
+google-horologist-compose-layout = { module = "com.google.android.horologist:horologist-compose-layout", version.ref = "google-horologist" }
jetbrains-androidx-navigation-compose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "jetbrains-androidx-navigation-compose" }
jetbrains-androidx-lifecycle-viewmodel-compose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "jetbrains-androidx-lifecycle-viewmodel-compose" }
@@ -45,6 +50,10 @@ androidx-activity-compose = { module = "androidx.activity:activity-compose", ver
androidx-core-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "androidx-core-splashscreen" }
androidx-lifecycle-viewmodel = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel", version.ref = "androidx-lifecycle" }
androidx-lifecycle-runtime-compose = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
+androidx-wear-compose-foundation = { module = "androidx.wear.compose:compose-foundation", version.ref = "wearCompose" }
+androidx-wear-compose-material = { module = "androidx.wear.compose:compose-material", version.ref = "wearCompose" }
+androidx-wear-compose-navigation = { module = "androidx.wear.compose:compose-navigation", version.ref = "wearCompose" }
+androidx-wear-ui-tooling = { module = "androidx.wear.compose:compose-ui-tooling", version.ref = "composeUiTooling" }
coil3-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil3" }
coil3-network-ktor = { module = "io.coil-kt.coil3:coil-network-ktor", version.ref = "coil3" }
@@ -67,6 +76,7 @@ napier = { module = "io.github.aakira:napier", version.ref = "napier" }
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
android-application = { id = "com.android.application", version.ref = "agp" }
compose = { id = "org.jetbrains.compose", version.ref = "jetbrains-compose" }
buildkonfig = { id = "com.codingfeline.buildkonfig", version.ref = "buildkonfig" }
\ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 7ce3f42..571588a 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -30,4 +30,5 @@ dependencyResolutionManagement {
}
}
-include(":composeApp")
\ No newline at end of file
+include(":composeApp")
+include(":wearApp")
\ No newline at end of file
diff --git a/wearApp/build.gradle.kts b/wearApp/build.gradle.kts
new file mode 100644
index 0000000..2b8e3ce
--- /dev/null
+++ b/wearApp/build.gradle.kts
@@ -0,0 +1,67 @@
+@file:OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class)
+
+import org.apache.commons.io.output.ByteArrayOutputStream
+import java.nio.charset.Charset
+
+plugins {
+ alias(libs.plugins.kotlin.serialization)
+ alias(libs.plugins.kotlin.compose)
+ alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.compose)
+}
+
+private val gitCommitsCount: Int by lazy {
+ val stdout = ByteArrayOutputStream()
+ rootProject.exec {
+ commandLine("git", "rev-list", "--count", "HEAD")
+ standardOutput = stdout
+ }
+ stdout.toString(Charset.defaultCharset()).trim().toInt()
+}
+
+kotlin {
+ jvmToolchain(21)
+}
+
+android {
+ namespace = "org.michaelbel.template"
+ compileSdk = libs.versions.compile.sdk.get().toInt()
+
+ defaultConfig {
+ applicationId = "org.michaelbel.template"
+ minSdk = libs.versions.min.sdk.get().toInt()
+ targetSdk = libs.versions.target.sdk.get().toInt()
+ versionName = "1.0.0"
+ versionCode = gitCommitsCount
+ }
+ buildFeatures {
+ compose = true
+ }
+}
+
+base {
+ archivesName.set("KmpTemplate-v${android.defaultConfig.versionName}(${android.defaultConfig.versionCode})")
+}
+
+dependencies {
+ implementation(libs.androidx.core.splashscreen)
+ implementation(libs.google.material)
+ implementation(libs.google.horologist.compose.layout)
+ implementation(libs.androidx.activity.compose)
+ implementation(libs.androidx.wear.compose.foundation)
+ implementation(libs.androidx.wear.compose.material)
+ implementation(libs.androidx.wear.compose.navigation)
+}
+
+tasks.register("printVersionName") {
+ doLast {
+ println(android.defaultConfig.versionName)
+ }
+}
+
+tasks.register("printVersionCode") {
+ doLast {
+ println(android.defaultConfig.versionCode.toString())
+ }
+}
\ No newline at end of file
diff --git a/wearApp/src/main/AndroidManifest.xml b/wearApp/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..c23ae4a
--- /dev/null
+++ b/wearApp/src/main/AndroidManifest.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wearApp/src/main/java/org/michaelbel/template/Template.wearos.kt b/wearApp/src/main/java/org/michaelbel/template/Template.wearos.kt
new file mode 100644
index 0000000..1367dbe
--- /dev/null
+++ b/wearApp/src/main/java/org/michaelbel/template/Template.wearos.kt
@@ -0,0 +1,4 @@
+package org.michaelbel.template
+
+val TemplateName: String
+ get() = "WearOS Template"
\ No newline at end of file
diff --git a/wearApp/src/main/java/org/michaelbel/template/WearApplication.kt b/wearApp/src/main/java/org/michaelbel/template/WearApplication.kt
new file mode 100644
index 0000000..ec22290
--- /dev/null
+++ b/wearApp/src/main/java/org/michaelbel/template/WearApplication.kt
@@ -0,0 +1,10 @@
+package org.michaelbel.template
+
+import android.app.Application
+
+class WearApplication: Application() {
+
+ override fun onCreate() {
+ super.onCreate()
+ }
+}
\ No newline at end of file
diff --git a/wearApp/src/main/java/org/michaelbel/template/WearMainActivity.kt b/wearApp/src/main/java/org/michaelbel/template/WearMainActivity.kt
new file mode 100644
index 0000000..2ca5a1e
--- /dev/null
+++ b/wearApp/src/main/java/org/michaelbel/template/WearMainActivity.kt
@@ -0,0 +1,105 @@
+@file:OptIn(ExperimentalHorologistApi::class)
+
+package org.michaelbel.template
+
+import android.os.Bundle
+import androidx.activity.compose.setContent
+import androidx.compose.runtime.Composable
+import androidx.activity.ComponentActivity
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.style.TextAlign
+import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
+import androidx.navigation.NavHostController
+import androidx.wear.compose.material.MaterialTheme
+import androidx.wear.compose.material.Text
+import androidx.wear.compose.navigation.SwipeDismissableNavHost
+import androidx.wear.compose.navigation.composable
+import androidx.wear.compose.navigation.rememberSwipeDismissableNavController
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+import com.google.android.horologist.compose.layout.AppScaffold
+import com.google.android.horologist.compose.layout.ScreenScaffold
+import com.google.android.horologist.compose.layout.rememberColumnState
+
+class WearMainActivity: ComponentActivity() {
+
+ private lateinit var navController: NavHostController
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ installSplashScreen()
+ super.onCreate(savedInstanceState)
+ setContent {
+ navController = rememberSwipeDismissableNavController()
+ WearApp(
+ navController = navController
+ )
+ }
+ }
+}
+
+@Composable
+fun WearApp(
+ navController: NavHostController
+) {
+ AppScaffold {
+ SwipeDismissableNavHost(
+ navController = navController,
+ startDestination = Screen.Home.route
+ ) {
+ composable(
+ route = Screen.Home.route
+ ) {
+ val scrollState = rememberColumnState()
+ ScreenScaffold(
+ modifier = Modifier.fillMaxSize(),
+ scrollState = scrollState
+ ) {
+
+ Text(
+ text = "Home",
+ modifier = Modifier.fillMaxSize().align(Alignment.Center),
+ style = MaterialTheme.typography.title1,
+ textAlign = TextAlign.Center
+ )
+ }
+ }
+ composable(
+ route = Screen.Chat.route
+ ) {
+ val scrollState = rememberColumnState()
+ ScreenScaffold(
+ scrollState = scrollState
+ ) {
+ Text(
+ text = "Chat",
+ style = MaterialTheme.typography.title1,
+ textAlign = TextAlign.Center
+ )
+ }
+ }
+ composable(
+ route = Screen.Settings.route
+ ) {
+ val scrollState = rememberColumnState()
+ ScreenScaffold(
+ scrollState = scrollState
+ ) {
+ Text(
+ text = "Settings",
+ style = MaterialTheme.typography.title1,
+ textAlign = TextAlign.Center
+ )
+ }
+ }
+ }
+ }
+}
+
+sealed class Screen(
+ val route: String
+) {
+ data object Home: Screen("home")
+ data object Chat: Screen("chat")
+ data object Settings: Screen("settings")
+}
\ No newline at end of file
diff --git a/wearApp/src/main/res/drawable-v24/ic_launcher_foreground.xml b/wearApp/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/wearApp/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wearApp/src/main/res/drawable/branding_image.xml b/wearApp/src/main/res/drawable/branding_image.xml
new file mode 100644
index 0000000..61f7b1f
--- /dev/null
+++ b/wearApp/src/main/res/drawable/branding_image.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/wearApp/src/main/res/drawable/ic_launcher_background.xml b/wearApp/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..e93e11a
--- /dev/null
+++ b/wearApp/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wearApp/src/main/res/drawable/ic_splashscreen.xml b/wearApp/src/main/res/drawable/ic_splashscreen.xml
new file mode 100644
index 0000000..9ebcc22
--- /dev/null
+++ b/wearApp/src/main/res/drawable/ic_splashscreen.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wearApp/src/main/res/drawable/ic_splashscreen_branding.xml b/wearApp/src/main/res/drawable/ic_splashscreen_branding.xml
new file mode 100644
index 0000000..6cd5122
--- /dev/null
+++ b/wearApp/src/main/res/drawable/ic_splashscreen_branding.xml
@@ -0,0 +1,11 @@
+
+
+
+
\ No newline at end of file
diff --git a/wearApp/src/main/res/drawable/ic_splashscreen_branding_layer_list.xml b/wearApp/src/main/res/drawable/ic_splashscreen_branding_layer_list.xml
new file mode 100644
index 0000000..32864d0
--- /dev/null
+++ b/wearApp/src/main/res/drawable/ic_splashscreen_branding_layer_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wearApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/wearApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/wearApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/wearApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/wearApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/wearApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/wearApp/src/main/res/mipmap-hdpi/ic_launcher.png b/wearApp/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a571e60
Binary files /dev/null and b/wearApp/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/wearApp/src/main/res/mipmap-hdpi/ic_launcher_round.png b/wearApp/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..61da551
Binary files /dev/null and b/wearApp/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/wearApp/src/main/res/mipmap-mdpi/ic_launcher.png b/wearApp/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c41dd28
Binary files /dev/null and b/wearApp/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/wearApp/src/main/res/mipmap-mdpi/ic_launcher_round.png b/wearApp/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..db5080a
Binary files /dev/null and b/wearApp/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/wearApp/src/main/res/mipmap-xhdpi/ic_launcher.png b/wearApp/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..6dba46d
Binary files /dev/null and b/wearApp/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/wearApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/wearApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..da31a87
Binary files /dev/null and b/wearApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/wearApp/src/main/res/mipmap-xxhdpi/ic_launcher.png b/wearApp/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..15ac681
Binary files /dev/null and b/wearApp/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/wearApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/wearApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..b216f2d
Binary files /dev/null and b/wearApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/wearApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/wearApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..f25a419
Binary files /dev/null and b/wearApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/wearApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/wearApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..e96783c
Binary files /dev/null and b/wearApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/wearApp/src/main/res/values-night/colors.xml b/wearApp/src/main/res/values-night/colors.xml
new file mode 100644
index 0000000..908cbfb
--- /dev/null
+++ b/wearApp/src/main/res/values-night/colors.xml
@@ -0,0 +1,32 @@
+
+
+ #1C1B1F
+ #CCC2DC
+
+ #1C1B1F
+ #F2B8B5
+ #8C1D18
+ #313033
+ #6750A4
+ #E6E1E5
+ #E6E1E5
+ #601410
+ #F2B8B5
+ #381E72
+ #EADDFF
+ #332D41
+ #E8DEF8
+ #E6E1E5
+ #CAC4D0
+ #492532
+ #FFD8E4
+ #938F99
+ #D0BCFF
+ #4F378B
+ #CCC2DC
+ #4A4458
+ #1C1B1F
+ #49454F
+ #EFB8C8
+ #633B48
+
\ No newline at end of file
diff --git a/wearApp/src/main/res/values-night/themes.xml b/wearApp/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..df629eb
--- /dev/null
+++ b/wearApp/src/main/res/values-night/themes.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wearApp/src/main/res/values/colors.xml b/wearApp/src/main/res/values/colors.xml
new file mode 100644
index 0000000..169812c
--- /dev/null
+++ b/wearApp/src/main/res/values/colors.xml
@@ -0,0 +1,32 @@
+
+
+ #FFFBFE
+ #625B71
+
+ #FFFBFE
+ #B3261E
+ #F9DEDC
+ #F4EFF4
+ #D0BCFF
+ #313033
+ #1C1B1F
+ #FFFFFF
+ #410E0B
+ #FFFFFF
+ #21005D
+ #FFFFFF
+ #1D192B
+ #1C1B1F
+ #49454F
+ #FFFFFF
+ #31111D
+ #79747E
+ #6750A4
+ #EADDFF
+ #625B71
+ #E8DEF8
+ #FFFBFE
+ #E7E0EC
+ #7D5260
+ #FFD8E4
+
\ No newline at end of file
diff --git a/wearApp/src/main/res/values/strings.xml b/wearApp/src/main/res/values/strings.xml
new file mode 100644
index 0000000..d02d321
--- /dev/null
+++ b/wearApp/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ KmpTemplate
+
\ No newline at end of file
diff --git a/wearApp/src/main/res/values/themes.xml b/wearApp/src/main/res/values/themes.xml
new file mode 100644
index 0000000..1808cdd
--- /dev/null
+++ b/wearApp/src/main/res/values/themes.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
\ No newline at end of file