121 lines
5.1 KiB
Kotlin
121 lines
5.1 KiB
Kotlin
package dev.inmo.postssystem.client.fsm.ui
|
|
|
|
import dev.inmo.postssystem.client.ui.fsm.*
|
|
import dev.inmo.postssystem.client.utils.HTMLViewContainer
|
|
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
|
|
import kotlinx.browser.document
|
|
import kotlinx.coroutines.*
|
|
import kotlinx.dom.clear
|
|
import kotlinx.html.*
|
|
import kotlinx.html.dom.append
|
|
import kotlinx.html.js.form
|
|
import kotlinx.html.js.onClickFunction
|
|
import org.w3c.dom.*
|
|
|
|
class AuthView(
|
|
private val viewModel: AuthUIViewModel,
|
|
private val uiScope: CoroutineScope
|
|
) : JSView<AuthUIFSMState>() {
|
|
private val usernameInput
|
|
get() = document.getElementById("authUsername") as? HTMLInputElement
|
|
private val passwordInput
|
|
get() = document.getElementById("authPassword") as? HTMLInputElement
|
|
private val authButton
|
|
get() = document.getElementById("authButton")
|
|
private val errorBadge
|
|
get() = document.getElementById("errorBadge") as? HTMLElement
|
|
private val progressBarDiv
|
|
get() = document.getElementById("progressBar") as? HTMLDivElement
|
|
|
|
override suspend fun StatesMachine<in UIFSMState>.safeHandleState(
|
|
htmlElement: HTMLElement,
|
|
container: HTMLViewContainer,
|
|
state: AuthUIFSMState
|
|
): UIFSMState? {
|
|
val completion = CompletableDeferred<UIFSMState?>()
|
|
htmlElement.clear()
|
|
|
|
htmlElement.append {
|
|
form(classes = "vertical_container") {
|
|
div(classes = "mdl-textfield mdl-js-textfield mdl-textfield--floating-label") {
|
|
input(type = InputType.text, classes = "mdl-textfield__input") {
|
|
id = "authUsername"
|
|
}
|
|
label(classes = "mdl-textfield__label") {
|
|
+"Имя пользователя"
|
|
}
|
|
}
|
|
div(classes = "mdl-textfield mdl-js-textfield mdl-textfield--floating-label") {
|
|
input(type = InputType.password, classes = "mdl-textfield__input") {
|
|
id = "authPassword"
|
|
}
|
|
label(classes = "mdl-textfield__label") {
|
|
+"Пароль"
|
|
}
|
|
}
|
|
div(classes = "mdl-progress mdl-js-progress") {
|
|
id = "progressBar"
|
|
}
|
|
span(classes = "material-icons mdl-badge mdl-badge--overlap gone") {
|
|
id = "errorBadge"
|
|
attributes["data-badge"] = "!"
|
|
}
|
|
button(classes = "mdl-button mdl-js-button mdl-button--raised") {
|
|
+"Авторизоваться"
|
|
id = "authButton"
|
|
onClickFunction = {
|
|
it.preventDefault()
|
|
val serverUrl = document.location ?.run { "$hostname:$port" }
|
|
val username = usernameInput ?.value
|
|
val password = passwordInput ?.value
|
|
if (serverUrl != null && username != null && password != null) {
|
|
uiScope.launchSafelyWithoutExceptions { viewModel.initAuth(serverUrl, username, password) }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
val viewJob = viewModel.currentState.subscribeSafelyWithoutExceptions(uiScope) {
|
|
when (it) {
|
|
is InitAuthUIState -> {
|
|
usernameInput ?.removeAttribute("disabled")
|
|
passwordInput ?.removeAttribute("disabled")
|
|
authButton ?.removeAttribute("disabled")
|
|
errorBadge ?.apply {
|
|
when (it.showError) {
|
|
ServerUnavailableAuthUIError -> {
|
|
classList.remove("gone")
|
|
innerText = "Сервер недоступен"
|
|
}
|
|
AuthIncorrectAuthUIError -> {
|
|
classList.remove("gone")
|
|
innerText = "Данные некорректны"
|
|
}
|
|
null -> classList.add("gone")
|
|
}
|
|
}
|
|
progressBarDiv ?.classList ?.add("gone")
|
|
}
|
|
LoadingAuthUIState -> {
|
|
usernameInput ?.setAttribute("disabled", "")
|
|
passwordInput ?.setAttribute("disabled", "")
|
|
authButton ?.setAttribute("disabled", "")
|
|
errorBadge ?.classList ?.add("gone")
|
|
progressBarDiv ?.classList ?.remove("gone")
|
|
}
|
|
AuthorizedAuthUIState -> {
|
|
htmlElement.clear()
|
|
completion.complete(state.from)
|
|
}
|
|
}
|
|
}
|
|
return completion.await().also {
|
|
viewJob.cancel()
|
|
}
|
|
}
|
|
}
|