Skip to content

Commit

Permalink
Merge pull request #57 from worldline/55-hello-world-compose-web-app-…
Browse files Browse the repository at this point in the history
…in-front-dev-section

55 hello world compose web app in front dev section
  • Loading branch information
wlybe authored Oct 3, 2023
2 parents fbce079 + ae25c0f commit 0e3e995
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 54 deletions.
Binary file added docs/src/assets/hello-compose-demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 4 additions & 12 deletions docs/src/en/front-development/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ Please find below a glimpse of the possibilities that you can do right from Inte
- On the **Web**
- [Ktor](https://ktor.io/docs/creating-interactive-website.html) can use templates engines [such as FreeMarker](https://freemarker.apache.org/) to create server pages.
- With **KotlinJS**, developers can create React, nodsjs, or vanilla JS Apps using Kotlin.
- Kotlin **WASM** compiles into *Web Assembly*. It can complement KotlinJS for computation intensive tasks.
- Kotlin **WASM** compiles into _Web Assembly_. It can complement KotlinJS for computation intensive tasks.
- On **Mobiles**
- Android developers use the [Jetpack Compose](https://developer.android.com/jetpack/compose) UI Framework or the legacy **xml layouts**. It is experimental on iOS.

Kotlin supports cross platform frontend development thanks to **Kotlin MultiPlatform (KMP)**

## Kotlin Multiplatform (KMP)

>"The Kotlin Multiplatform technology is designed to simplify the development of cross-platform projects. It reduces time spent writing and maintaining the same code for different platforms while retaining the flexibility and benefits of native programming." [](https://kotlinlang.org/docs/multiplatform.html)
> "The Kotlin Multiplatform technology is designed to simplify the development of cross-platform projects. It reduces time spent writing and maintaining the same code for different platforms while retaining the flexibility and benefits of native programming." [](https://kotlinlang.org/docs/multiplatform.html)
[KMP](https://blog.jetbrains.com/kotlin/2021/08/compose-multiplatform-goes-alpha/) relies on Kotlin native and other Kotlin features to help developers create projects that target multiple platforms using a common Kotlin code-base.

Expand Down Expand Up @@ -90,7 +90,6 @@ Button(

It is based on [Android Jetpack Compose](https://developer.android.com/jetpack/compose) declarative UI approach ( which is similar also to [iOS SwiftUI](https://developer.apple.com/xcode/swiftui/) ) [1](https://www.jetbrains.com/lp/compose-multiplatform/)


::: tip Compose multiplatform vs Jetpack Compose

While very similar, Compose multiplatform is different from Jetpack Compose as the latter is only compatible with Android.
Expand Down Expand Up @@ -121,7 +120,7 @@ At the time of writing, this template does not include a compose web target.
- In order to run the Android App, the simplest way is to launch it from IntelliJ ![Alt text](../../assets/launch-android-app.png). It is also possible [define a gradle task](https://gist.github.com/MoshDev/a61080cc5e1f5bafdf3cc0bf70fd86fd) that installs the app on the device and issues a command to the device to launch it.
- In order to run the iOS App, the simplest way is to run it on the simulator using IntelliJ. In order to run it on a real device, the TramID needs to be defined as [explained here](https://github.com/JetBrains/compose-multiplatform-template#on-ios)

![Alt text](..//../assets/kmp-compose-desktop.png)
![Alt text](../../assets/kmp-compose-desktop.png =200x)

### 🧪 Playing with the Compose multiplatform API

Expand Down Expand Up @@ -159,19 +158,12 @@ RandomNumberList()

- Exercise: Make the "Hello, .." button switch between showing the list and and the image.

### 🧪 Compose multiplatform with web target

Even though the official template does not support the web target, we can use the sample GitHub project [Kotlin/kotlin-wasm-examples/compose-imageviewer](https://github.com/Kotlin/kotlin-wasm-examples/tree/main/compose-imageviewer) with fortunately support all compose targets.

- Similarly to the previous PW, download the project and open it in your IDE.
- The web target can be run with: `./gradlew --console=plain :webApp:wasmRun`. The other targets can be run as seen above.
- Exercise: develop a compose app that behaves like the below animation.
![Hello compose demo](../../assets/hello-compose-demo.gif)

## 🎯 Solutions

- [Kotlin/JS and Kotlin/WASM PW](https://github.com/worldline/learning-kotlin/tree/main/material/webapp-kotlin-wasm)
- [Compose multiplatform PW2](https://github.com/worldline/learning-kotlin/tree/main/material/app-compose-multiplatform)
- [Compose multiplatform PW3](https://github.com/worldline/learning-kotlin/tree/main/material/app-compose-multiplatform-with-web)

## 📖 Further reading

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
kotlin {
jvm()
sourceSets {
val jvmMain by getting {
val jvmMain by getting {
dependencies {
implementation(compose.desktop.currentOs)
implementation(project(":shared"))
Expand All @@ -20,7 +20,6 @@ kotlin {
compose.desktop {
application {
mainClass = "MainKt"

nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "KotlinMultiplatformComposeDesktopApplication"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application

fun main() = application {
Window(onCloseRequest = ::exitApplication) {
Window(title = "Hello Compose", onCloseRequest = ::exitApplication) {
MainView()
}
}
4 changes: 2 additions & 2 deletions material/app-compose-multiplatform/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ android.targetSdk=34
android.minSdk=24

#Versions
kotlin.version=1.9.10
kotlin.version=1.9.20-Beta
agp.version=8.0.2
compose.version=1.5.1
compose.version=1.5.10-beta02
2 changes: 1 addition & 1 deletion material/app-compose-multiplatform/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
rootProject.name = "MyApplication"
rootProject.name = "HelloCompose"

include(":androidApp")
include(":shared")
Expand Down
11 changes: 1 addition & 10 deletions material/app-compose-multiplatform/shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,9 @@ kotlin {
dependencies {
api("androidx.activity:activity-compose:1.7.2")
api("androidx.appcompat:appcompat:1.6.1")
api("androidx.core:core-ktx:1.10.1")
api("androidx.core:core-ktx:1.12.0")
}
}
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
val desktopMain by getting {
dependencies {
implementation(compose.desktop.common)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,8 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.ExperimentalResourceApi
Expand All @@ -21,35 +15,44 @@ import kotlin.random.Random
@Composable
fun App() {
MaterialTheme {
var greetingText by remember { mutableStateOf("Hello, World!") }
var showImage by remember { mutableStateOf(false) }
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
Button(onClick = {
greetingText = "Hello, ${getPlatformName()}"
showImage = !showImage
}) {
Text(greetingText)
Scaffold(
topBar = {
TopAppBar {
TopAppBar(title = { Text("Hello Compose") }, backgroundColor = MaterialTheme.colors.primary)
}
}
AnimatedVisibility(showImage) {
Image(
painterResource("compose-multiplatform.xml"),
null
)
}
AnimatedVisibility(!showImage){
RandomNumberList()
) {
var greetingText by remember { mutableStateOf("Show Image") }
var showImage by remember { mutableStateOf(false) }
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
Text("You are running on ${getPlatformName()}")
Button(onClick = {
greetingText = if (showImage) "Show image" else "Show numbers"
showImage = !showImage
}) {
Text(greetingText)
}
AnimatedVisibility(showImage) {
Image(
painterResource("compose-multiplatform.xml"),
null
)
}
AnimatedVisibility(!showImage) {
RandomNumberList()
}
}
}
}
}

@Composable
fun RandomNumberList(){
fun RandomNumberList() {
// Generate a list of random numbers
val myRandomValues = List(5) { Random.nextInt(0, 30) }
// LazyColumn is a vertically scrolling list that renders items on demand
LazyColumn {
items(myRandomValues.size){
items(myRandomValues.size) {
Text(text = "$it")
}
}
Expand Down

0 comments on commit 0e3e995

Please sign in to comment.