import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.androidKotlinMultiplatformLibrary) alias(libs.plugins.jetbrainsComposeCompiler) alias(libs.plugins.composeMultiplatform) alias(libs.plugins.serialization) } kotlin { compilerOptions { freeCompilerArgs.add("-Xexpect-actual-classes") } jvm { compilerOptions { jvmTarget.set(JvmTarget.JVM_21) } } android { namespace = "com.vitorpamplona.amethyst.commons" compileSdk = libs.versions.android.compileSdk .get() .toInt() minSdk = libs.versions.android.minSdk .get() .toInt() compilerOptions { jvmTarget.set(JvmTarget.JVM_21) } androidResources.enable = true withHostTest {} withDeviceTest { instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } } sourceSets { commonMain { dependencies { implementation(project(":quartz")) // Audio-rooms ViewModel needs the listener orchestration + audio // pipeline types (NestsListener, AudioRoomPlayer, AudioPlayer // interface). Concrete OkHttp/Quic/MediaCodec/AudioTrack actuals // stay in :nestsClient's platform source sets. implementation(project(":nestsClient")) // Compose Multiplatform implementation(libs.jetbrains.compose.ui) implementation(libs.jetbrains.compose.foundation) implementation(libs.jetbrains.compose.runtime) implementation(libs.jetbrains.compose.material3) implementation(libs.jetbrains.compose.ui.tooling.preview) // Lifecycle ViewModel (KMP since 2.8.0) implementation(libs.androidx.lifecycle.viewmodel.compose) implementation(libs.androidx.lifecycle.runtime.compose) // Image loading (Coil 3 - KMP) implementation(libs.coil.compose) implementation(libs.coil.okhttp) // LruCache (KMP-ready) implementation(libs.androidx.collection) // Immutable collections api(libs.kotlinx.collections.immutable) // Compose Multiplatform Resources implementation(libs.jetbrains.compose.components.resources) // Markdown rendering (richtext-commonmark) implementation(libs.markdown.commonmark) implementation(libs.markdown.ui) implementation(libs.markdown.ui.material3) } } commonTest { dependencies { implementation(libs.kotlin.test) implementation(libs.kotlinx.coroutines.test) } } // Shared JVM code for both Android and Desktop val jvmAndroid = create("jvmAndroid") { dependsOn(commonMain.get()) dependencies { } } jvmMain { dependsOn(jvmAndroid) dependencies { // Desktop-specific Compose implementation(compose.desktop.currentOs) implementation(libs.jetbrains.compose.ui.tooling) // Secure key storage via OS keychain (macOS/Windows/Linux) implementation(libs.java.keyring) // EXIF stripping for image uploads (used by service/upload/MediaCompressor). implementation(libs.commons.imaging) } } androidMain { dependsOn(jvmAndroid) dependencies { // Android-specific Compose tooling implementation(libs.androidx.ui.tooling.preview) // Secure key storage via Android Keystore implementation(libs.androidx.security.crypto.ktx) implementation(libs.androidx.datastore.preferences) } } getByName("androidHostTest") { dependencies { implementation(libs.junit) // Bitcoin secp256k1 bindings implementation(libs.secp256k1.kmp.jni.jvm) } } getByName("androidDeviceTest") { dependencies { implementation(libs.androidx.junit) implementation(libs.androidx.espresso.core) } } } } compose.resources { publicResClass = true packageOfResClass = "com.vitorpamplona.amethyst.commons.resources" generateResClass = always }