temporal unworkable progress

This commit is contained in:
2022-03-13 21:58:10 +06:00
parent b7bdc6cc75
commit ab10f20723
37 changed files with 313 additions and 53 deletions
client
build.gradle
src
commonMain
kotlin
dev
inmo
postssystem
client
jsMain
kotlin
dev
inmo
postssystem
features
common
client
build.gradle
src
commonMain
kotlin
dev
inmo
postssystem
common
src
commonMain
kotlin
dev
inmo
postssystem
features
content
client
src
jsMain
kotlin
dev
inmo
postssystem
features
text
client
build.gradle
src
jsMain
kotlin
dev
inmo
postssystem
features
gradle.properties
gradle
server/src/main/resources/web
services/posts
client
src
commonMain
kotlin
dev
inmo
postssystem
server
src
jvmMain
kotlin
dev
inmo
postssystem
settings.gradle
targets/telegram
content
polls
client
build.gradle
src
commonMain
kotlin
dev
inmo
postssystem
targets
telegram
content
polls
client
main
common
build.gradle
src
commonMain
kotlin
dev
inmo
postssystem
targets
telegram
content
polls
main
server
build.gradle
src
jvmMain
kotlin
dev
inmo
postssystem
targets
telegram
content
polls
server
loader
client
build.gradle
src
commonMain
kotlin
dev
inmo
postssystem
targets
telegram
server
build.gradle
src
jvmMain
kotlin
dev
inmo
postssystem
targets
telegram
template
client
build.gradle
src
commonMain
kotlin
dev
inmo
postssystem
targets
telegram
template
client
main
common
build.gradle
src
commonMain
kotlin
dev
inmo
postssystem
targets
telegram
template
common
main
server
build.gradle
src
jvmMain
kotlin
dev
inmo
postssystem
targets
telegram
template
server

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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