From 7fe7416388084fc76d3ea43ca623b9c137be7351 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Tue, 25 Apr 2023 15:20:28 +0200 Subject: [PATCH] added getview function --- .../timer_functional/FunctionalCustomTimer.kt | 19 +- .../FunctionalEndlessTimer.kt | 9 +- .../FunctionalPomodoroTimer.kt | 20 +- .../timer_functional/FunctionalTimer.kt | 6 +- .../studeez/screens/session/SessionRoute.kt | 51 +++++ .../studeez/screens/session/SessionScreen.kt | 212 ------------------ .../sessionScreens/AbstractSessionScreen.kt | 138 ++++++++++++ .../sessionScreens/BreakSessionScreen.kt | 30 +++ .../sessionScreens/CustomSessionScreen.kt | 21 ++ .../sessionScreens/EndlessSessionScreen.kt | 17 ++ 10 files changed, 293 insertions(+), 230 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session/SessionRoute.kt delete mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/AbstractSessionScreen.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/BreakSessionScreen.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/CustomSessionScreen.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/EndlessSessionScreen.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt index ab533dd..15dd00c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt @@ -1,21 +1,26 @@ package be.ugent.sel.studeez.data.local.models.timer_functional +import be.ugent.sel.studeez.screens.session.sessionScreens.CustomSessionScreen +import be.ugent.sel.studeez.screens.session.sessionScreens.AbstractSessionScreen + class FunctionalCustomTimer(studyTime: Int) : FunctionalTimer(studyTime) { override fun tick() { - if (time.time == 0) { - view = StudyState.DONE - } else { + if (!hasEnded()) { time.minOne() } } override fun hasEnded(): Boolean { - return view == StudyState.DONE - } - - override fun hasCurrentCountdownEnded(): Boolean { return time.time == 0 } + override fun hasCurrentCountdownEnded(): Boolean { + return hasEnded() + } + + override fun getView(): AbstractSessionScreen { + return CustomSessionScreen(this) + } + } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalEndlessTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalEndlessTimer.kt index 70fcf7d..eb368f4 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalEndlessTimer.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalEndlessTimer.kt @@ -1,6 +1,9 @@ package be.ugent.sel.studeez.data.local.models.timer_functional -class FunctionalEndlessTimer() : FunctionalTimer(0) { +import be.ugent.sel.studeez.screens.session.sessionScreens.EndlessSessionScreen +import be.ugent.sel.studeez.screens.session.sessionScreens.AbstractSessionScreen + +class FunctionalEndlessTimer : FunctionalTimer(0) { override fun hasEnded(): Boolean { return false @@ -13,4 +16,8 @@ class FunctionalEndlessTimer() : FunctionalTimer(0) { override fun tick() { time.plusOne() } + + override fun getView(): AbstractSessionScreen { + return EndlessSessionScreen() + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt index 3e2b97e..931cbe6 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt @@ -1,5 +1,8 @@ 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( private var studyTime: Int, private var breakTime: Int, repeats: Int @@ -9,18 +12,15 @@ class FunctionalPomodoroTimer( var isInBreak = false override fun tick() { - if (time.time == 0 && breaksRemaining == 0) { - view = StudyState.DONE + if (hasEnded()) { return } - if (time.time == 0) { + if (hasCurrentCountdownEnded()) { if (isInBreak) { breaksRemaining-- - view = StudyState.FOCUS_REMAINING time.time = studyTime } else { - view = StudyState.BREAK time.time = breakTime } isInBreak = !isInBreak @@ -29,10 +29,18 @@ class FunctionalPomodoroTimer( } override fun hasEnded(): Boolean { - return breaksRemaining == 0 && time.time == 0 + return !hasBreaksRemaining() && hasCurrentCountdownEnded() + } + + private fun hasBreaksRemaining(): Boolean { + return breaksRemaining > 0 } override fun hasCurrentCountdownEnded(): Boolean { return time.time == 0 } + + override fun getView(): AbstractSessionScreen { + return BreakSessionScreen(this) + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt index dae27c6..449b85c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt @@ -1,8 +1,8 @@ package be.ugent.sel.studeez.data.local.models.timer_functional +import be.ugent.sel.studeez.screens.session.sessionScreens.AbstractSessionScreen abstract class FunctionalTimer(initialValue: Int) { val time: Time = Time(initialValue) - var view: StudyState = StudyState.FOCUS fun getHoursMinutesSeconds(): HoursMinutesSeconds { return time.getAsHMS() @@ -14,8 +14,6 @@ abstract class FunctionalTimer(initialValue: Int) { abstract fun hasCurrentCountdownEnded(): Boolean - enum class StudyState { - FOCUS, DONE, BREAK, FOCUS_REMAINING - } + abstract fun getView(): AbstractSessionScreen } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionRoute.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionRoute.kt new file mode 100644 index 0000000..bf81215 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionRoute.kt @@ -0,0 +1,51 @@ +package be.ugent.sel.studeez.screens.session + +import android.media.MediaPlayer +import android.media.RingtoneManager +import android.net.Uri +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer + +data class SessionActions( + val getTimer: () -> FunctionalTimer, + val getTask: () -> String, + val prepareMediaPlayer: () -> Unit, + val releaseMediaPlayer: () -> Unit, +) + +private fun getSessionActions( + viewModel: SessionViewModel, + mediaplayer: MediaPlayer, +): SessionActions { + return SessionActions( + getTimer = viewModel::getTimer, + getTask = viewModel::getTask, + prepareMediaPlayer = mediaplayer::prepareAsync, + releaseMediaPlayer = mediaplayer::release, + ) +} + +@Composable +fun SessionRoute( + open: (String) -> Unit, + viewModel: SessionViewModel, +) { + val context = LocalContext.current + val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) + val mediaplayer = MediaPlayer() + mediaplayer.setDataSource(context, uri) + mediaplayer.setOnCompletionListener { + mediaplayer.stop() + //if (timerEnd) { +// mediaplayer.release() + //} + } + mediaplayer.setOnPreparedListener { +// mediaplayer.start() + } + viewModel.getTimer().getView().SessionScreen( + open = open, + sessionActions = getSessionActions(viewModel, mediaplayer), + ) +} diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt deleted file mode 100644 index 3db95c1..0000000 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt +++ /dev/null @@ -1,212 +0,0 @@ -package be.ugent.sel.studeez.screens.session - -import android.media.MediaPlayer -import android.media.RingtoneManager -import android.net.Uri -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Text -import androidx.compose.material.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import be.ugent.sel.studeez.R -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.FunctionalTimer -import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer.StudyState -import be.ugent.sel.studeez.navigation.StudeezDestinations -import be.ugent.sel.studeez.resources -import kotlinx.coroutines.delay -import kotlin.time.Duration.Companion.seconds - -var timerEnd = false - -data class SessionActions( - val getTimer: () -> FunctionalTimer, - val getTask: () -> String, - val prepareMediaPlayer: () -> Unit, - val releaseMediaPlayer: () -> Unit, -) - -fun getSessionActions( - viewModel: SessionViewModel, - mediaplayer: MediaPlayer, -): SessionActions { - return SessionActions( - getTimer = viewModel::getTimer, - getTask = viewModel::getTask, - prepareMediaPlayer = mediaplayer::prepareAsync, - releaseMediaPlayer = mediaplayer::release, - ) -} - -@Composable -fun SessionRoute( - open: (String) -> Unit, - viewModel: SessionViewModel, -) { - val context = LocalContext.current - val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) - val mediaplayer = MediaPlayer() - mediaplayer.setDataSource(context, uri) - mediaplayer.setOnCompletionListener { - mediaplayer.stop() - if (timerEnd) { -// mediaplayer.release() - } - } - mediaplayer.setOnPreparedListener { -// mediaplayer.start() - } - SessionScreen( - open = open, - sessionActions = getSessionActions(viewModel, mediaplayer), - ) -} - -@Composable -fun SessionScreen( - open: (String) -> Unit, - sessionActions: SessionActions, -) { - Column( - modifier = Modifier.padding(10.dp) - ) { - Timer( - sessionActions = sessionActions, - ) - Box( - contentAlignment = Alignment.Center, modifier = Modifier - .fillMaxWidth() - .padding(50.dp) - ) { - TextButton( - onClick = { - sessionActions.releaseMediaPlayer - open(StudeezDestinations.HOME_SCREEN) - // Vanaf hier ook naar report gaan als "end session" knop word ingedrukt - }, - modifier = Modifier - .padding(horizontal = 20.dp) - .border(1.dp, Color.Red, RoundedCornerShape(32.dp)) - .background(Color.Transparent) - ) { - Text( - text = "End session", - color = Color.Red, - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - modifier = Modifier.padding(1.dp) - ) - } - } - } -} - -@Composable -private fun Timer( - sessionActions: SessionActions, -) { - var tikker by remember { mutableStateOf(false) } - LaunchedEffect(tikker) { - delay(1.seconds) - sessionActions.getTimer().tick() - 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() - Column { - Text( - text = "${hms.hours} : ${hms.minutes} : ${hms.seconds}", - modifier = Modifier - .fillMaxWidth() - .padding(50.dp), - textAlign = TextAlign.Center, - fontWeight = FontWeight.Bold, - fontSize = 40.sp, - ) - val stateString: String = when (sessionActions.getTimer().view) { - StudyState.DONE -> resources().getString(R.string.state_done) - StudyState.FOCUS -> resources().getString(R.string.state_focus) - StudyState.BREAK -> resources().getString(R.string.state_take_a_break) - StudyState.FOCUS_REMAINING -> (sessionActions.getTimer() as FunctionalPomodoroTimer?)?.breaksRemaining?.let { - resources().getQuantityString(R.plurals.state_focus_remaining, it, it) - }.toString() - } - - Text( - text = stateString, - modifier = Modifier.fillMaxWidth(), - textAlign = TextAlign.Center, - fontWeight = FontWeight.Light, - fontSize = 30.sp - ) - - Box( - contentAlignment = Alignment.Center, modifier = Modifier - .fillMaxWidth() - .padding(50.dp) - ) { - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .padding(16.dp) - .background(Color.Blue, RoundedCornerShape(32.dp)) - ) { - Text( - text = sessionActions.getTask(), - color = Color.White, - fontSize = 18.sp, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(vertical = 4.dp, horizontal = 20.dp) - ) - } - } - } -} - -@Preview -@Composable -fun TimerPreview() { - Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {})) -} - -@Preview -@Composable -fun SessionPreview() { - SessionScreen( - open = {}, - sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {}) - ) -} diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/AbstractSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/AbstractSessionScreen.kt new file mode 100644 index 0000000..effa1ba --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/AbstractSessionScreen.kt @@ -0,0 +1,138 @@ +package be.ugent.sel.studeez.screens.session.sessionScreens + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import be.ugent.sel.studeez.navigation.StudeezDestinations +import be.ugent.sel.studeez.screens.session.SessionActions +import kotlinx.coroutines.delay +import kotlin.time.Duration.Companion.seconds + +abstract class SessionScreen { + + var timerEnd = false + + @Composable + fun SessionScreen( + open: (String) -> Unit, + sessionActions: SessionActions, + ) { + Column( + modifier = Modifier.padding(10.dp) + ) { + Timer( + sessionActions = sessionActions, + ) + Box( + contentAlignment = Alignment.Center, modifier = Modifier + .fillMaxWidth() + .padding(50.dp) + ) { + TextButton( + onClick = { + sessionActions.releaseMediaPlayer + open(StudeezDestinations.HOME_SCREEN) + // Vanaf hier ook naar report gaan als "end session" knop word ingedrukt + }, + modifier = Modifier + .padding(horizontal = 20.dp) + .border(1.dp, Color.Red, RoundedCornerShape(32.dp)) + .background(Color.Transparent) + ) { + Text( + text = "End session", + color = Color.Red, + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(1.dp) + ) + } + } + } + } + + @Composable + private fun Timer( + sessionActions: SessionActions, + ) { + var tikker by remember { mutableStateOf(false) } + LaunchedEffect(tikker) { + delay(1.seconds) + sessionActions.getTimer().tick() + 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() + Column { + Text( + text = "${hms.hours} : ${hms.minutes} : ${hms.seconds}", + modifier = Modifier + .fillMaxWidth() + .padding(50.dp), + textAlign = TextAlign.Center, + fontWeight = FontWeight.Bold, + fontSize = 40.sp, + ) + + Text( + text = motivationString(), + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center, + fontWeight = FontWeight.Light, + fontSize = 30.sp + ) + + Box( + contentAlignment = Alignment.Center, modifier = Modifier + .fillMaxWidth() + .padding(50.dp) + ) { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier + .padding(16.dp) + .background(Color.Blue, RoundedCornerShape(32.dp)) + ) { + Text( + text = sessionActions.getTask(), + color = Color.White, + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(vertical = 4.dp, horizontal = 20.dp) + ) + } + } + } + } + + @Composable + abstract fun motivationString(): String + +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/BreakSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/BreakSessionScreen.kt new file mode 100644 index 0000000..b2fd53f --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/BreakSessionScreen.kt @@ -0,0 +1,30 @@ +package be.ugent.sel.studeez.screens.session.SessionScreens + +import androidx.compose.runtime.Composable +import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer +import be.ugent.sel.studeez.resources +import be.ugent.sel.studeez.R.string as AppText + +class BreakSessionScreen( + private val funPomoDoroTimer: FunctionalPomodoroTimer +): SessionScreen(funPomoDoroTimer) { + + @Composable + override fun motivationString(): String { + if (funPomoDoroTimer.isInBreak) { + return resources().getString(AppText.state_take_a_break) + } + + if (funPomoDoroTimer.hasEnded()) { + return resources().getString(AppText.state_done) + } + + return resources().getQuantityString( + R.plurals.state_focus_remaining, + funPomoDoroTimer.breaksRemaining, + funPomoDoroTimer.breaksRemaining + ) + } + +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/CustomSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/CustomSessionScreen.kt new file mode 100644 index 0000000..92c2b5e --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/CustomSessionScreen.kt @@ -0,0 +1,21 @@ +package be.ugent.sel.studeez.screens.session.SessionScreens + +import androidx.compose.runtime.Composable +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer +import be.ugent.sel.studeez.resources +import be.ugent.sel.studeez.R.string as AppText + + +class CustomSessionScreen( + private val functionalTimer: FunctionalCustomTimer +): SessionScreen(functionalTimer) { + + @Composable + override fun motivationString(): String { + if (functionalTimer.hasEnded()) { + return resources().getString(AppText.state_done) + } + return resources().getString(AppText.state_focus) + } + +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/EndlessSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/EndlessSessionScreen.kt new file mode 100644 index 0000000..688243b --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/EndlessSessionScreen.kt @@ -0,0 +1,17 @@ +package be.ugent.sel.studeez.screens.session.SessionScreens + +import androidx.compose.runtime.Composable +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer +import be.ugent.sel.studeez.resources +import be.ugent.sel.studeez.R.string as AppText + + +class EndlessSessionScreen( + functionalTimer: FunctionalEndlessTimer + ): SessionScreen(functionalTimer) { + + @Composable + override fun motivationString(): String { + return resources().getString(AppText.state_focus) + } +} \ No newline at end of file