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.elements.*
import dev.inmo.jsuikit.modifiers.* import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.utils.Attrs 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.coroutines.launchSafelyWithoutExceptions
import dev.inmo.micro_utils.fsm.common.StatesMachine import dev.inmo.micro_utils.fsm.common.StatesMachine
import dev.inmo.postssystem.client.ui.fsm.CreatePostUIFSMState 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 dev.inmo.postssystem.services.posts.client.ui.create.PostCreateUIViewModel
import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.StateFlow
import org.jetbrains.compose.web.dom.Div import org.jetbrains.compose.web.dom.Div
import org.jetbrains.compose.web.dom.Text import org.jetbrains.compose.web.dom.Text
import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLElement
@ -31,27 +29,16 @@ class PostCreateView(
): UIFSMState? { ): UIFSMState? {
val result = CompletableDeferred<UIFSMState?>() val result = CompletableDeferred<UIFSMState?>()
val contentProvidersList = mutableStateListOf<ContentClientProvider>() val contentProvidersList = mutableStateListOf<Pair<ContentClientProvider, MutableState<Content?>>>()
val statesList = mutableListOf<StateFlow<Content>>()
renderComposableAndLinkToContext(htmlElement) { renderComposableAndLinkToContext(htmlElement) {
Flex( Flex(
UIKitFlex.Alignment.Horizontal.Center UIKitFlex.Alignment.Horizontal.Center
) { ) {
Div ({ include(UIKitWidth.Fixed.XLarge) }) { Div ({ include(UIKitWidth.Fixed.XLarge) }) {
contentProvidersList.forEachIndexed { i, renderer -> contentProvidersList.forEachIndexed { i, (provider, state) ->
Flex(UIKitWidth.Expand) { Flex(UIKitWidth.Expand) {
Div( provider.renderNewInstance(state)
{
ref {
val flow = renderer.drawNewContent(it)
statesList.add(i, flow)
DefaultDisposableEffectResult {
statesList.removeAt(i)
}
}
}
)
DefaultButton("Remove") { DefaultButton("Remove") {
contentProvidersList.removeAt(i) contentProvidersList.removeAt(i)
@ -65,7 +52,8 @@ class PostCreateView(
NavItemElement( NavItemElement(
attributesCustomizer = { attributesCustomizer = {
onClick { _ -> onClick { _ ->
contentProvidersList.add(it) val newContentState = mutableStateOf<Content?>(null)
contentProvidersList.add(it to newContentState)
} }
} }
) { ) {
@ -81,7 +69,7 @@ class PostCreateView(
it.preventDefault() it.preventDefault()
uiScope.launchSafelyWithoutExceptions { uiScope.launchSafelyWithoutExceptions {
createPostCreateUIModel.create( 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.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.library"
alias(libs.plugins.compose)
} }
apply from: "$mppProjectWithSerializationPresetPath" apply from: "$mppProjectWithSerializationPresetPath"
@ -12,6 +13,8 @@ kotlin {
dependencies { dependencies {
api project(":postssystem.features.content.binary.common") api project(":postssystem.features.content.binary.common")
api project(":postssystem.features.common.client") 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.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.library"
alias(libs.plugins.compose)
} }
apply from: "$mppProjectWithSerializationPresetPath" apply from: "$mppProjectWithSerializationPresetPath"

@ -1,5 +1,6 @@
package dev.inmo.postssystem.features.content.client package dev.inmo.postssystem.features.content.client
import androidx.compose.runtime.*
import dev.inmo.postssystem.features.content.common.Content import dev.inmo.postssystem.features.content.common.Content
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLElement
@ -7,5 +8,6 @@ import org.w3c.dom.HTMLElement
interface ContentClientProvider { interface ContentClientProvider {
fun contentTypeNameForUser(): String 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.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.library"
alias(libs.plugins.compose)
} }
apply from: "$mppProjectWithSerializationPresetPath" apply from: "$mppProjectWithSerializationPresetPath"

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

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