valid and first booleans in map
This commit is contained in:
parent
e8f2d71df3
commit
eb28fa4ae4
1 changed files with 27 additions and 29 deletions
|
@ -6,43 +6,37 @@ import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import be.ugent.sel.studeez.R
|
import be.ugent.sel.studeez.R
|
||||||
import be.ugent.sel.studeez.common.composable.BasicButton
|
import be.ugent.sel.studeez.common.composable.BasicButton
|
||||||
import be.ugent.sel.studeez.common.composable.LabeledErrorTextField
|
import be.ugent.sel.studeez.common.composable.LabeledErrorTextField
|
||||||
import be.ugent.sel.studeez.common.composable.LabelledInputField
|
|
||||||
import be.ugent.sel.studeez.common.ext.basicButton
|
import be.ugent.sel.studeez.common.ext.basicButton
|
||||||
|
import be.ugent.sel.studeez.common.snackbar.SnackbarManager
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
|
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
|
||||||
import be.ugent.sel.studeez.R.string as AppText
|
import be.ugent.sel.studeez.R.string as AppText
|
||||||
|
|
||||||
abstract class AbstractTimerFormScreen(private val timerInfo: TimerInfo) {
|
abstract class AbstractTimerFormScreen(private val timerInfo: TimerInfo) {
|
||||||
|
|
||||||
|
protected val valids = mutableMapOf(
|
||||||
|
"name" to mutableStateOf(textPredicate(timerInfo.name)),
|
||||||
|
"description" to mutableStateOf(textPredicate(timerInfo.description))
|
||||||
|
)
|
||||||
|
|
||||||
|
protected val firsts = mutableMapOf(
|
||||||
|
"name" to mutableStateOf(true),
|
||||||
|
"description" to mutableStateOf(true)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
operator fun invoke(
|
operator fun invoke(
|
||||||
onSaveClick: (TimerInfo) -> Unit,
|
onSaveClick: (TimerInfo) -> Unit,
|
||||||
extraButton: @Composable () -> Unit
|
extraButton: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
||||||
var name by remember { mutableStateOf(timerInfo.name) }
|
|
||||||
val isNameValid = remember { mutableStateOf(false) }
|
|
||||||
val hasEditedName = remember { mutableStateOf(true) }
|
|
||||||
|
|
||||||
var description by remember { mutableStateOf(timerInfo.description) }
|
|
||||||
val isDescriptionValid = remember { mutableStateOf(false) }
|
|
||||||
val hasEditedDescription = remember { mutableStateOf(true) }
|
|
||||||
|
|
||||||
// This shall rerun whenever name and description change
|
|
||||||
timerInfo.name = name
|
|
||||||
timerInfo.description = description
|
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.SpaceBetween,
|
verticalArrangement = Arrangement.SpaceBetween,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -59,25 +53,25 @@ abstract class AbstractTimerFormScreen(private val timerInfo: TimerInfo) {
|
||||||
initialValue = timerInfo.name,
|
initialValue = timerInfo.name,
|
||||||
label = R.string.name,
|
label = R.string.name,
|
||||||
errorText = AppText.name_error,
|
errorText = AppText.name_error,
|
||||||
isValid = isNameValid,
|
isValid = valids.getValue("name"),
|
||||||
isFirst = hasEditedName,
|
isFirst = firsts.getValue("name"),
|
||||||
keyboardType = KeyboardType.Text,
|
keyboardType = KeyboardType.Text,
|
||||||
predicate = { it.isNotBlank() }
|
predicate = { it.isNotBlank() }
|
||||||
) { correctName ->
|
) { correctName ->
|
||||||
name = correctName
|
timerInfo.name = correctName
|
||||||
}
|
}
|
||||||
|
|
||||||
LabeledErrorTextField(
|
LabeledErrorTextField(
|
||||||
initialValue = timerInfo.description,
|
initialValue = timerInfo.description,
|
||||||
label = R.string.description,
|
label = R.string.description,
|
||||||
errorText = AppText.description_error,
|
errorText = AppText.description_error,
|
||||||
isValid = isDescriptionValid,
|
isValid = valids.getValue("description"),
|
||||||
isFirst = hasEditedDescription,
|
isFirst = firsts.getValue("description"),
|
||||||
singleLine= false,
|
singleLine= false,
|
||||||
keyboardType = KeyboardType.Text,
|
keyboardType = KeyboardType.Text,
|
||||||
predicate = { it.isNotBlank() }
|
predicate = { textPredicate(it) }
|
||||||
) { correctName ->
|
) { correctName ->
|
||||||
description = correctName
|
timerInfo.description = correctName
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtraFields()
|
ExtraFields()
|
||||||
|
@ -86,11 +80,11 @@ abstract class AbstractTimerFormScreen(private val timerInfo: TimerInfo) {
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
BasicButton(R.string.save, Modifier.basicButton()) {
|
BasicButton(R.string.save, Modifier.basicButton()) {
|
||||||
if (isNameValid.value && isDescriptionValid.value) {
|
if (valids.all { it.component2().value }) { // All fields are valid
|
||||||
onSaveClick(timerInfo)
|
onSaveClick(timerInfo)
|
||||||
} else {
|
} else {
|
||||||
hasEditedName.value = false
|
firsts.map { it.component2().value = false } // dont mask error because its not been filled out yet
|
||||||
hasEditedDescription.value = false
|
SnackbarManager.showMessage(AppText.fill_out_error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extraButton()
|
extraButton()
|
||||||
|
@ -98,6 +92,10 @@ abstract class AbstractTimerFormScreen(private val timerInfo: TimerInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun textPredicate(text: String): Boolean {
|
||||||
|
return text.isNotBlank()
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
open fun ExtraFields() {
|
open fun ExtraFields() {
|
||||||
// By default no extra fields, unless overwritten by subclass.
|
// By default no extra fields, unless overwritten by subclass.
|
||||||
|
|
Reference in a new issue