LazyColumn not fixed

This commit is contained in:
Rune Dyselinck 2023-04-27 17:01:39 +02:00
parent 601740f258
commit 2ca112ee0e
6 changed files with 303 additions and 28 deletions

View file

@ -34,6 +34,7 @@ import be.ugent.sel.studeez.screens.session.SessionRoute
import be.ugent.sel.studeez.screens.sign_up.SignUpRoute
import be.ugent.sel.studeez.screens.splash.SplashRoute
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.ui.theme.StudeezTheme
import kotlinx.coroutines.CoroutineScope
@ -167,5 +168,14 @@ fun StudeezNavGraph(
navBarViewModel = navBarViewModel,
)
}
composable(StudeezDestinations.ADD_TIMER_SCREEN) {
AddTimerRoute(
open = open,
openAndPopUp = openAndPopUp,
goBack = goBack,
viewModel = hiltViewModel()
)
}
}
}

View file

@ -23,7 +23,14 @@ import be.ugent.sel.studeez.common.ext.card
@Composable
fun BasicTextButton(@StringRes text: Int, modifier: Modifier, action: () -> Unit) {
TextButton(onClick = action, modifier = modifier) { Text(text = stringResource(text)) }
TextButton(
onClick = action,
modifier = modifier
) {
Text(
text = stringResource(text)
)
}
}
@Composable

View file

@ -23,6 +23,7 @@ import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions
import be.ugent.sel.studeez.common.ext.basicButton
import be.ugent.sel.studeez.data.local.models.timer_info.CustomTimerInfo
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
import be.ugent.sel.studeez.navigation.StudeezDestinations
import be.ugent.sel.studeez.resources
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
@ -31,15 +32,18 @@ data class TimerOverviewActions(
val getUserTimers: () -> Flow<List<TimerInfo>>,
val getDefaultTimers: () -> List<TimerInfo>,
val onEditClick: (TimerInfo) -> Unit,
val open: (String) -> Unit,
)
fun getTimerOverviewActions(
viewModel: TimerOverviewViewModel,
open: (String) -> Unit,
): TimerOverviewActions {
return TimerOverviewActions(
getUserTimers = viewModel::getUserTimers,
getDefaultTimers = viewModel::getDefaultTimers,
onEditClick = { viewModel.update(it) },
open = open
)
}
@ -52,7 +56,7 @@ fun TimerOverviewRoute(
navBarViewModel: NavigationBarViewModel,
) {
TimerOverviewScreen(
timerOverviewActions = getTimerOverviewActions(viewModel),
timerOverviewActions = getTimerOverviewActions(viewModel, open),
drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp),
navigationBarActions = getNavigationBarActions(navBarViewModel, open),
)
@ -95,7 +99,7 @@ fun TimerOverviewScreen(
}
}
BasicButton(R.string.add_timer, Modifier.basicButton()) {
// TODO
timerOverviewActions.open(StudeezDestinations.ADD_TIMER_SCREEN)
}
}
}
@ -111,7 +115,9 @@ fun TimerOverviewPreview() {
timerOverviewActions = TimerOverviewActions(
{ flowOf() },
{ listOf(customTimer, customTimer) },
{}),
{},
{}
),
drawerActions = DrawerActions({}, {}, {}, {}, {}),
navigationBarActions = NavigationBarActions({}, {}, {}, {})
)

View file

@ -0,0 +1,11 @@
package be.ugent.sel.studeez.screens.timer_overview.add_timer
data class AddTimerUiState(
val studyTimeHours: Float = 1f,
val studyTimeMinutes: Float = 0f,
val withBreaks: Boolean = false,
val breakTime: Float = 5f,
val repeats: Float = 1f,
val name: String = "",
val description: String = "",
)

View file

@ -1,13 +1,85 @@
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.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 AddTimerViewModel @Inject constructor(
logService: LogService
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 breakTime
get() = uiState.value.breakTime
private val repeats
get() = uiState.value.repeats
private val name
get() = uiState.value.name
private val description
get() = uiState.value.description
fun onStudyTimeHoursChange(newValue: Float) {
uiState.value = uiState.value.copy(studyTimeHours = newValue)
}
fun onStudyTimeMinutesChange(newValue: Float) {
uiState.value = uiState.value.copy(studyTimeMinutes = newValue)
}
fun onWithBreaksChange(newValue: Boolean) {
uiState.value = uiState.value.copy(withBreaks = newValue)
}
fun onBreakTimeChange(newValue: Float) {
uiState.value = uiState.value.copy(breakTime = newValue)
}
fun onRepeatsChange(newValue: Float) {
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.toInt() * 60 * 60 + studyTimeMinutes.toInt() * 60,
breakTime = breakTime.toInt() * 60,
repeats = repeats.toInt()
))
} else {
timerDAO.saveTimer(CustomTimerInfo(
name = uiState.value.name,
description = uiState.value.description,
studyTime = studyTimeHours.toInt() * 60 * 60 + studyTimeMinutes.toInt() * 60
))
}
}
fun onNameChange(newValue: String) {
uiState.value = uiState.value.copy(name = newValue)
}
fun onDescriptionChange(newValue: String) {
uiState.value = uiState.value.copy(description = newValue)
}
}

View file

@ -1,42 +1,211 @@
package be.ugent.sel.studeez.screens.timer_overview.add_timer
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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.Checkbox
import androidx.compose.material.Slider
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.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.drawer.DrawerActions
import be.ugent.sel.studeez.common.composable.drawer.DrawerViewModel
import be.ugent.sel.studeez.common.composable.drawer.getDrawerActions
import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions
import be.ugent.sel.studeez.common.composable.navbar.NavigationBarViewModel
import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions
import be.ugent.sel.studeez.resources
data class AddTimerActions(
val goBack: () -> Unit,
val onStudyTimeHoursChange: (Float) -> Unit,
val onStudyTimeMinutesChange: (Float) -> Unit,
val onBreakTimeChange: (Float) -> Unit,
val onRepeatsChange: (Float) -> Unit,
val onWithBreaksChange: (Boolean) -> Unit,
val addTimer: () -> Unit,
val onNameChange: (String) -> Unit,
val onDescriptionChange: (String) -> Unit,
)
fun getAddTimerActions(
goBack: () -> Unit,
viewModel: AddTimerViewModel,
): AddTimerActions {
return AddTimerActions(
goBack = goBack,
onWithBreaksChange = viewModel::onWithBreaksChange,
onStudyTimeHoursChange = viewModel::onStudyTimeHoursChange,
onStudyTimeMinutesChange = viewModel::onStudyTimeMinutesChange,
onBreakTimeChange = viewModel::onBreakTimeChange,
onRepeatsChange = viewModel::onRepeatsChange,
addTimer = viewModel::addTimer,
onNameChange = viewModel::onNameChange,
onDescriptionChange = viewModel::onDescriptionChange
)
}
@Composable
fun AddTimerRoute(
open: (String) -> Unit,
openAndPopUp: (String, String) -> Unit
openAndPopUp: (String, String) -> Unit,
goBack: () -> Unit,
viewModel: AddTimerViewModel,
drawerViewModel: DrawerViewModel,
navBarViewModel: NavigationBarViewModel,
) {
addTimerScreen(
drawerActions = getDrawerActions(
drawerViewModel = drawerViewModel,
open = open,
openAndPopUp = openAndPopUp
val uiState by viewModel.uiState
AddTimerScreen(
addTimerActions = getAddTimerActions(
goBack = goBack,
viewModel = viewModel,
),
navigationBarActions = getNavigationBarActions(
navigationBarViewModel = navBarViewModel,
open = open
)
uiState = uiState
)
}
fun addTimerScreen(
drawerActions: DrawerActions,
navigationBarActions: NavigationBarActions
@Composable
fun AddTimerScreen(
addTimerActions: AddTimerActions,
uiState: AddTimerUiState,
) {
SecondaryScreenTemplate(
title = ,
popUp = { /*TODO*/ }) {
title = resources().getString(R.string.add_timer),
popUp = addTimerActions.goBack
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Text(
text = "How long do you want to study?",
textAlign = TextAlign.Center
)
}
LazyColumn(
modifier = Modifier
.padding(16.dp)
) {
item{
Text(
text = "${uiState.studyTimeHours.toInt()} hour${ if (uiState.studyTimeHours == 1f) "" else "s"}"
)
Slider(
value = uiState.studyTimeHours,
onValueChange = {
addTimerActions.onStudyTimeHoursChange(it)
},
steps = 8,
valueRange = 1f..10f,
enabled = true
)
Text(
text = "${uiState.studyTimeMinutes.toInt()} minutes"
)
Slider(
value = uiState.studyTimeMinutes,
onValueChange = {
addTimerActions.onStudyTimeMinutesChange(it)
},
steps = 11,
valueRange = 0f..60f,
enabled = true
)
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Text(
text = "With breaks?",
)
Checkbox(
checked = uiState.withBreaks,
onCheckedChange = { addTimerActions.onWithBreaksChange(it) }
)
}
Text(
text = if (uiState.withBreaks) "breaks of ${uiState.breakTime.toInt()} minutes" else "",
)
Slider(
value = uiState.breakTime,
onValueChange = {
addTimerActions.onBreakTimeChange(it)
},
steps = 11,
valueRange = 0f..60f,
enabled = uiState.withBreaks
)
Text(
text = if (uiState.withBreaks) "${uiState.repeats.toInt()} breaks" else ""
)
Slider(
value = uiState.repeats,
onValueChange = {
addTimerActions.onRepeatsChange(it)
},
steps = 8,
valueRange = 1f..10f,
enabled = uiState.withBreaks
)
Text(
text = "Timer name"
)
TextField(
value = uiState.name,
onValueChange = { addTimerActions.onNameChange(it) }
)
Text(
text = "Timer description"
)
TextField(
value = uiState.description,
onValueChange = { addTimerActions.onDescriptionChange(it) }
)
Row(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(),
verticalAlignment = Alignment.Bottom,
horizontalArrangement = Arrangement.Center
) {
BasicButton(
text = R.string.add_timer,
modifier = Modifier,
onClick = addTimerActions.addTimer
)
}
}
}
}
}
}
@Preview
@Composable
fun AddTimerScreenPreview() {
AddTimerScreen(
addTimerActions = AddTimerActions({}, {}, {}, {}, {}, {}, {}, {}, {}),
uiState = AddTimerUiState()
)
}