make it possible to connect modules in project

This commit is contained in:
2022-03-17 23:23:35 +06:00
parent 31047f9382
commit 1dafe0a679
8 changed files with 78 additions and 41 deletions
client/src/jsMain/kotlin/dev/inmo/postssystem/client/fsm/ui
features/content
binary
client
build.gradle
src
jsMain
kotlin
dev
inmo
postssystem
features
client
build.gradle
src
jsMain
kotlin
dev
inmo
postssystem
features
text
client
build.gradle
src
jsMain
kotlin
dev
inmo
postssystem
features
server

@ -4,7 +4,6 @@ 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
@ -15,7 +14,6 @@ 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
@ -31,27 +29,16 @@ class PostCreateView(
): UIFSMState? {
val result = CompletableDeferred<UIFSMState?>()
val contentProvidersList = mutableStateListOf<ContentClientProvider>()
val statesList = mutableListOf<StateFlow<Content>>()
val contentProvidersList = mutableStateListOf<Pair<ContentClientProvider, MutableState<Content?>>>()
renderComposableAndLinkToContext(htmlElement) {
Flex(
UIKitFlex.Alignment.Horizontal.Center
) {
Div ({ include(UIKitWidth.Fixed.XLarge) }) {
contentProvidersList.forEachIndexed { i, renderer ->
contentProvidersList.forEachIndexed { i, (provider, state) ->
Flex(UIKitWidth.Expand) {
Div(
{
ref {
val flow = renderer.drawNewContent(it)
statesList.add(i, flow)
DefaultDisposableEffectResult {
statesList.removeAt(i)
}
}
}
)
provider.renderNewInstance(state)
DefaultButton("Remove") {
contentProvidersList.removeAt(i)
@ -65,7 +52,8 @@ class PostCreateView(
NavItemElement(
attributesCustomizer = {
onClick { _ ->
contentProvidersList.add(it)
val newContentState = mutableStateOf<Content?>(null)
contentProvidersList.add(it to newContentState)
}
}
) {
@ -81,7 +69,7 @@ class PostCreateView(
it.preventDefault()
uiScope.launchSafelyWithoutExceptions {
createPostCreateUIModel.create(
statesList.map { it.value }
contentProvidersList.mapNotNull { it.second.value }
)
}
}

@ -2,6 +2,7 @@ plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library"
alias(libs.plugins.compose)
}
apply from: "$mppProjectWithSerializationPresetPath"
@ -12,6 +13,8 @@ kotlin {
dependencies {
api project(":postssystem.features.content.binary.common")
api project(":postssystem.features.common.client")
api project(":postssystem.features.content.client")
api libs.microutils.common.compose
}
}
}

@ -0,0 +1,44 @@
package dev.inmo.postssystem.features.content.binary.client
import androidx.compose.runtime.*
import dev.inmo.jsuikit.elements.DefaultButton
import dev.inmo.jsuikit.modifiers.UIKitWidth
import dev.inmo.micro_utils.common.selectFile
import dev.inmo.postssystem.features.common.common.*
import dev.inmo.postssystem.features.content.client.ContentClientProvider
import dev.inmo.postssystem.features.content.common.*
import org.koin.core.module.Module
object LoadingClientModule : ModuleLoader {
init {
AdditionalModules.addModule(this)
}
override fun Module.load() {
singleWithRandomQualifier<ContentClientProvider> {
BinaryContentClientProvider
}
}
}
private val loadingClientModuleForLoadingAtRuntime = LoadingClientModule
object BinaryContentClientProvider : ContentClientProvider {
override fun contentTypeNameForUser(): String = "File"
@Composable
override fun renderNewInstance(state: MutableState<Content?>) {
console.log(state.value)
val value = (state.value as? BinaryContent)
if (value == null) {
selectFile {
state.value = it.binaryContent()
}
}
DefaultButton(value ?.filename ?.name ?: "Select file", UIKitWidth.Expand) {
selectFile {
state.value = it.binaryContent()
}
}
}
}

@ -2,6 +2,7 @@ plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library"
alias(libs.plugins.compose)
}
apply from: "$mppProjectWithSerializationPresetPath"

@ -1,5 +1,6 @@
package dev.inmo.postssystem.features.content.client
import androidx.compose.runtime.*
import dev.inmo.postssystem.features.content.common.Content
import kotlinx.coroutines.flow.StateFlow
import org.w3c.dom.HTMLElement
@ -7,5 +8,6 @@ import org.w3c.dom.HTMLElement
interface ContentClientProvider {
fun contentTypeNameForUser(): String
fun drawNewContent(root: HTMLElement): StateFlow<Content>
@Composable
fun renderNewInstance(state: MutableState<Content?>)
}

@ -2,6 +2,7 @@ plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library"
alias(libs.plugins.compose)
}
apply from: "$mppProjectWithSerializationPresetPath"

@ -3,39 +3,37 @@ package dev.inmo.postssystem.features.content.text.client
import androidx.compose.runtime.*
import dev.inmo.jsuikit.modifiers.UIKitWidth
import dev.inmo.jsuikit.modifiers.include
import dev.inmo.micro_utils.common.compose.renderComposableAndLinkToRoot
import dev.inmo.postssystem.features.common.common.*
import dev.inmo.postssystem.features.content.client.ContentClientProvider
import dev.inmo.postssystem.features.content.common.Content
import dev.inmo.postssystem.features.content.text.common.TextContent
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import org.jetbrains.compose.web.dom.TextArea
import org.jetbrains.compose.web.renderComposable
import org.w3c.dom.HTMLElement
import org.koin.core.module.Module
val loadingClientModule = ModuleLoader {
singleWithRandomQualifier<ContentClientProvider> {
TextContentClientProvider
object LoadingClientModule : ModuleLoader {
init {
AdditionalModules.addModule(this)
}
override fun Module.load() {
singleWithRandomQualifier<ContentClientProvider> {
TextContentClientProvider
}
}
}.also {
AdditionalModules.addModule(it)
}
private val loadingClientModuleForLoadingAtRuntime = LoadingClientModule
object TextContentClientProvider : ContentClientProvider {
override fun contentTypeNameForUser(): String = "Text"
override fun drawNewContent(root: HTMLElement): StateFlow<Content> {
val flow = MutableStateFlow(TextContent(""))
renderComposableAndLinkToRoot(root) {
val state = remember { flow.collectAsState() }
TextArea(state.value.text) {
include(UIKitWidth.Expand)
onInput { flow.value = TextContent(it.value) }
}
@Composable
override fun renderNewInstance(state: MutableState<Content?>) {
console.log(state.value)
val value = state.value as? TextContent
TextArea(value ?.text) {
include(UIKitWidth.Expand)
onInput { state.value = TextContent(it.value) }
}
return flow
}
}

@ -42,7 +42,7 @@ task copyClient(type: Copy) {
File clientSources = project(":postssystem.client").file("build/distributions")
SourceDirectorySet resources = sourceSets.main.resources
File webFolderPath = new File(resources.getSrcDirs()[0].toString(), "web")
exclude("*.map")
// exclude("*.map")
from clientSources.absolutePath
into webFolderPath.absolutePath
}