temporal unworkable progress

This commit is contained in:
InsanusMokrassar 2022-03-13 21:58:10 +06:00
parent b7bdc6cc75
commit ab10f20723
37 changed files with 313 additions and 53 deletions

View File

@ -10,6 +10,12 @@ apply from: "$mppProjectWithSerializationPresetPath"
kotlin {
js(IR) {
binaries.executable()
compileKotlinJs {
kotlinOptions {
freeCompilerArgs += "-Xir-property-lazy-initialization"
}
}
}
sourceSets {
commonMain {

View File

@ -23,8 +23,7 @@ import dev.inmo.postssystem.client.settings.DefaultSettings
import dev.inmo.postssystem.client.settings.Settings
import dev.inmo.postssystem.client.settings.auth.AuthSettings
import dev.inmo.postssystem.client.settings.auth.DefaultAuthSettings
import dev.inmo.postssystem.features.common.common.SerializersModuleConfigurator
import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier
import dev.inmo.postssystem.features.common.common.*
import dev.inmo.postssystem.features.content.common.ContentSerializersModuleConfigurator
import dev.inmo.postssystem.features.content.common.OtherContentSerializerModuleConfigurator
import dev.inmo.postssystem.features.content.text.common.TextContentSerializerModuleConfigurator
@ -95,6 +94,10 @@ fun baseKoin(
)) } }
single<AuthSettings> { DefaultAuthSettings(get(SettingsQualifier), get(), koin, get()) }
single<Settings> { DefaultSettings(get()) }
AdditionalModules.modules.forEach {
it.apply { load() }
}
}
)
}.koin.apply {

View File

@ -13,6 +13,7 @@ import dev.inmo.micro_utils.fsm.common.StatesMachine
import dev.inmo.micro_utils.repos.mappers.withMapper
import dev.inmo.micro_utils.serialization.typed_serializer.TypedSerializer
import dev.inmo.postssystem.client.settings.auth.AuthSettings
import dev.inmo.postssystem.features.common.common.getAllDistinct
import dev.inmo.postssystem.services.posts.client.ui.create.*
import kotlinx.browser.*
import kotlinx.coroutines.*
@ -92,7 +93,7 @@ fun baseKoin(): Koin {
factory<PostCreateUIModel> { DefaultPostCreateUIModel(get(), get()) }
factory { PostCreateUIViewModel(get()) }
factory { PostCreateView(get(), get(UIScopeQualifier)) }
factory { PostCreateView(get(), getAllDistinct(), get(UIScopeQualifier)) }
}
)
strictlyOn<AuthUIFSMState>(get<AuthView>())

View File

@ -1,24 +1,25 @@
package dev.inmo.postssystem.client.fsm.ui
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.*
import dev.inmo.jsuikit.elements.*
import dev.inmo.jsuikit.modifiers.*
import dev.inmo.micro_utils.common.*
import dev.inmo.jsuikit.utils.Attrs
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.common.*
import dev.inmo.postssystem.features.content.text.common.TextContent
import dev.inmo.postssystem.features.content.client.ContentClientProvider
import dev.inmo.postssystem.services.posts.client.ui.create.PostCreateUIViewModel
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import org.jetbrains.compose.web.dom.*
import org.jetbrains.compose.web.dom.Div
import org.w3c.dom.HTMLElement
import org.w3c.dom.Text
class PostCreateView(
private val createPostCreateUIModel: PostCreateUIViewModel,
private val contentClientProviders: List<ContentClientProvider>,
private val uiScope: CoroutineScope
) : JSView<CreatePostUIFSMState>() {
override suspend fun StatesMachine<in UIFSMState>.safeHandleState(
@ -27,68 +28,46 @@ class PostCreateView(
): UIFSMState? {
val result = CompletableDeferred<UIFSMState?>()
val contentStatesList = mutableStateListOf<Content>()
val contentProvidersList = mutableStateListOf<ContentClientProvider.ContentRenderer>()
renderComposableAndLinkToContext(htmlElement) {
Flex(
UIKitFlex.Alignment.Horizontal.Center
) {
Div({ include(UIKitWidth.Fixed.XLarge) }) {
contentStatesList.forEachIndexed { i, it ->
Div ({ include(UIKitWidth.Fixed.XLarge) }) {
contentProvidersList.forEachIndexed { i, it ->
Flex(UIKitWidth.Expand) {
when (it) {
is TextContent -> {
TextArea(it.text) {
include(UIKitWidth.Expand)
onInput { contentStatesList[i] = TextContent(it.value) }
}
}
is BinaryContent -> {
DefaultButton(it.filename.name, UIKitWidth.Expand) {
selectFile {
contentStatesList[i] = it.binaryContent()
}
}
}
}
it.render()
DefaultButton("Remove") {
contentStatesList.removeAt(i)
contentProvidersList.removeAt(i)
}
}
}
DefaultButton("Add content")
Label("Add content", Attrs.empty())
Dropdown {
DefaultNav {
NavItemElement(
attributesCustomizer = {
onClick {
contentStatesList.add(TextContent(""))
}
}
) {
Text("Text")
}
NavItemElement(
attributesCustomizer = {
onClick {
selectFile {
contentStatesList.add(it.binaryContent())
contentClientProviders.forEach {
NavItemElement(
attributesCustomizer = {
onClick { _ ->
contentProvidersList.add(it.createNewContentRenderer())
}
}
) {
Text(it.contentTypeNameForUser())
}
) {
Text("File")
}
}
}
DefaultButton(
"Upload",
disabled = contentStatesList.isEmpty()
disabled = contentProvidersList.isEmpty()
) {
it.preventDefault()
uiScope.launchSafelyWithoutExceptions {
createPostCreateUIModel.create(
contentStatesList.toList()
contentProvidersList.mapNotNull { it.state.value }
)
}
}

View File

@ -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"
@ -14,6 +15,15 @@ kotlin {
api libs.microutils.repos.ktor.client
api "io.ktor:ktor-client-auth:$ktor_version"
api "io.ktor:ktor-client-logging:$ktor_version"
api compose.runtime
}
}
jsMain {
dependencies {
api compose.web.core
api libs.jsuikit
}
}
}

View File

@ -0,0 +1,11 @@
package dev.inmo.postssystem.features.common.common
object AdditionalModules {
private val additionalModules = mutableListOf<ModuleLoader>()
val modules: List<ModuleLoader>
get() = additionalModules.toList()
fun addModule(moduleLoader: ModuleLoader): Boolean {
return additionalModules.add(moduleLoader)
}
}

View File

@ -0,0 +1,7 @@
package dev.inmo.postssystem.features.common.common
import org.koin.core.module.Module
fun interface ModuleLoader {
fun Module.load()
}

View File

@ -34,6 +34,8 @@ expect class FileBasedInputProvider : SimpleInputProvider {
@Serializable(SimpleInputProviderSerializer::class)
class CustomInputProvider(private val provider: () -> Input) : SimpleInputProvider {
override val contentBytes: Long?
get() = null
override fun invoke(): Input = provider()
}

View File

@ -0,0 +1,40 @@
package dev.inmo.postssystem.features.content.client
import androidx.compose.runtime.*
import dev.inmo.postssystem.features.content.common.Content
interface ContentClientProvider {
fun contentTypeNameForUser(): String
interface ContentRenderer {
val state: State<Content?>
@Composable
fun render()
class Default<T : Content?>(
initValue: T,
private val onRender: @Composable (MutableState<T>) -> Unit
) : ContentRenderer {
private val mutableState = mutableStateOf(initValue)
override val state: State<Content?>
get() = mutableState
@Composable
override fun render() { onRender(mutableState) }
}
companion object {
fun <T: Content> default(onRender: @Composable (MutableState<T?>) -> Unit) = Default(
null,
onRender
)
fun <T: Content?> default(initValue: T, onRender: @Composable (MutableState<T>) -> Unit) = Default(
initValue,
onRender
)
}
}
fun createNewContentRenderer(): ContentRenderer
}

View File

@ -12,6 +12,7 @@ kotlin {
dependencies {
api project(":postssystem.features.content.text.common")
api project(":postssystem.features.common.client")
api project(":postssystem.features.content.client")
}
}
}

View File

@ -0,0 +1,32 @@
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.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 org.jetbrains.compose.web.dom.TextArea
import org.w3c.dom.Text
val loadingClientModule = ModuleLoader {
singleWithRandomQualifier<ContentClientProvider> {
TextContentClientProvider
}
}.also {
AdditionalModules.addModule(it)
}
object TextContentClientProvider : ContentClientProvider {
override fun contentTypeNameForUser(): String = "Text"
override fun createNewContentRenderer(): ContentClientProvider.ContentRenderer {
return ContentClientProvider.ContentRenderer.default(TextContent("")) { state ->
TextArea(state.value.text) {
include(UIKitWidth.Expand)
onInput { state.value = TextContent(it.value) }
}
}
}
}

View File

@ -15,7 +15,7 @@ kotlin_serialisation_core_version=1.3.2
koin_version=3.1.2
ktor_version=1.6.7
logback_version=1.2.10
uuid_version=0.3.1
uuid_version=0.4.0
# JS

View File

@ -2,12 +2,12 @@
kotlin = "1.6.10"
kotlin-serialization = "1.3.2"
jsuikit = "0.0.43"
compose = "1.1.0"
microutils = "0.9.12"
tgbotapi = "0.38.6"
jsuikit = "0.0.44"
compose = "1.1.1"
microutils = "0.9.13"
tgbotapi = "0.38.7"
ktor = "1.6.7"
klock = "2.6.1"
klock = "2.6.2"
exposed = "0.37.3"
psql = "42.3.0"

File diff suppressed because one or more lines are too long

View File

@ -9,6 +9,9 @@ import kotlinx.serialization.Serializable
internal data class TempFileIdentifierInputProvider(
private val tempFile: FileId
) : SimpleInputProvider {
override val contentBytes: Long?
get() = null
override fun invoke(): Input {
TODO("Not yet implemented")
}

View File

@ -9,6 +9,9 @@ import kotlinx.serialization.Serializable
internal data class TempFileIdentifierInputProvider(
val tempFile: FileId
) : SimpleInputProvider {
override val contentBytes: Long?
get() = null
override fun invoke(): Input {
TODO("Not yet implemented")
}

View File

@ -58,9 +58,15 @@ String[] includes = [
":publicators:simple:server",
":targets:telegram:publication:server",
":targets:telegram:loader:client",
":targets:telegram:loader:common",
":targets:telegram:loader:server",
":targets:telegram:content:polls:client",
":targets:telegram:content:polls:common",
":targets:telegram:content:polls:server",
":server",
":client",
":client:uikit",

View File

@ -0,0 +1,18 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library"
}
apply from: "$mppProjectWithSerializationPresetPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api project(":postssystem.targets.telegram.content.polls.common")
api project(":postssystem.features.common.client")
}
}
}
}

View File

@ -0,0 +1 @@
<manifest package="dev.inmo.postssystem.targets.telegram.content.polls.client"/>

View File

@ -0,0 +1,18 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library"
}
apply from: "$mppProjectWithSerializationPresetPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api project(":postssystem.features.common.common")
api project(":postssystem.features.content.common")
}
}
}
}

View File

@ -0,0 +1,16 @@
package dev.inmo.postssystem.targets.telegram.content.polls.common
import dev.inmo.postssystem.features.content.common.Content
import kotlinx.serialization.Serializable
@Serializable
data class PollContent(
val options: List<String>,
val answer: Int?
) : Content {
init {
require(answer == null || answer in options.indices) {
"Answer should be in indexes of options ($options), ($answer)"
}
}
}

View File

@ -0,0 +1 @@
<manifest package="dev.inmo.postssystem.targets.telegram.content.polls.common"/>

View File

@ -0,0 +1,17 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
}
apply from: "$mppJavaProjectPresetPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api project(":postssystem.targets.telegram.content.polls.common")
api project(":postssystem.features.common.server")
}
}
}
}

View File

@ -12,6 +12,7 @@ kotlin {
dependencies {
api project(":postssystem.targets.telegram.loader.common")
api project(":postssystem.features.common.client")
api project(":postssystem.targets.telegram.content.polls.client")
}
}
}

View File

@ -0,0 +1,22 @@
package dev.inmo.postssystem.targets.telegram.loader.client
import dev.inmo.postssystem.features.common.common.*
import dev.inmo.postssystem.features.content.common.ContentSerializersModuleConfigurator
import dev.inmo.postssystem.targets.telegram.content.polls.common.PollContent
import org.koin.core.module.Module
val defaultTelegramTargetModuleLoader = TelegramTargetModuleLoader
object TelegramTargetModuleLoader : ModuleLoader {
init {
AdditionalModules.addModule(this)
}
override fun Module.load() {
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> {
ContentSerializersModuleConfigurator.Element {
subclass(PollContent::class, PollContent.serializer())
}
}
}
}

View File

@ -11,6 +11,7 @@ kotlin {
dependencies {
api project(":postssystem.targets.telegram.loader.common")
api project(":postssystem.targets.telegram.publication.server")
api project(":postssystem.targets.telegram.content.polls.server")
api project(":postssystem.features.common.server")
}
}

View File

@ -2,7 +2,9 @@ package dev.inmo.postssystem.targets.telegram.loader.server
import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier
import dev.inmo.postssystem.features.common.server.sessions.ModuleLoader
import dev.inmo.postssystem.features.content.common.ContentSerializersModuleConfigurator
import dev.inmo.postssystem.features.publication.server.PublicationTarget
import dev.inmo.postssystem.targets.telegram.content.polls.common.PollContent
import dev.inmo.postssystem.targets.telegram.publication.server.PublicationTargetTelegram
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.types.ChatId
@ -28,6 +30,11 @@ class TelegramTargetModuleLoader : ModuleLoader {
singleWithRandomQualifier<PublicationTarget> {
PublicationTargetTelegram(get(), get(postingChatIdQualifier))
}
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> {
ContentSerializersModuleConfigurator.Element {
subclass(PollContent::class, PollContent.serializer())
}
}
}
}
}

View File

@ -0,0 +1,18 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library"
}
apply from: "$mppProjectWithSerializationPresetPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api project(":postssystem.targets.telegram.template.common")
api project(":postssystem.features.common.client")
}
}
}
}

View File

@ -0,0 +1 @@
<manifest package="dev.inmo.postssystem.targets.telegram.template.client"/>

View File

@ -0,0 +1,17 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library"
}
apply from: "$mppProjectWithSerializationPresetPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api project(":postssystem.features.common.common")
}
}
}
}

View File

@ -0,0 +1 @@
<manifest package="dev.inmo.postssystem.targets.telegram.template.common"/>

View File

@ -0,0 +1,17 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
}
apply from: "$mppJavaProjectPresetPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api project(":postssystem.targets.telegram.template.common")
api project(":postssystem.features.common.server")
}
}
}
}