Skip to content

Instantly share code, notes, and snippets.

@marschwar
Last active February 12, 2024 12:46
Show Gist options
  • Save marschwar/7d5ce82f85459bba279a23e7764c78b3 to your computer and use it in GitHub Desktop.
Save marschwar/7d5ce82f85459bba279a23e7764c78b3 to your computer and use it in GitHub Desktop.
multiplatform-webview-config
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.kotlinSerialization)
alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsCompose)
}
kotlin {
androidTarget {
compilations.all {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
jvm("desktop")
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "ComposeApp"
isStatic = false
}
}
sourceSets {
val desktopMain by getting
androidMain.dependencies {
implementation(libs.compose.ui.tooling.preview)
implementation(libs.androidx.activity.compose)
}
commonMain.dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(libs.kermit)
implementation(libs.bundles.decompose)
api(libs.webview)
}
desktopMain.dependencies {
implementation(compose.desktop.currentOs)
}
}
}
android {
namespace = "com.example.sekolah"
compileSdk = libs.versions.android.compileSdk.get().toInt()
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
sourceSets["main"].res.srcDirs("src/androidMain/res")
sourceSets["main"].resources.srcDirs("src/commonMain/resources")
defaultConfig {
applicationId = "com.example.sekolah"
minSdk = libs.versions.android.minSdk.get().toInt()
targetSdk = libs.versions.android.targetSdk.get().toInt()
versionCode = 1
versionName = "1.0"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
dependencies {
debugImplementation(libs.compose.ui.tooling)
}
}
compose.desktop {
application {
mainClass = "MainKt"
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "com.example.sekolah"
packageVersion = "1.0.0"
}
}
}
afterEvaluate {
tasks.withType<JavaExec> {
jvmArgs("--add-opens", "java.desktop/sun.awt=ALL-UNNAMED")
jvmArgs(
"--add-opens",
"java.desktop/java.awt.peer=ALL-UNNAMED"
)
if (System.getProperty("os.name").contains("Mac")) {
jvmArgs("--add-opens", "java.desktop/sun.awt=ALL-UNNAMED")
jvmArgs("--add-opens", "java.desktop/sun.lwawt=ALL-UNNAMED")
jvmArgs("--add-opens", "java.desktop/sun.lwawt.macosx=ALL-UNNAMED")
}
}
}
[versions]
agp = "8.2.2"
android-compileSdk = "34"
android-minSdk = "24"
android-targetSdk = "34"
androidx-activityCompose = "1.8.2"
compose = "1.6.0"
compose-plugin = "1.6.0-beta02"
kotlin = "1.9.21"
kermit-logging = "2.0.3"
decompose = "3.0.0-alpha05"
[libraries]
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
kermit = { module = "co.touchlab:kermit", version.ref = "kermit-logging" }
decompose-core = { module = "com.arkivanov.decompose:decompose", version.ref = "decompose" }
decompose-ext = { module = "com.arkivanov.decompose:extensions-compose", version.ref = "decompose" }
webview = { module = "io.github.kevinnzou:compose-webview-multiplatform", version = "1.8.8" }
[bundles]
decompose = ["decompose-core", "decompose-ext"]
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
androidLibrary = { id = "com.android.library", version.ref = "agp" }
jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Text
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
import co.touchlab.kermit.Logger
import com.arkivanov.decompose.DefaultComponentContext
import com.arkivanov.decompose.ExperimentalDecomposeApi
import com.arkivanov.decompose.extensions.compose.lifecycle.LifecycleController
import com.arkivanov.essenty.lifecycle.LifecycleRegistry
import dev.datlag.kcef.KCEF
import java.io.File
import kotlin.math.max
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@OptIn(ExperimentalDecomposeApi::class)
fun main() {
val lifecycle = LifecycleRegistry()
val rootComponent =
DefaultRootComponent(componentContext = DefaultComponentContext(lifecycle = lifecycle))
application {
val windowState = rememberWindowState()
LifecycleController(lifecycle, windowState)
Window(onCloseRequest = ::exitApplication, title = "Sekolah") {
var restartRequired by remember { mutableStateOf(false) }
var downloading by remember { mutableStateOf(0F) }
var initialized by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
KCEF.init(builder = {
installDir(File("kcef-bundle"))
progress {
onDownloading {
downloading = max(it / 100f, 0F)
}
onInitialized {
initialized = true
}
}
settings {
cachePath = File("cache").absolutePath
}
}, onError = {
Logger.e("Main", it) { "Unexpected error initializing kcef file cache" }
}, onRestartRequired = {
restartRequired = true
})
}
}
if (restartRequired) {
Text(text = "Restart required.")
} else {
if (initialized) {
App(root = rootComponent)
} else {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Downloading")
CircularProgressIndicator(progress = downloading)
}
}
}
DisposableEffect(Unit) {
onDispose {
KCEF.disposeBlocking()
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment