commit
						6bcc4ce4c4
					
				
					 13 changed files with 482 additions and 39 deletions
				
			
		
							
								
								
									
										2
									
								
								.idea/misc.xml
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/misc.xml
									
										
									
										generated
									
									
									
								
							|  | @ -1,7 +1,7 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project version="4"> | ||||
|   <component name="ExternalStorageConfigurationManager" enabled="true" /> | ||||
|   <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK"> | ||||
|   <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK"> | ||||
|     <output url="file://$PROJECT_DIR$/build/classes" /> | ||||
|   </component> | ||||
|   <component name="ProjectType"> | ||||
|  |  | |||
|  | @ -33,6 +33,7 @@ import be.ugent.sel.studeez.screens.settings.SettingsRoute | |||
| 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 | ||||
|  | @ -140,6 +141,7 @@ fun StudeezNavGraph( | |||
|             TimerOverviewRoute( | ||||
|                 viewModel = hiltViewModel(), | ||||
|                 drawerActions = drawerActions, | ||||
|                 open = open | ||||
|             ) | ||||
|         } | ||||
| 
 | ||||
|  | @ -195,6 +197,14 @@ fun StudeezNavGraph( | |||
|             ) | ||||
|         } | ||||
| 
 | ||||
|         composable(StudeezDestinations.ADD_TIMER_SCREEN) { | ||||
|             AddTimerRoute( | ||||
|                 open = open, | ||||
|                 goBack = goBack, | ||||
|                 viewModel = hiltViewModel() | ||||
|             ) | ||||
|         } | ||||
| 
 | ||||
|         // Friends flow | ||||
|         composable(StudeezDestinations.SEARCH_FRIENDS_SCREEN) { | ||||
|             // TODO | ||||
|  |  | |||
|  | @ -16,7 +16,14 @@ import be.ugent.sel.studeez.common.ext.defaultButtonShape | |||
| 
 | ||||
| @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 | ||||
|  |  | |||
|  | @ -0,0 +1,24 @@ | |||
| package be.ugent.sel.studeez.common.composable.navbar | ||||
| 
 | ||||
| import android.app.TimePickerDialog | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.ui.platform.LocalContext | ||||
| 
 | ||||
| @Composable | ||||
| fun BasicTimePicker( | ||||
|     onHoursChange: (Int) -> Unit, | ||||
|     onMinutesChange: (Int) -> Unit, | ||||
|     Hours: Int, | ||||
|     Minutes: Int, | ||||
| ): TimePickerDialog { | ||||
|     return TimePickerDialog( | ||||
|         LocalContext.current, | ||||
|         { _, mHour: Int, mMinute: Int -> | ||||
|             onHoursChange(mHour) | ||||
|             onMinutesChange(mMinute) | ||||
|         }, | ||||
|         Hours, | ||||
|         Minutes, | ||||
|         true | ||||
|     ) | ||||
| } | ||||
|  | @ -28,4 +28,6 @@ object StudeezDestinations { | |||
|     const val CREATE_TASK_SCREEN = "create_task" | ||||
|     const val CREATE_SESSION_SCREEN = "create_session" | ||||
|     const val EDIT_PROFILE_SCREEN = "edit_profile" | ||||
| 
 | ||||
|     const val ADD_TIMER_SCREEN = "add_timer" | ||||
| } | ||||
|  | @ -47,7 +47,9 @@ fun SessionRecapScreen(modifier: Modifier, sessionRecapActions: SessionRecapActi | |||
|     val sessionReport: SessionReport = sessionRecapActions.getSessionReport() | ||||
|     val studyTime: Int = sessionReport.studyTime | ||||
|     val hms: HoursMinutesSeconds = Time(studyTime).getAsHMS() | ||||
|     Column { | ||||
|     Column( | ||||
|         modifier = modifier | ||||
|     ) { | ||||
|         Text(text = "You studied: ${hms.hours} : ${hms.minutes} : ${hms.seconds}") | ||||
| 
 | ||||
|         BasicButton( | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ import javax.inject.Inject | |||
| 
 | ||||
| @HiltViewModel | ||||
| class SessionRecapViewModel @Inject constructor( | ||||
|     private val sessionReportState: SessionReportState, | ||||
|     sessionReportState: SessionReportState, | ||||
|     private val sessionDAO: SessionDAO, | ||||
|     logService: LogService | ||||
| ) : StudeezViewModel(logService) { | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| package be.ugent.sel.studeez.screens.timer_overview | ||||
| 
 | ||||
| import androidx.compose.foundation.layout.Column | ||||
| import androidx.compose.foundation.lazy.LazyColumn | ||||
| import androidx.compose.foundation.lazy.items | ||||
| import androidx.compose.runtime.Composable | ||||
|  | @ -16,6 +15,7 @@ import be.ugent.sel.studeez.common.composable.drawer.DrawerActions | |||
| 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 | ||||
|  | @ -24,25 +24,29 @@ 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 | ||||
|     ) | ||||
| } | ||||
| 
 | ||||
| @Composable | ||||
| fun TimerOverviewRoute( | ||||
|     open: (String) -> Unit, | ||||
|     viewModel: TimerOverviewViewModel, | ||||
|     drawerActions: DrawerActions, | ||||
| ) { | ||||
|     TimerOverviewScreen( | ||||
|         timerOverviewActions = getTimerOverviewActions(viewModel), | ||||
|         timerOverviewActions = getTimerOverviewActions(viewModel, open), | ||||
|         drawerActions = drawerActions, | ||||
|     ) | ||||
| } | ||||
|  | @ -59,36 +63,35 @@ fun TimerOverviewScreen( | |||
|         title = resources().getString(R.string.timers), | ||||
|         drawerActions = drawerActions | ||||
|     ) { | ||||
|         Column { | ||||
|             LazyColumn { | ||||
|                 // Custom timer, select new duration each time | ||||
|                 item { | ||||
|                     TimerEntry(timerInfo = CustomTimerInfo( | ||||
|                         name = resources().getString(R.string.custom_name), | ||||
|                         description = resources().getString(R.string.custom_name), | ||||
|                         studyTime = 0 | ||||
|                     )) | ||||
|                 } | ||||
| 
 | ||||
|                 // Default Timers, cannot be edited | ||||
|                 items(timerOverviewActions.getDefaultTimers()) { | ||||
|                     TimerEntry(timerInfo = it) {} | ||||
|                 } | ||||
|                 // User timers, can be edited | ||||
|                 items(timers.value) { timerInfo -> | ||||
|                     TimerEntry( | ||||
|                         timerInfo = timerInfo, | ||||
|                     ) { | ||||
|                         StealthButton( | ||||
|                             text = R.string.edit, | ||||
|                             onClick = { timerOverviewActions.onEditClick(timerInfo) } | ||||
|                         ) | ||||
|                     } | ||||
| 
 | ||||
|                 } | ||||
|         LazyColumn { | ||||
|             // Custom timer, select new duration each time | ||||
|             item { | ||||
|                 TimerEntry(timerInfo = CustomTimerInfo( | ||||
|                     name = resources().getString(R.string.custom_name), | ||||
|                     description = resources().getString(R.string.custom_name), | ||||
|                     studyTime = 0 | ||||
|                 )) | ||||
|             } | ||||
|             BasicButton(R.string.add_timer, Modifier.basicButton()) { | ||||
|                 // TODO | ||||
|             // Default Timers, cannot be edited | ||||
|             items(timerOverviewActions.getDefaultTimers()) { | ||||
|                 TimerEntry(timerInfo = it) {} | ||||
|             } | ||||
|             // User timers, can be edited | ||||
|             items(timers.value) { timerInfo -> | ||||
|                 TimerEntry( | ||||
|                     timerInfo = timerInfo, | ||||
|                 ) { | ||||
|                     StealthButton( | ||||
|                         text = R.string.edit, | ||||
|                         onClick = { timerOverviewActions.onEditClick(timerInfo) } | ||||
|                     ) | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
|             item { | ||||
|                 BasicButton(R.string.add_timer, Modifier.basicButton()) { | ||||
|                     timerOverviewActions.open(StudeezDestinations.ADD_TIMER_SCREEN) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -104,7 +107,9 @@ fun TimerOverviewPreview() { | |||
|         timerOverviewActions = TimerOverviewActions( | ||||
|             { flowOf() }, | ||||
|             { listOf(customTimer, customTimer) }, | ||||
|             {}), | ||||
|             {}, | ||||
|             {} | ||||
|         ), | ||||
|         drawerActions = DrawerActions({}, {}, {}, {}, {}) | ||||
|     ) | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,12 @@ | |||
| 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", | ||||
| ) | ||||
|  | @ -0,0 +1,91 @@ | |||
| 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) | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,274 @@ | |||
| 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_OVERVIEW_SCREEN) | ||||
|                             } | ||||
|                          } | ||||
|                     ) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @Preview | ||||
| @Composable | ||||
| fun AddTimerScreenPreview() { StudeezTheme { | ||||
|     AddTimerScreen( | ||||
|         addTimerActions = AddTimerActions({}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}), | ||||
|         uiState = AddTimerUiState() | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|  | @ -107,5 +107,20 @@ | |||
| 
 | ||||
|     <!-- Session --> | ||||
|     <string name="create_session_not_possible_yet">Creating sessions still needs to be implemented. Hang on tight!</string> <!-- TODO Remove this description line once implemented. --> | ||||
|    | ||||
|     <!-- Add Timer --> | ||||
|     <string name="addTimer_description_error">Timer description cannot be empty!</string> | ||||
|     <string name="addTimer_description">Timer description</string> | ||||
|     <string name="addTimer_name_error">Timer name cannot be empty!</string> | ||||
|     <string name="addTimer_name">Timer name</string> | ||||
|     <string name="addTimer_timepicker">Open Time Picker</string> | ||||
|     <string name="breakTime_1">" hours and "</string> | ||||
|     <string name="breakTime_2">" minutes of breaktime"</string> | ||||
|     <string name="addTimer_break_1">" break"</string> | ||||
|     <string name="addTimer_break_s">" breaks"</string> | ||||
|     <string name="addTimer_break_question">With breaks?</string> | ||||
|     <string name="addTimer_studytime_1">" hours and "</string> | ||||
|     <string name="addTimer_studytime_2">" minutes of studytime"</string> | ||||
|     <string name="addTimer_question">How long do you want to study?</string> | ||||
| 
 | ||||
| </resources> | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ package be.ugent.sel.studeez.timer_functional | |||
| 
 | ||||
| import android.media.MediaPlayer | ||||
| import be.ugent.sel.studeez.data.SelectedTimerState | ||||
| import be.ugent.sel.studeez.data.SessionReportState | ||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer | ||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer | ||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer | ||||
|  | @ -24,7 +25,7 @@ class InvisibleSessionManagerTest { | |||
|     @Test | ||||
|     fun InvisibleEndlessTimerTest() = runTest { | ||||
|         timerState.selectedTimer = FunctionalEndlessTimer() | ||||
|         viewModel = SessionViewModel(timerState, mock()) | ||||
|         viewModel = SessionViewModel(timerState, SessionReportState(), mock()) | ||||
|         InvisibleSessionManager.setParameters(viewModel, mediaPlayer) | ||||
| 
 | ||||
|         val test = launch { | ||||
|  | @ -46,7 +47,7 @@ class InvisibleSessionManagerTest { | |||
|         val breakTime = 5 | ||||
|         val repeats = 1 | ||||
|         timerState.selectedTimer = FunctionalPomodoroTimer(studyTime, breakTime, repeats) | ||||
|         viewModel = SessionViewModel(timerState, mock()) | ||||
|         viewModel = SessionViewModel(timerState, SessionReportState(), mock()) | ||||
|         InvisibleSessionManager.setParameters(viewModel, mediaPlayer) | ||||
| 
 | ||||
|         val test = launch { | ||||
|  | @ -79,7 +80,7 @@ class InvisibleSessionManagerTest { | |||
|     @Test | ||||
|     fun InvisibleCustomTimerTest() = runTest { | ||||
|         timerState.selectedTimer = FunctionalCustomTimer(5) | ||||
|         viewModel = SessionViewModel(timerState, mock()) | ||||
|         viewModel = SessionViewModel(timerState, SessionReportState(), mock()) | ||||
|         InvisibleSessionManager.setParameters(viewModel, mediaPlayer) | ||||
| 
 | ||||
|         val test = launch { | ||||
|  |  | |||
		Reference in a new issue
	
	 GitHub Enterprise
							GitHub Enterprise