Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ dependencies {
implementation(libs.kotlin.plugin)
implementation(libs.kotlin.plugin.compose)
implementation(libs.kotlin.plugin.serialization)
implementation(libs.compose.gradlePlugin)
implementation(libs.kotlinova.gradle)
implementation(libs.metro.plugin)
implementation(libs.moduleGraphAssert)
Expand Down
54 changes: 54 additions & 0 deletions buildSrc/src/main/kotlin/library-kmp-module.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import dev.detekt.gradle.Detekt
import org.gradle.accessors.dm.LibrariesForLibs
import tasks.setupTooManyKotlinFilesTaskForCommon

val libs = the<LibrariesForLibs>()

plugins {
id("org.jetbrains.kotlin.multiplatform")
id("com.android.kotlin.multiplatform.library")
id("org.jetbrains.kotlin.plugin.compose")
id("org.jetbrains.compose")

id("checks")
}

val isMac = System.getProperty("os.name").contains("mac", ignoreCase = true)

kotlin {
jvmToolchain(21)

androidLibrary {
// Modules with resources must override this.
namespace = "com.matejdro.micropebble.noresources"
compileSdk = 36
minSdk = 30
}

if (isMac) {
iosX64()
iosArm64()
iosSimulatorArm64()
}

compilerOptions {
optIn.add("kotlin.time.ExperimentalTime")
optIn.add("kotlin.uuid.ExperimentalUuidApi")
optIn.add("kotlin.ExperimentalUnsignedTypes")
freeCompilerArgs.add("-Xannotation-default-target=param-property")
}

sourceSets {
commonMain.dependencies {
implementation(libs.compose.runtime)
}
}
}

if (name.startsWith("common-")) {
setupTooManyKotlinFilesTaskForCommon()
}

tasks.register("runDebugDetekt") {
dependsOn(tasks.withType<Detekt>())
}
3 changes: 3 additions & 0 deletions buildSrc/src/main/kotlin/util/PluginAccessors.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ inline val PluginDependenciesSpec.androidAppModule: PluginDependencySpec
inline val PluginDependenciesSpec.androidLibraryModule: PluginDependencySpec
get() = id("library-android-module")

inline val PluginDependenciesSpec.kmpLibraryModule: PluginDependencySpec
get() = id("library-kmp-module")

inline val PluginDependenciesSpec.pureKotlinModule: PluginDependencySpec
get() = id("pure-kotlin-module")

Expand Down
27 changes: 17 additions & 10 deletions common-navigation/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
plugins {
androidLibraryModule
compose
parcelize
serialization
kmpLibraryModule
id("org.jetbrains.kotlin.plugin.serialization")
}

dependencies {
api(libs.kotlinova.navigation)
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.core)
implementation(libs.androidx.compose.material3.sizeClasses)
implementation(libs.kotlinova.compose)
kotlin {
androidLibrary {
namespace = "com.matejdro.micropebble.navigation"
}

sourceSets {
androidMain.dependencies {
api(libs.kotlinova.navigation)
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.core)
implementation(libs.kotlin.serialization.core)
implementation(libs.compose.animation)
implementation(libs.compose.ui)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.matejdro.micropebble.navigation.keys

import com.matejdro.micropebble.navigation.keys.base.Tab
import com.matejdro.micropebble.navigation.keys.base.TabKey
import kotlinx.serialization.Serializable
import si.inova.kotlinova.navigation.screenkeys.ScreenKey

@Serializable
data object NotificationAppListKey : ScreenKey(), TabKey {
override val tab get() = Tab.NOTIFICATIONS
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.matejdro.micropebble.navigation.keys

import com.matejdro.micropebble.navigation.keys.base.Tab
import com.matejdro.micropebble.navigation.keys.base.TabKey
import kotlinx.serialization.Serializable
import si.inova.kotlinova.navigation.screenkeys.ScreenKey

@Serializable
data object WatchListKey : ScreenKey(), TabKey {
override val tab get() = Tab.WATCHES
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.matejdro.micropebble.navigation.keys

import com.matejdro.micropebble.navigation.keys.base.Tab
import com.matejdro.micropebble.navigation.keys.base.TabKey
import com.matejdro.micropebble.navigation.keys.common.InputFile
import kotlinx.serialization.Serializable
import si.inova.kotlinova.navigation.screenkeys.ScreenKey

@Serializable
data class WatchappListKey(
val pbwFile: InputFile? = null,
) : ScreenKey() {
) : ScreenKey(), TabKey {
override val tab get() = Tab.WATCH_APPS

override fun getScopeTag(): String {
return this::class.java.name
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.matejdro.micropebble.navigation.keys.base

/**
* Key for a screen that shows a list of tabs + container. Container will be filled from the next entry on the backstack.
*/
interface TabContainerKey
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ package com.matejdro.micropebble.navigation.keys.base

import androidx.compose.runtime.Composable
import androidx.compose.runtime.staticCompositionLocalOf
import si.inova.kotlinova.navigation.screenkeys.ScreenKey

/**
* Key for a screen that shows a list of tabs + container. Container will be filled from the next entry on the backstack.
*/
interface TabContainerKey
enum class Tab {
WATCHES,
WATCH_APPS,
NOTIFICATIONS,
TOOLS,
}

/** Implemented by screen keys that act as a top-level tab destination. */
interface TabKey {
val tab: Tab
}

val LocalSelectedTabContent = staticCompositionLocalOf<SelectedTabContent> { error("SelectedTabContent not provided") }

data class SelectedTabContent(val content: @Composable () -> Unit, val key: ScreenKey, val contentKey: Any)
/** Content shown inside a tab container, plus which [Tab] is currently selected (null when none is). */
data class SelectedTabContent(val content: @Composable () -> Unit, val tab: Tab?, val contentKey: Any)

This file was deleted.

This file was deleted.

12 changes: 12 additions & 0 deletions config/libs.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ androidx-test-runner = "1.7.0"
androidx-work = "2.11.2"
coil = "3.4.0"
composeDnd = "0.4.0"
# @pin CMP material3 tracks its own version; 1.10.0-alpha05 matches libpebble3 (1.11.x alpha is broken)
composeMaterial3 = "1.10.0-alpha05"
# @pin needs to match libpebble3's Compose Multiplatform version
composeMultiplatform = "1.10.1"
composePreference = "2.2.0"
composeWebview = "0.33.6"
dependencyAnalysis = "3.15.0"
Expand Down Expand Up @@ -102,6 +106,14 @@ androidx-work-runtime = { module = "androidx.work:work-runtime-ktx", version.ref
coil = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" }
coil-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" }
composeDnd = { module = "com.mohamedrejeb.dnd:compose-dnd", version.ref = "composeDnd" }
# Compose Multiplatform artifacts (used by KMP modules; android variants relocate to androidx.compose)
compose-animation = { module = "org.jetbrains.compose.animation:animation", version.ref = "composeMultiplatform" }
compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "composeMultiplatform" }
# Compose Multiplatform Gradle plugin, used by the library-kmp-module convention plugin in buildSrc
compose-gradlePlugin = { module = "org.jetbrains.compose:compose-gradle-plugin", version.ref = "composeMultiplatform" }
compose-material3 = { module = "org.jetbrains.compose.material3:material3", version.ref = "composeMaterial3" }
compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "composeMultiplatform" }
compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "composeMultiplatform" }
composePreference = { module = "me.zhanghai.compose.preference:preference", version.ref = "composePreference" }
composeWebview = { module = "io.github.kevinnzou:compose-webview", version.ref = "composeWebview" }
dependencyAnalysis = { module = "com.autonomousapps:dependency-analysis-gradle-plugin", version.ref = "dependencyAnalysis" }
Expand Down
88 changes: 62 additions & 26 deletions home/ui/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,33 +1,69 @@
plugins {
androidLibraryModule
compose
di
navigation
parcelize
serialization
showkase
kmpLibraryModule
id("dev.zacsweers.metro")
id("com.google.devtools.ksp")
id("org.jetbrains.kotlin.plugin.serialization")
}

android {
namespace = "com.matejdro.micropebble.home.ui"
androidResources.enable = true
kotlin {
androidLibrary {
namespace = "com.matejdro.micropebble.home.ui"
androidResources.enable = true
}

sourceSets {
commonMain.dependencies {
implementation(projects.commonNavigation)
implementation(libs.compose.foundation)
implementation(libs.compose.material3)
implementation(libs.compose.animation)
implementation(libs.compose.ui)
}

androidMain {
languageSettings.optIn("com.google.accompanist.permissions.ExperimentalPermissionsApi")

dependencies {
api(projects.notification.api)
api(projects.common)
api(projects.logging.api)
api(projects.voice.api)
api(libs.androidx.core)
api(libs.kotlinova.core)
api(libs.kotlinova.navigation)

implementation(projects.sharedResources)
implementation(projects.commonCompose)
implementation(libs.accompanist.permissions)
implementation(libs.composePreference)
implementation(libs.kotlin.coroutines)
implementation(libs.kotlin.serialization.core)
implementation(libs.dispatch)
implementation(libs.androidx.compose.material3.sizeClasses)
implementation(libs.libpebble3)
implementation(libs.showkase)

implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.ui.graphics)
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.lifecycle.compose)
implementation(libs.kotlinova.compose)
}
}
}
}

val stableClassesFile = project.layout.settingsDirectory.file("config/global_compose_stable_classes.txt")
composeCompiler {
stabilityConfigurationFiles.add(stableClassesFile)
}

ksp {
arg("skipPrivatePreviews", "true")
}

dependencies {
api(projects.notification.api)
api(projects.common)
api(projects.logging.api)
api(projects.voice.api)
api(libs.androidx.core)
api(libs.kotlinova.core)
api(libs.kotlinova.navigation)

implementation(projects.sharedResources)
implementation(projects.commonCompose)
implementation(libs.accompanist.permissions)
implementation(libs.composePreference)
implementation(libs.kotlin.coroutines)
implementation(libs.dispatch)
implementation(libs.androidx.compose.material3.sizeClasses)
implementation(libs.libpebble3)
add("kspAndroid", libs.showkase.processor)
add("kspAndroid", libs.kotlinova.navigation.compiler)
}
Loading