diff options
Diffstat (limited to 'sw-ui-kt')
5 files changed, 63 insertions, 7 deletions
diff --git a/sw-ui-kt/build.gradle.kts b/sw-ui-kt/build.gradle.kts index a3b453ee..20dd9439 100644 --- a/sw-ui-kt/build.gradle.kts +++ b/sw-ui-kt/build.gradle.kts @@ -19,12 +19,17 @@ kotlin { implementation(kotlin("stdlib-js")) implementation(project(":sw-client")) - implementation("org.jetbrains:kotlin-react:16.6.0-pre.78-kotlin-1.3.41") - implementation(npm("react", "16.8.3")) - implementation("org.jetbrains:kotlin-react-dom:16.6.0-pre.78-kotlin-1.3.41") - implementation(npm("react-dom", "16.8.3")) + implementation("org.jetbrains:kotlin-react:16.8.6-pre.80-kotlin-1.3.41") + implementation(npm("react", "16.8.6")) + + implementation("org.jetbrains:kotlin-react-dom:16.8.6-pre.80-kotlin-1.3.41") + implementation(npm("react-dom", "16.8.6")) + + implementation("org.jetbrains:kotlin-react-redux:5.0.7-pre.80-kotlin-1.3.41") + implementation(npm("react-redux", "5.0.7")) + implementation(npm("redux", "4.0.4")) + // implementation(npm("@blueprintjs/core", "3.15.1")) - // implementation(npm("react-redux", "5.0.7")) } } } @@ -34,10 +39,13 @@ val staticFilesBuildDir = "${project.buildDir.path}/static" val staticFilesSrcDir = "$projectDir/src/main/web" tasks { - "compileKotlinJs"(KotlinJsCompile::class) { + compileKotlinJs { kotlinOptions.metaInfo = true kotlinOptions.outputFile = "${project.buildDir.path}/js/${project.name}.js" kotlinOptions.sourceMap = true + + // non-plain module kind is necessary to use top-level declarations from UMD modules (e.g. react-redux) + // because the Kotlin wrapper didn't specify @JsNonModule kotlinOptions.moduleKind = "commonjs" kotlinOptions.main = "call" } diff --git a/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/SevenWondersUi.kt b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/SevenWondersUi.kt index 5d9d9be6..8ad20702 100644 --- a/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/SevenWondersUi.kt +++ b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/SevenWondersUi.kt @@ -1,13 +1,28 @@ package org.luxons.sevenwonders.ui +import org.luxons.sevenwonders.ui.redux.configureStore +import org.w3c.dom.Element import react.RBuilder import react.dom.* +import react.redux.provider import kotlin.browser.document import kotlin.browser.window fun main() { window.onload = { - render(document.getElementById("root")!!) { + val rootElement = document.getElementById("root") + if (rootElement != null) { + initializeAndRender(rootElement) + } else { + console.error("Element with ID 'root' was not found, cannot bootstrap react app") + } + } +} + +private fun initializeAndRender(rootElement: Element) { + val store = configureStore() + render(rootElement) { + provider(store) { app() } } diff --git a/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Actions.kt b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Actions.kt new file mode 100644 index 00000000..3fc51d6e --- /dev/null +++ b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Actions.kt @@ -0,0 +1,5 @@ +package org.luxons.sevenwonders.ui.redux + +import redux.RAction + +class ChooseUserName(val newUsername: String): RAction diff --git a/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Reducers.kt b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Reducers.kt new file mode 100644 index 00000000..d811d32e --- /dev/null +++ b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Reducers.kt @@ -0,0 +1,8 @@ +package org.luxons.sevenwonders.ui.redux + +import redux.RAction + +fun rootReducer(state: SwState, action: RAction) = when (action) { + is ChooseUserName -> state.copy(playerName = action.newUsername) + else -> state +} diff --git a/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Store.kt b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Store.kt new file mode 100644 index 00000000..75f7e8a8 --- /dev/null +++ b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Store.kt @@ -0,0 +1,20 @@ +package org.luxons.sevenwonders.ui.redux + +import redux.RAction +import redux.Store +import redux.WrapperAction +import redux.createStore +import redux.rEnhancer + +data class SwState( + val playerName: String +) + +val INITIAL_STATE = SwState("Bob") + +fun configureStore(initialState: SwState = INITIAL_STATE): Store<SwState, RAction, WrapperAction> { + + // TODO configure middlewares + + return createStore(::rootReducer, initialState, rEnhancer()) +} |