make it possible to connect modules in project

This commit is contained in:
InsanusMokrassar 2022-03-17 23:23:35 +06:00
parent 31047f9382
commit 1dafe0a679
8 changed files with 78 additions and 41 deletions

View File

@ -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 }
) )
} }
} }

View File

@ -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
} }
} }
} }

View File

@ -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()
}
}
}
}

View File

@ -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"

View File

@ -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?>)
} }

View File

@ -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"

View File

@ -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
}
} }

View File

@ -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
} }