Implementing client logic
expect object PhotoRenderer{
fun render(photos: List<Photo>)
}
- CommonPhotoProvider
- Modify logic to get photos and call render function from object
- build.gradle
- Modify JS compile options to output
commonjs
modules
compileKotlin2Js.kotlinOptions.moduleKind = "commonjs"
- build.gradle
- Add frontend plugin, add DCE plugin, add node.js, add webpack configs
buildscript {
repositories {
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" }
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
def kotlin_frontend_plugin_version = "0.0.27"
def gradle_node_plugin_version = "1.2.0"
classpath "org.jetbrains.kotlin:kotlin-frontend-plugin:" + kotlin_frontend_plugin_version
classpath "com.moowork.gradle:gradle-node-plugin:" + gradle_node_plugin_version
}
}
apply plugin: 'kotlinx-serialization'
apply plugin: 'org.jetbrains.kotlin.frontend'
apply plugin: 'kotlin2js'
apply plugin: 'kotlin-platform-js'
apply plugin: 'kotlin-dce-js'
apply plugin: 'com.moowork.node'
node {
download = true
}
compileKotlin2Js.kotlinOptions.moduleKind = "commonjs"
kotlinFrontend {
downloadNodeJsVersion = 'latest'
npm {
dependency("react", "16.2.0")
dependency("react-dom", "16.2.0")
devDependency("webpack-cli", "2.0.10")
}
webpackBundle {
bundleName = "bundle"
sourceMapEnabled = true
publicPath = "/"
port = 3000
stats = "verbose"
}
}
task buildBundle(type: NpmTask, dependsOn: [npmInstall, runDceKotlinJs]) {
args = ["run", "bundle"]
}
task copyStatic {
copy {
from "src/main/static"
into 'build'
}
}
assemble.dependsOn(buildBundle, copyStatic)
run.dependsOn(copyStatic)
repositories {
maven { url "https://kotlin.bintray.com/kotlin-js-wrappers" }
}
dependencies {
compile project(":multiplat-workshop-js")
expectedBy project(":multiplat-workshop-client")
compile "org.jetbrains:kotlin-extensions:$js_wrappers_version"
compile "org.jetbrains:kotlin-react:$react_wrapper_version"
compile "org.jetbrains:kotlin-react-dom:$react_wrapper_version"
compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutines_version"
compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serialization_version"
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
}
kotlin {
experimental {
coroutines "enable"
}
}
- gradle.properties
- Add JS wrappers and React wrappers
js_wrappers_version=1.0.1-pre.11-kotlin-1.2.21
react_wrapper_version=16.2.1-pre.11-kotlin-1.2.21
- static folder
- Move index.html to static folder
- Modify contents to display only bundle
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Kotlin/JS ‘Hello, World’ Multiplatters</title>
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="bundle.js"></script>
</body>
</html>
interface PhotoProps : RProps {
var photos: List<Photo>
}
class PhotoComponent : RComponent<PhotoProps, RState>() {
override fun RBuilder.render() {
props.photos.forEach {
div {
img {
attrs.alt = it.member.name
attrs.src = it.photo_link
attrs.height = "400"
attrs.width = "400"
}
}
}
}
}
fun RBuilder.reactPhotoComponent(photos: List<Photo> = listOf()) = child(PhotoComponent::class) {
attrs.photos = photos
}
- PhotoRenderer.kt
- Modify to use reactDOM
render
function with our 'root' id as element to render our PhotoComponent
actual fun render(photos: List<Photo>) {
react.dom.render(document.getElementById("root")){
reactPhotoComponent(photos)
}
}
- webpack.config.js
- Add webpack config to handle bundling of correct dependencies and serving via dev-server
var webpack = require("webpack");
var path = require("path");
module.exports = {
entry: path.resolve(__dirname, "build/kotlin-js-min/main/multiplat-workshop-client-react.js"),
output: {
path: path.resolve(__dirname, "build"),
filename: "bundle.js"
},
resolve: {
modules : [
"node_modules",
path.resolve(__dirname, "build/kotlin-js-min/main/")
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin()
]
};
- package.json
- Add package.json to enable node.js build
{
"dependencies": {
"webpack": "3.4.1"
},
"scripts": {
"bundle": "webpack"
}
}
- gradle.properties
- Add tornadofx version -
tornadofx_version=1.7.15
- build.gradle
- Modify to contain tornado FX plugin and a main class
buildscript {
dependencies {
def javafx_gradle_plugin_version='8.8.2'
classpath "de.dynamicfiles.projects.gradle.plugins:javafx-gradle-plugin:$javafx_gradle_plugin_version"
}
}
apply plugin: 'kotlin-platform-jvm'
apply plugin: 'javafx-gradle-plugin'
dependencies {
compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
compile "no.tornado:tornadofx:$tornadofx_version"
compile project(":multiplat-workshop-jvm")
expectedBy project(":multiplat-workshop-client")
compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
jar {
manifest {
attributes 'Main-Class': 'MainKt'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
jfx {
mainClass = 'MainKt'
vendor = 'jussi'
}
kotlin {
experimental {
coroutines = "enable"
}
}
class PhotoComponent : View() {
override val root = ScrollPane()
init {
with(root) {
prefWidth = 800.0
prefHeight = 600.0
vbox {
photos.forEach {
imageview(it.photo_link) {
scaleX = .50
scaleY = .50
}
}
}
}
}
companion object {
var photos = listOf<Photo>()
}
}
class TornadoApplication : App() {
override val primaryView = PhotoComponent::class
}
- PhotoRenderer.kt
- Add photos list to static field on Component
- call
launch
with TornadoApplication
type param