commit
						d3159e0b2a
					
				
					 29 changed files with 583 additions and 110 deletions
				
			
		|  | @ -32,6 +32,7 @@ import be.ugent.sel.studeez.screens.sessions.SessionsRoute | ||||||
| import be.ugent.sel.studeez.screens.settings.SettingsRoute | import be.ugent.sel.studeez.screens.settings.SettingsRoute | ||||||
| import be.ugent.sel.studeez.screens.sign_up.SignUpRoute | import be.ugent.sel.studeez.screens.sign_up.SignUpRoute | ||||||
| import be.ugent.sel.studeez.screens.splash.SplashRoute | import be.ugent.sel.studeez.screens.splash.SplashRoute | ||||||
|  | import be.ugent.sel.studeez.screens.timer_edit.TimerEditRoute | ||||||
| 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_overview.add_timer.AddTimerRoute | ||||||
| import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute | import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute | ||||||
|  | @ -205,6 +206,14 @@ fun StudeezNavGraph( | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         composable(StudeezDestinations.TIMER_EDIT_SCREEN) { | ||||||
|  |             TimerEditRoute( | ||||||
|  |                 open = open, | ||||||
|  |                 popUp = goBack, | ||||||
|  |                 viewModel = hiltViewModel() | ||||||
|  |             ) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         // Friends flow |         // Friends flow | ||||||
|         composable(StudeezDestinations.SEARCH_FRIENDS_SCREEN) { |         composable(StudeezDestinations.SEARCH_FRIENDS_SCREEN) { | ||||||
|             // TODO |             // TODO | ||||||
|  |  | ||||||
|  | @ -3,46 +3,113 @@ package be.ugent.sel.studeez.common.composable | ||||||
| import android.app.TimePickerDialog | import android.app.TimePickerDialog | ||||||
| import android.app.TimePickerDialog.OnTimeSetListener | import android.app.TimePickerDialog.OnTimeSetListener | ||||||
| import android.content.Context | import android.content.Context | ||||||
|  | import androidx.annotation.StringRes | ||||||
| import androidx.compose.foundation.BorderStroke | import androidx.compose.foundation.BorderStroke | ||||||
|  | import androidx.compose.foundation.layout.Arrangement | ||||||
|  | import androidx.compose.foundation.layout.Row | ||||||
|  | import androidx.compose.foundation.layout.fillMaxWidth | ||||||
| import androidx.compose.foundation.shape.RoundedCornerShape | import androidx.compose.foundation.shape.RoundedCornerShape | ||||||
| import androidx.compose.material.Button | import androidx.compose.material.* | ||||||
| import androidx.compose.material.ButtonColors |  | ||||||
| import androidx.compose.material.ButtonDefaults |  | ||||||
| import androidx.compose.material.Text |  | ||||||
| import androidx.compose.runtime.Composable | import androidx.compose.runtime.Composable | ||||||
|  | import androidx.compose.runtime.MutableState | ||||||
|  | import androidx.compose.runtime.mutableStateOf | ||||||
|  | import androidx.compose.runtime.remember | ||||||
|  | import androidx.compose.ui.Alignment | ||||||
| import androidx.compose.ui.Modifier | import androidx.compose.ui.Modifier | ||||||
| import androidx.compose.ui.platform.LocalContext | import androidx.compose.ui.platform.LocalContext | ||||||
|  | import androidx.compose.ui.res.stringResource | ||||||
|  | import androidx.compose.ui.text.font.FontWeight | ||||||
|  | import androidx.compose.ui.tooling.preview.Preview | ||||||
| import androidx.compose.ui.unit.dp | import androidx.compose.ui.unit.dp | ||||||
|  | import be.ugent.sel.studeez.R | ||||||
|  | import be.ugent.sel.studeez.common.ext.fieldModifier | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds | import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds | ||||||
| import java.util.* | import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||||
|  | 
 | ||||||
|  | @Composable | ||||||
|  | fun TimePickerCard( | ||||||
|  |     @StringRes text: Int, | ||||||
|  |     initialSeconds: Int, | ||||||
|  |     onTimeChosen: (Int) -> Unit | ||||||
|  | ) { | ||||||
|  |     Card( | ||||||
|  |         modifier = Modifier | ||||||
|  |             .fillMaxWidth() | ||||||
|  |             .fieldModifier(), | ||||||
|  |         elevation = 10.dp | ||||||
|  |     ) { | ||||||
|  |         Row( | ||||||
|  |             modifier = Modifier | ||||||
|  |                 .fillMaxWidth() | ||||||
|  |                 .fieldModifier(), | ||||||
|  |             horizontalArrangement = Arrangement.SpaceBetween, | ||||||
|  |             verticalAlignment = Alignment.CenterVertically | ||||||
|  |         ) { | ||||||
|  |             Text( | ||||||
|  |                 text = stringResource(id = text), | ||||||
|  |                 fontWeight = FontWeight.Medium | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |             TimePickerButton( | ||||||
|  |                 initialSeconds = initialSeconds, | ||||||
|  |                 onTimeChosen = onTimeChosen | ||||||
|  |             ) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| fun TimePickerButton( | fun TimePickerButton( | ||||||
|     hoursMinutesSeconds: HoursMinutesSeconds, |     initialSeconds: Int, | ||||||
|     modifier: Modifier = Modifier, |     modifier: Modifier = Modifier, | ||||||
|     colors: ButtonColors = ButtonDefaults.buttonColors(), |     colors: ButtonColors = ButtonDefaults.buttonColors(), | ||||||
|     border: BorderStroke? = null, |     border: BorderStroke? = null, | ||||||
|     onTimeSetListener: OnTimeSetListener |     onTimeChosen: (Int) -> Unit | ||||||
| ) { | ) { | ||||||
|     val context = LocalContext.current |     val context = LocalContext.current | ||||||
|  |     val timeState: MutableState<Int> = remember { | ||||||
|  |         mutableStateOf(initialSeconds) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     Button( |     Button( | ||||||
|         onClick = { pickDuration(context, onTimeSetListener) }, |         onClick = { pickDuration(context, onTimeChosen, timeState) }, | ||||||
|         modifier = modifier, |         modifier = modifier, | ||||||
|         shape = RoundedCornerShape(20.dp), |         shape = RoundedCornerShape(20.dp), | ||||||
|         colors = colors, |         colors = colors, | ||||||
|         border = border |         border = border | ||||||
|     ) { |     ) { | ||||||
|         Text(text = hoursMinutesSeconds.toString()) |         Text(text = HoursMinutesSeconds(timeState.value).toString()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| private fun pickDuration(context: Context, listener: OnTimeSetListener) { | private fun pickDuration(context: Context, onTimeChosen: (Int) -> Unit, timeState: MutableState<Int>) { | ||||||
|     val timePickerDialog = TimePickerDialog( |     val listener = OnTimeSetListener { _, hour, minute -> | ||||||
|  |         timeState.value = HoursMinutesSeconds(hour, minute, 0).getTotalSeconds() | ||||||
|  |         onTimeChosen(timeState.value) | ||||||
|  |     } | ||||||
|  |     val hms = HoursMinutesSeconds(timeState.value) | ||||||
|  |     val mTimePickerDialog = TimePickerDialog( | ||||||
|         context, |         context, | ||||||
|         listener, |         listener, | ||||||
|         0, |         hms.hours, | ||||||
|         0, |         hms.minutes, | ||||||
|         true |         true | ||||||
|     ) |     ) | ||||||
|     timePickerDialog.show() |     mTimePickerDialog.show() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Preview | ||||||
|  | @Composable | ||||||
|  | fun TimePickerButtonPreview() { | ||||||
|  |     StudeezTheme { | ||||||
|  |         TimePickerButton(initialSeconds = 5 * 60 + 12, onTimeChosen = {}) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Preview | ||||||
|  | @Composable | ||||||
|  | fun TimePickerCardPreview() { | ||||||
|  |     StudeezTheme { | ||||||
|  |         TimePickerCard(text = R.string.studyTime, initialSeconds = 5 * 60 + 12, onTimeChosen = {}) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -1,4 +1,11 @@ | ||||||
| package be.ugent.sel.studeez.data | package be.ugent.sel.studeez.data | ||||||
| 
 | 
 | ||||||
| class EditTimerState { | import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer | ||||||
|  | import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo | ||||||
|  | import javax.inject.Inject | ||||||
|  | import javax.inject.Singleton | ||||||
|  | 
 | ||||||
|  | @Singleton | ||||||
|  | class EditTimerState @Inject constructor(){ | ||||||
|  |     lateinit var timerInfo: TimerInfo | ||||||
| } | } | ||||||
|  | @ -4,7 +4,7 @@ class FunctionalCustomTimer(studyTime: Int) : FunctionalTimer(studyTime) { | ||||||
| 
 | 
 | ||||||
|     override fun tick() { |     override fun tick() { | ||||||
|         if (!hasEnded()) { |         if (!hasEnded()) { | ||||||
|             time.minOne() |             time-- | ||||||
|             totalStudyTime++ |             totalStudyTime++ | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -11,7 +11,7 @@ class FunctionalEndlessTimer : FunctionalTimer(0) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun tick() { |     override fun tick() { | ||||||
|         time.plusOne() |         time++ | ||||||
|         totalStudyTime++ |         totalStudyTime++ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ class FunctionalPomodoroTimer( | ||||||
|             } |             } | ||||||
|             isInBreak = !isInBreak |             isInBreak = !isInBreak | ||||||
|         } |         } | ||||||
|         time.minOne() |         time-- | ||||||
| 
 | 
 | ||||||
|         if (!isInBreak) { |         if (!isInBreak) { | ||||||
|             totalStudyTime++ |             totalStudyTime++ | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ import be.ugent.sel.studeez.data.local.models.SessionReport | ||||||
| import com.google.firebase.Timestamp | import com.google.firebase.Timestamp | ||||||
| 
 | 
 | ||||||
| abstract class FunctionalTimer(initialValue: Int) { | abstract class FunctionalTimer(initialValue: Int) { | ||||||
|     val time: Time = Time(initialValue) |     var time: Time = Time(initialValue) | ||||||
|     var totalStudyTime: Int = 0 |     var totalStudyTime: Int = 0 | ||||||
| 
 | 
 | ||||||
|     fun getHoursMinutesSeconds(): HoursMinutesSeconds { |     fun getHoursMinutesSeconds(): HoursMinutesSeconds { | ||||||
|  |  | ||||||
|  | @ -2,6 +2,12 @@ package be.ugent.sel.studeez.data.local.models.timer_functional | ||||||
| 
 | 
 | ||||||
| data class HoursMinutesSeconds(val hours: Int, val minutes: Int, val seconds: Int) { | data class HoursMinutesSeconds(val hours: Int, val minutes: Int, val seconds: Int) { | ||||||
| 
 | 
 | ||||||
|  |     constructor(sec: Int): this( | ||||||
|  |         sec / (60 * 60), | ||||||
|  |         (sec / (60)) % 60, | ||||||
|  |         sec % 60 | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|     fun getTotalSeconds(): Int { |     fun getTotalSeconds(): Int { | ||||||
|         return hours * 60 * 60 + minutes * 60 + seconds |         return hours * 60 * 60 + minutes * 60 + seconds | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,23 +1,13 @@ | ||||||
| package be.ugent.sel.studeez.data.local.models.timer_functional | package be.ugent.sel.studeez.data.local.models.timer_functional | ||||||
| 
 | 
 | ||||||
| class Time(initialTime: Int) { | class Time(var time: Int) { | ||||||
|  |     operator fun invoke() = time | ||||||
| 
 | 
 | ||||||
|     var time = initialTime |     operator fun inc(): Time = Time(time + 1) | ||||||
| 
 | 
 | ||||||
|     fun minOne() { |     operator fun dec(): Time = Time(time - 1) | ||||||
|         time-- |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fun plusOne() { |  | ||||||
|         time++ |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     fun getAsHMS(): HoursMinutesSeconds { |     fun getAsHMS(): HoursMinutesSeconds { | ||||||
|         val hours: Int = time / (60 * 60) |         return HoursMinutesSeconds(time) | ||||||
|         val minutes: Int = (time / (60)) % 60 |  | ||||||
|         val seconds: Int = time % 60 |  | ||||||
| 
 |  | ||||||
|         return HoursMinutesSeconds(hours, minutes, seconds) |  | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | @ -7,8 +7,8 @@ import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimerVi | ||||||
| class PomodoroTimerInfo( | class PomodoroTimerInfo( | ||||||
|     name: String, |     name: String, | ||||||
|     description: String, |     description: String, | ||||||
|     val studyTime: Int, |     var studyTime: Int, | ||||||
|     val breakTime: Int, |     var breakTime: Int, | ||||||
|     val repeats: Int, |     val repeats: Int, | ||||||
|     id: String = "" |     id: String = "" | ||||||
| ):  TimerInfo(id, name, description) { | ):  TimerInfo(id, name, description) { | ||||||
|  |  | ||||||
|  | @ -18,6 +18,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 SESSION_SCREEN = "session" |     const val SESSION_SCREEN = "session" | ||||||
|     const val SESSION_RECAP = "session_recap" |     const val SESSION_RECAP = "session_recap" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -78,7 +78,7 @@ abstract class AbstractSessionScreen { | ||||||
|         val hms = sessionActions.getTimer().getHoursMinutesSeconds() |         val hms = sessionActions.getTimer().getHoursMinutesSeconds() | ||||||
|         Column { |         Column { | ||||||
|             Text( |             Text( | ||||||
|                 text = "${hms.hours} : ${hms.minutes} : ${hms.seconds}", |                 text = hms.toString(), | ||||||
|                 modifier = Modifier |                 modifier = Modifier | ||||||
|                     .fillMaxWidth() |                     .fillMaxWidth() | ||||||
|                     .padding(50.dp), |                     .padding(50.dp), | ||||||
|  |  | ||||||
|  | @ -50,7 +50,7 @@ fun SessionRecapScreen(modifier: Modifier, sessionRecapActions: SessionRecapActi | ||||||
|     Column( |     Column( | ||||||
|         modifier = modifier |         modifier = modifier | ||||||
|     ) { |     ) { | ||||||
|         Text(text = "You studied: ${hms.hours} : ${hms.minutes} : ${hms.seconds}") |         Text(text = "You studied: $hms") | ||||||
| 
 | 
 | ||||||
|         BasicButton( |         BasicButton( | ||||||
|             R.string.save, Modifier.basicButton() |             R.string.save, Modifier.basicButton() | ||||||
|  |  | ||||||
|  | @ -0,0 +1,44 @@ | ||||||
|  | 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) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,29 @@ | ||||||
|  | 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() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,43 @@ | ||||||
|  | package be.ugent.sel.studeez.screens.timer_add | ||||||
|  | 
 | ||||||
|  | import androidx.compose.foundation.layout.Column | ||||||
|  | import androidx.compose.foundation.layout.fillMaxWidth | ||||||
|  | import androidx.compose.material.Button | ||||||
|  | import androidx.compose.material.Text | ||||||
|  | import androidx.compose.runtime.Composable | ||||||
|  | import androidx.compose.ui.Alignment | ||||||
|  | import androidx.compose.ui.Modifier | ||||||
|  | import androidx.hilt.navigation.compose.hiltViewModel | ||||||
|  | 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.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.ENDLESS | ||||||
|  | 
 | ||||||
|  | val defaultTimerInfo: Map<TimerType, TimerInfo> = mapOf( | ||||||
|  |     CUSTOM to CustomTimerInfo("", "", 0), | ||||||
|  |     BREAK to PomodoroTimerInfo("", "", 0, 0, 0), | ||||||
|  |     ENDLESS to EndlessTimerInfo("", ""), | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @Composable | ||||||
|  | fun TimerTypeSelectScreen( | ||||||
|  |     open: (String) -> Unit, | ||||||
|  |     popUp: () -> Unit, | ||||||
|  |     viewModel: TimerTypeSelectViewModel = hiltViewModel() | ||||||
|  | ) { | ||||||
|  | 
 | ||||||
|  |     SecondaryScreenTemplate(title = "Edit Timer", popUp = popUp) { | ||||||
|  |         Column( | ||||||
|  |             horizontalAlignment = Alignment.CenterHorizontally, | ||||||
|  |             modifier = Modifier.fillMaxWidth() | ||||||
|  |         ) { | ||||||
|  |             TimerType.values().forEach { timerType -> | ||||||
|  |                 Button(onClick = { viewModel.onTimerTypeChosen(defaultTimerInfo[timerType]!!, open) }) { | ||||||
|  |                     Text(text = timerType.name) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,25 @@ | ||||||
|  | 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.navigation.StudeezDestinations | ||||||
|  | import be.ugent.sel.studeez.screens.StudeezViewModel | ||||||
|  | import dagger.hilt.android.lifecycle.HiltViewModel | ||||||
|  | import kotlinx.coroutines.flow.Flow | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | @HiltViewModel | ||||||
|  | class TimerTypeSelectViewModel @Inject constructor( | ||||||
|  |     private val editTimerState: EditTimerState, | ||||||
|  |     private val timerDAO: TimerDAO, | ||||||
|  |     logService: LogService | ||||||
|  | ) : StudeezViewModel(logService) { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     fun onTimerTypeChosen(timerInfo: TimerInfo, open: (String) -> Unit) { | ||||||
|  |         editTimerState.timerInfo = timerInfo | ||||||
|  |         open(StudeezDestinations.TIMER_EDIT_SCREEN) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,34 +1,26 @@ | ||||||
| package be.ugent.sel.studeez.screens.timer_edit | package be.ugent.sel.studeez.screens.timer_edit | ||||||
| 
 | 
 | ||||||
| import android.annotation.SuppressLint |  | ||||||
| import androidx.compose.foundation.layout.Column |  | ||||||
| import androidx.compose.foundation.layout.Row |  | ||||||
| import androidx.compose.material.Text |  | ||||||
| import androidx.compose.runtime.Composable |  | ||||||
| import androidx.compose.ui.Modifier |  | ||||||
| import be.ugent.sel.studeez.R |  | ||||||
| import be.ugent.sel.studeez.common.composable.BasicButton |  | ||||||
| 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.CustomTimerInfo | ||||||
| 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.data.local.models.timer_info.PomodoroTimerInfo | 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.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 GetTimerEditView: TimerInfoVisitor<Unit> { | class GetTimerEditScreen: TimerInfoVisitor<AbstractTimerEditScreen> { | ||||||
| 
 |  | ||||||
|     @SuppressLint("ComposableNaming") |  | ||||||
|     override fun visitCustomTimerInfo(customTimerInfo: CustomTimerInfo) { |  | ||||||
| 
 | 
 | ||||||
|  |     override fun visitCustomTimerInfo(customTimerInfo: CustomTimerInfo): AbstractTimerEditScreen { | ||||||
|  |         return CustomTimerEditScreen(customTimerInfo) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @SuppressLint("ComposableNaming") |     override fun visitEndlessTimerInfo(endlessTimerInfo: EndlessTimerInfo): AbstractTimerEditScreen { | ||||||
|     override fun visitEndlessTimerInfo(endlessTimerInfo: EndlessTimerInfo) { |         return EndlessTimerEditScreen(endlessTimerInfo) | ||||||
| 
 |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @SuppressLint("ComposableNaming") |     override fun visitBreakTimerInfo(pomodoroTimerInfo: PomodoroTimerInfo): AbstractTimerEditScreen { | ||||||
|     override fun visitBreakTimerInfo(pomodoroTimerInfo: PomodoroTimerInfo) { |         return BreakTimerEditScreen(pomodoroTimerInfo) | ||||||
| 
 |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,2 +1,65 @@ | ||||||
| package be.ugent.sel.studeez.screens.timer_edit | 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) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,29 @@ | ||||||
| package be.ugent.sel.studeez.screens.timer_edit | package be.ugent.sel.studeez.screens.timer_edit | ||||||
| 
 | 
 | ||||||
| class TimerEditViewModel { | 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 TimerEditViewModel @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,4 +1,70 @@ | ||||||
| package be.ugent.sel.studeez.screens.timer_edit | package be.ugent.sel.studeez.screens.timer_edit.editScreens | ||||||
|  | 
 | ||||||
|  | import androidx.compose.foundation.layout.Arrangement | ||||||
|  | import androidx.compose.foundation.layout.Column | ||||||
|  | import androidx.compose.foundation.layout.fillMaxHeight | ||||||
|  | import androidx.compose.foundation.layout.fillMaxWidth | ||||||
|  | import androidx.compose.foundation.rememberScrollState | ||||||
|  | import androidx.compose.foundation.verticalScroll | ||||||
|  | import androidx.compose.runtime.* | ||||||
|  | import androidx.compose.ui.Alignment | ||||||
|  | import androidx.compose.ui.Modifier | ||||||
|  | import be.ugent.sel.studeez.R | ||||||
|  | import be.ugent.sel.studeez.common.composable.BasicButton | ||||||
|  | import be.ugent.sel.studeez.common.composable.LabelledInputField | ||||||
|  | import be.ugent.sel.studeez.common.ext.basicButton | ||||||
|  | import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo | ||||||
|  | 
 | ||||||
|  | abstract class AbstractTimerEditScreen(private val timerInfo: TimerInfo) { | ||||||
|  | 
 | ||||||
|  |     @Composable | ||||||
|  |     operator fun invoke(onSaveClick: (TimerInfo) -> Unit) { | ||||||
|  | 
 | ||||||
|  |         var name by remember { mutableStateOf(timerInfo.name) } | ||||||
|  |         var description by remember { mutableStateOf(timerInfo.description) } | ||||||
|  | 
 | ||||||
|  |         // This shall rerun whenever name and description change | ||||||
|  |         timerInfo.name = name | ||||||
|  |         timerInfo.description = description | ||||||
|  | 
 | ||||||
|  |         Column( | ||||||
|  |             verticalArrangement = Arrangement.SpaceBetween, | ||||||
|  |             modifier = Modifier.fillMaxHeight().verticalScroll(rememberScrollState()), | ||||||
|  |         ) { | ||||||
|  |             Column( | ||||||
|  |                 modifier = Modifier.fillMaxWidth(), | ||||||
|  |                 horizontalAlignment = Alignment.CenterHorizontally | ||||||
|  |             ) { | ||||||
|  | 
 | ||||||
|  |                 // Fields that every timer shares (ommited id) | ||||||
|  |                 LabelledInputField( | ||||||
|  |                     value = name, | ||||||
|  |                     onNewValue = { name = it }, | ||||||
|  |                     label = R.string.name | ||||||
|  |                 ) | ||||||
|  | 
 | ||||||
|  |                 repeat(20) { | ||||||
|  |                     LabelledInputField( | ||||||
|  |                         value = description, | ||||||
|  |                         onNewValue = { description = it }, | ||||||
|  |                         label = R.string.description, | ||||||
|  |                         singleLine = false | ||||||
|  |                     ) | ||||||
|  | 
 | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 ExtraFields() | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  |             BasicButton(R.string.save, Modifier.basicButton()) { | ||||||
|  |                 onSaveClick(timerInfo) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Composable | ||||||
|  |     open fun ExtraFields() { | ||||||
|  |         // By default no extra fields, unless overwritten by subclass. | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| abstract class AbstractTimerEditScreen { |  | ||||||
| } | } | ||||||
|  | @ -1,4 +1,46 @@ | ||||||
| package be.ugent.sel.studeez.screens.timer_edit.editScreens | package be.ugent.sel.studeez.screens.timer_edit.editScreens | ||||||
| 
 | 
 | ||||||
| class BreakTimerEditScreen { | import androidx.compose.runtime.* | ||||||
|  | import androidx.compose.ui.tooling.preview.Preview | ||||||
|  | import be.ugent.sel.studeez.R | ||||||
|  | import be.ugent.sel.studeez.common.composable.TimePickerButton | ||||||
|  | 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.ui.theme.StudeezTheme | ||||||
|  | 
 | ||||||
|  | class BreakTimerEditScreen( | ||||||
|  |     private val breakTimerInfo: PomodoroTimerInfo | ||||||
|  | ): AbstractTimerEditScreen(breakTimerInfo) { | ||||||
|  | 
 | ||||||
|  |     @Composable | ||||||
|  |     override fun ExtraFields() { | ||||||
|  |         // If the user presses the OK button on the timepicker, the time in the button should change | ||||||
|  | 
 | ||||||
|  |         TimePickerCard(R.string.studyTime, breakTimerInfo.studyTime) { newTime -> | ||||||
|  |             breakTimerInfo.studyTime = newTime | ||||||
|  |         } | ||||||
|  |         TimePickerCard(R.string.breakTime, breakTimerInfo.breakTime) { newTime -> | ||||||
|  |             breakTimerInfo.breakTime = newTime | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Preview | ||||||
|  | @Composable | ||||||
|  | fun BreakEditScreenPreview() { | ||||||
|  |     val pomodoroTimerInfo = PomodoroTimerInfo( | ||||||
|  |         "Breaky the Breaktimer", | ||||||
|  |         "Breaky is a breakdancer", | ||||||
|  |         10 * 60, | ||||||
|  |         60, | ||||||
|  |         5 | ||||||
|  |     ) | ||||||
|  |     StudeezTheme { | ||||||
|  |         BreakTimerEditScreen(pomodoroTimerInfo).invoke(onSaveClick = {}) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -1,4 +1,34 @@ | ||||||
| package be.ugent.sel.studeez.screens.timer_edit | package be.ugent.sel.studeez.screens.timer_edit.editScreens | ||||||
| 
 | 
 | ||||||
| class CustomTimerEditScreen { | import androidx.compose.runtime.* | ||||||
|  | import androidx.compose.ui.tooling.preview.Preview | ||||||
|  | import be.ugent.sel.studeez.common.composable.TimePickerCard | ||||||
|  | import be.ugent.sel.studeez.data.local.models.timer_info.CustomTimerInfo | ||||||
|  | import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||||
|  | import be.ugent.sel.studeez.R.string as AppText | ||||||
|  | 
 | ||||||
|  | class CustomTimerEditScreen( | ||||||
|  |     private val customTimerInfo: CustomTimerInfo | ||||||
|  |     ): AbstractTimerEditScreen(customTimerInfo) { | ||||||
|  | 
 | ||||||
|  |     @Composable | ||||||
|  |     override fun ExtraFields() { | ||||||
|  |         TimePickerCard( | ||||||
|  |             text = AppText.studyTime, | ||||||
|  |             initialSeconds = customTimerInfo.studyTime | ||||||
|  |         ) { newTime -> | ||||||
|  |             customTimerInfo.studyTime = newTime | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Preview | ||||||
|  | @Composable | ||||||
|  | fun CustomEditScreenPreview() { | ||||||
|  |     val customTimerInfo = CustomTimerInfo("custom", "my description", 25) | ||||||
|  |     StudeezTheme { | ||||||
|  |         CustomTimerEditScreen(customTimerInfo).invoke(onSaveClick = {}) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -1,4 +1,23 @@ | ||||||
| package be.ugent.sel.studeez.screens.timer_edit.editScreens | package be.ugent.sel.studeez.screens.timer_edit.editScreens | ||||||
| 
 | 
 | ||||||
| class EndlessTimerEditScreen { | import androidx.compose.runtime.Composable | ||||||
|  | import androidx.compose.ui.tooling.preview.Preview | ||||||
|  | import be.ugent.sel.studeez.data.local.models.timer_info.EndlessTimerInfo | ||||||
|  | import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||||
|  | 
 | ||||||
|  | class EndlessTimerEditScreen( | ||||||
|  |     endlessTimerInfo: EndlessTimerInfo | ||||||
|  | ): AbstractTimerEditScreen(endlessTimerInfo) { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Preview | ||||||
|  | @Composable | ||||||
|  | fun EndlessEditScreenPreview() { | ||||||
|  |     val endlessTimerInfo = EndlessTimerInfo( | ||||||
|  |         "Forever and beyond", | ||||||
|  |         "My endless timer description", | ||||||
|  |     ) | ||||||
|  |     StudeezTheme { | ||||||
|  |         EndlessTimerEditScreen(endlessTimerInfo).invoke(onSaveClick = {}) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| package be.ugent.sel.studeez.screens.timer_overview | 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.LazyColumn | ||||||
| import androidx.compose.foundation.lazy.items | import androidx.compose.foundation.lazy.items | ||||||
| import androidx.compose.runtime.Composable | import androidx.compose.runtime.Composable | ||||||
|  | @ -24,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 open: (String) -> Unit, |     val onAddClick: () -> Unit, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| fun getTimerOverviewActions( | fun getTimerOverviewActions( | ||||||
|  | @ -34,20 +35,20 @@ fun getTimerOverviewActions( | ||||||
|     return TimerOverviewActions( |     return TimerOverviewActions( | ||||||
|         getUserTimers = viewModel::getUserTimers, |         getUserTimers = viewModel::getUserTimers, | ||||||
|         getDefaultTimers = viewModel::getDefaultTimers, |         getDefaultTimers = viewModel::getDefaultTimers, | ||||||
|         onEditClick = { viewModel.update(it) }, |         onEditClick = { viewModel.update(it, open) }, | ||||||
|         open = open |         onAddClick = { viewModel.create(open) } | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| fun TimerOverviewRoute( | fun TimerOverviewRoute( | ||||||
|     open: (String) -> Unit, |  | ||||||
|     viewModel: TimerOverviewViewModel, |     viewModel: TimerOverviewViewModel, | ||||||
|     drawerActions: DrawerActions, |     drawerActions: DrawerActions, | ||||||
|  |     open: (String) -> Unit | ||||||
| ) { | ) { | ||||||
|     TimerOverviewScreen( |     TimerOverviewScreen( | ||||||
|         timerOverviewActions = getTimerOverviewActions(viewModel, open), |         timerOverviewActions = getTimerOverviewActions(viewModel, open), | ||||||
|         drawerActions = drawerActions, |         drawerActions = drawerActions | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -63,6 +64,7 @@ fun TimerOverviewScreen( | ||||||
|         title = resources().getString(R.string.timers), |         title = resources().getString(R.string.timers), | ||||||
|         drawerActions = drawerActions |         drawerActions = drawerActions | ||||||
|     ) { |     ) { | ||||||
|  |         Column { // TODO knop beneden | ||||||
|             LazyColumn { |             LazyColumn { | ||||||
|                 // Custom timer, select new duration each time |                 // Custom timer, select new duration each time | ||||||
|                 item { |                 item { | ||||||
|  | @ -88,9 +90,12 @@ fun TimerOverviewScreen( | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                 } |                 } | ||||||
|  | 
 | ||||||
|  |                 // TODO uit lazy column | ||||||
|                 item { |                 item { | ||||||
|                     BasicButton(R.string.add_timer, Modifier.basicButton()) { |                     BasicButton(R.string.add_timer, Modifier.basicButton()) { | ||||||
|                     timerOverviewActions.open(StudeezDestinations.ADD_TIMER_SCREEN) |                         timerOverviewActions.onAddClick() | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -1,9 +1,11 @@ | ||||||
| package be.ugent.sel.studeez.screens.timer_overview | package be.ugent.sel.studeez.screens.timer_overview | ||||||
| 
 | 
 | ||||||
|  | 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.ConfigurationService | import be.ugent.sel.studeez.domain.ConfigurationService | ||||||
| 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.domain.TimerDAO | ||||||
|  | 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 kotlinx.coroutines.flow.Flow | ||||||
|  | @ -13,6 +15,7 @@ import javax.inject.Inject | ||||||
| class TimerOverviewViewModel @Inject constructor( | class TimerOverviewViewModel @Inject constructor( | ||||||
|     private val configurationService: ConfigurationService, |     private val configurationService: ConfigurationService, | ||||||
|     private val timerDAO: TimerDAO, |     private val timerDAO: TimerDAO, | ||||||
|  |     private val editTimerState: EditTimerState, | ||||||
|     logService: LogService |     logService: LogService | ||||||
| ) : StudeezViewModel(logService) { | ) : StudeezViewModel(logService) { | ||||||
| 
 | 
 | ||||||
|  | @ -24,7 +27,14 @@ class TimerOverviewViewModel @Inject constructor( | ||||||
|         return configurationService.getDefaultTimers() |         return configurationService.getDefaultTimers() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun update(timerInfo: TimerInfo) = timerDAO.updateTimer(timerInfo) |     fun update(timerInfo: TimerInfo, open: (String) -> Unit)  { | ||||||
|  |         editTimerState.timerInfo = timerInfo | ||||||
|  |         open(StudeezDestinations.TIMER_EDIT_SCREEN) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun create(open: (String) -> Unit) { | ||||||
|  |         open(StudeezDestinations.ADD_TIMER_SCREEN) | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     fun delete(timerInfo: TimerInfo) =timerDAO.deleteTimer(timerInfo) |     fun delete(timerInfo: TimerInfo) =timerDAO.deleteTimer(timerInfo) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -253,7 +253,7 @@ fun AddTimerScreen( | ||||||
|                         onClick = { |                         onClick = { | ||||||
|                             if (uiState.description != "" && uiState.name != "") { |                             if (uiState.description != "" && uiState.name != "") { | ||||||
|                                 addTimerActions.addTimer() |                                 addTimerActions.addTimer() | ||||||
|                                 addTimerActions.open(StudeezDestinations.TIMER_OVERVIEW_SCREEN) |                                 addTimerActions.open(StudeezDestinations.TIMER_SCREEN) | ||||||
|                             } |                             } | ||||||
|                          } |                          } | ||||||
|                     ) |                     ) | ||||||
|  |  | ||||||
|  | @ -1,11 +1,9 @@ | ||||||
| package be.ugent.sel.studeez.screens.timer_selection | package be.ugent.sel.studeez.screens.timer_selection | ||||||
| 
 | 
 | ||||||
| import android.widget.TimePicker |  | ||||||
| import androidx.compose.foundation.lazy.LazyColumn | import androidx.compose.foundation.lazy.LazyColumn | ||||||
| import androidx.compose.foundation.lazy.items | import androidx.compose.foundation.lazy.items | ||||||
| import androidx.compose.runtime.Composable | import androidx.compose.runtime.Composable | ||||||
| import androidx.compose.runtime.collectAsState | import androidx.compose.runtime.collectAsState | ||||||
| import androidx.compose.ui.platform.LocalContext |  | ||||||
| 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.SecondaryScreenTemplate | import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate | ||||||
|  | @ -23,7 +21,6 @@ import kotlinx.coroutines.flow.flowOf | ||||||
| data class TimerSelectionActions( | data class TimerSelectionActions( | ||||||
|     val getAllTimers: () -> Flow<List<TimerInfo>>, |     val getAllTimers: () -> Flow<List<TimerInfo>>, | ||||||
|     val startSession: (TimerInfo) -> Unit, |     val startSession: (TimerInfo) -> Unit, | ||||||
|     val pickDuration: (TimePicker?, Int, Int) -> Unit, |  | ||||||
|     val customTimeStudyTime: Int |     val customTimeStudyTime: Int | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -34,9 +31,6 @@ fun getTimerSelectionActions( | ||||||
|     return TimerSelectionActions( |     return TimerSelectionActions( | ||||||
|         getAllTimers = viewModel::getAllTimers, |         getAllTimers = viewModel::getAllTimers, | ||||||
|         startSession = { viewModel.startSession(open, it) }, |         startSession = { viewModel.startSession(open, it) }, | ||||||
|         pickDuration = { _, hour: Int, minute: Int -> |  | ||||||
|             viewModel.customTimerStudyTime.value = hour * 60 * 60 + minute * 60 |  | ||||||
|         }, |  | ||||||
|         customTimeStudyTime = viewModel.customTimerStudyTime.value |         customTimeStudyTime = viewModel.customTimerStudyTime.value | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  | @ -105,10 +99,9 @@ fun CustomTimerEntry( | ||||||
|             ) |             ) | ||||||
|         }, |         }, | ||||||
|         rightButton = { |         rightButton = { | ||||||
|             TimePickerButton( |             TimePickerButton(initialSeconds = hms.getTotalSeconds()) { chosenTime -> | ||||||
|                 hoursMinutesSeconds = hms, |                 timerInfo.studyTime = chosenTime | ||||||
|                 onTimeSetListener = timerSelectionActions.pickDuration |             } | ||||||
|             ) |  | ||||||
|         } |         } | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  | @ -117,7 +110,7 @@ fun CustomTimerEntry( | ||||||
| @Composable | @Composable | ||||||
| fun TimerSelectionPreview() { | fun TimerSelectionPreview() { | ||||||
|     TimerSelectionScreen( |     TimerSelectionScreen( | ||||||
|         timerSelectionActions = TimerSelectionActions({ flowOf() }, {}, { _, _, _ -> {} }, 0), |         timerSelectionActions = TimerSelectionActions({ flowOf() }, {}, 0), | ||||||
|         popUp = {} |         popUp = {} | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  | @ -123,4 +123,11 @@ | ||||||
|     <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> | ||||||
| 
 | 
 | ||||||
|  |     <!-- Edit Timer--> | ||||||
|  |     <string name="name">Name</string> | ||||||
|  |     <string name="description">Description</string> | ||||||
|  |     <string name="studyTime">Study Time</string> | ||||||
|  |     <string name="breakTime">Break Time</string> | ||||||
|  |     <string name="repeats">Number of Repeats</string> | ||||||
|  | 
 | ||||||
| </resources> | </resources> | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 lbarraga
						lbarraga