add class for js repo of states and start adding of posts list mvvm

This commit is contained in:
InsanusMokrassar 2022-03-26 10:19:11 +06:00
parent cb5de073fb
commit 90293d7ffc
7 changed files with 54 additions and 32 deletions

View File

@ -1,19 +1,16 @@
package dev.inmo.postssystem.client package dev.inmo.postssystem.client
import dev.inmo.postssystem.client.fsm.ui.*
import dev.inmo.postssystem.features.auth.common.AuthTokenInfo import dev.inmo.postssystem.features.auth.common.AuthTokenInfo
import dev.inmo.micro_utils.coroutines.ContextSafelyExceptionHandler import dev.inmo.micro_utils.coroutines.ContextSafelyExceptionHandler
import dev.inmo.micro_utils.fsm.common.CheckableHandlerHolder
import dev.inmo.micro_utils.fsm.common.StatesMachine
import dev.inmo.micro_utils.repos.mappers.withMapper import dev.inmo.micro_utils.repos.mappers.withMapper
import dev.inmo.micro_utils.serialization.typed_serializer.TypedSerializer import dev.inmo.micro_utils.serialization.typed_serializer.TypedSerializer
import dev.inmo.postssystem.features.auth.client.settings.AuthSettings
import dev.inmo.postssystem.features.auth.client.ui.* import dev.inmo.postssystem.features.auth.client.ui.*
import dev.inmo.postssystem.features.common.common.baseKoin import dev.inmo.postssystem.features.common.common.baseKoin
import dev.inmo.postssystem.features.common.common.getAllDistinct import dev.inmo.postssystem.features.common.common.getAllDistinct
import dev.inmo.postssystem.features.common.common.ui.fsm.UIFSMHandler import dev.inmo.postssystem.features.common.common.ui.fsm.UIFSMHandler
import dev.inmo.postssystem.features.common.common.ui.fsm.UIFSMStateSerializer import dev.inmo.postssystem.features.common.common.ui.fsm.UIFSMStateSerializer
import dev.inmo.postssystem.services.posts.client.ui.create.* import dev.inmo.postssystem.services.posts.client.ui.posts_list.PostsListUIFSMState
import dev.inmo.postssystem.services.posts.client.ui.posts_list.PostsListUIState
import kotlinx.browser.* import kotlinx.browser.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer
@ -21,11 +18,8 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.serializer import kotlinx.serialization.serializer
import org.koin.core.Koin import org.koin.core.Koin
import org.koin.core.context.loadKoinModules import org.koin.core.context.loadKoinModules
import org.koin.core.parameter.ParametersHolder
import org.koin.core.qualifier.Qualifier
import org.koin.dsl.module import org.koin.dsl.module
import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLElement
import kotlin.reflect.KClass
val defaultTypedSerializer = TypedSerializer<Any>( val defaultTypedSerializer = TypedSerializer<Any>(
"AuthTokenInfo" to AuthTokenInfo.serializer(), "AuthTokenInfo" to AuthTokenInfo.serializer(),
@ -81,7 +75,7 @@ fun baseKoin(): Koin {
) )
}, },
{ {
JSUIFSMStatesRepo(window.history) JSUIFSMStatesRepo(window.history, AuthUIFSMState(PostsListUIFSMState()), getAllDistinct())
} }
) { ) {
val scope = first val scope = first

View File

@ -3,18 +3,18 @@ package dev.inmo.postssystem.client
import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManagerRepo import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManagerRepo
import dev.inmo.postssystem.features.common.common.ui.fsm.UIFSMState import dev.inmo.postssystem.features.common.common.ui.fsm.UIFSMState
import kotlinx.browser.window import kotlinx.browser.window
import kotlinx.serialization.StringFormat
import org.w3c.dom.* import org.w3c.dom.*
import org.w3c.dom.url.URL import org.w3c.dom.url.URL
private fun History.refreshHistory( private fun History.refreshHistory(
states: Iterable<UIFSMState>, states: Iterable<UIFSMState>,
fillers: List<UIFSMStateSearchParamsHandler>
) { ) {
val currentUrl = window.location.pathname val currentUrl = window.location.pathname
val params = states.mapNotNull<UIFSMState, Pair<String, String>> { val currentParams = (URL(window.location.href)).searchParams
when (it) { val params = states.flatMap<UIFSMState, Pair<String, String>> { state ->
is AuthUIFSMState -> null fillers.flatMap {
is CreatePostUIFSMState -> null it.takeParams(state, currentParams)
} }
} }
pushState( pushState(
@ -24,9 +24,11 @@ private fun History.refreshHistory(
) )
} }
private fun takeStates(initialState: UIFSMState): List<UIFSMState> { private fun takeStates(initialState: UIFSMState, fillers: List<UIFSMStateSearchParamsHandler>): List<UIFSMState> {
val params = (URL(window.location.href)).searchParams val params = (URL(window.location.href)).searchParams
val additionalStates = listOfNotNull<UIFSMState>() val additionalStates = fillers.mapNotNull {
it.takeState(params)
}
return additionalStates + listOfNotNull( return additionalStates + listOfNotNull(
if (additionalStates.isEmpty()) { if (additionalStates.isEmpty()) {
@ -41,12 +43,13 @@ private fun takeStates(initialState: UIFSMState): List<UIFSMState> {
class JSUIFSMStatesRepo( class JSUIFSMStatesRepo(
private val history: History, private val history: History,
private val initialState: UIFSMState = DefaultAuthUIFSMState private val initialState: UIFSMState,
private val fillers: List<UIFSMStateSearchParamsHandler>
) : DefaultStatesManagerRepo<UIFSMState> { ) : DefaultStatesManagerRepo<UIFSMState> {
private val statesMap = mutableMapOf<String, UIFSMState>() private val statesMap = mutableMapOf<String, UIFSMState>()
init { init {
val states = takeStates(initialState) val states = takeStates(initialState, fillers)
states.forEach { states.forEach {
statesMap[it.context] = it statesMap[it.context] = it
} }
@ -68,12 +71,12 @@ class JSUIFSMStatesRepo(
override suspend fun removeState(state: UIFSMState) { override suspend fun removeState(state: UIFSMState) {
statesMap.remove((state.context as? String) ?: return) statesMap.remove((state.context as? String) ?: return)
history.refreshHistory(statesMap.values) history.refreshHistory(statesMap.values, fillers)
} }
override suspend fun set(state: UIFSMState) { override suspend fun set(state: UIFSMState) {
console.log(state) console.log(state)
statesMap[state.context] = state statesMap[state.context] = state
history.refreshHistory(statesMap.values) history.refreshHistory(statesMap.values, fillers)
} }
} }

View File

@ -0,0 +1,9 @@
package dev.inmo.postssystem.client
import dev.inmo.postssystem.features.common.common.ui.fsm.UIFSMState
import org.w3c.dom.url.URLSearchParams
interface UIFSMStateSearchParamsHandler {
fun takeParams(state: UIFSMState, currentParams: URLSearchParams): List<Pair<String, String>>
fun takeState(params: URLSearchParams): UIFSMState?
}

View File

@ -2,11 +2,10 @@ package dev.inmo.postssystem.services.posts.client
import dev.inmo.postssystem.features.auth.client.AuthorizedModuleLoader import dev.inmo.postssystem.features.auth.client.AuthorizedModuleLoader
import dev.inmo.postssystem.features.auth.client.AuthorizedQualifiers import dev.inmo.postssystem.features.auth.client.AuthorizedQualifiers
import dev.inmo.postssystem.features.common.common.DefaultQualifiers import dev.inmo.postssystem.features.common.common.ui.fsm.UIFSMStateSerializer
import dev.inmo.postssystem.features.common.common.getAllDistinct
import dev.inmo.postssystem.services.posts.client.ui.create.* import dev.inmo.postssystem.services.posts.client.ui.create.*
import dev.inmo.postssystem.services.posts.client.ui.posts_list.PostsListUIFSMState
import dev.inmo.postssystem.services.posts.common.* import dev.inmo.postssystem.services.posts.common.*
import org.koin.core.qualifier.Qualifier
import org.koin.dsl.binds import org.koin.dsl.binds
val loader = AuthorizedModuleLoader { val loader = AuthorizedModuleLoader {
@ -15,6 +14,9 @@ val loader = AuthorizedModuleLoader {
WritePostsService::class WritePostsService::class
) )
UIFSMStateSerializer.include("posts_create", PostsCreateUIFSMState.serializer())
UIFSMStateSerializer.include("posts_list", PostsListUIFSMState.serializer())
factory<PostCreateUIModel> { DefaultPostCreateUIModel(get(), get()) } factory<PostCreateUIModel> { DefaultPostCreateUIModel(get(), get()) }
factory { PostCreateUIViewModel(get()) } factory { PostCreateUIViewModel(get()) }
} }

View File

@ -0,0 +1,10 @@
package dev.inmo.postssystem.services.posts.client.ui.create
import dev.inmo.postssystem.features.common.common.ui.fsm.UIFSMState
import kotlinx.serialization.Serializable
@Serializable
data class PostsCreateUIFSMState(
override val from: UIFSMState? = null,
override val context: String = "main"
) : UIFSMState

View File

@ -0,0 +1,10 @@
package dev.inmo.postssystem.services.posts.client.ui.posts_list
import dev.inmo.postssystem.features.common.common.ui.fsm.UIFSMState
import kotlinx.serialization.Serializable
@Serializable
data class PostsListUIFSMState(
override val from: UIFSMState? = null,
override val context: String = "main"
) : UIFSMState

View File

@ -13,10 +13,10 @@ import dev.inmo.postssystem.features.common.common.ui.JSView
import dev.inmo.postssystem.features.common.common.ui.fsm.* import dev.inmo.postssystem.features.common.common.ui.fsm.*
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.services.posts.client.ui.create.PostsCreateUIFSMState
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.serialization.Serializable
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,21 +31,15 @@ val jsLoader = DefaultModuleLoader {
} }
} }
@Serializable
data class CreatePostUIFSMState(
override val from: UIFSMState? = null,
override val context: String = "main"
) : UIFSMState
class PostCreateView( class PostCreateView(
private val createPostCreateUIModel: PostCreateUIViewModel, private val createPostCreateUIModel: PostCreateUIViewModel,
private val contentClientProviders: List<ContentClientProvider>, private val contentClientProviders: List<ContentClientProvider>,
private val uiScope: CoroutineScope, private val uiScope: CoroutineScope,
defaultExceptionsHandlers: Iterable<UIFSMExceptionHandler> defaultExceptionsHandlers: Iterable<UIFSMExceptionHandler>
) : JSView<CreatePostUIFSMState>(defaultExceptionsHandlers) { ) : JSView<PostsCreateUIFSMState>(defaultExceptionsHandlers) {
override suspend fun StatesMachine<in UIFSMState>.safeHandleState( override suspend fun StatesMachine<in UIFSMState>.safeHandleState(
htmlElement: HTMLElement, htmlElement: HTMLElement,
state: CreatePostUIFSMState state: PostsCreateUIFSMState
): UIFSMState? { ): UIFSMState? {
val result = CompletableDeferred<UIFSMState?>() val result = CompletableDeferred<UIFSMState?>()