new: init kmp project

This commit is contained in:
2026-05-18 18:21:49 +02:00
commit af66fd04e5
63 changed files with 5080 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidMultiplatformLibrary)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
}
kotlin {
listOf(
iosArm64(),
iosSimulatorArm64(),
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "Shared"
isStatic = true
}
}
jvm()
js {
browser()
}
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser()
}
androidLibrary {
namespace = "fr.ajaury.gwenedeg.shared"
compileSdk =
libs.versions.android.compileSdk
.get()
.toInt()
minSdk =
libs.versions.android.minSdk
.get()
.toInt()
compilerOptions {
jvmTarget = JvmTarget.JVM_11
}
androidResources {
enable = true
}
withHostTest {
isIncludeAndroidResources = true
}
}
sourceSets {
androidMain.dependencies {
implementation(libs.compose.uiToolingPreview)
}
commonMain.dependencies {
implementation(libs.compose.runtime)
implementation(libs.compose.foundation)
implementation(libs.compose.material3)
implementation(libs.compose.ui)
implementation(libs.compose.components.resources)
implementation(libs.compose.uiToolingPreview)
implementation(libs.androidx.lifecycle.viewmodelCompose)
implementation(libs.androidx.lifecycle.runtimeCompose)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
}
jsMain.dependencies {
implementation(libs.wrappers.browser)
}
}
}
dependencies {
androidRuntimeClasspath(libs.compose.uiTooling)
}
@@ -0,0 +1,12 @@
package fr.ajaury.gwenedeg
import kotlin.test.Test
import kotlin.test.assertEquals
class SharedLogicAndroidHostTest {
@Test
fun example() {
assertEquals(3, 1 + 2)
}
}
@@ -0,0 +1,9 @@
package fr.ajaury.gwenedeg
import android.os.Build
class AndroidPlatform : Platform {
override val name: String = "Android ${Build.VERSION.SDK_INT}"
}
actual fun getPlatform(): Platform = AndroidPlatform()
@@ -0,0 +1,44 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="450dp"
android:height="450dp"
android:viewportWidth="64"
android:viewportHeight="64">
<path
android:pathData="M56.25,18V46L32,60 7.75,46V18L32,4Z"
android:fillColor="#6075f2"/>
<path
android:pathData="m41.5,26.5v11L32,43V60L56.25,46V18Z"
android:fillColor="#6b57ff"/>
<path
android:pathData="m32,43 l-9.5,-5.5v-11L7.75,18V46L32,60Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="23.131"
android:centerY="18.441"
android:gradientRadius="42.132"
android:type="radial">
<item android:offset="0" android:color="#FF5383EC"/>
<item android:offset="0.867" android:color="#FF7F52FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M22.5,26.5 L32,21 41.5,26.5 56.25,18 32,4 7.75,18Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="44.172"
android:startY="4.377"
android:endX="17.973"
android:endY="34.035"
android:type="linear">
<item android:offset="0" android:color="#FF33C3FF"/>
<item android:offset="0.878" android:color="#FF5383EC"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="m32,21 l9.526,5.5v11L32,43 22.474,37.5v-11z"
android:fillColor="#000000"/>
</vector>
@@ -0,0 +1,49 @@
package fr.ajaury.gwenedeg
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import org.jetbrains.compose.resources.painterResource
import gwenedeg.shared.generated.resources.Res
import gwenedeg.shared.generated.resources.compose_multiplatform
@Composable
@Preview
fun App() {
MaterialTheme {
var showContent by remember { mutableStateOf(false) }
Column(
modifier = Modifier
.background(MaterialTheme.colorScheme.primaryContainer)
.safeContentPadding()
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Button(onClick = { showContent = !showContent }) {
Text("Click me!")
}
AnimatedVisibility(showContent) {
val greeting = remember { Greeting().greet() }
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Image(painterResource(Res.drawable.compose_multiplatform), null)
Text("Compose: $greeting")
}
}
}
}
}
@@ -0,0 +1,9 @@
package fr.ajaury.gwenedeg
class Greeting {
private val platform = getPlatform()
fun greet(): String {
return sayHello(platform.name)
}
}
@@ -0,0 +1,4 @@
package fr.ajaury.gwenedeg
fun sayHello(to: String): String =
"Hello, $to!"
@@ -0,0 +1,7 @@
package fr.ajaury.gwenedeg
interface Platform {
val name: String
}
expect fun getPlatform(): Platform
@@ -0,0 +1,12 @@
package fr.ajaury.gwenedeg
import kotlin.test.Test
import kotlin.test.assertEquals
class SharedCommonTest {
@Test
fun example() {
assertEquals(3, 1 + 2)
}
}
@@ -0,0 +1,5 @@
package fr.ajaury.gwenedeg
import androidx.compose.ui.window.ComposeUIViewController
fun MainViewController() = ComposeUIViewController { App() }
@@ -0,0 +1,9 @@
package fr.ajaury.gwenedeg
import platform.UIKit.UIDevice
class IOSPlatform: Platform {
override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}
actual fun getPlatform(): Platform = IOSPlatform()
@@ -0,0 +1,12 @@
package fr.ajaury.gwenedeg
import kotlin.test.Test
import kotlin.test.assertEquals
class SharedLogicIOSTest {
@Test
fun example() {
assertEquals(3, 1 + 2)
}
}
@@ -0,0 +1,14 @@
package fr.ajaury.gwenedeg
import web.navigator.navigator
class JsPlatform: Platform {
private val userAgent = navigator.userAgent
private val browserList = listOf("Chrome", "Firefox", "Safari", "Edge")
override val name: String = userAgent.findAnyOf(browserList, ignoreCase = true)
?.let { (startIndex) -> userAgent.substring(startIndex).substringBefore(" ") }
?: "Unknown"
}
actual fun getPlatform(): Platform = JsPlatform()
@@ -0,0 +1,7 @@
package fr.ajaury.gwenedeg
class JVMPlatform: Platform {
override val name: String = "Java ${System.getProperty("java.version")}"
}
actual fun getPlatform(): Platform = JVMPlatform()
@@ -0,0 +1,12 @@
package fr.ajaury.gwenedeg
import kotlin.test.Test
import kotlin.test.assertEquals
class SharedLogicDesktopTest {
@Test
fun example() {
assertEquals(3, 1 + 2)
}
}
@@ -0,0 +1,7 @@
package fr.ajaury.gwenedeg
class WasmPlatform: Platform {
override val name: String = "Web with Kotlin/Wasm"
}
actual fun getPlatform(): Platform = WasmPlatform()