resolve merge conflicts when merging to development
This commit is contained in:
commit
5b8d59cb75
23 changed files with 231 additions and 592 deletions
|
@ -1,11 +1,11 @@
|
||||||
package be.ugent.sel.studeez.common.composable
|
package be.ugent.sel.studeez.common.composable
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.*
|
||||||
import androidx.compose.material.IconButton
|
|
||||||
import androidx.compose.material.OutlinedTextField
|
|
||||||
import androidx.compose.material.Text
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Email
|
import androidx.compose.material.icons.filled.Email
|
||||||
import androidx.compose.material.icons.filled.Lock
|
import androidx.compose.material.icons.filled.Lock
|
||||||
|
@ -14,10 +14,15 @@ import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||||
import androidx.compose.ui.text.input.VisualTransformation
|
import androidx.compose.ui.text.input.VisualTransformation
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import be.ugent.sel.studeez.common.ext.fieldModifier
|
import be.ugent.sel.studeez.common.ext.fieldModifier
|
||||||
|
import be.ugent.sel.studeez.resources
|
||||||
|
import kotlin.math.sin
|
||||||
import be.ugent.sel.studeez.R.drawable as AppIcon
|
import be.ugent.sel.studeez.R.drawable as AppIcon
|
||||||
import be.ugent.sel.studeez.R.string as AppText
|
import be.ugent.sel.studeez.R.string as AppText
|
||||||
|
|
||||||
|
@ -85,6 +90,86 @@ fun EmailField(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun LabeledNumberInputField(
|
||||||
|
value: Int,
|
||||||
|
onNewValue: (Int) -> Unit,
|
||||||
|
@StringRes label: Int,
|
||||||
|
singleLine: Boolean = false
|
||||||
|
) {
|
||||||
|
var number by remember { mutableStateOf(value) }
|
||||||
|
OutlinedTextField(
|
||||||
|
value = number.toString(),
|
||||||
|
singleLine = singleLine,
|
||||||
|
label = { Text(resources().getString(label)) },
|
||||||
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
|
onValueChange = {typedInt ->
|
||||||
|
val isNumber = typedInt.matches(Regex("[1-9]+\\d*]"))
|
||||||
|
if (isNumber) {
|
||||||
|
number = typedInt.toInt()
|
||||||
|
onNewValue(typedInt.toInt())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun LabeledErrorTextField(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
initialValue: String,
|
||||||
|
@StringRes label: Int,
|
||||||
|
singleLine: Boolean = false,
|
||||||
|
errorText: Int,
|
||||||
|
keyboardType: KeyboardType,
|
||||||
|
predicate: (String) -> Boolean,
|
||||||
|
onNewCorrectValue: (String) -> Unit
|
||||||
|
) {
|
||||||
|
var value by remember {
|
||||||
|
mutableStateOf(initialValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
var isValid by remember {
|
||||||
|
mutableStateOf(predicate(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
OutlinedTextField(
|
||||||
|
modifier = modifier.fieldModifier(),
|
||||||
|
value = value,
|
||||||
|
onValueChange = { newText ->
|
||||||
|
value = newText
|
||||||
|
isValid = predicate(value)
|
||||||
|
if (isValid) {
|
||||||
|
onNewCorrectValue(newText)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
singleLine = singleLine,
|
||||||
|
label = { Text(text = stringResource(id = label)) },
|
||||||
|
isError = !isValid,
|
||||||
|
keyboardOptions = KeyboardOptions(
|
||||||
|
keyboardType = keyboardType,
|
||||||
|
imeAction = ImeAction.Done
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!isValid) {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.padding(start = 16.dp),
|
||||||
|
text = stringResource(id = errorText),
|
||||||
|
color = MaterialTheme.colors.error
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun IntInputPreview() {
|
||||||
|
LabeledNumberInputField(value = 1, onNewValue = {}, label = AppText.email)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PasswordField(
|
fun PasswordField(
|
||||||
value: String,
|
value: String,
|
||||||
|
|
|
@ -9,7 +9,7 @@ class PomodoroTimerInfo(
|
||||||
description: String,
|
description: String,
|
||||||
var studyTime: Int,
|
var studyTime: Int,
|
||||||
var breakTime: Int,
|
var breakTime: Int,
|
||||||
val repeats: Int,
|
var repeats: Int,
|
||||||
id: String = ""
|
id: String = ""
|
||||||
): TimerInfo(id, name, description) {
|
): TimerInfo(id, name, description) {
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ object StudeezDestinations {
|
||||||
// Studying flow
|
// Studying flow
|
||||||
const val TIMER_SELECTION_SCREEN = "timer_selection"
|
const val TIMER_SELECTION_SCREEN = "timer_selection"
|
||||||
const val TIMER_EDIT_SCREEN = "timer_edit"
|
const val TIMER_EDIT_SCREEN = "timer_edit"
|
||||||
|
const val TIMER_TYPE_CHOOSING_SCREEN = "timer_type_choosing_screen"
|
||||||
const val SESSION_SCREEN = "session"
|
const val SESSION_SCREEN = "session"
|
||||||
const val SESSION_RECAP = "session_recap"
|
const val SESSION_RECAP = "session_recap"
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,10 @@ import be.ugent.sel.studeez.screens.tasks.forms.SubjectAddRoute
|
||||||
import be.ugent.sel.studeez.screens.tasks.forms.SubjectEditRoute
|
import be.ugent.sel.studeez.screens.tasks.forms.SubjectEditRoute
|
||||||
import be.ugent.sel.studeez.screens.tasks.forms.TaskAddRoute
|
import be.ugent.sel.studeez.screens.tasks.forms.TaskAddRoute
|
||||||
import be.ugent.sel.studeez.screens.tasks.forms.TaskEditRoute
|
import be.ugent.sel.studeez.screens.tasks.forms.TaskEditRoute
|
||||||
import be.ugent.sel.studeez.screens.timer_edit.TimerEditRoute
|
import be.ugent.sel.studeez.screens.timer_form.TimerAddRoute
|
||||||
|
import be.ugent.sel.studeez.screens.timer_form.TimerEditRoute
|
||||||
|
import be.ugent.sel.studeez.screens.timer_form.timer_type_select.TimerTypeSelectScreen
|
||||||
import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute
|
import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute
|
||||||
import be.ugent.sel.studeez.screens.timer_overview.add_timer.AddTimerRoute
|
|
||||||
import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute
|
import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -182,6 +183,13 @@ fun StudeezNavGraph(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
composable(StudeezDestinations.TIMER_TYPE_CHOOSING_SCREEN) {
|
||||||
|
TimerTypeSelectScreen(
|
||||||
|
open = open,
|
||||||
|
popUp = goBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
composable(StudeezDestinations.SESSION_SCREEN) {
|
composable(StudeezDestinations.SESSION_SCREEN) {
|
||||||
SessionRoute(
|
SessionRoute(
|
||||||
open,
|
open,
|
||||||
|
@ -198,16 +206,14 @@ fun StudeezNavGraph(
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(StudeezDestinations.ADD_TIMER_SCREEN) {
|
composable(StudeezDestinations.ADD_TIMER_SCREEN) {
|
||||||
AddTimerRoute(
|
TimerAddRoute(
|
||||||
open = open,
|
popUp = goBack,
|
||||||
goBack = goBack,
|
|
||||||
viewModel = hiltViewModel()
|
viewModel = hiltViewModel()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(StudeezDestinations.TIMER_EDIT_SCREEN) {
|
composable(StudeezDestinations.TIMER_EDIT_SCREEN) {
|
||||||
TimerEditRoute(
|
TimerEditRoute(
|
||||||
open = open,
|
|
||||||
popUp = goBack,
|
popUp = goBack,
|
||||||
viewModel = hiltViewModel()
|
viewModel = hiltViewModel()
|
||||||
)
|
)
|
||||||
|
@ -236,3 +242,4 @@ fun StudeezNavGraph(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_add
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
|
|
||||||
import be.ugent.sel.studeez.screens.timer_edit.GetTimerEditScreen
|
|
||||||
import be.ugent.sel.studeez.screens.timer_edit.TimerEditViewModel
|
|
||||||
import be.ugent.sel.studeez.screens.timer_edit.editScreens.AbstractTimerEditScreen
|
|
||||||
import be.ugent.sel.studeez.ui.theme.StudeezTheme
|
|
||||||
|
|
||||||
data class TimerEditActions(
|
|
||||||
val getTimerInfo: () -> TimerInfo,
|
|
||||||
val saveTimer: (TimerInfo, () -> Unit) -> Unit
|
|
||||||
)
|
|
||||||
|
|
||||||
fun getTimerEditActions(
|
|
||||||
viewModel: TimerEditViewModel,
|
|
||||||
open: (String) -> Unit
|
|
||||||
): TimerEditActions {
|
|
||||||
return TimerEditActions(
|
|
||||||
getTimerInfo = viewModel::getTimerInfo,
|
|
||||||
saveTimer = viewModel::saveTimer
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun TimerEditRoute(
|
|
||||||
open: (String) -> Unit,
|
|
||||||
popUp: () -> Unit,
|
|
||||||
viewModel: TimerEditViewModel,
|
|
||||||
) {
|
|
||||||
|
|
||||||
val timerEditActions = getTimerEditActions(viewModel, open)
|
|
||||||
|
|
||||||
SecondaryScreenTemplate(title = "Edit Timer", popUp = popUp) {
|
|
||||||
|
|
||||||
val timerEditScreen = timerEditActions.getTimerInfo().accept(GetTimerEditScreen())
|
|
||||||
timerEditScreen { timerInfo ->
|
|
||||||
timerEditActions.saveTimer(timerInfo, popUp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_add
|
|
||||||
|
|
||||||
import be.ugent.sel.studeez.data.EditTimerState
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
|
|
||||||
import be.ugent.sel.studeez.domain.LogService
|
|
||||||
import be.ugent.sel.studeez.domain.TimerDAO
|
|
||||||
import be.ugent.sel.studeez.screens.StudeezViewModel
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@HiltViewModel
|
|
||||||
class TimerAddViewModel @Inject constructor(
|
|
||||||
private val editTimerState: EditTimerState,
|
|
||||||
private val timerDAO: TimerDAO,
|
|
||||||
logService: LogService
|
|
||||||
) : StudeezViewModel(logService) {
|
|
||||||
|
|
||||||
private val timerInfo: TimerInfo = editTimerState.timerInfo
|
|
||||||
|
|
||||||
fun getTimerInfo(): TimerInfo {
|
|
||||||
return timerInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveTimer(timerInfo: TimerInfo, goBack: () -> Unit) {
|
|
||||||
timerDAO.updateTimer(timerInfo)
|
|
||||||
goBack()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_edit
|
|
||||||
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.CustomTimerInfo
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.EndlessTimerInfo
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.PomodoroTimerInfo
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfoVisitor
|
|
||||||
import be.ugent.sel.studeez.screens.timer_edit.editScreens.AbstractTimerEditScreen
|
|
||||||
import be.ugent.sel.studeez.screens.timer_edit.editScreens.BreakTimerEditScreen
|
|
||||||
import be.ugent.sel.studeez.screens.timer_edit.editScreens.CustomTimerEditScreen
|
|
||||||
import be.ugent.sel.studeez.screens.timer_edit.editScreens.EndlessTimerEditScreen
|
|
||||||
|
|
||||||
class GetTimerEditScreen: TimerInfoVisitor<AbstractTimerEditScreen> {
|
|
||||||
|
|
||||||
override fun visitCustomTimerInfo(customTimerInfo: CustomTimerInfo): AbstractTimerEditScreen {
|
|
||||||
return CustomTimerEditScreen(customTimerInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitEndlessTimerInfo(endlessTimerInfo: EndlessTimerInfo): AbstractTimerEditScreen {
|
|
||||||
return EndlessTimerEditScreen(endlessTimerInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitBreakTimerInfo(pomodoroTimerInfo: PomodoroTimerInfo): AbstractTimerEditScreen {
|
|
||||||
return BreakTimerEditScreen(pomodoroTimerInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_edit
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
|
|
||||||
import be.ugent.sel.studeez.screens.timer_edit.editScreens.AbstractTimerEditScreen
|
|
||||||
import be.ugent.sel.studeez.ui.theme.StudeezTheme
|
|
||||||
|
|
||||||
data class TimerEditActions(
|
|
||||||
val getTimerInfo: () -> TimerInfo,
|
|
||||||
val saveTimer: (TimerInfo, () -> Unit) -> Unit
|
|
||||||
)
|
|
||||||
|
|
||||||
fun getTimerEditActions(
|
|
||||||
viewModel: TimerEditViewModel,
|
|
||||||
open: (String) -> Unit
|
|
||||||
): TimerEditActions {
|
|
||||||
return TimerEditActions(
|
|
||||||
getTimerInfo = viewModel::getTimerInfo,
|
|
||||||
saveTimer = viewModel::saveTimer
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun TimerEditRoute(
|
|
||||||
open: (String) -> Unit,
|
|
||||||
popUp: () -> Unit,
|
|
||||||
viewModel: TimerEditViewModel,
|
|
||||||
) {
|
|
||||||
|
|
||||||
val timerEditActions = getTimerEditActions(viewModel, open)
|
|
||||||
|
|
||||||
SecondaryScreenTemplate(title = "Edit Timer", popUp = popUp) {
|
|
||||||
|
|
||||||
val timerEditScreen = timerEditActions.getTimerInfo().accept(GetTimerEditScreen())
|
|
||||||
timerEditScreen { timerInfo ->
|
|
||||||
timerEditActions.saveTimer(timerInfo, popUp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package be.ugent.sel.studeez.screens.timer_form
|
||||||
|
|
||||||
|
import be.ugent.sel.studeez.data.local.models.timer_info.CustomTimerInfo
|
||||||
|
import be.ugent.sel.studeez.data.local.models.timer_info.EndlessTimerInfo
|
||||||
|
import be.ugent.sel.studeez.data.local.models.timer_info.PomodoroTimerInfo
|
||||||
|
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfoVisitor
|
||||||
|
import be.ugent.sel.studeez.screens.timer_form.form_screens.AbstractTimerFormScreen
|
||||||
|
import be.ugent.sel.studeez.screens.timer_form.form_screens.BreakTimerFormScreen
|
||||||
|
import be.ugent.sel.studeez.screens.timer_form.form_screens.CustomTimerFormScreen
|
||||||
|
import be.ugent.sel.studeez.screens.timer_form.form_screens.EndlessTimerFormScreen
|
||||||
|
|
||||||
|
class GetTimerFormScreen: TimerInfoVisitor<AbstractTimerFormScreen> {
|
||||||
|
|
||||||
|
override fun visitCustomTimerInfo(customTimerInfo: CustomTimerInfo): AbstractTimerFormScreen {
|
||||||
|
return CustomTimerFormScreen(customTimerInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitEndlessTimerInfo(endlessTimerInfo: EndlessTimerInfo): AbstractTimerFormScreen {
|
||||||
|
return EndlessTimerFormScreen(endlessTimerInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitBreakTimerInfo(pomodoroTimerInfo: PomodoroTimerInfo): AbstractTimerFormScreen {
|
||||||
|
return BreakTimerFormScreen(pomodoroTimerInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package be.ugent.sel.studeez.screens.timer_form
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate
|
||||||
|
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
|
||||||
|
import be.ugent.sel.studeez.R.string as AppText
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TimerAddRoute(
|
||||||
|
popUp: () -> Unit,
|
||||||
|
viewModel: TimerFormViewModel
|
||||||
|
) {
|
||||||
|
TimerFormScreen(popUp = popUp, getTimerInfo = viewModel::getTimerInfo, AppText.add_timer) {
|
||||||
|
viewModel.saveTimer(it, goBack = popUp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TimerEditRoute(
|
||||||
|
popUp: () -> Unit,
|
||||||
|
viewModel: TimerFormViewModel
|
||||||
|
) {
|
||||||
|
TimerFormScreen(popUp = popUp, getTimerInfo = viewModel::getTimerInfo, AppText.edit_timer) {
|
||||||
|
viewModel.editTimer(it, goBack = popUp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TimerFormScreen(
|
||||||
|
popUp: () -> Unit,
|
||||||
|
getTimerInfo: () -> TimerInfo,
|
||||||
|
@StringRes label: Int,
|
||||||
|
onConfirmClick: (TimerInfo) -> Unit
|
||||||
|
) {
|
||||||
|
val timerFormScreen = getTimerInfo().accept(GetTimerFormScreen())
|
||||||
|
|
||||||
|
SecondaryScreenTemplate(title = stringResource(id = label), popUp = popUp) {
|
||||||
|
timerFormScreen(onConfirmClick)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_edit
|
package be.ugent.sel.studeez.screens.timer_form
|
||||||
|
|
||||||
import be.ugent.sel.studeez.data.EditTimerState
|
import be.ugent.sel.studeez.data.EditTimerState
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
|
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
|
||||||
|
@ -9,7 +9,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class TimerEditViewModel @Inject constructor(
|
class TimerFormViewModel @Inject constructor(
|
||||||
private val editTimerState: EditTimerState,
|
private val editTimerState: EditTimerState,
|
||||||
private val timerDAO: TimerDAO,
|
private val timerDAO: TimerDAO,
|
||||||
logService: LogService
|
logService: LogService
|
||||||
|
@ -21,9 +21,13 @@ class TimerEditViewModel @Inject constructor(
|
||||||
return timerInfo
|
return timerInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
fun saveTimer(timerInfo: TimerInfo, goBack: () -> Unit) {
|
fun editTimer(timerInfo: TimerInfo, goBack: () -> Unit) {
|
||||||
timerDAO.updateTimer(timerInfo)
|
timerDAO.updateTimer(timerInfo)
|
||||||
goBack()
|
goBack()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun saveTimer(timerInfo: TimerInfo, goBack: () -> Unit) {
|
||||||
|
timerDAO.saveTimer(timerInfo)
|
||||||
|
goBack()
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_edit.editScreens
|
package be.ugent.sel.studeez.screens.timer_form.form_screens
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
@ -18,8 +18,9 @@ import be.ugent.sel.studeez.common.composable.BasicButton
|
||||||
import be.ugent.sel.studeez.common.composable.LabelledInputField
|
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.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
|
||||||
|
|
||||||
abstract class AbstractTimerEditScreen(private val timerInfo: TimerInfo) {
|
abstract class AbstractTimerFormScreen(private val timerInfo: TimerInfo) {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
operator fun invoke(onSaveClick: (TimerInfo) -> Unit) {
|
operator fun invoke(onSaveClick: (TimerInfo) -> Unit) {
|
||||||
|
@ -50,7 +51,7 @@ abstract class AbstractTimerEditScreen(private val timerInfo: TimerInfo) {
|
||||||
LabelledInputField(
|
LabelledInputField(
|
||||||
value = description,
|
value = description,
|
||||||
onNewValue = { description = it },
|
onNewValue = { description = it },
|
||||||
label = R.string.description,
|
label = AppText.description,
|
||||||
singleLine = false
|
singleLine = false
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_edit.editScreens
|
package be.ugent.sel.studeez.screens.timer_form.form_screens
|
||||||
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import be.ugent.sel.studeez.R
|
import be.ugent.sel.studeez.R
|
||||||
import be.ugent.sel.studeez.common.composable.TimePickerButton
|
import be.ugent.sel.studeez.common.composable.LabeledErrorTextField
|
||||||
import be.ugent.sel.studeez.common.composable.TimePickerCard
|
import be.ugent.sel.studeez.common.composable.TimePickerCard
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_functional.Time
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.CustomTimerInfo
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.EndlessTimerInfo
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.PomodoroTimerInfo
|
import be.ugent.sel.studeez.data.local.models.timer_info.PomodoroTimerInfo
|
||||||
import be.ugent.sel.studeez.ui.theme.StudeezTheme
|
import be.ugent.sel.studeez.ui.theme.StudeezTheme
|
||||||
|
import be.ugent.sel.studeez.R.string as AppText
|
||||||
|
|
||||||
class BreakTimerEditScreen(
|
|
||||||
|
class BreakTimerFormScreen(
|
||||||
private val breakTimerInfo: PomodoroTimerInfo
|
private val breakTimerInfo: PomodoroTimerInfo
|
||||||
): AbstractTimerEditScreen(breakTimerInfo) {
|
): AbstractTimerFormScreen(breakTimerInfo) {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ExtraFields() {
|
override fun ExtraFields() {
|
||||||
|
@ -26,8 +25,18 @@ class BreakTimerEditScreen(
|
||||||
TimePickerCard(R.string.breakTime, breakTimerInfo.breakTime) { newTime ->
|
TimePickerCard(R.string.breakTime, breakTimerInfo.breakTime) { newTime ->
|
||||||
breakTimerInfo.breakTime = newTime
|
breakTimerInfo.breakTime = newTime
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
LabeledErrorTextField(
|
||||||
|
initialValue = breakTimerInfo.repeats.toString(),
|
||||||
|
label = R.string.repeats,
|
||||||
|
errorText = AppText.repeats_error,
|
||||||
|
keyboardType = KeyboardType.Decimal,
|
||||||
|
predicate = { it.matches(Regex("[1-9]+\\d*")) }
|
||||||
|
) { correctlyTypedInt ->
|
||||||
|
breakTimerInfo.repeats = correctlyTypedInt.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
|
@ -41,6 +50,6 @@ fun BreakEditScreenPreview() {
|
||||||
5
|
5
|
||||||
)
|
)
|
||||||
StudeezTheme {
|
StudeezTheme {
|
||||||
BreakTimerEditScreen(pomodoroTimerInfo).invoke(onSaveClick = {})
|
BreakTimerFormScreen(pomodoroTimerInfo).invoke(onSaveClick = {})
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_edit.editScreens
|
package be.ugent.sel.studeez.screens.timer_form.form_screens
|
||||||
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
@ -7,9 +7,9 @@ import be.ugent.sel.studeez.data.local.models.timer_info.CustomTimerInfo
|
||||||
import be.ugent.sel.studeez.ui.theme.StudeezTheme
|
import be.ugent.sel.studeez.ui.theme.StudeezTheme
|
||||||
import be.ugent.sel.studeez.R.string as AppText
|
import be.ugent.sel.studeez.R.string as AppText
|
||||||
|
|
||||||
class CustomTimerEditScreen(
|
class CustomTimerFormScreen(
|
||||||
private val customTimerInfo: CustomTimerInfo
|
private val customTimerInfo: CustomTimerInfo
|
||||||
): AbstractTimerEditScreen(customTimerInfo) {
|
): AbstractTimerFormScreen(customTimerInfo) {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ExtraFields() {
|
override fun ExtraFields() {
|
||||||
|
@ -29,6 +29,6 @@ class CustomTimerEditScreen(
|
||||||
fun CustomEditScreenPreview() {
|
fun CustomEditScreenPreview() {
|
||||||
val customTimerInfo = CustomTimerInfo("custom", "my description", 25)
|
val customTimerInfo = CustomTimerInfo("custom", "my description", 25)
|
||||||
StudeezTheme {
|
StudeezTheme {
|
||||||
CustomTimerEditScreen(customTimerInfo).invoke(onSaveClick = {})
|
CustomTimerFormScreen(customTimerInfo).invoke(onSaveClick = {})
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,13 +1,13 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_edit.editScreens
|
package be.ugent.sel.studeez.screens.timer_form.form_screens
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.EndlessTimerInfo
|
import be.ugent.sel.studeez.data.local.models.timer_info.EndlessTimerInfo
|
||||||
import be.ugent.sel.studeez.ui.theme.StudeezTheme
|
import be.ugent.sel.studeez.ui.theme.StudeezTheme
|
||||||
|
|
||||||
class EndlessTimerEditScreen(
|
class EndlessTimerFormScreen(
|
||||||
endlessTimerInfo: EndlessTimerInfo
|
endlessTimerInfo: EndlessTimerInfo
|
||||||
): AbstractTimerEditScreen(endlessTimerInfo) {
|
): AbstractTimerFormScreen(endlessTimerInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
|
@ -18,6 +18,6 @@ fun EndlessEditScreenPreview() {
|
||||||
"My endless timer description",
|
"My endless timer description",
|
||||||
)
|
)
|
||||||
StudeezTheme {
|
StudeezTheme {
|
||||||
EndlessTimerEditScreen(endlessTimerInfo).invoke(onSaveClick = {})
|
EndlessTimerFormScreen(endlessTimerInfo).invoke(onSaveClick = {})
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_add
|
package be.ugent.sel.studeez.screens.timer_form.timer_type_select
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
@ -7,16 +7,18 @@ import androidx.compose.material.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate
|
import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.*
|
import be.ugent.sel.studeez.data.local.models.timer_info.*
|
||||||
|
import be.ugent.sel.studeez.R.string as AppText
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.TimerType.CUSTOM
|
import be.ugent.sel.studeez.data.local.models.timer_info.TimerType.CUSTOM
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.TimerType.BREAK
|
import be.ugent.sel.studeez.data.local.models.timer_info.TimerType.BREAK
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.TimerType.ENDLESS
|
import be.ugent.sel.studeez.data.local.models.timer_info.TimerType.ENDLESS
|
||||||
|
|
||||||
val defaultTimerInfo: Map<TimerType, TimerInfo> = mapOf(
|
val defaultTimerInfo: Map<TimerType, TimerInfo> = mapOf(
|
||||||
CUSTOM to CustomTimerInfo("", "", 0),
|
CUSTOM to CustomTimerInfo("", "", 0),
|
||||||
BREAK to PomodoroTimerInfo("", "", 0, 0, 0),
|
BREAK to PomodoroTimerInfo("", "", 0, 0, 1),
|
||||||
ENDLESS to EndlessTimerInfo("", ""),
|
ENDLESS to EndlessTimerInfo("", ""),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,13 +30,14 @@ fun TimerTypeSelectScreen(
|
||||||
viewModel: TimerTypeSelectViewModel = hiltViewModel()
|
viewModel: TimerTypeSelectViewModel = hiltViewModel()
|
||||||
) {
|
) {
|
||||||
|
|
||||||
SecondaryScreenTemplate(title = "Edit Timer", popUp = popUp) {
|
SecondaryScreenTemplate(title = stringResource(id = AppText.timer_type_select), popUp = popUp) {
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
TimerType.values().forEach { timerType ->
|
TimerType.values().forEach { timerType ->
|
||||||
Button(onClick = { viewModel.onTimerTypeChosen(defaultTimerInfo[timerType]!!, open) }) {
|
val default: TimerInfo = defaultTimerInfo.getValue(timerType)
|
||||||
|
Button(onClick = { viewModel.onTimerTypeChosen(default, open) }) {
|
||||||
Text(text = timerType.name)
|
Text(text = timerType.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,25 +1,22 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_add
|
package be.ugent.sel.studeez.screens.timer_form.timer_type_select
|
||||||
|
|
||||||
import be.ugent.sel.studeez.data.EditTimerState
|
import be.ugent.sel.studeez.data.EditTimerState
|
||||||
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.domain.LogService
|
import be.ugent.sel.studeez.domain.LogService
|
||||||
import be.ugent.sel.studeez.domain.TimerDAO
|
|
||||||
import be.ugent.sel.studeez.navigation.StudeezDestinations
|
import be.ugent.sel.studeez.navigation.StudeezDestinations
|
||||||
import be.ugent.sel.studeez.screens.StudeezViewModel
|
import be.ugent.sel.studeez.screens.StudeezViewModel
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class TimerTypeSelectViewModel @Inject constructor(
|
class TimerTypeSelectViewModel @Inject constructor(
|
||||||
private val editTimerState: EditTimerState,
|
private val editTimerState: EditTimerState,
|
||||||
private val timerDAO: TimerDAO,
|
|
||||||
logService: LogService
|
logService: LogService
|
||||||
) : StudeezViewModel(logService) {
|
) : StudeezViewModel(logService) {
|
||||||
|
|
||||||
|
|
||||||
fun onTimerTypeChosen(timerInfo: TimerInfo, open: (String) -> Unit) {
|
fun onTimerTypeChosen(timerInfo: TimerInfo, open: (String) -> Unit) {
|
||||||
editTimerState.timerInfo = timerInfo
|
editTimerState.timerInfo = timerInfo
|
||||||
open(StudeezDestinations.TIMER_EDIT_SCREEN)
|
open(StudeezDestinations.ADD_TIMER_SCREEN)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,7 +25,7 @@ data class TimerOverviewActions(
|
||||||
val getUserTimers: () -> Flow<List<TimerInfo>>,
|
val getUserTimers: () -> Flow<List<TimerInfo>>,
|
||||||
val getDefaultTimers: () -> List<TimerInfo>,
|
val getDefaultTimers: () -> List<TimerInfo>,
|
||||||
val onEditClick: (TimerInfo) -> Unit,
|
val onEditClick: (TimerInfo) -> Unit,
|
||||||
val onAddClick: () -> Unit,
|
val onAddClick: () -> Unit
|
||||||
)
|
)
|
||||||
|
|
||||||
fun getTimerOverviewActions(
|
fun getTimerOverviewActions(
|
||||||
|
@ -36,7 +36,7 @@ fun getTimerOverviewActions(
|
||||||
getUserTimers = viewModel::getUserTimers,
|
getUserTimers = viewModel::getUserTimers,
|
||||||
getDefaultTimers = viewModel::getDefaultTimers,
|
getDefaultTimers = viewModel::getDefaultTimers,
|
||||||
onEditClick = { viewModel.update(it, open) },
|
onEditClick = { viewModel.update(it, open) },
|
||||||
onAddClick = { viewModel.create(open) }
|
onAddClick = { viewModel.onAddClick(open) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,14 +48,14 @@ fun TimerOverviewRoute(
|
||||||
) {
|
) {
|
||||||
TimerOverviewScreen(
|
TimerOverviewScreen(
|
||||||
timerOverviewActions = getTimerOverviewActions(viewModel, open),
|
timerOverviewActions = getTimerOverviewActions(viewModel, open),
|
||||||
drawerActions = drawerActions
|
drawerActions = drawerActions,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TimerOverviewScreen(
|
fun TimerOverviewScreen(
|
||||||
timerOverviewActions: TimerOverviewActions,
|
timerOverviewActions: TimerOverviewActions,
|
||||||
drawerActions: DrawerActions
|
drawerActions: DrawerActions,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val timers = timerOverviewActions.getUserTimers().collectAsState(initial = emptyList())
|
val timers = timerOverviewActions.getUserTimers().collectAsState(initial = emptyList())
|
||||||
|
|
|
@ -32,8 +32,8 @@ class TimerOverviewViewModel @Inject constructor(
|
||||||
open(StudeezDestinations.TIMER_EDIT_SCREEN)
|
open(StudeezDestinations.TIMER_EDIT_SCREEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun create(open: (String) -> Unit) {
|
fun onAddClick(open: (String) -> Unit) {
|
||||||
open(StudeezDestinations.ADD_TIMER_SCREEN)
|
open(StudeezDestinations.TIMER_TYPE_CHOOSING_SCREEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun delete(timerInfo: TimerInfo) =timerDAO.deleteTimer(timerInfo)
|
fun delete(timerInfo: TimerInfo) =timerDAO.deleteTimer(timerInfo)
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_overview.add_timer
|
|
||||||
|
|
||||||
data class AddTimerUiState(
|
|
||||||
val studyTimeHours: Int = 1,
|
|
||||||
val studyTimeMinutes: Int = 0,
|
|
||||||
val withBreaks: Boolean = false,
|
|
||||||
val breakTimeMinutes: Int = 5,
|
|
||||||
val breakTimeHours: Int = 0,
|
|
||||||
val repeats: Int = 1,
|
|
||||||
val name: String = "Timer",
|
|
||||||
val description: String = "Long study session",
|
|
||||||
)
|
|
|
@ -1,91 +0,0 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_overview.add_timer
|
|
||||||
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.CustomTimerInfo
|
|
||||||
import be.ugent.sel.studeez.data.local.models.timer_info.PomodoroTimerInfo
|
|
||||||
import be.ugent.sel.studeez.domain.LogService
|
|
||||||
import be.ugent.sel.studeez.domain.TimerDAO
|
|
||||||
import be.ugent.sel.studeez.screens.StudeezViewModel
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@HiltViewModel
|
|
||||||
class AddTimerViewModel @Inject constructor(
|
|
||||||
logService: LogService,
|
|
||||||
private val timerDAO: TimerDAO,
|
|
||||||
): StudeezViewModel(logService) {
|
|
||||||
var uiState = mutableStateOf(AddTimerUiState())
|
|
||||||
private set
|
|
||||||
|
|
||||||
private val studyTimeHours
|
|
||||||
get() = uiState.value.studyTimeHours
|
|
||||||
|
|
||||||
private val studyTimeMinutes
|
|
||||||
get() = uiState.value.studyTimeMinutes
|
|
||||||
|
|
||||||
private val breakTimeHours
|
|
||||||
get() = uiState.value.breakTimeHours
|
|
||||||
|
|
||||||
private val breakTimeMinutes
|
|
||||||
get() = uiState.value.breakTimeMinutes
|
|
||||||
|
|
||||||
private val repeats
|
|
||||||
get() = uiState.value.repeats
|
|
||||||
|
|
||||||
private val name
|
|
||||||
get() = uiState.value.name
|
|
||||||
|
|
||||||
private val description
|
|
||||||
get() = uiState.value.description
|
|
||||||
|
|
||||||
fun onStudyTimeHoursChange(newValue: Int) {
|
|
||||||
uiState.value = uiState.value.copy(studyTimeHours = newValue)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onStudyTimeMinutesChange(newValue: Int) {
|
|
||||||
uiState.value = uiState.value.copy(studyTimeMinutes = newValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onWithBreaksChange() {
|
|
||||||
uiState.value = uiState.value.copy(withBreaks = !uiState.value.withBreaks)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onBreakTimeHourChange(newValue: Int) {
|
|
||||||
uiState.value = uiState.value.copy(breakTimeHours = newValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onBreakTimeMinutesChange(newValue: Int) {
|
|
||||||
uiState.value = uiState.value.copy(breakTimeMinutes = newValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onRepeatsChange(newValue: Int) {
|
|
||||||
uiState.value = uiState.value.copy(repeats = newValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addTimer() {
|
|
||||||
if (uiState.value.withBreaks) {
|
|
||||||
timerDAO.saveTimer(PomodoroTimerInfo(
|
|
||||||
name = uiState.value.name,
|
|
||||||
description = uiState.value.description,
|
|
||||||
studyTime = studyTimeHours * 60 * 60 + studyTimeMinutes * 60,
|
|
||||||
breakTime = breakTimeHours * 60 * 60 + breakTimeMinutes * 60,
|
|
||||||
repeats = repeats
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
timerDAO.saveTimer(CustomTimerInfo(
|
|
||||||
name = uiState.value.name,
|
|
||||||
description = uiState.value.description,
|
|
||||||
studyTime = studyTimeHours * 60 * 60 + studyTimeMinutes * 60
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onNameChange(newValue: String) {
|
|
||||||
uiState.value = uiState.value.copy(name = newValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onDescriptionChange(newValue: String) {
|
|
||||||
uiState.value = uiState.value.copy(description = newValue)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,274 +0,0 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_overview.add_timer
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.material.Button
|
|
||||||
import androidx.compose.material.Checkbox
|
|
||||||
import androidx.compose.material.Text
|
|
||||||
import androidx.compose.material.TextField
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import be.ugent.sel.studeez.R
|
|
||||||
import be.ugent.sel.studeez.common.composable.BasicButton
|
|
||||||
import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate
|
|
||||||
import be.ugent.sel.studeez.common.composable.navbar.BasicTimePicker
|
|
||||||
import be.ugent.sel.studeez.navigation.StudeezDestinations
|
|
||||||
import be.ugent.sel.studeez.resources
|
|
||||||
import be.ugent.sel.studeez.ui.theme.StudeezTheme
|
|
||||||
|
|
||||||
data class AddTimerActions(
|
|
||||||
val open: (String) -> Unit,
|
|
||||||
val goBack: () -> Unit,
|
|
||||||
val onStudyTimeHoursChange: (Int) -> Unit,
|
|
||||||
val onStudyTimeMinutesChange: (Int) -> Unit,
|
|
||||||
val onBreakTimeHourChange: (Int) -> Unit,
|
|
||||||
val onBreakTimeMinutesChange: (Int) -> Unit,
|
|
||||||
val onRepeatsChange: (Int) -> Unit,
|
|
||||||
val onWithBreaksChange: () -> Unit,
|
|
||||||
val addTimer: () -> Unit,
|
|
||||||
val onNameChange: (String) -> Unit,
|
|
||||||
val onDescriptionChange: (String) -> Unit,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun getAddTimerActions(
|
|
||||||
open: (String) -> Unit,
|
|
||||||
goBack: () -> Unit,
|
|
||||||
viewModel: AddTimerViewModel,
|
|
||||||
): AddTimerActions {
|
|
||||||
return AddTimerActions(
|
|
||||||
open = open,
|
|
||||||
goBack = goBack,
|
|
||||||
onWithBreaksChange = viewModel::onWithBreaksChange,
|
|
||||||
onStudyTimeHoursChange = viewModel::onStudyTimeHoursChange,
|
|
||||||
onStudyTimeMinutesChange = viewModel::onStudyTimeMinutesChange,
|
|
||||||
onBreakTimeHourChange = viewModel::onBreakTimeHourChange,
|
|
||||||
onBreakTimeMinutesChange = viewModel::onBreakTimeMinutesChange,
|
|
||||||
onRepeatsChange = viewModel::onRepeatsChange,
|
|
||||||
addTimer = viewModel::addTimer,
|
|
||||||
onNameChange = viewModel::onNameChange,
|
|
||||||
onDescriptionChange = viewModel::onDescriptionChange
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun AddTimerRoute(
|
|
||||||
open: (String) -> Unit,
|
|
||||||
goBack: () -> Unit,
|
|
||||||
viewModel: AddTimerViewModel,
|
|
||||||
) {
|
|
||||||
val uiState by viewModel.uiState
|
|
||||||
|
|
||||||
AddTimerScreen(
|
|
||||||
addTimerActions = getAddTimerActions(
|
|
||||||
open = open,
|
|
||||||
goBack = goBack,
|
|
||||||
viewModel = viewModel,
|
|
||||||
),
|
|
||||||
uiState = uiState
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun AddTimerScreen(
|
|
||||||
addTimerActions: AddTimerActions,
|
|
||||||
uiState: AddTimerUiState,
|
|
||||||
) {
|
|
||||||
val mStudyTimePicker = BasicTimePicker(
|
|
||||||
onHoursChange = addTimerActions.onStudyTimeHoursChange,
|
|
||||||
onMinutesChange = addTimerActions.onStudyTimeMinutesChange,
|
|
||||||
Hours = uiState.studyTimeHours,
|
|
||||||
Minutes = uiState.studyTimeMinutes
|
|
||||||
)
|
|
||||||
|
|
||||||
val mBreakTimePicker = BasicTimePicker(
|
|
||||||
onHoursChange = addTimerActions.onBreakTimeHourChange,
|
|
||||||
onMinutesChange = addTimerActions.onBreakTimeMinutesChange,
|
|
||||||
Hours = uiState.breakTimeHours,
|
|
||||||
Minutes = uiState.breakTimeMinutes
|
|
||||||
)
|
|
||||||
|
|
||||||
SecondaryScreenTemplate(
|
|
||||||
title = resources().getString(R.string.add_timer),
|
|
||||||
popUp = addTimerActions.goBack
|
|
||||||
) {
|
|
||||||
LazyColumn(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(16.dp),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
|
||||||
) {
|
|
||||||
item {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(16.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.addTimer_question),
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
Text(
|
|
||||||
text = uiState.studyTimeHours.toString() + stringResource(R.string.addTimer_studytime_1) + uiState.studyTimeMinutes + stringResource(
|
|
||||||
R.string.addTimer_studytime_2)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
Button(
|
|
||||||
onClick = {
|
|
||||||
mStudyTimePicker.show()
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.addTimer_timepicker),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.Center
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.addTimer_break_question),
|
|
||||||
)
|
|
||||||
Checkbox(
|
|
||||||
checked = uiState.withBreaks,
|
|
||||||
onCheckedChange = { addTimerActions.onWithBreaksChange() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uiState.withBreaks) {
|
|
||||||
item {
|
|
||||||
Text(
|
|
||||||
text = if (uiState.repeats == 1) uiState.repeats.toString() + stringResource(
|
|
||||||
R.string.addTimer_break_1)
|
|
||||||
else uiState.repeats.toString() + stringResource(
|
|
||||||
R.string.addTimer_break_s)
|
|
||||||
)
|
|
||||||
TextField(
|
|
||||||
value = uiState.repeats.toString(),
|
|
||||||
onValueChange = { it: String ->
|
|
||||||
it.toIntOrNull()?.let { it1 ->
|
|
||||||
addTimerActions.onRepeatsChange(
|
|
||||||
kotlin.math.abs(it1)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
Text(
|
|
||||||
text = uiState.breakTimeHours.toString() + stringResource(R.string.breakTime_1) + uiState.breakTimeMinutes + stringResource(
|
|
||||||
R.string.breakTime_2)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
Button(
|
|
||||||
onClick = {
|
|
||||||
mBreakTimePicker.show()
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.addTimer_timepicker),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.addTimer_name)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
TextField(
|
|
||||||
value = uiState.name,
|
|
||||||
onValueChange = { addTimerActions.onNameChange(it) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
if (uiState.name == "") {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.addTimer_name_error),
|
|
||||||
color = Color.Red
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.addTimer_description)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
TextField(
|
|
||||||
value = uiState.description,
|
|
||||||
onValueChange = { addTimerActions.onDescriptionChange(it) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
if (uiState.description == "") {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.addTimer_description_error),
|
|
||||||
color = Color.Red
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.fillMaxHeight(),
|
|
||||||
verticalAlignment = Alignment.Bottom,
|
|
||||||
horizontalArrangement = Arrangement.Center
|
|
||||||
) {
|
|
||||||
BasicButton(
|
|
||||||
text = R.string.add_timer,
|
|
||||||
modifier = Modifier,
|
|
||||||
onClick = {
|
|
||||||
if (uiState.description != "" && uiState.name != "") {
|
|
||||||
addTimerActions.addTimer()
|
|
||||||
addTimerActions.open(StudeezDestinations.TIMER_SCREEN)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun AddTimerScreenPreview() { StudeezTheme {
|
|
||||||
AddTimerScreen(
|
|
||||||
addTimerActions = AddTimerActions({}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}),
|
|
||||||
uiState = AddTimerUiState()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -131,8 +131,13 @@
|
||||||
<string name="addTimer_studytime_2">" minutes of studytime"</string>
|
<string name="addTimer_studytime_2">" minutes of studytime"</string>
|
||||||
<string name="addTimer_question">How long do you want to study?</string>
|
<string name="addTimer_question">How long do you want to study?</string>
|
||||||
|
|
||||||
|
<!-- Timer Type Select -->
|
||||||
|
<string name="timer_type_select">Select Timer Type</string>
|
||||||
|
|
||||||
<!-- Edit Timer-->
|
<!-- Edit Timer-->
|
||||||
<string name="name">Name</string>
|
<string name="name">Name</string>
|
||||||
|
<string name="edit_timer">Edit Timer</string>
|
||||||
|
<string name="repeats_error">Repeats must be a positive non-zero number</string>
|
||||||
<string name="description">Description</string>
|
<string name="description">Description</string>
|
||||||
<string name="studyTime">Study Time</string>
|
<string name="studyTime">Study Time</string>
|
||||||
<string name="breakTime">Break Time</string>
|
<string name="breakTime">Break Time</string>
|
||||||
|
|
Reference in a new issue