diff --git a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/BlockComponent.kt b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/BlockComponent.kt index fd3ef97a..1badb243 100644 --- a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/BlockComponent.kt +++ b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/BlockComponent.kt @@ -21,6 +21,7 @@ import dev.d1s.beam.commons.MetadataKeys import dev.d1s.beam.ui.contententity.renderEntities import dev.d1s.beam.ui.util.Size.sizeOf import dev.d1s.exkt.kvision.component.Component +import dev.d1s.exkt.kvision.component.Effect import io.kvision.html.div import io.kvision.panel.SimplePanel import io.kvision.utils.minus @@ -30,7 +31,7 @@ import org.koin.core.component.KoinComponent class BlockComponent : Component(::Config), KoinComponent { - override fun SimplePanel.render() { + override fun SimplePanel.render(): Effect { val block = requireNotNull(config.block.value) { "Block isn't set" } @@ -56,6 +57,8 @@ class BlockComponent : Component(::Config), KoinComponent renderEntities(block.entities) } } + + return Effect.Success } private fun SimplePanel.setOptionalBlockId(block: Block) { diff --git a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/BlockContainerComponent.kt b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/BlockContainerComponent.kt index 2d689a8e..2609d3a0 100644 --- a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/BlockContainerComponent.kt +++ b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/BlockContainerComponent.kt @@ -22,6 +22,7 @@ import dev.d1s.beam.ui.Qualifier import dev.d1s.beam.ui.state.Observable import dev.d1s.beam.ui.util.Size import dev.d1s.exkt.kvision.component.Component +import dev.d1s.exkt.kvision.component.Effect import dev.d1s.exkt.kvision.component.render import io.kvision.core.JustifyContent import io.kvision.html.div @@ -38,12 +39,14 @@ class BlockContainerComponent : Component(), KoinComponent { private val currentSpaceContentChangeObservable by inject>(Qualifier.CurrentSpaceContentChangeObservable) - override fun SimplePanel.render() { + override fun SimplePanel.render(): Effect { div(className = "mb-5").bind(currentSpaceContentChangeObservable.state) { change -> change?.let { blocks -> renderBlocks(blocks) } } + + return Effect.Success } private fun SimplePanel.renderBlocks(blocks: Blocks) { diff --git a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/DaemonStatusComponent.kt b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/DaemonStatusComponent.kt index f0d9e583..eb094648 100644 --- a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/DaemonStatusComponent.kt +++ b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/DaemonStatusComponent.kt @@ -24,6 +24,7 @@ import dev.d1s.beam.ui.theme.currentTheme import dev.d1s.beam.ui.util.Texts import dev.d1s.beam.ui.util.iconWithMargin import dev.d1s.exkt.kvision.component.Component +import dev.d1s.exkt.kvision.component.Effect import io.kvision.core.Color import io.kvision.html.div import io.kvision.html.span @@ -43,7 +44,7 @@ class DaemonStatusComponent : Component(), KoinComponent { private val renderingScope = CoroutineScope(Dispatchers.Main) - override fun SimplePanel.render() { + override fun SimplePanel.render(): Effect { div().bind( daemonStatusWithPingObservable.state, runImmediately = false @@ -58,6 +59,8 @@ class DaemonStatusComponent : Component(), KoinComponent { } } } + + return Effect.Success } private fun SimplePanel.reportConnectedState(status: DaemonStatusWithPing) { diff --git a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/DisconnectedDaemonStatusBlankslateComponent.kt b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/DisconnectedDaemonStatusBlankslateComponent.kt index e45cb707..694a3526 100644 --- a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/DisconnectedDaemonStatusBlankslateComponent.kt +++ b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/DisconnectedDaemonStatusBlankslateComponent.kt @@ -19,6 +19,7 @@ package dev.d1s.beam.ui.component import dev.d1s.beam.ui.theme.setSecondaryText import dev.d1s.beam.ui.util.Texts import dev.d1s.exkt.kvision.component.Component +import dev.d1s.exkt.kvision.component.Effect import io.kvision.core.AlignItems import io.kvision.html.div import io.kvision.html.p @@ -29,7 +30,7 @@ import org.koin.core.component.KoinComponent class DisconnectedDaemonStatusBlankslateComponent : Component(), KoinComponent { - override fun SimplePanel.render() { + override fun SimplePanel.render(): Effect { div(className = "container-fluid d-flex justify-content-center") { marginTop = 20.vh @@ -42,6 +43,8 @@ class DisconnectedDaemonStatusBlankslateComponent : Component(), KoinCompo visible = true } + + return Effect.Success } private fun SimplePanel.h2(text: String) { diff --git a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/ExploreDropdownComponent.kt b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/ExploreDropdownComponent.kt index d14cf964..eedc9588 100644 --- a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/ExploreDropdownComponent.kt +++ b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/ExploreDropdownComponent.kt @@ -18,52 +18,75 @@ package dev.d1s.beam.ui.component import dev.d1s.beam.commons.BlockSize import dev.d1s.beam.ui.Qualifier +import dev.d1s.beam.ui.client.DaemonStatusWithPing +import dev.d1s.beam.ui.state.Observable import dev.d1s.beam.ui.state.bindToMaxBlockSize import dev.d1s.beam.ui.theme.setOutline import dev.d1s.beam.ui.theme.setOverlay import dev.d1s.beam.ui.util.Size.sizeOf import dev.d1s.beam.ui.util.Texts import dev.d1s.exkt.kvision.component.Component +import dev.d1s.exkt.kvision.component.Effect +import dev.d1s.exkt.kvision.component.LazyEffect import dev.d1s.exkt.kvision.component.render import io.kvision.html.ButtonStyle import io.kvision.html.button import io.kvision.html.div import io.kvision.panel.SimplePanel +import io.kvision.state.bind import io.kvision.utils.px import org.koin.core.component.KoinComponent import org.koin.core.component.inject class ExploreDropdownComponent : Component(), KoinComponent { + private val daemonStatusObservable by inject>(Qualifier.DaemonStatusObservable) + private val spaceListingComponent by inject>(Qualifier.SpaceListingComponent) - override fun SimplePanel.render() { - div(className = "d-flex") { - div(className = "dropdown") { - button( - Texts.Heading.ExploreDropdown.CALLOUT, - style = ButtonStyle.OUTLINELIGHT, - className = "btn-sm dropdown-toggle" - ) { - setAttribute("data-bs-toggle", "dropdown") - setAttribute("data-bs-auto-close", "outside") - setAttribute("aria-expanded", "false") - } + override fun SimplePanel.render(): Effect { + div().bind(daemonStatusObservable.state, runImmediately = false) { status -> + if (status != null) { + renderDropdown() + } + } + + return Effect.Success + } - div(className = "dropdown-menu p-3") { - bindToMaxBlockSize { size -> - val sizes = BlockSize.entries - val previousSize = sizes.getOrNull(sizes.indexOf(size) - 1) + private fun SimplePanel.renderDropdown() { + div(className = "dropdown") dropdown@{ + visible = false - previousSize?.let { - width = sizeOf(it).px - } + button( + Texts.Heading.ExploreDropdown.CALLOUT, + style = ButtonStyle.OUTLINELIGHT, + className = "btn-sm dropdown-toggle" + ) { + setAttribute("data-bs-toggle", "dropdown") + setAttribute("data-bs-auto-close", "outside") + setAttribute("data-bs-offset", "0,20") + setAttribute("aria-expanded", "false") + } + + div(className = "dropdown-menu p-3") { + bindToMaxBlockSize { size -> + val sizes = BlockSize.entries + val previousSize = sizes.getOrNull(sizes.indexOf(size) - 1) + + previousSize?.let { + width = sizeOf(it).px } + } + + setOutline() + setOverlay() - setOutline() - setOverlay() + val effect = render(spaceListingComponent) - render(spaceListingComponent) + (effect as? LazyEffect)?.state?.subscribe { success -> + println("aboba: exploreDropdown: received state: $success") + this@dropdown.visible = success } } } diff --git a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/FooterComponent.kt b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/FooterComponent.kt index 52c32a5c..c8ca087e 100644 --- a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/FooterComponent.kt +++ b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/FooterComponent.kt @@ -20,6 +20,7 @@ import dev.d1s.beam.ui.theme.setSecondaryBlue import dev.d1s.beam.ui.theme.setSecondaryText import dev.d1s.beam.ui.util.Texts import dev.d1s.exkt.kvision.component.Component +import dev.d1s.exkt.kvision.component.Effect import io.kvision.html.div import io.kvision.html.link import io.kvision.html.span @@ -29,7 +30,7 @@ import org.koin.core.component.KoinComponent class FooterComponent : Component(), KoinComponent { - override fun SimplePanel.render() { + override fun SimplePanel.render(): Effect { div(className = "container-fluid pt-5 pb-2 mt-auto d-flex flex-column align-items-start") { fontSize = 0.85.rem @@ -51,6 +52,8 @@ class FooterComponent : Component(), KoinComponent { } } } + + return Effect.Success } private fun SimplePanel.nbsp() = diff --git a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/HeadingComponent.kt b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/HeadingComponent.kt index b8e4be97..4d943c08 100644 --- a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/HeadingComponent.kt +++ b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/HeadingComponent.kt @@ -21,6 +21,7 @@ import dev.d1s.beam.ui.Qualifier import dev.d1s.beam.ui.state.CurrentSpaceChange import dev.d1s.beam.ui.state.Observable import dev.d1s.exkt.kvision.component.Component +import dev.d1s.exkt.kvision.component.Effect import dev.d1s.exkt.kvision.component.render import io.kvision.html.div import io.kvision.panel.SimplePanel @@ -38,11 +39,13 @@ class HeadingComponent : Component(), KoinComponent { private val daemonStatusComponent by inject>(Qualifier.DaemonStatusComponent) - override fun SimplePanel.render() { + override fun SimplePanel.render(): Effect { div(className = "container-fluid mt-3 mb-4 my-5 d-flex flex-column flex-lg-row justify-content-lg-between") { renderSpaceHeading() renderDaemonStatus() } + + return Effect.Success } private fun SimplePanel.renderSpaceHeading() { diff --git a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/RootComponent.kt b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/RootComponent.kt index bee28b08..3ecfdc30 100644 --- a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/RootComponent.kt +++ b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/RootComponent.kt @@ -22,6 +22,7 @@ import dev.d1s.beam.ui.state.Observable import dev.d1s.beam.ui.theme.setBackground import dev.d1s.beam.ui.theme.setTextColor import dev.d1s.exkt.kvision.component.Component +import dev.d1s.exkt.kvision.component.Effect import dev.d1s.exkt.kvision.component.render import io.kvision.panel.SimplePanel import io.kvision.utils.vh @@ -41,13 +42,15 @@ class RootComponent : Component.Root(), KoinComponent { private val footerComponent by inject>(Qualifier.FooterComponent) - override fun SimplePanel.render() { + override fun SimplePanel.render(): Effect { title() sizing() display() font() background() components() + + return Effect.Success } private fun title() { diff --git a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceCardComponent.kt b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceCardComponent.kt index ec5781f2..d13eed09 100644 --- a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceCardComponent.kt +++ b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceCardComponent.kt @@ -25,6 +25,7 @@ import dev.d1s.beam.ui.theme.setSecondaryText import dev.d1s.beam.ui.util.Texts import dev.d1s.beam.ui.util.currentSpaceLink import dev.d1s.exkt.kvision.component.Component +import dev.d1s.exkt.kvision.component.Effect import io.kvision.core.JustifyContent import io.kvision.html.div import io.kvision.html.image @@ -43,7 +44,7 @@ class SpaceCardComponent : Component(::Config), KoinC private val currentSpaceChangeObservable by inject>(Qualifier.CurrentSpaceChangeObservable) - override fun SimplePanel.render() { + override fun SimplePanel.render(): Effect { if (config.bare.value) { renderCardContent() } else { @@ -54,6 +55,8 @@ class SpaceCardComponent : Component(::Config), KoinC renderCardContent() } } + + return Effect.Success } // Господи. Мне страшно. Я боюсь за все. diff --git a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceContentComponent.kt b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceContentComponent.kt index bc979a78..4dc6283e 100644 --- a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceContentComponent.kt +++ b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceContentComponent.kt @@ -23,6 +23,7 @@ import dev.d1s.beam.ui.client.DaemonStatusWithPing import dev.d1s.beam.ui.state.CurrentSpaceChange import dev.d1s.beam.ui.state.Observable import dev.d1s.exkt.kvision.component.Component +import dev.d1s.exkt.kvision.component.Effect import dev.d1s.exkt.kvision.component.render import io.kvision.html.div import io.kvision.panel.SimplePanel @@ -49,7 +50,7 @@ class SpaceContentComponent : Component(), KoinComponent { private val showBlockContainer = ObservableValue(true) - override fun SimplePanel.render() { + override fun SimplePanel.render(): Effect { div(className = "container-fluid mt-4") { bind(daemonStatusObservable.state, runImmediately = false) { status -> div().bind(maxBlockSizeChangeObservable.state) { @@ -63,6 +64,8 @@ class SpaceContentComponent : Component(), KoinComponent { } } } + + return Effect.Success } private fun SimplePanel.handleNotFound() { diff --git a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceFailureCardComponent.kt b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceFailureCardComponent.kt index b5d5a840..7cec3f81 100644 --- a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceFailureCardComponent.kt +++ b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceFailureCardComponent.kt @@ -19,6 +19,7 @@ package dev.d1s.beam.ui.component import dev.d1s.beam.ui.Qualifier import dev.d1s.beam.ui.util.Size import dev.d1s.exkt.kvision.component.Component +import dev.d1s.exkt.kvision.component.Effect import dev.d1s.exkt.kvision.component.render import io.kvision.html.div import io.kvision.panel.SimplePanel @@ -44,7 +45,7 @@ class SpaceFailureCardComponent : Component(:: } ?: error("$mode is unsupported") } - override fun SimplePanel.render() { + override fun SimplePanel.render(): Effect { div(className = "container d-flex justify-content-center") { maxWidth = Size.Lg.px @@ -54,6 +55,8 @@ class SpaceFailureCardComponent : Component(:: spaceListing() } } + + return Effect.Success } private fun SimplePanel.image() { diff --git a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceListingComponent.kt b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceListingComponent.kt index b5a28b96..eccae173 100644 --- a/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceListingComponent.kt +++ b/beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/component/SpaceListingComponent.kt @@ -28,6 +28,7 @@ import dev.d1s.beam.ui.util.Texts import dev.d1s.beam.ui.util.currentSpace import dev.d1s.exkt.common.pagination.Paginator import dev.d1s.exkt.kvision.component.Component +import dev.d1s.exkt.kvision.component.Effect import dev.d1s.exkt.kvision.component.render import io.kvision.html.ButtonStyle import io.kvision.html.button @@ -63,9 +64,11 @@ class SpaceListingComponent : Component(), KoinComponent { private val runImmediately = atomic(false) - override fun SimplePanel.render() { + override fun SimplePanel.render(): Effect { fetchAllSpaces() + val (state, effect) = Effect.lazy() + div().bind(spaces, runImmediately = runImmediately.getAndSet(true)) { (fetchedSpaces, totalCount) -> if (fetchedSpaces.isNotEmpty()) { p(Texts.SpaceListing.CALLOUT, className = "fs-bold") { @@ -81,8 +84,16 @@ class SpaceListingComponent : Component(), KoinComponent { if (totalCount !in (paginator.offset + 1)..paginator.limit) { fetchMoreButton() } + + state.value = true + } else { + println("aboba: spaceListing: setting false state") + + state.value = false } } + + return effect } private fun SimplePanel.renderRow(spaces: List) { diff --git a/gradle.properties b/gradle.properties index 105dcf75..93fb7d13 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ koinVersion=3.4.1 versionsPluginVersion=0.47.0 -exktVersion=1.4.0-dev-f3ea4d8 +exktVersion=1.4.0-dev-3260ef9 kotlinxCoroutinesVersion=1.7.2