commit
						6b7ec41f32
					
				
					 23 changed files with 207 additions and 57 deletions
				
			
		
							
								
								
									
										1
									
								
								.idea/inspectionProfiles/Project_Default.xml
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								.idea/inspectionProfiles/Project_Default.xml
									
										
									
										generated
									
									
									
								
							|  | @ -42,5 +42,6 @@ | ||||||
|       <option name="processLiterals" value="true" /> |       <option name="processLiterals" value="true" /> | ||||||
|       <option name="processComments" value="true" /> |       <option name="processComments" value="true" /> | ||||||
|     </inspection_tool> |     </inspection_tool> | ||||||
|  |     <inspection_tool class="TestFunctionName" enabled="false" level="WEAK WARNING" enabled_by_default="false" /> | ||||||
|   </profile> |   </profile> | ||||||
| </component> | </component> | ||||||
							
								
								
									
										2
									
								
								.idea/misc.xml
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/misc.xml
									
										
									
										generated
									
									
									
								
							|  | @ -1,7 +1,7 @@ | ||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <project version="4"> | <project version="4"> | ||||||
|   <component name="ExternalStorageConfigurationManager" enabled="true" /> |   <component name="ExternalStorageConfigurationManager" enabled="true" /> | ||||||
|   <component name="ProjectRootManager" version="2" languageLevel="JDK_17_PREVIEW" project-jdk-name="jbr-17" project-jdk-type="JavaSDK"> |   <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK"> | ||||||
|     <output url="file://$PROJECT_DIR$/build/classes" /> |     <output url="file://$PROJECT_DIR$/build/classes" /> | ||||||
|   </component> |   </component> | ||||||
|   <component name="ProjectType"> |   <component name="ProjectType"> | ||||||
|  |  | ||||||
|  | @ -66,6 +66,7 @@ dependencies { | ||||||
|     implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" |     implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" | ||||||
|     implementation 'androidx.compose.material:material:1.2.0' |     implementation 'androidx.compose.material:material:1.2.0' | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|     debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version" |     debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version" | ||||||
| 
 | 
 | ||||||
|     // ViewModel |     // ViewModel | ||||||
|  | @ -97,6 +98,9 @@ dependencies { | ||||||
|     testImplementation 'junit:junit:4.13.2' |     testImplementation 'junit:junit:4.13.2' | ||||||
|     androidTestImplementation 'androidx.test.ext:junit:1.1.5' |     androidTestImplementation 'androidx.test.ext:junit:1.1.5' | ||||||
| 
 | 
 | ||||||
|  |     // Coroutine testing | ||||||
|  |     testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4' | ||||||
|  | 
 | ||||||
|     // Mocking |     // Mocking | ||||||
|     testImplementation 'org.mockito.kotlin:mockito-kotlin:3.2.0' |     testImplementation 'org.mockito.kotlin:mockito-kotlin:3.2.0' | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,9 +10,15 @@ import androidx.compose.material.Text | ||||||
| import androidx.compose.runtime.Composable | import androidx.compose.runtime.Composable | ||||||
| import androidx.compose.ui.Modifier | import androidx.compose.ui.Modifier | ||||||
| import androidx.compose.ui.tooling.preview.Preview | import androidx.compose.ui.tooling.preview.Preview | ||||||
|  | import androidx.lifecycle.lifecycleScope | ||||||
| import be.ugent.sel.studeez.StudeezApp | import be.ugent.sel.studeez.StudeezApp | ||||||
|  | import be.ugent.sel.studeez.screens.session.InvisibleSessionManager | ||||||
| import be.ugent.sel.studeez.ui.theme.StudeezTheme | import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||||
| import dagger.hilt.android.AndroidEntryPoint | import dagger.hilt.android.AndroidEntryPoint | ||||||
|  | import kotlinx.coroutines.Job | ||||||
|  | import kotlinx.coroutines.launch | ||||||
|  | 
 | ||||||
|  | var onTimerInvisible: Job? = null | ||||||
| 
 | 
 | ||||||
| @AndroidEntryPoint | @AndroidEntryPoint | ||||||
| class MainActivity : ComponentActivity() { | class MainActivity : ComponentActivity() { | ||||||
|  | @ -30,6 +36,18 @@ class MainActivity : ComponentActivity() { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     override fun onStop() { | ||||||
|  |         onTimerInvisible = lifecycleScope.launch { | ||||||
|  |             InvisibleSessionManager.updateTimer() | ||||||
|  |         } | ||||||
|  |         super.onStop() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun onStart() { | ||||||
|  |         onTimerInvisible?.cancel() | ||||||
|  |         super.onStart() | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
|  |  | ||||||
|  | @ -1,6 +1,5 @@ | ||||||
| package be.ugent.sel.studeez.common.composable.navbar | package be.ugent.sel.studeez.common.composable.navbar | ||||||
| 
 | 
 | ||||||
| import android.util.Log |  | ||||||
| import androidx.compose.material.BottomNavigation | import androidx.compose.material.BottomNavigation | ||||||
| import androidx.compose.material.BottomNavigationItem | import androidx.compose.material.BottomNavigationItem | ||||||
| import androidx.compose.material.Icon | import androidx.compose.material.Icon | ||||||
|  |  | ||||||
|  | @ -1,9 +1,5 @@ | ||||||
| package be.ugent.sel.studeez.data.local.models.timer_functional | package be.ugent.sel.studeez.data.local.models.timer_functional | ||||||
| 
 | 
 | ||||||
| import be.ugent.sel.studeez.data.local.models.SessionReport |  | ||||||
| import be.ugent.sel.studeez.screens.session.sessionScreens.CustomSessionScreen |  | ||||||
| import be.ugent.sel.studeez.screens.session.sessionScreens.AbstractSessionScreen |  | ||||||
| 
 |  | ||||||
| class FunctionalCustomTimer(studyTime: Int) : FunctionalTimer(studyTime) { | class FunctionalCustomTimer(studyTime: Int) : FunctionalTimer(studyTime) { | ||||||
| 
 | 
 | ||||||
|     override fun tick() { |     override fun tick() { | ||||||
|  |  | ||||||
|  | @ -1,8 +1,5 @@ | ||||||
| package be.ugent.sel.studeez.data.local.models.timer_functional | package be.ugent.sel.studeez.data.local.models.timer_functional | ||||||
| 
 | 
 | ||||||
| import be.ugent.sel.studeez.screens.session.sessionScreens.BreakSessionScreen |  | ||||||
| import be.ugent.sel.studeez.screens.session.sessionScreens.AbstractSessionScreen |  | ||||||
| 
 |  | ||||||
| class FunctionalPomodoroTimer( | class FunctionalPomodoroTimer( | ||||||
|     private var studyTime: Int, |     private var studyTime: Int, | ||||||
|     private var breakTime: Int, repeats: Int |     private var breakTime: Int, repeats: Int | ||||||
|  |  | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| package be.ugent.sel.studeez.data.local.models.timer_functional | package be.ugent.sel.studeez.data.local.models.timer_functional | ||||||
| 
 | 
 | ||||||
| import be.ugent.sel.studeez.data.local.models.SessionReport | import be.ugent.sel.studeez.data.local.models.SessionReport | ||||||
| import be.ugent.sel.studeez.screens.session.sessionScreens.AbstractSessionScreen |  | ||||||
| import com.google.firebase.Timestamp | import com.google.firebase.Timestamp | ||||||
| 
 | 
 | ||||||
| abstract class FunctionalTimer(initialValue: Int) { | abstract class FunctionalTimer(initialValue: Int) { | ||||||
|  |  | ||||||
|  | @ -5,7 +5,6 @@ import androidx.compose.runtime.Composable | ||||||
| import androidx.compose.runtime.getValue | import androidx.compose.runtime.getValue | ||||||
| import androidx.compose.ui.Modifier | import androidx.compose.ui.Modifier | ||||||
| import androidx.compose.ui.tooling.preview.Preview | import androidx.compose.ui.tooling.preview.Preview | ||||||
| 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.BasicTextButton | import be.ugent.sel.studeez.common.composable.BasicTextButton | ||||||
| import be.ugent.sel.studeez.common.composable.LabelledInputField | import be.ugent.sel.studeez.common.composable.LabelledInputField | ||||||
|  |  | ||||||
|  | @ -0,0 +1,29 @@ | ||||||
|  | package be.ugent.sel.studeez.screens.session | ||||||
|  | 
 | ||||||
|  | import android.media.MediaPlayer | ||||||
|  | import kotlinx.coroutines.delay | ||||||
|  | import javax.inject.Singleton | ||||||
|  | import kotlin.time.Duration.Companion.seconds | ||||||
|  | 
 | ||||||
|  | @Singleton | ||||||
|  | object InvisibleSessionManager { | ||||||
|  |     private var viewModel: SessionViewModel? = null | ||||||
|  |     private lateinit var mediaPlayer: MediaPlayer | ||||||
|  | 
 | ||||||
|  |     fun setParameters(viewModel: SessionViewModel, mediaplayer: MediaPlayer) { | ||||||
|  |         this.viewModel = viewModel | ||||||
|  |         this.mediaPlayer = mediaplayer | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     suspend fun updateTimer() { | ||||||
|  |         viewModel?.let { | ||||||
|  |             while (!it.getTimer().hasEnded()) { | ||||||
|  |                 delay(1.seconds) | ||||||
|  |                 it.getTimer().tick() | ||||||
|  |                 if (it.getTimer().hasCurrentCountdownEnded()) { | ||||||
|  |                     mediaPlayer.start() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -12,7 +12,7 @@ import be.ugent.sel.studeez.screens.session.sessionScreens.GetSessionScreen | ||||||
| data class SessionActions( | data class SessionActions( | ||||||
|     val getTimer: () -> FunctionalTimer, |     val getTimer: () -> FunctionalTimer, | ||||||
|     val getTask: () -> String, |     val getTask: () -> String, | ||||||
|     val prepareMediaPlayer: () -> Unit, |     val startMediaPlayer: () -> Unit, | ||||||
|     val releaseMediaPlayer: () -> Unit, |     val releaseMediaPlayer: () -> Unit, | ||||||
|     val endSession: () -> Unit |     val endSession: () -> Unit | ||||||
| ) | ) | ||||||
|  | @ -26,8 +26,8 @@ private fun getSessionActions( | ||||||
|         getTimer = viewModel::getTimer, |         getTimer = viewModel::getTimer, | ||||||
|         getTask = viewModel::getTask, |         getTask = viewModel::getTask, | ||||||
|         endSession = { viewModel.endSession(openAndPopUp) }, |         endSession = { viewModel.endSession(openAndPopUp) }, | ||||||
|         prepareMediaPlayer = mediaplayer::prepareAsync, |         startMediaPlayer = mediaplayer::start, | ||||||
|         releaseMediaPlayer = mediaplayer::release |         releaseMediaPlayer = mediaplayer::release, | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -39,26 +39,15 @@ fun SessionRoute( | ||||||
| ) { | ) { | ||||||
|     val context = LocalContext.current |     val context = LocalContext.current | ||||||
|     val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) |     val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) | ||||||
|     val mediaplayer = MediaPlayer() |     val mediaplayer = MediaPlayer.create(context, uri) | ||||||
|     mediaplayer.setDataSource(context, uri) |     mediaplayer.isLooping = false | ||||||
|     mediaplayer.setOnCompletionListener { |  | ||||||
|         mediaplayer.stop() |  | ||||||
|         //if (timerEnd) { |  | ||||||
| //            mediaplayer.release() |  | ||||||
|         //} |  | ||||||
|     } |  | ||||||
|     mediaplayer.setOnPreparedListener { |  | ||||||
| //        mediaplayer.start() |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     val sessionScreen: AbstractSessionScreen = viewModel.getTimer().accept(GetSessionScreen()) |     InvisibleSessionManager.setParameters( | ||||||
|  |         viewModel = viewModel, | ||||||
|  |         mediaplayer = mediaplayer | ||||||
|  |     ) | ||||||
| 
 | 
 | ||||||
|     //val sessionScreen = when (val timer = viewModel.getTimer()) { |     val sessionScreen: AbstractSessionScreen = viewModel.getTimer().accept(GetSessionScreen(mediaplayer)) | ||||||
|     //    is FunctionalCustomTimer -> CustomSessionScreen(timer) |  | ||||||
|     //    is FunctionalPomodoroTimer -> BreakSessionScreen(timer) |  | ||||||
|     //    is FunctionalEndlessTimer -> EndlessSessionScreen() |  | ||||||
|     //    else -> throw java.lang.IllegalArgumentException("Unknown Timer") |  | ||||||
|     //} |  | ||||||
| 
 | 
 | ||||||
|     sessionScreen( |     sessionScreen( | ||||||
|         open = open, |         open = open, | ||||||
|  |  | ||||||
|  | @ -19,15 +19,12 @@ import androidx.compose.ui.tooling.preview.Preview | ||||||
| import androidx.compose.ui.unit.dp | import androidx.compose.ui.unit.dp | ||||||
| import androidx.compose.ui.unit.sp | import androidx.compose.ui.unit.sp | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer | import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations |  | ||||||
| import be.ugent.sel.studeez.screens.session.SessionActions | import be.ugent.sel.studeez.screens.session.SessionActions | ||||||
| import kotlinx.coroutines.delay | import kotlinx.coroutines.delay | ||||||
| import kotlin.time.Duration.Companion.seconds | import kotlin.time.Duration.Companion.seconds | ||||||
| 
 | 
 | ||||||
| abstract class AbstractSessionScreen { | abstract class AbstractSessionScreen { | ||||||
| 
 | 
 | ||||||
|     var timerEnd = false |  | ||||||
| 
 |  | ||||||
|     @Composable |     @Composable | ||||||
|     operator fun invoke( |     operator fun invoke( | ||||||
|         open: (String) -> Unit, |         open: (String) -> Unit, | ||||||
|  | @ -74,22 +71,10 @@ abstract class AbstractSessionScreen { | ||||||
|         LaunchedEffect(tikker) { |         LaunchedEffect(tikker) { | ||||||
|             delay(1.seconds) |             delay(1.seconds) | ||||||
|             sessionActions.getTimer().tick() |             sessionActions.getTimer().tick() | ||||||
|  |             callMediaPlayer() | ||||||
|             tikker = !tikker |             tikker = !tikker | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if ( |  | ||||||
|             sessionActions.getTimer().hasCurrentCountdownEnded() && !sessionActions.getTimer() |  | ||||||
|                 .hasEnded() |  | ||||||
|         ) { |  | ||||||
| //        sessionActions.prepareMediaPlayer() |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!timerEnd && sessionActions.getTimer().hasEnded()) { |  | ||||||
| //        sessionActions.prepareMediaPlayer() |  | ||||||
|              timerEnd = |  | ||||||
|                  true // Placeholder, vanaf hier moet het report opgestart worden en de sessie afgesloten |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         val hms = sessionActions.getTimer().getHoursMinutesSeconds() |         val hms = sessionActions.getTimer().getHoursMinutesSeconds() | ||||||
|         Column { |         Column { | ||||||
|             Text( |             Text( | ||||||
|  | @ -136,6 +121,8 @@ abstract class AbstractSessionScreen { | ||||||
|     @Composable |     @Composable | ||||||
|     abstract fun motivationString(): String |     abstract fun motivationString(): String | ||||||
| 
 | 
 | ||||||
|  |     abstract fun callMediaPlayer() | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Preview | @Preview | ||||||
|  | @ -144,6 +131,7 @@ fun TimerPreview() { | ||||||
|     val sessionScreen = object : AbstractSessionScreen() { |     val sessionScreen = object : AbstractSessionScreen() { | ||||||
|         @Composable |         @Composable | ||||||
|         override fun motivationString(): String = "Test" |         override fun motivationString(): String = "Test" | ||||||
|  |         override fun callMediaPlayer() {} | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
|     sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {}, {})) |     sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {}, {})) | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| package be.ugent.sel.studeez.screens.session.sessionScreens | package be.ugent.sel.studeez.screens.session.sessionScreens | ||||||
| 
 | 
 | ||||||
|  | import android.media.MediaPlayer | ||||||
| import androidx.compose.runtime.Composable | import androidx.compose.runtime.Composable | ||||||
| import be.ugent.sel.studeez.R | import be.ugent.sel.studeez.R | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer | import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer | ||||||
|  | @ -7,7 +8,8 @@ import be.ugent.sel.studeez.resources | ||||||
| import be.ugent.sel.studeez.R.string as AppText | import be.ugent.sel.studeez.R.string as AppText | ||||||
| 
 | 
 | ||||||
| class BreakSessionScreen( | class BreakSessionScreen( | ||||||
|     private val funPomoDoroTimer: FunctionalPomodoroTimer |     private val funPomoDoroTimer: FunctionalPomodoroTimer, | ||||||
|  |     private var mediaplayer: MediaPlayer? | ||||||
| ): AbstractSessionScreen() { | ): AbstractSessionScreen() { | ||||||
| 
 | 
 | ||||||
|     @Composable |     @Composable | ||||||
|  | @ -27,4 +29,17 @@ class BreakSessionScreen( | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     override fun callMediaPlayer() { | ||||||
|  |         if (funPomoDoroTimer.hasEnded()) { | ||||||
|  |             mediaplayer?.let { it: MediaPlayer -> | ||||||
|  |                 it.setOnCompletionListener { | ||||||
|  |                     it.release() | ||||||
|  |                     mediaplayer = null | ||||||
|  |                 } | ||||||
|  |                 it.start() | ||||||
|  |             } | ||||||
|  |         } else if (funPomoDoroTimer.hasCurrentCountdownEnded()) { | ||||||
|  |             mediaplayer?.start() | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| package be.ugent.sel.studeez.screens.session.sessionScreens | package be.ugent.sel.studeez.screens.session.sessionScreens | ||||||
| 
 | 
 | ||||||
|  | import android.media.MediaPlayer | ||||||
| import androidx.compose.runtime.Composable | import androidx.compose.runtime.Composable | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer | import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer | ||||||
| import be.ugent.sel.studeez.resources | import be.ugent.sel.studeez.resources | ||||||
|  | @ -7,7 +8,8 @@ import be.ugent.sel.studeez.R.string as AppText | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class CustomSessionScreen( | class CustomSessionScreen( | ||||||
|     private val functionalTimer: FunctionalCustomTimer |     private val functionalTimer: FunctionalCustomTimer, | ||||||
|  |     private var mediaplayer: MediaPlayer? | ||||||
| ): AbstractSessionScreen() { | ): AbstractSessionScreen() { | ||||||
| 
 | 
 | ||||||
|     @Composable |     @Composable | ||||||
|  | @ -18,4 +20,16 @@ class CustomSessionScreen( | ||||||
|         return resources().getString(AppText.state_focus) |         return resources().getString(AppText.state_focus) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     override fun callMediaPlayer() { | ||||||
|  |         if (functionalTimer.hasEnded()) { | ||||||
|  |             mediaplayer?.let { it: MediaPlayer -> | ||||||
|  |                 it.setOnCompletionListener { | ||||||
|  |                     it.release() | ||||||
|  |                     mediaplayer = null | ||||||
|  |                 } | ||||||
|  |                 it.start() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  | @ -11,4 +11,6 @@ class EndlessSessionScreen : AbstractSessionScreen() { | ||||||
|     override fun motivationString(): String { |     override fun motivationString(): String { | ||||||
|         return resources().getString(AppText.state_focus) |         return resources().getString(AppText.state_focus) | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     override fun callMediaPlayer() {} | ||||||
| } | } | ||||||
|  | @ -1,17 +1,18 @@ | ||||||
| package be.ugent.sel.studeez.screens.session.sessionScreens | package be.ugent.sel.studeez.screens.session.sessionScreens | ||||||
| 
 | 
 | ||||||
|  | import android.media.MediaPlayer | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer | 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.FunctionalEndlessTimer | ||||||
| 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.FunctionalTimerVisitor | import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimerVisitor | ||||||
| 
 | 
 | ||||||
| class GetSessionScreen : FunctionalTimerVisitor<AbstractSessionScreen> { | class GetSessionScreen(private val mediaplayer: MediaPlayer?) : FunctionalTimerVisitor<AbstractSessionScreen> { | ||||||
|     override fun visitFunctionalCustomTimer(functionalCustomTimer: FunctionalCustomTimer): AbstractSessionScreen = |     override fun visitFunctionalCustomTimer(functionalCustomTimer: FunctionalCustomTimer): AbstractSessionScreen = | ||||||
|         CustomSessionScreen(functionalCustomTimer) |         CustomSessionScreen(functionalCustomTimer, mediaplayer) | ||||||
| 
 | 
 | ||||||
|     override fun visitFunctionalEndlessTimer(functionalEndlessTimer: FunctionalEndlessTimer): AbstractSessionScreen = |     override fun visitFunctionalEndlessTimer(functionalEndlessTimer: FunctionalEndlessTimer): AbstractSessionScreen = | ||||||
|         EndlessSessionScreen() |         EndlessSessionScreen() | ||||||
| 
 | 
 | ||||||
|     override fun visitFunctionalBreakTimer(functionalPomodoroTimer: FunctionalPomodoroTimer): AbstractSessionScreen = |     override fun visitFunctionalBreakTimer(functionalPomodoroTimer: FunctionalPomodoroTimer): AbstractSessionScreen = | ||||||
|         BreakSessionScreen(functionalPomodoroTimer) |         BreakSessionScreen(functionalPomodoroTimer, mediaplayer) | ||||||
| } | } | ||||||
|  | @ -26,7 +26,7 @@ fun getSessionRecapActions( | ||||||
|     return SessionRecapActions( |     return SessionRecapActions( | ||||||
|         viewModel::getSessionReport, |         viewModel::getSessionReport, | ||||||
|         {viewModel.saveSession(openAndPopUp)}, |         {viewModel.saveSession(openAndPopUp)}, | ||||||
|         {viewModel.saveSession(openAndPopUp)} |         {viewModel.discardSession(openAndPopUp)} | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -45,6 +45,7 @@ | ||||||
| 
 | 
 | ||||||
|     <!-- Sessions --> |     <!-- Sessions --> | ||||||
|     <string name="sessions">Sessions</string> |     <string name="sessions">Sessions</string> | ||||||
|  |     <string name="end_session">End session</string> | ||||||
| 
 | 
 | ||||||
|     <!-- Profile --> |     <!-- Profile --> | ||||||
|     <string name="profile">Profile</string> |     <string name="profile">Profile</string> | ||||||
|  |  | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| package be.ugent.sel.studeez.timer_functional | package be.ugent.sel.studeez.timer_functional | ||||||
| 
 | 
 | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer | import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer |  | ||||||
| import org.junit.Assert | import org.junit.Assert | ||||||
| import org.junit.Test | import org.junit.Test | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| package be.ugent.sel.studeez.timer_functional | package be.ugent.sel.studeez.timer_functional | ||||||
| 
 | 
 | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer | import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer | ||||||
| import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer |  | ||||||
| import org.junit.Assert | import org.junit.Assert | ||||||
| import org.junit.Test | import org.junit.Test | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| package be.ugent.sel.studeez.timer_functional | package be.ugent.sel.studeez.timer_functional | ||||||
| 
 | 
 | ||||||
| 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 org.junit.Assert | import org.junit.Assert | ||||||
| import org.junit.Test | import org.junit.Test | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,99 @@ | ||||||
|  | package be.ugent.sel.studeez.timer_functional | ||||||
|  | 
 | ||||||
|  | import android.media.MediaPlayer | ||||||
|  | import be.ugent.sel.studeez.data.SelectedTimerState | ||||||
|  | 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 | ||||||
|  | import be.ugent.sel.studeez.screens.session.InvisibleSessionManager | ||||||
|  | import be.ugent.sel.studeez.screens.session.SessionViewModel | ||||||
|  | import kotlinx.coroutines.ExperimentalCoroutinesApi | ||||||
|  | import kotlinx.coroutines.launch | ||||||
|  | import kotlinx.coroutines.test.advanceTimeBy | ||||||
|  | import kotlinx.coroutines.test.runTest | ||||||
|  | import org.junit.Assert | ||||||
|  | import org.junit.Test | ||||||
|  | import org.mockito.kotlin.mock | ||||||
|  | 
 | ||||||
|  | @ExperimentalCoroutinesApi | ||||||
|  | class InvisibleSessionManagerTest { | ||||||
|  |     private var timerState: SelectedTimerState = SelectedTimerState() | ||||||
|  |     private lateinit var viewModel: SessionViewModel | ||||||
|  |     private var mediaPlayer: MediaPlayer = mock() | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun InvisibleEndlessTimerTest() = runTest { | ||||||
|  |         timerState.selectedTimer = FunctionalEndlessTimer() | ||||||
|  |         viewModel = SessionViewModel(timerState, mock()) | ||||||
|  |         InvisibleSessionManager.setParameters(viewModel, mediaPlayer) | ||||||
|  | 
 | ||||||
|  |         val test = launch { | ||||||
|  |             InvisibleSessionManager.updateTimer() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Assert.assertEquals(viewModel.getTimer().time.time, 0) | ||||||
|  |         advanceTimeBy(1_000) // Start tikker | ||||||
|  |         advanceTimeBy(10_000_000) | ||||||
|  |         Assert.assertEquals(viewModel.getTimer().time.time, 10000) | ||||||
|  | 
 | ||||||
|  |         test.cancel() | ||||||
|  |         return@runTest | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun InvisiblePomodoroTimerTest() = runTest { | ||||||
|  |         val studyTime = 10 | ||||||
|  |         val breakTime = 5 | ||||||
|  |         val repeats = 1 | ||||||
|  |         timerState.selectedTimer = FunctionalPomodoroTimer(studyTime, breakTime, repeats) | ||||||
|  |         viewModel = SessionViewModel(timerState, mock()) | ||||||
|  |         InvisibleSessionManager.setParameters(viewModel, mediaPlayer) | ||||||
|  | 
 | ||||||
|  |         val test = launch { | ||||||
|  |             InvisibleSessionManager.updateTimer() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Assert.assertEquals(viewModel.getTimer().time.time, 10) | ||||||
|  |         advanceTimeBy(1_000) // start tikker | ||||||
|  | 
 | ||||||
|  |         advanceTimeBy(9_000) | ||||||
|  |         Assert.assertEquals(viewModel.getTimer().time.time, 1) | ||||||
|  |         // focus, 9 sec, 1 sec nog | ||||||
|  | 
 | ||||||
|  |         advanceTimeBy(2_000) | ||||||
|  |         Assert.assertEquals(viewModel.getTimer().time.time, 4) | ||||||
|  |         // pauze, 11 sec bezig, 4 seconden nog pauze | ||||||
|  | 
 | ||||||
|  |         advanceTimeBy(5_000) | ||||||
|  |         Assert.assertEquals(viewModel.getTimer().time.time, 9) | ||||||
|  |         // 2e focus, 16 sec, 9 sec in 2e focus nog | ||||||
|  | 
 | ||||||
|  |         advanceTimeBy(13_000) | ||||||
|  |         Assert.assertTrue(viewModel.getTimer().hasEnded()) | ||||||
|  |         // Done | ||||||
|  | 
 | ||||||
|  |         test.cancel() | ||||||
|  |         return@runTest | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun InvisibleCustomTimerTest() = runTest { | ||||||
|  |         timerState.selectedTimer = FunctionalCustomTimer(5) | ||||||
|  |         viewModel = SessionViewModel(timerState, mock()) | ||||||
|  |         InvisibleSessionManager.setParameters(viewModel, mediaPlayer) | ||||||
|  | 
 | ||||||
|  |         val test = launch { | ||||||
|  |             InvisibleSessionManager.updateTimer() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Assert.assertEquals(viewModel.getTimer().time.time, 5) | ||||||
|  |         advanceTimeBy(1_000) // Start tikker | ||||||
|  |         advanceTimeBy(4_000) | ||||||
|  |         Assert.assertEquals(viewModel.getTimer().time.time, 1) | ||||||
|  |         advanceTimeBy(1_000) | ||||||
|  |         Assert.assertEquals(viewModel.getTimer().time.time, 0) | ||||||
|  | 
 | ||||||
|  |         test.cancel() | ||||||
|  |         return@runTest | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -7,6 +7,8 @@ | ||||||
| # Specifies the JVM arguments used for the daemon process. | # Specifies the JVM arguments used for the daemon process. | ||||||
| # The setting is particularly useful for tweaking memory settings. | # The setting is particularly useful for tweaking memory settings. | ||||||
| org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 | ||||||
|  | org.gradle.daemon=true | ||||||
|  | org.gradle.parallel=true | ||||||
| # When configured, Gradle will run in incubating parallel mode. | # When configured, Gradle will run in incubating parallel mode. | ||||||
| # This option should only be used with decoupled projects. More details, visit | # This option should only be used with decoupled projects. More details, visit | ||||||
| # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 lbarraga
						lbarraga