Skip to content

Commit

Permalink
setup project
Browse files Browse the repository at this point in the history
  • Loading branch information
RivuChk committed Feb 11, 2024
1 parent b2df519 commit 2e1996f
Show file tree
Hide file tree
Showing 12 changed files with 217 additions and 8 deletions.
4 changes: 2 additions & 2 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ plugins {
}

kotlin {
@OptIn(ExperimentalWasmDsl::class)
/*@OptIn(ExperimentalWasmDsl::class)
wasmJs {
moduleName = "composeApp"
browser {
Expand All @@ -18,7 +18,7 @@ kotlin {
}
}
binaries.executable()
}
}*/

androidTarget {
compilations.all {
Expand Down
3 changes: 3 additions & 0 deletions composeApp/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@android:style/Theme.Material.Light.NoActionBar">
<activity
android:exported="true"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">0.0.0.0</domain>
</domain-config>
</network-security-config>
14 changes: 13 additions & 1 deletion composeApp/src/commonMain/kotlin/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,33 @@ import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
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 kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.painterResource

@OptIn(ExperimentalResourceApi::class)
@Composable
fun App() {
MaterialTheme {
val greetingClass = Greeting()
var showContent by remember { mutableStateOf(false) }
val greeting = remember { Greeting().greet() }
var greeting by remember { mutableStateOf(greetingClass.greet()) }

LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
greeting += greetingClass.getResponseFromServer()
}
}

Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
Button(onClick = { showContent = !showContent }) {
Text("Click me!")
Expand Down
43 changes: 42 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ junit = "4.13.2"
kotlin = "1.9.21"
ktor = "2.3.8"
logback = "1.4.14"
coroutines = "1.8.0-RC2"
okHttpLoggingInterceptor = "4.11.0"
sqlDelight = "2.0.1"
kotlinInject = '0.6.3'
ksp = '1.9.21-1.0.16'
arrowCore = "1.2.0"


[libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
Expand All @@ -35,10 +42,44 @@ ktor-server-core = { module = "io.ktor:ktor-server-core-jvm", version.ref = "kto
ktor-server-netty = { module = "io.ktor:ktor-server-netty-jvm", version.ref = "ktor" }
ktor-server-tests = { module = "io.ktor:ktor-server-tests-jvm", version.ref = "ktor" }

arrow-core = { module = "io.arrow-kt:arrow-core", version.ref = "arrowCore" }

kotlinInject-compiler = { module = 'me.tatarka.inject:kotlin-inject-compiler-ksp', version.ref = 'kotlinInject' }
kotlinInject-runtime = { module = 'me.tatarka.inject:kotlin-inject-runtime', version.ref = 'kotlinInject' }

sqlDelight-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqlDelight" }
sqlDelight-native = { module = "app.cash.sqldelight:native-driver", version.ref = "sqlDelight" }
sqlDelight-jvm = { module = "app.cash.sqldelight:sqlite-driver", version.ref = "sqlDelight" }
okhttp-loggingInterceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okHttpLoggingInterceptor" }

ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-ios = { module = "io.ktor:ktor-client-ios", version.ref = "ktor" }
ktor-client-okHttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }
ktor-client-serialization-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" }

ktor-client-contentNegotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }

coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }


[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" }
kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
ktor = { id = "io.ktor.plugin", version.ref = "ktor" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
ksp = { id = 'com.google.devtools.ksp', version.ref = 'ksp' }
sqlDelight = { id = "app.cash.sqldelight", version.ref = "sqlDelight" }

[bundles]
common-ktor-client = [
"ktor-client-core",
"ktor-client-logging",
"ktor-client-serialization-json",
"ktor-client-contentNegotiation",
]
39 changes: 36 additions & 3 deletions shared/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import org.jetbrains.kotlin.gradle.plugin.sources.dependsOnClosure
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl

plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidLibrary)
alias(libs.plugins.ksp)
alias(libs.plugins.sqlDelight)
}

kotlin {
@OptIn(ExperimentalWasmDsl::class)
/*@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser()
}
}*/
applyDefaultHierarchyTemplate()

androidTarget {
compilations.all {
Expand All @@ -27,7 +31,26 @@ kotlin {

sourceSets {
commonMain.dependencies {
// put your Multiplatform dependencies here
implementation(libs.bundles.common.ktor.client)
implementation(libs.coroutines.core)
implementation(libs.arrow.core)
implementation(libs.kotlinInject.runtime)
}

androidMain.dependencies {
implementation(libs.sqlDelight.android)
implementation(libs.ktor.client.okHttp)
implementation(libs.okhttp.loggingInterceptor)
}

// or iosMain, windowsMain, etc.
nativeMain.dependencies {
implementation(libs.ktor.client.darwin)
implementation(libs.sqlDelight.native)
}

jvmMain.dependencies {
implementation(libs.sqlDelight.jvm)
}
}
}
Expand All @@ -39,3 +62,13 @@ android {
minSdk = libs.versions.android.minSdk.get().toInt()
}
}

dependencies {
// KSP will eventually have better multiplatform support and we'll be able to simply have
// `ksp libs.kotlinInject.compiler` in the dependencies block of each source set
// https://github.com/google/ksp/pull/1021
add("kspIosX64", libs.kotlinInject.compiler)
add("kspIosArm64", libs.kotlinInject.compiler)
add("kspIosSimulatorArm64", libs.kotlinInject.compiler)
add("kspAndroid", libs.kotlinInject.compiler)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package dev.rivu.courses.indiaconferences.remote

import android.util.Log
import io.ktor.client.HttpClient
import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.plugins.HttpRequestRetry
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import isDebug
import okhttp3.internal.platform.android.AndroidLogHandler.setLevel
import okhttp3.logging.HttpLoggingInterceptor

actual val KtorClient: HttpClient by lazy {
Log.d("SDK","KtorClient Android")

HttpClient(OkHttp) {
// default validation to throw exceptions for non-2xx responses
expectSuccess = true

engine {
// add logging interceptor
if (isDebug()) {
addInterceptor(
HttpLoggingInterceptor().apply {
setLevel(
HttpLoggingInterceptor.Level.BODY,
)
},
)
}
}

install(ContentNegotiation) {
json
}

install(HttpRequestRetry) {
retryConfig()
}
}
}
10 changes: 10 additions & 0 deletions shared/src/commonMain/kotlin/Greeting.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import dev.rivu.courses.indiaconferences.remote.KtorClient
import io.ktor.client.call.body
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText

class Greeting {
private val platform = getPlatform()

fun greet(): String {
return "Hello, ${platform.name}!"
}

suspend fun getResponseFromServer(): String {
val response = KtorClient.get("http://0.0.0.0:8080")
return response.bodyAsText()
}
}
4 changes: 3 additions & 1 deletion shared/src/commonMain/kotlin/Platform.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ interface Platform {
val name: String
}

expect fun getPlatform(): Platform
expect fun getPlatform(): Platform

fun isDebug(): Boolean = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dev.rivu.courses.indiaconferences.remote

import io.ktor.client.HttpClient
import io.ktor.client.plugins.HttpRequestRetry.Configuration
import kotlinx.serialization.json.Json


expect val KtorClient: HttpClient


val json = Json {
ignoreUnknownKeys = true
isLenient = true
}

fun Configuration.retryConfig() {
retryOnServerErrors(maxRetries = 3)
exponentialDelay()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package dev.rivu.courses.indiaconferences.remote

import io.ktor.client.HttpClient

actual val KtorClient: HttpClient
get() = HttpClient()
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package dev.rivu.courses.indiaconferences.remote

import io.ktor.client.HttpClient
import io.ktor.client.engine.darwin.Darwin
import io.ktor.client.plugins.HttpRequestRetry
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.logging.LogLevel
import io.ktor.client.plugins.logging.Logging
import isDebug

actual val KtorClient: HttpClient by lazy {
HttpClient(Darwin) {
// default validation to throw exceptions for non-2xx responses
expectSuccess = true

if (isDebug()) {
install(Logging) {
level = LogLevel.ALL
}
}

engine {
configureRequest {
setAllowsCellularAccess(true)
setAllowsExpensiveNetworkAccess(true)
}
}

install(ContentNegotiation) {
json
}

install(HttpRequestRetry) {
retryConfig()
}
}
}

0 comments on commit 2e1996f

Please sign in to comment.