core/client/src/jsMain/kotlin/dev/inmo/postssystem/client/fsm/ui/PostCreateView.kt

95 lines
3.9 KiB
Kotlin

package dev.inmo.postssystem.client.fsm.ui
import androidx.compose.runtime.*
import dev.inmo.jsuikit.elements.*
import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.utils.Attrs
import dev.inmo.micro_utils.common.compose.DefaultDisposableEffectResult
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.micro_utils.fsm.common.StatesMachine
import dev.inmo.postssystem.client.ui.fsm.CreatePostUIFSMState
import dev.inmo.postssystem.client.ui.fsm.UIFSMState
import dev.inmo.postssystem.client.utils.renderComposableAndLinkToContext
import dev.inmo.postssystem.features.content.client.ContentClientProvider
import dev.inmo.postssystem.features.content.common.Content
import dev.inmo.postssystem.services.posts.client.ui.create.PostCreateUIViewModel
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.StateFlow
import org.jetbrains.compose.web.dom.Div
import org.jetbrains.compose.web.dom.Text
import org.w3c.dom.HTMLElement
class PostCreateView(
private val createPostCreateUIModel: PostCreateUIViewModel,
private val contentClientProviders: List<ContentClientProvider>,
private val uiScope: CoroutineScope
) : JSView<CreatePostUIFSMState>() {
override suspend fun StatesMachine<in UIFSMState>.safeHandleState(
htmlElement: HTMLElement,
state: CreatePostUIFSMState
): UIFSMState? {
val result = CompletableDeferred<UIFSMState?>()
val contentProvidersList = mutableStateListOf<ContentClientProvider>()
val statesList = mutableListOf<StateFlow<Content>>()
renderComposableAndLinkToContext(htmlElement) {
Flex(
UIKitFlex.Alignment.Horizontal.Center
) {
Div ({ include(UIKitWidth.Fixed.XLarge) }) {
contentProvidersList.forEachIndexed { i, renderer ->
Flex(UIKitWidth.Expand) {
Div(
{
ref {
val flow = renderer.drawNewContent(it)
statesList.add(i, flow)
DefaultDisposableEffectResult {
statesList.removeAt(i)
}
}
}
)
DefaultButton("Remove") {
contentProvidersList.removeAt(i)
}
}
}
Label("Add content", Attrs.empty())
Dropdown {
DefaultNav {
contentClientProviders.forEach {
NavItemElement(
attributesCustomizer = {
onClick { _ ->
contentProvidersList.add(it)
}
}
) {
Text(it.contentTypeNameForUser())
}
}
}
}
DefaultButton(
"Upload",
disabled = contentProvidersList.isEmpty()
) {
it.preventDefault()
uiScope.launchSafelyWithoutExceptions {
createPostCreateUIModel.create(
statesList.map { it.value }
)
}
}
}
}
}
return result.await()
}
}