commit
						86bc8d9e1a
					
				
					 13 changed files with 123 additions and 41 deletions
				
			
		|  | @ -26,6 +26,7 @@ import be.ugent.sel.studeez.screens.profile.ProfileScreen | ||||||
| import be.ugent.sel.studeez.screens.sign_up.SignUpScreen | import be.ugent.sel.studeez.screens.sign_up.SignUpScreen | ||||||
| import be.ugent.sel.studeez.screens.splash.SplashScreen | import be.ugent.sel.studeez.screens.splash.SplashScreen | ||||||
| import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewScreen | import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewScreen | ||||||
|  | import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionScreen | ||||||
| import be.ugent.sel.studeez.ui.theme.StudeezTheme | import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||||
| import kotlinx.coroutines.CoroutineScope | import kotlinx.coroutines.CoroutineScope | ||||||
| 
 | 
 | ||||||
|  | @ -130,4 +131,8 @@ fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) { | ||||||
|     composable(StudeezDestinations.EDIT_PROFILE_SCREEN) { |     composable(StudeezDestinations.EDIT_PROFILE_SCREEN) { | ||||||
|         EditProfileScreen(goBack, openAndPopUp) |         EditProfileScreen(goBack, openAndPopUp) | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     composable(StudeezDestinations.TIMER_SELECTION_SCREEN) { | ||||||
|  |         TimerSelectionScreen(open, openAndPopUp) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | package be.ugent.sel.studeez.data | ||||||
|  | 
 | ||||||
|  | import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer | ||||||
|  | import javax.inject.Inject | ||||||
|  | import javax.inject.Singleton | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Used to communicate the SelectedTimer from the selection screen to the session screen. | ||||||
|  |  * Because this is a singleton-class the view-models of both screens observe the same data. | ||||||
|  |  */ | ||||||
|  | @Singleton | ||||||
|  | class SelectedTimerState @Inject constructor(){ | ||||||
|  |     var selectedTimer: FunctionalTimer? = null | ||||||
|  | } | ||||||
|  | @ -3,7 +3,7 @@ package be.ugent.sel.studeez.data.local.models.timer_info | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer | import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer | import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer | ||||||
| 
 | 
 | ||||||
| class BreakTimerInfo( | class PomodoroTimerInfo( | ||||||
|     name: String, |     name: String, | ||||||
|     description: String, |     description: String, | ||||||
|     private val studyTime: Int, |     private val studyTime: Int, | ||||||
|  | @ -30,7 +30,7 @@ class ToTimerConverter { | ||||||
|             it.studyTime, |             it.studyTime, | ||||||
|             it.id |             it.id | ||||||
|         ) }, |         ) }, | ||||||
|         TimerType.BREAK to TimerFactory { BreakTimerInfo( |         TimerType.BREAK to TimerFactory { PomodoroTimerInfo( | ||||||
|             it.name, |             it.name, | ||||||
|             it.description, |             it.description, | ||||||
|             it.studyTime, |             it.studyTime, | ||||||
|  |  | ||||||
|  | @ -5,8 +5,9 @@ object StudeezDestinations { | ||||||
|     const val SIGN_UP_SCREEN = "signup" |     const val SIGN_UP_SCREEN = "signup" | ||||||
|     const val LOGIN_SCREEN = "login" |     const val LOGIN_SCREEN = "login" | ||||||
| 
 | 
 | ||||||
|      const val HOME_SCREEN = "home" |     const val HOME_SCREEN = "home" | ||||||
|     const val TIMER_OVERVIEW_SCREEN = "timer_overview" |     const val TIMER_OVERVIEW_SCREEN = "timer_overview" | ||||||
|  |     const val TIMER_SELECTION_SCREEN = "timer_selection" | ||||||
|     const val SESSION_SCREEN = "session" |     const val SESSION_SCREEN = "session" | ||||||
|  //    const val TASKS_SCREEN = "tasks" |  //    const val TASKS_SCREEN = "tasks" | ||||||
|  //    const val SESSIONS_SCREEN = "sessions" |  //    const val SESSIONS_SCREEN = "sessions" | ||||||
|  |  | ||||||
|  | @ -15,14 +15,7 @@ class HomeViewModel @Inject constructor( | ||||||
|     logService: LogService |     logService: LogService | ||||||
| ) : StudeezViewModel(logService) { | ) : StudeezViewModel(logService) { | ||||||
| 
 | 
 | ||||||
|     fun onStartSessionClick(openAndPopUp: (String) -> Unit) { |     fun onStartSessionClick(open: (String) -> Unit) { | ||||||
|         openAndPopUp(StudeezDestinations.SESSION_SCREEN) |         open(StudeezDestinations.TIMER_SELECTION_SCREEN) | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fun onLogoutClick(openAndPopup: (String, String) -> Unit) { |  | ||||||
|         launchCatching { |  | ||||||
|             accountDAO.signOut() |  | ||||||
|             openAndPopup(LOGIN_SCREEN, HOME_SCREEN) |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -7,37 +7,32 @@ import androidx.compose.runtime.* | ||||||
| import androidx.compose.ui.Modifier | import androidx.compose.ui.Modifier | ||||||
| import androidx.compose.ui.text.font.FontWeight | import androidx.compose.ui.text.font.FontWeight | ||||||
| import androidx.compose.ui.text.style.TextAlign | import androidx.compose.ui.text.style.TextAlign | ||||||
| import androidx.compose.ui.unit.TextUnit |  | ||||||
| import androidx.compose.ui.unit.dp |  | ||||||
| import androidx.compose.ui.unit.sp | import androidx.compose.ui.unit.sp | ||||||
| import androidx.hilt.navigation.compose.hiltViewModel | import androidx.hilt.navigation.compose.hiltViewModel | ||||||
| import be.ugent.sel.studeez.R | import be.ugent.sel.studeez.R | ||||||
| import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate | import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate | ||||||
|  | import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate | ||||||
| import be.ugent.sel.studeez.resources | import be.ugent.sel.studeez.resources | ||||||
| import kotlinx.coroutines.delay | import kotlinx.coroutines.delay | ||||||
|  | import kotlin.time.Duration.Companion.seconds | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| fun SessionScreen( | fun SessionScreen( | ||||||
|     open: (String) -> Unit, |     open: (String) -> Unit, | ||||||
|     openAndPopUp: (String, String) -> Unit, |     openAndPopUp: (String, String) -> Unit, | ||||||
|     viewModel: SessionViewModel = hiltViewModel() |  | ||||||
| ) { | ) { | ||||||
|     PrimaryScreenTemplate( |     Timer() | ||||||
|         title = resources().getString(R.string.start_session), |  | ||||||
|         open = open, |  | ||||||
|         openAndPopUp = openAndPopUp |  | ||||||
|     ) { |  | ||||||
|         Timer(viewModel) |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| private fun Timer(viewModel: SessionViewModel = hiltViewModel()) { | fun Timer(viewModel: SessionViewModel = hiltViewModel()) { | ||||||
|     var tikker by remember { mutableStateOf(false) } | 
 | ||||||
|     LaunchedEffect(tikker) { | 
 | ||||||
|         delay(1000) |     var ticker by remember { mutableStateOf(false) } | ||||||
|  |     LaunchedEffect(ticker) { | ||||||
|  |         delay(1.seconds) | ||||||
|         viewModel.getTimer().tick() |         viewModel.getTimer().tick() | ||||||
|         tikker = !tikker |         ticker = !ticker | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     val hms = viewModel.getTimer().getHoursMinutesSeconds() |     val hms = viewModel.getTimer().getHoursMinutesSeconds() | ||||||
|  |  | ||||||
|  | @ -1,20 +1,19 @@ | ||||||
| package be.ugent.sel.studeez.screens.session | package be.ugent.sel.studeez.screens.session | ||||||
| 
 | 
 | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer |  | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer | import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer | ||||||
| import be.ugent.sel.studeez.domain.LogService | import be.ugent.sel.studeez.domain.LogService | ||||||
| import be.ugent.sel.studeez.screens.StudeezViewModel | import be.ugent.sel.studeez.screens.StudeezViewModel | ||||||
|  | import be.ugent.sel.studeez.data.SelectedTimerState | ||||||
| import dagger.hilt.android.lifecycle.HiltViewModel | import dagger.hilt.android.lifecycle.HiltViewModel | ||||||
| import javax.inject.Inject | import javax.inject.Inject | ||||||
| 
 | 
 | ||||||
| @HiltViewModel | @HiltViewModel | ||||||
| class SessionViewModel @Inject constructor( | class SessionViewModel @Inject constructor( | ||||||
|  |     private val selectedTimerState: SelectedTimerState, | ||||||
|     logService: LogService |     logService: LogService | ||||||
| ) : StudeezViewModel(logService) { | ) : StudeezViewModel(logService) { | ||||||
| 
 | 
 | ||||||
|     private val timer: FunctionalTimer = FunctionalPomodoroTimer(15, 5, 3) |  | ||||||
| 
 |  | ||||||
|     fun getTimer() : FunctionalTimer { |     fun getTimer() : FunctionalTimer { | ||||||
|         return timer |         return selectedTimerState.selectedTimer!! | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| package be.ugent.sel.studeez.screens.timer_overview | package be.ugent.sel.studeez.screens.timer_overview | ||||||
| 
 | 
 | ||||||
|  | import androidx.annotation.StringRes | ||||||
| import androidx.compose.foundation.layout.Arrangement | import androidx.compose.foundation.layout.Arrangement | ||||||
| import androidx.compose.foundation.layout.Column | import androidx.compose.foundation.layout.Column | ||||||
| import androidx.compose.foundation.layout.Row | import androidx.compose.foundation.layout.Row | ||||||
|  | @ -46,12 +47,12 @@ fun TimerOverviewScreen( | ||||||
|             ) { |             ) { | ||||||
|                 // Default Timers, cannot be edited |                 // Default Timers, cannot be edited | ||||||
|                 items(viewModel.getDefaultTimers()) { |                 items(viewModel.getDefaultTimers()) { | ||||||
|                     TimerEntry(timerInfo = it, canEdit = false) |                     TimerEntry(timerInfo = it, canDisplay = false) | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 // User timers, can be edited |                 // User timers, can be edited | ||||||
|                 items(timers.value) { |                 items(timers.value) { | ||||||
|                     TimerEntry(timerInfo = it, true) { timerInfo -> |                     TimerEntry(timerInfo = it, true, R.string.edit) { timerInfo -> | ||||||
|                         viewModel.update(timerInfo) |                         viewModel.update(timerInfo) | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  | @ -65,7 +66,12 @@ fun TimerOverviewScreen( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| fun TimerEntry(timerInfo: TimerInfo, canEdit: Boolean, update: (TimerInfo) -> Unit = {}) { | fun TimerEntry( | ||||||
|  |     timerInfo: TimerInfo, | ||||||
|  |     canDisplay: Boolean, | ||||||
|  |     @StringRes buttonName: Int = -1, | ||||||
|  |     buttonFunction: (TimerInfo) -> Unit = {} | ||||||
|  | ) { | ||||||
|     Row( |     Row( | ||||||
|         verticalAlignment = Alignment.CenterVertically, |         verticalAlignment = Alignment.CenterVertically, | ||||||
|         modifier = Modifier.fillMaxWidth(), |         modifier = Modifier.fillMaxWidth(), | ||||||
|  | @ -83,9 +89,9 @@ fun TimerEntry(timerInfo: TimerInfo, canEdit: Boolean, update: (TimerInfo) -> Un | ||||||
|                 fontSize = 15.sp |                 fontSize = 15.sp | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
|         if (canEdit) { |         if (canDisplay) { | ||||||
|             BasicButton(R.string.edit, Modifier.card()) { |             BasicButton(buttonName, Modifier.card()) { | ||||||
|                 // TODO |                 buttonFunction(timerInfo) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,44 @@ | ||||||
|  | package be.ugent.sel.studeez.screens.timer_selection | ||||||
|  | 
 | ||||||
|  | import androidx.compose.foundation.layout.Arrangement | ||||||
|  | import androidx.compose.foundation.lazy.LazyColumn | ||||||
|  | import androidx.compose.foundation.lazy.items | ||||||
|  | import androidx.compose.runtime.* | ||||||
|  | import androidx.compose.ui.unit.dp | ||||||
|  | import androidx.hilt.navigation.compose.hiltViewModel | ||||||
|  | import be.ugent.sel.studeez.R | ||||||
|  | import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate | ||||||
|  | import be.ugent.sel.studeez.resources | ||||||
|  | import be.ugent.sel.studeez.screens.timer_overview.TimerEntry | ||||||
|  | 
 | ||||||
|  | @Composable | ||||||
|  | fun TimerSelectionScreen( | ||||||
|  |     open: (String) -> Unit, | ||||||
|  |     openAndPopUp: (String, String) -> Unit, | ||||||
|  |     viewModel: TimerSelectionViewModel = hiltViewModel() | ||||||
|  | ) { | ||||||
|  | 
 | ||||||
|  |     val timers = viewModel.getAllTimers().collectAsState(initial = emptyList()) | ||||||
|  | 
 | ||||||
|  |     PrimaryScreenTemplate( | ||||||
|  |         title = resources().getString(R.string.timers), | ||||||
|  |         open = open, | ||||||
|  |         openAndPopUp = openAndPopUp, | ||||||
|  |     ) { | ||||||
|  | 
 | ||||||
|  |         LazyColumn(verticalArrangement = Arrangement.spacedBy(7.dp)) { | ||||||
|  | 
 | ||||||
|  |             // All timers | ||||||
|  |             items(timers.value) { | ||||||
|  |                 TimerEntry( | ||||||
|  |                     timerInfo = it, | ||||||
|  |                     canDisplay = true, | ||||||
|  |                     buttonName = R.string.start | ||||||
|  |                 ) { timerInfo -> | ||||||
|  |                     viewModel.startSession(open, timerInfo) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,28 @@ | ||||||
|  | package be.ugent.sel.studeez.screens.timer_selection | ||||||
|  | 
 | ||||||
|  | import be.ugent.sel.studeez.data.SelectedTimerState | ||||||
|  | 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 TimerSelectionViewModel @Inject constructor( | ||||||
|  |     private val timerDAO: TimerDAO, | ||||||
|  |     private val selectedTimerState: SelectedTimerState, | ||||||
|  |     logService: LogService | ||||||
|  | ) : StudeezViewModel(logService) { | ||||||
|  | 
 | ||||||
|  |     fun getAllTimers() : Flow<List<TimerInfo>> { | ||||||
|  |         return timerDAO.getAllTimers() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun startSession(open: (String) -> Unit, timerInfo: TimerInfo) { | ||||||
|  |         selectedTimerState.selectedTimer = timerInfo.getFunctionalTimer() | ||||||
|  |         open(StudeezDestinations.SESSION_SCREEN) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,4 +0,0 @@ | ||||||
| package be.ugent.sel.studeez.screens.timers |  | ||||||
| 
 |  | ||||||
| class TimerScreen { |  | ||||||
| } |  | ||||||
|  | @ -13,6 +13,7 @@ | ||||||
|         <string name="cancel">Cancel</string> |         <string name="cancel">Cancel</string> | ||||||
|         <string name="go_back">Go back</string> |         <string name="go_back">Go back</string> | ||||||
|         <string name="next">Next</string> |         <string name="next">Next</string> | ||||||
|  |         <string name="start">Start</string> | ||||||
| 
 | 
 | ||||||
|         <!-- Messages --> |         <!-- Messages --> | ||||||
|         <string name="success">Success!</string> |         <string name="success">Success!</string> | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 brreynie
						brreynie