2021-11-24 07:52:27 +00:00
|
|
|
package dev.inmo.postssystem.client.fsm.ui
|
|
|
|
|
2022-01-22 14:19:50 +00:00
|
|
|
import androidx.compose.runtime.mutableStateOf
|
|
|
|
import androidx.compose.runtime.remember
|
|
|
|
import dev.inmo.jsuikit.elements.*
|
2022-01-25 09:21:01 +00:00
|
|
|
import dev.inmo.jsuikit.modifiers.*
|
|
|
|
import dev.inmo.jsuikit.utils.Attrs
|
2021-11-24 07:52:27 +00:00
|
|
|
import dev.inmo.postssystem.client.ui.fsm.*
|
|
|
|
import dev.inmo.postssystem.features.auth.client.ui.*
|
|
|
|
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
|
|
|
|
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
|
|
|
import dev.inmo.micro_utils.fsm.common.StatesMachine
|
2022-01-22 14:19:50 +00:00
|
|
|
import dev.inmo.postssystem.client.utils.renderComposableAndLinkToContext
|
2021-11-24 07:52:27 +00:00
|
|
|
import kotlinx.browser.document
|
|
|
|
import kotlinx.coroutines.*
|
2022-01-25 09:21:01 +00:00
|
|
|
import kotlinx.dom.*
|
2022-01-22 14:19:50 +00:00
|
|
|
import org.jetbrains.compose.web.attributes.InputType
|
2022-01-25 18:55:43 +00:00
|
|
|
import org.jetbrains.compose.web.dom.*
|
2022-01-25 09:21:01 +00:00
|
|
|
import org.jetbrains.compose.web.dom.Text
|
2021-11-24 07:52:27 +00:00
|
|
|
import org.w3c.dom.*
|
|
|
|
|
|
|
|
class AuthView(
|
|
|
|
private val viewModel: AuthUIViewModel,
|
|
|
|
private val uiScope: CoroutineScope
|
|
|
|
) : JSView<AuthUIFSMState>() {
|
|
|
|
|
|
|
|
override suspend fun StatesMachine<in UIFSMState>.safeHandleState(
|
|
|
|
htmlElement: HTMLElement,
|
|
|
|
state: AuthUIFSMState
|
|
|
|
): UIFSMState? {
|
|
|
|
val completion = CompletableDeferred<UIFSMState?>()
|
|
|
|
|
2022-01-22 14:19:50 +00:00
|
|
|
val usernameState = mutableStateOf("")
|
|
|
|
val passwordState = mutableStateOf("")
|
2022-01-25 18:55:43 +00:00
|
|
|
val disabled = mutableStateOf(true)
|
2022-01-22 14:19:50 +00:00
|
|
|
val errorText = mutableStateOf<String?>(null)
|
|
|
|
|
2022-01-25 18:55:43 +00:00
|
|
|
val root = htmlElement.appendElement("div") {}
|
2022-01-25 09:21:01 +00:00
|
|
|
val composition = renderComposableAndLinkToContext(root) {
|
|
|
|
val authBtnDisabled = usernameState.value.isBlank() || passwordState.value.isBlank()
|
|
|
|
|
2022-01-25 18:55:43 +00:00
|
|
|
Flex(
|
|
|
|
UIKitFlex.Alignment.Horizontal.Center
|
|
|
|
) {
|
|
|
|
Card(
|
2022-03-02 08:36:17 +00:00
|
|
|
Attrs(UIKitText.Alignment.Horizontal.Center),
|
2022-01-25 18:55:43 +00:00
|
|
|
bodyAttrs = Attrs(UIKitWidth.Fixed.Medium),
|
|
|
|
) {
|
|
|
|
CardTitle { Text("Log in") }
|
|
|
|
|
|
|
|
if (errorText.value != null) {
|
|
|
|
CardBadge(Attrs(UIKitLabel.Error)) {
|
|
|
|
Text(errorText.value.toString())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TextField(
|
|
|
|
InputType.Text,
|
|
|
|
usernameState,
|
|
|
|
disabled,
|
|
|
|
"Username",
|
|
|
|
)
|
|
|
|
TextField(
|
|
|
|
InputType.Password,
|
|
|
|
passwordState,
|
|
|
|
disabled,
|
|
|
|
"Password"
|
|
|
|
)
|
|
|
|
|
|
|
|
DefaultButton("Authorise", UIKitButton.Type.Primary, UIKitMargin.Small, disabled = authBtnDisabled) {
|
2022-01-25 09:21:01 +00:00
|
|
|
it.nativeEvent.preventDefault()
|
|
|
|
val serverUrl = document.location ?.run { "$hostname:$port" }
|
|
|
|
if (serverUrl != null) {
|
|
|
|
uiScope.launchSafelyWithoutExceptions { viewModel.initAuth(serverUrl, usernameState.value, passwordState.value) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-11-24 07:52:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
val viewJob = viewModel.currentState.subscribeSafelyWithoutExceptions(uiScope) {
|
|
|
|
when (it) {
|
|
|
|
is InitAuthUIState -> {
|
2022-01-25 18:55:43 +00:00
|
|
|
disabled.value = false
|
2022-01-22 14:19:50 +00:00
|
|
|
|
|
|
|
errorText.value = when (it.showError) {
|
2022-01-25 18:55:43 +00:00
|
|
|
ServerUnavailableAuthUIError -> "Server unavailable"
|
|
|
|
AuthIncorrectAuthUIError -> {
|
|
|
|
passwordState.value = ""
|
|
|
|
"Username or password is incorrect"
|
|
|
|
}
|
2022-01-22 14:19:50 +00:00
|
|
|
null -> null
|
2021-11-24 07:52:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
LoadingAuthUIState -> {
|
2022-01-25 18:55:43 +00:00
|
|
|
disabled.value = true
|
2022-01-22 14:19:50 +00:00
|
|
|
errorText.value = null
|
2021-11-24 07:52:27 +00:00
|
|
|
}
|
|
|
|
AuthorizedAuthUIState -> {
|
|
|
|
completion.complete(state.from)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return completion.await().also {
|
2022-01-22 14:19:50 +00:00
|
|
|
composition.dispose()
|
2021-11-24 07:52:27 +00:00
|
|
|
viewJob.cancel()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|