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