From dc43b26dc025d354e87feef31cb68cde41ac84ba Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Mon, 24 Apr 2023 12:17:43 +0200 Subject: [PATCH 01/41] timerstates fixed --- .../studeez/screens/session/SessionScreen.kt | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) 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 index 451f705..0559291 100644 --- 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 @@ -35,8 +35,6 @@ import be.ugent.sel.studeez.resources import kotlinx.coroutines.delay import kotlin.time.Duration.Companion.seconds -var timerEnd = false - @Composable fun SessionScreen( open: (String) -> Unit, @@ -46,17 +44,7 @@ fun SessionScreen( val context = LocalContext.current val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) val mediaplayer = MediaPlayer.create(context, uri) - mediaplayer.setOnCompletionListener { - if (!mediaplayer.isPlaying) { - mediaplayer.stop() - } - if (timerEnd) { - mediaplayer.release() - } - } - mediaplayer.setOnPreparedListener { - mediaplayer.start() - } + mediaplayer.isLooping = false Column( modifier = Modifier.padding(10.dp) @@ -71,6 +59,7 @@ fun SessionScreen( ) { TextButton( onClick = { + mediaplayer.stop() mediaplayer.release() open(StudeezDestinations.HOME_SCREEN) // Vanaf hier ook naar report gaan als "end session" knop word ingedrukt @@ -102,12 +91,7 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me } if (viewModel.getTimer().hasCurrentCountdownEnded() && !viewModel.getTimer().hasEnded()) { - mediaplayer.prepare() - } - - if (!timerEnd && viewModel.getTimer().hasEnded()) { - mediaplayer.prepare() - timerEnd = true // Placeholder, vanaf hier moet het report opgestart worden en de sessie afgesloten + mediaplayer.start() } val hms = viewModel.getTimer().getHoursMinutesSeconds() From e20e972b88d9d778953ee4df6b00ac4cf81e7d7a Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Mon, 24 Apr 2023 19:52:36 +0200 Subject: [PATCH 02/41] localdatetime version --- .idea/misc.xml | 2 +- .../sel/studeez/activities/MainActivity.kt | 13 ++++++ .../timer_functional/FunctionalTimer.kt | 2 +- .../local/models/timer_functional/Time.kt | 4 ++ .../studeez/screens/session/SessionScreen.kt | 45 +++++++++++++++++++ 5 files changed, 64 insertions(+), 2 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 704c883..bdd9278 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,7 @@ - + diff --git a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt index 318fe7a..6829e7f 100644 --- a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt +++ b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt @@ -1,6 +1,7 @@ package be.ugent.sel.studeez.activities import android.os.Bundle +import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize @@ -11,6 +12,8 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import be.ugent.sel.studeez.StudeezApp +import be.ugent.sel.studeez.screens.session.SessionTest +import be.ugent.sel.studeez.screens.session.test import be.ugent.sel.studeez.ui.theme.StudeezTheme import dagger.hilt.android.AndroidEntryPoint @@ -30,6 +33,16 @@ class MainActivity : ComponentActivity() { } } } + + override fun onStop() { + test() + super.onStop() + } + + override fun onStart() { + SessionTest.updateTimer() + super.onStart() + } } @Composable 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..bb7423e 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,7 +1,7 @@ package be.ugent.sel.studeez.data.local.models.timer_functional abstract class FunctionalTimer(initialValue: Int) { - val time: Time = Time(initialValue) + var time: Time = Time(initialValue) var view: StudyState = StudyState.FOCUS fun getHoursMinutesSeconds(): HoursMinutesSeconds { diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt index ec7702d..83be75d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt @@ -4,6 +4,10 @@ class Time(initialTime: Int) { var time = initialTime + fun min(i: Int) { + time -= i + } + fun minOne() { time-- } 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 index 0559291..dee4f12 100644 --- 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 @@ -3,6 +3,7 @@ package be.ugent.sel.studeez.screens.session import android.media.MediaPlayer import android.media.RingtoneManager import android.net.Uri +import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.Box @@ -31,10 +32,20 @@ import androidx.hilt.navigation.compose.hiltViewModel 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.FunctionalTimer.StudyState +import be.ugent.sel.studeez.data.local.models.timer_functional.Time import be.ugent.sel.studeez.resources import kotlinx.coroutines.delay +import java.time.Duration +import java.time.LocalDateTime +import java.time.ZoneId +import java.util.* +import kotlin.properties.Delegates +import kotlin.time.Duration.Companion.hours +import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds +var start: LocalDateTime = Calendar.getInstance().time.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() + @Composable fun SessionScreen( open: (String) -> Unit, @@ -46,6 +57,8 @@ fun SessionScreen( val mediaplayer = MediaPlayer.create(context, uri) mediaplayer.isLooping = false + SessionTest.setNewViewModel(viewModel = viewModel) + Column( modifier = Modifier.padding(10.dp) ) { @@ -81,6 +94,11 @@ fun SessionScreen( } } +private operator fun Time.minus(time: Time): Time { + return Time(this.time - time.time) + +} + @Composable private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: MediaPlayer) { var tikker by remember { mutableStateOf(false) } @@ -146,6 +164,33 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me } } } +} + +fun test() { + start = Calendar.getInstance().time.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() +} + +object SessionTest { + lateinit var viewModel: SessionViewModel + private var isSession: Boolean = false + + fun setNewViewModel(viewModel: SessionViewModel) { + isSession = true + this.viewModel = viewModel + } + + fun updateTimer() { + if (isSession) { + val end = Calendar.getInstance().time.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() + + val duration = Duration.between(start, end) + + val hours = duration.toHours() + val minutes = duration.toMinutes() % 60 + val seconds = duration.seconds % 60 + viewModel.getTimer().time.min((hours + minutes + seconds).toInt()) + } + } } \ No newline at end of file From ea4e7a4790e43751c75d0ae0ad9a67f234d6db74 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Mon, 24 Apr 2023 21:35:48 +0200 Subject: [PATCH 03/41] timer can run when invisible (but no sound) --- .../sel/studeez/activities/MainActivity.kt | 17 +++++++--- .../local/models/timer_functional/Time.kt | 4 --- .../studeez/screens/session/SessionScreen.kt | 32 ++++++------------- 3 files changed, 21 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt index 6829e7f..734908b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt +++ b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt @@ -1,7 +1,6 @@ package be.ugent.sel.studeez.activities import android.os.Bundle -import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize @@ -11,11 +10,15 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.lifecycle.lifecycleScope import be.ugent.sel.studeez.StudeezApp -import be.ugent.sel.studeez.screens.session.SessionTest -import be.ugent.sel.studeez.screens.session.test +import be.ugent.sel.studeez.screens.session.InvisibleSessionManager import be.ugent.sel.studeez.ui.theme.StudeezTheme import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch + +var onTimerInvisible: Job? = null @AndroidEntryPoint class MainActivity : ComponentActivity() { @@ -34,13 +37,17 @@ class MainActivity : ComponentActivity() { } } + + override fun onStop() { - test() + onTimerInvisible = lifecycleScope.launch { + InvisibleSessionManager.updateTimer() + } super.onStop() } override fun onStart() { - SessionTest.updateTimer() + onTimerInvisible?.cancel() super.onStart() } } diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt index 83be75d..ec7702d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt @@ -4,10 +4,6 @@ class Time(initialTime: Int) { var time = initialTime - fun min(i: Int) { - time -= i - } - fun minOne() { time-- } 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 index dee4f12..48cf209 100644 --- 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 @@ -3,7 +3,6 @@ package be.ugent.sel.studeez.screens.session import android.media.MediaPlayer import android.media.RingtoneManager import android.net.Uri -import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.Box @@ -35,17 +34,11 @@ import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer.S import be.ugent.sel.studeez.data.local.models.timer_functional.Time import be.ugent.sel.studeez.resources import kotlinx.coroutines.delay -import java.time.Duration import java.time.LocalDateTime import java.time.ZoneId import java.util.* -import kotlin.properties.Delegates -import kotlin.time.Duration.Companion.hours -import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds -var start: LocalDateTime = Calendar.getInstance().time.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() - @Composable fun SessionScreen( open: (String) -> Unit, @@ -57,7 +50,7 @@ fun SessionScreen( val mediaplayer = MediaPlayer.create(context, uri) mediaplayer.isLooping = false - SessionTest.setNewViewModel(viewModel = viewModel) + InvisibleSessionManager.setNewViewModel(viewModel = viewModel) Column( modifier = Modifier.padding(10.dp) @@ -75,6 +68,7 @@ fun SessionScreen( mediaplayer.stop() mediaplayer.release() open(StudeezDestinations.HOME_SCREEN) + InvisibleSessionManager.isSession = false // Vanaf hier ook naar report gaan als "end session" knop word ingedrukt }, modifier = Modifier @@ -166,29 +160,21 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me } } -fun test() { - start = Calendar.getInstance().time.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() -} - -object SessionTest { +object InvisibleSessionManager { lateinit var viewModel: SessionViewModel - private var isSession: Boolean = false + var isSession: Boolean = false fun setNewViewModel(viewModel: SessionViewModel) { isSession = true this.viewModel = viewModel } - fun updateTimer() { + suspend fun updateTimer() { if (isSession) { - val end = Calendar.getInstance().time.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() - - val duration = Duration.between(start, end) - - val hours = duration.toHours() - val minutes = duration.toMinutes() % 60 - val seconds = duration.seconds % 60 - viewModel.getTimer().time.min((hours + minutes + seconds).toInt()) + while (true) { + delay(1.seconds) + viewModel.getTimer().tick() + } } } From addfb7e12650c3bf02ebe09e502b811ea926a561 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Tue, 25 Apr 2023 08:44:24 +0200 Subject: [PATCH 04/41] temporary solution to notification when app is in background --- .../sel/studeez/activities/MainActivity.kt | 20 ++++++++++++++++--- .../studeez/screens/session/SessionScreen.kt | 15 +++++--------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt index 734908b..96868f1 100644 --- a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt +++ b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt @@ -1,5 +1,8 @@ package be.ugent.sel.studeez.activities +import android.media.MediaPlayer +import android.media.RingtoneManager +import android.net.Uri import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -22,7 +25,13 @@ var onTimerInvisible: Job? = null @AndroidEntryPoint class MainActivity : ComponentActivity() { + + private var mediaPlayer: MediaPlayer? = null override fun onCreate(savedInstanceState: Bundle?) { + val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) + mediaPlayer = MediaPlayer.create(this, uri) + mediaPlayer?.isLooping = false + super.onCreate(savedInstanceState) setContent { StudeezTheme { @@ -37,19 +46,24 @@ class MainActivity : ComponentActivity() { } } - - override fun onStop() { onTimerInvisible = lifecycleScope.launch { - InvisibleSessionManager.updateTimer() + InvisibleSessionManager.updateTimer(mediaPlayer) } super.onStop() } override fun onStart() { + mediaPlayer?.stop() onTimerInvisible?.cancel() super.onStart() } + + override fun onDestroy() { + mediaPlayer?.stop() + mediaPlayer?.release() + super.onDestroy() + } } @Composable 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 index 48cf209..9f009f4 100644 --- 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 @@ -31,12 +31,8 @@ import androidx.hilt.navigation.compose.hiltViewModel 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.FunctionalTimer.StudyState -import be.ugent.sel.studeez.data.local.models.timer_functional.Time import be.ugent.sel.studeez.resources import kotlinx.coroutines.delay -import java.time.LocalDateTime -import java.time.ZoneId -import java.util.* import kotlin.time.Duration.Companion.seconds @Composable @@ -50,6 +46,7 @@ fun SessionScreen( val mediaplayer = MediaPlayer.create(context, uri) mediaplayer.isLooping = false + // evt mediaplayer meegeven vanaf hier als reserve oplossing InvisibleSessionManager.setNewViewModel(viewModel = viewModel) Column( @@ -88,11 +85,6 @@ fun SessionScreen( } } -private operator fun Time.minus(time: Time): Time { - return Time(this.time - time.time) - -} - @Composable private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: MediaPlayer) { var tikker by remember { mutableStateOf(false) } @@ -169,11 +161,14 @@ object InvisibleSessionManager { this.viewModel = viewModel } - suspend fun updateTimer() { + suspend fun updateTimer(mediaPlayer: MediaPlayer?) { if (isSession) { while (true) { delay(1.seconds) viewModel.getTimer().tick() + if (viewModel.getTimer().hasCurrentCountdownEnded() && !viewModel.getTimer().hasEnded()) { + mediaPlayer?.start() + } } } } From 9c105f96a97fe33cab50af12d235142eb326b418 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Tue, 25 Apr 2023 09:37:50 +0200 Subject: [PATCH 05/41] mediaplayer from SessionScreen.kt instead of MainActivity.kt --- .../ugent/sel/studeez/activities/MainActivity.kt | 2 +- .../sel/studeez/screens/session/SessionScreen.kt | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt index 96868f1..02656bd 100644 --- a/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt +++ b/app/src/main/java/be/ugent/sel/studeez/activities/MainActivity.kt @@ -48,7 +48,7 @@ class MainActivity : ComponentActivity() { override fun onStop() { onTimerInvisible = lifecycleScope.launch { - InvisibleSessionManager.updateTimer(mediaPlayer) + InvisibleSessionManager.updateTimer() } super.onStop() } 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 index 9f009f4..7b0ad3c 100644 --- 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 @@ -47,7 +47,7 @@ fun SessionScreen( mediaplayer.isLooping = false // evt mediaplayer meegeven vanaf hier als reserve oplossing - InvisibleSessionManager.setNewViewModel(viewModel = viewModel) + InvisibleSessionManager.setParameters(viewModel = viewModel, mediaplayer = mediaplayer) Column( modifier = Modifier.padding(10.dp) @@ -153,25 +153,25 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me } object InvisibleSessionManager { - lateinit var viewModel: SessionViewModel + private lateinit var viewModel: SessionViewModel + private lateinit var mediaplayer: MediaPlayer var isSession: Boolean = false - fun setNewViewModel(viewModel: SessionViewModel) { + fun setParameters(viewModel: SessionViewModel, mediaplayer: MediaPlayer) { isSession = true this.viewModel = viewModel + this.mediaplayer = mediaplayer } - suspend fun updateTimer(mediaPlayer: MediaPlayer?) { + suspend fun updateTimer() { if (isSession) { while (true) { delay(1.seconds) viewModel.getTimer().tick() if (viewModel.getTimer().hasCurrentCountdownEnded() && !viewModel.getTimer().hasEnded()) { - mediaPlayer?.start() + mediaplayer.start() } } } } - - -} \ No newline at end of file +} From 7b3a82cc30798ea87d518157b2493bddb08b1430 Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Tue, 25 Apr 2023 09:43:10 +0200 Subject: [PATCH 06/41] New DrawerScreen for TimerOverView --- .../java/be/ugent/sel/studeez/StudeezApp.kt | 3 +- .../composable/DrawerScreenComposable.kt | 51 +++++++++++++++++++ .../timer_overview/TimerOverviewScreen.kt | 23 +++------ 3 files changed, 59 insertions(+), 18 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/common/composable/DrawerScreenComposable.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index a6830a5..c9b0963 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -141,8 +141,7 @@ fun StudeezNavGraph( open, openAndPopUp, viewModel = hiltViewModel(), - drawerViewModel = drawerViewModel, - navBarViewModel = navBarViewModel, + drawerViewModel = drawerViewModel ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/DrawerScreenComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/DrawerScreenComposable.kt new file mode 100644 index 0000000..e6f55f7 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/DrawerScreenComposable.kt @@ -0,0 +1,51 @@ +package be.ugent.sel.studeez.common.composable + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.RowScope +import androidx.compose.material.* +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Menu +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import be.ugent.sel.studeez.common.composable.drawer.Drawer +import be.ugent.sel.studeez.common.composable.drawer.DrawerActions +import be.ugent.sel.studeez.resources +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import be.ugent.sel.studeez.R.string as AppText + +@Composable +fun DrawerScreenTemplate( + title: String, + drawerActions: DrawerActions, + action: @Composable RowScope.() -> Unit = {}, + content: @Composable (PaddingValues) -> Unit +) { + val scaffoldState: ScaffoldState = rememberScaffoldState() + val coroutineScope: CoroutineScope = rememberCoroutineScope() + + Scaffold( + scaffoldState = scaffoldState, + + topBar = { TopAppBar( + title = { Text(text = title) }, + navigationIcon = { + IconButton(onClick = { + coroutineScope.launch { scaffoldState.drawerState.open() } + }) { + Icon( + imageVector = Icons.Default.Menu, + contentDescription = resources().getString(AppText.menu) + ) + } + }, + actions = action + )}, + + drawerContent = { + Drawer(drawerActions) + } + ) { + content(it) + } +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt index fafdf02..9537965 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt @@ -10,10 +10,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import be.ugent.sel.studeez.R -import be.ugent.sel.studeez.common.composable.BasicButton -import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate -import be.ugent.sel.studeez.common.composable.StealthButton -import be.ugent.sel.studeez.common.composable.TimerEntry +import be.ugent.sel.studeez.common.composable.* import be.ugent.sel.studeez.common.composable.drawer.DrawerActions import be.ugent.sel.studeez.common.composable.drawer.DrawerViewModel import be.ugent.sel.studeez.common.composable.drawer.getDrawerActions @@ -48,30 +45,25 @@ fun TimerOverviewRoute( open: (String) -> Unit, openAndPopUp: (String, String) -> Unit, viewModel: TimerOverviewViewModel, - drawerViewModel: DrawerViewModel, - navBarViewModel: NavigationBarViewModel, + drawerViewModel: DrawerViewModel ) { TimerOverviewScreen( timerOverviewActions = getTimerOverviewActions(viewModel), - drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp), - navigationBarActions = getNavigationBarActions(navBarViewModel, open), + drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp) ) } @Composable fun TimerOverviewScreen( timerOverviewActions: TimerOverviewActions, - drawerActions: DrawerActions, - navigationBarActions: NavigationBarActions, + drawerActions: DrawerActions ) { val timers = timerOverviewActions.getUserTimers().collectAsState(initial = emptyList()) - // TODO moet geen primary screen zijn: geen navbar nodig - PrimaryScreenTemplate( + DrawerScreenTemplate( title = resources().getString(R.string.timers), - drawerActions = drawerActions, - navigationBarActions = navigationBarActions, + drawerActions = drawerActions ) { Column { LazyColumn( @@ -112,7 +104,6 @@ fun TimerOverviewPreview() { { flowOf() }, { listOf(customTimer, customTimer) }, {}), - drawerActions = DrawerActions({}, {}, {}, {}, {}), - navigationBarActions = NavigationBarActions({}, {}, {}, {}) + drawerActions = DrawerActions({}, {}, {}, {}, {}) ) } From 7fe7416388084fc76d3ea43ca623b9c137be7351 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Tue, 25 Apr 2023 15:20:28 +0200 Subject: [PATCH 07/41] 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 From ae9a36373145611d23b1931b47bffdafaa54fe67 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Tue, 25 Apr 2023 15:22:01 +0200 Subject: [PATCH 08/41] abstract session screen --- .../screens/session/sessionScreens/AbstractSessionScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index effa1ba..9bb9d73 100644 --- 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 @@ -22,7 +22,7 @@ import be.ugent.sel.studeez.screens.session.SessionActions import kotlinx.coroutines.delay import kotlin.time.Duration.Companion.seconds -abstract class SessionScreen { +abstract class AbstractSessionScreen { var timerEnd = false From d318016f95762c2ccd14820f673e6aa9979e28f9 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Tue, 25 Apr 2023 15:22:20 +0200 Subject: [PATCH 09/41] session screen implementations --- .../screens/session/sessionScreens/BreakSessionScreen.kt | 4 ++-- .../screens/session/sessionScreens/CustomSessionScreen.kt | 4 ++-- .../screens/session/sessionScreens/EndlessSessionScreen.kt | 7 ++----- 3 files changed, 6 insertions(+), 9 deletions(-) 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 index b2fd53f..edc8475 100644 --- 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 @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.session.SessionScreens +package be.ugent.sel.studeez.screens.session.sessionScreens import androidx.compose.runtime.Composable import be.ugent.sel.studeez.R @@ -8,7 +8,7 @@ import be.ugent.sel.studeez.R.string as AppText class BreakSessionScreen( private val funPomoDoroTimer: FunctionalPomodoroTimer -): SessionScreen(funPomoDoroTimer) { +): AbstractSessionScreen() { @Composable override fun motivationString(): String { 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 index 92c2b5e..36ee492 100644 --- 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 @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.session.SessionScreens +package be.ugent.sel.studeez.screens.session.sessionScreens import androidx.compose.runtime.Composable import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer @@ -8,7 +8,7 @@ import be.ugent.sel.studeez.R.string as AppText class CustomSessionScreen( private val functionalTimer: FunctionalCustomTimer -): SessionScreen(functionalTimer) { +): AbstractSessionScreen() { @Composable override fun motivationString(): String { 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 index 688243b..fc46c9d 100644 --- 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 @@ -1,14 +1,11 @@ -package be.ugent.sel.studeez.screens.session.SessionScreens +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) { +class EndlessSessionScreen : AbstractSessionScreen() { @Composable override fun motivationString(): String { From 4996d387ad3170ed9f23f5e5fe3c5690be7cf51b Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Tue, 25 Apr 2023 15:22:42 +0200 Subject: [PATCH 10/41] route is now a single file --- .../java/be/ugent/sel/studeez/screens/session/SessionRoute.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 index bf81215..0d930dc 100644 --- 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 @@ -6,6 +6,7 @@ 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 +import be.ugent.sel.studeez.screens.session.sessionScreens.AbstractSessionScreen data class SessionActions( val getTimer: () -> FunctionalTimer, @@ -31,6 +32,7 @@ fun SessionRoute( open: (String) -> Unit, viewModel: SessionViewModel, ) { + val sessionScreen: AbstractSessionScreen = viewModel.getTimer().getView() val context = LocalContext.current val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) val mediaplayer = MediaPlayer() @@ -44,7 +46,7 @@ fun SessionRoute( mediaplayer.setOnPreparedListener { // mediaplayer.start() } - viewModel.getTimer().getView().SessionScreen( + sessionScreen.SessionScreen( open = open, sessionActions = getSessionActions(viewModel, mediaplayer), ) From d5f3962afe86d5acb741e3e4442d95c8eb693202 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Tue, 25 Apr 2023 15:46:13 +0200 Subject: [PATCH 11/41] tests added --- .idea/inspectionProfiles/Project_Default.xml | 1 + app/build.gradle | 4 + .../studeez/screens/session/SessionScreen.kt | 1 - .../InvisibleSessionManagerTest.kt | 83 +++++++++++++++++++ gradle.properties | 2 + 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 53a1745..cd54531 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -42,5 +42,6 @@ \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index bca9a30..6489d31 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,6 +66,7 @@ dependencies { implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" implementation 'androidx.compose.material:material:1.2.0' + debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version" // ViewModel @@ -97,6 +98,9 @@ dependencies { testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' + // Coroutine testing + testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4' + // Mocking testImplementation 'org.mockito.kotlin:mockito-kotlin:3.2.0' 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 index 7b0ad3c..ac2d225 100644 --- 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 @@ -46,7 +46,6 @@ fun SessionScreen( val mediaplayer = MediaPlayer.create(context, uri) mediaplayer.isLooping = false - // evt mediaplayer meegeven vanaf hier als reserve oplossing InvisibleSessionManager.setParameters(viewModel = viewModel, mediaplayer = mediaplayer) Column( diff --git a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt new file mode 100644 index 0000000..5649f46 --- /dev/null +++ b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt @@ -0,0 +1,83 @@ +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.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.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 val 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().view, FunctionalTimer.StudyState.FOCUS) // Tijdens het focussen + + advanceTimeBy(1_000) + Assert.assertEquals(viewModel.getTimer().time.time, 0) // Focussen gedaan + + advanceTimeBy(4_000) + Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.BREAK) // Tijdens pauze + + advanceTimeBy(1_000) + Assert.assertEquals(viewModel.getTimer().time.time, 0) // Pauze gedaan + + advanceTimeBy(9_000) + Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.FOCUS_REMAINING) // Tijdens 2e focus + + advanceTimeBy(1_000) + Assert.assertEquals(viewModel.getTimer().time.time, 0) // 2e focus gedaan + + advanceTimeBy(4_000) + Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.DONE) // Done + + test.cancel() + return@runTest + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 3c5031e..edf11ef 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,8 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. 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. # 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 From b0c4f44833d1c908f57994bed342ca6ba37968c7 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Tue, 25 Apr 2023 18:05:33 +0200 Subject: [PATCH 12/41] #76 total studytime toevoegen aan een functionaltimer --- .../be/ugent/sel/studeez/data/SessionReportState.kt | 4 ++++ .../models/timer_functional/FunctionalCustomTimer.kt | 2 ++ .../models/timer_functional/FunctionalEndlessTimer.kt | 1 + .../timer_functional/FunctionalPomodoroTimer.kt | 4 ++++ .../local/models/timer_functional/FunctionalTimer.kt | 11 +++++++++++ .../screens/session_recap/SessionRecapScreen.kt | 2 ++ .../screens/session_recap/SessionRecapViewModel.kt | 4 ++++ 7 files changed, 28 insertions(+) create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/SessionReportState.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapScreen.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/data/SessionReportState.kt b/app/src/main/java/be/ugent/sel/studeez/data/SessionReportState.kt new file mode 100644 index 0000000..81e5244 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/SessionReportState.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.data + +class SessionReportState { +} \ No newline at end of file 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 15dd00c..6c035de 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,5 +1,6 @@ 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 @@ -8,6 +9,7 @@ class FunctionalCustomTimer(studyTime: Int) : FunctionalTimer(studyTime) { override fun tick() { if (!hasEnded()) { time.minOne() + totalStudyTime++ } } 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 eb368f4..24007e7 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 @@ -15,6 +15,7 @@ class FunctionalEndlessTimer : FunctionalTimer(0) { override fun tick() { time.plusOne() + totalStudyTime++ } override fun getView(): AbstractSessionScreen { 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 931cbe6..152cfa4 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 @@ -26,6 +26,10 @@ class FunctionalPomodoroTimer( isInBreak = !isInBreak } time.minOne() + + if (!isInBreak) { + totalStudyTime++ + } } override fun hasEnded(): Boolean { 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 449b85c..41733bd 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,12 @@ 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.AbstractSessionScreen +import com.google.firebase.Timestamp + abstract class FunctionalTimer(initialValue: Int) { val time: Time = Time(initialValue) + var totalStudyTime: Int = 0 fun getHoursMinutesSeconds(): HoursMinutesSeconds { return time.getAsHMS() @@ -15,5 +19,12 @@ abstract class FunctionalTimer(initialValue: Int) { abstract fun hasCurrentCountdownEnded(): Boolean abstract fun getView(): AbstractSessionScreen + fun getSessionReport(): SessionReport { + return SessionReport( + id = "", + studyTime = totalStudyTime, + endTime = Timestamp.now() + ) + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapScreen.kt new file mode 100644 index 0000000..440e1d9 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapScreen.kt @@ -0,0 +1,2 @@ +package be.ugent.sel.studeez.screens.session_recap + diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt new file mode 100644 index 0000000..aaa77af --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.screens.session_recap + +class SessionRecapViewModel { +} \ No newline at end of file From ae685070aed7870eb2a3e2776bd3da10e40b3f56 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Tue, 25 Apr 2023 18:07:06 +0200 Subject: [PATCH 13/41] #76 sessionreportstate om een sessionreport mee te geven van scherm naar scherm --- .../be/ugent/sel/studeez/data/SessionReportState.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/data/SessionReportState.kt b/app/src/main/java/be/ugent/sel/studeez/data/SessionReportState.kt index 81e5244..47770d0 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/SessionReportState.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/SessionReportState.kt @@ -1,4 +1,14 @@ package be.ugent.sel.studeez.data -class SessionReportState { +import be.ugent.sel.studeez.data.local.models.SessionReport +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 SessionReportState @Inject constructor(){ + var sessionReport: SessionReport? = null } \ No newline at end of file From 53d292aef4d04abf21170ebf16129c68a707cdd7 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Tue, 25 Apr 2023 18:07:30 +0200 Subject: [PATCH 14/41] #76 added session recap to routes --- .../java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt index 760c814..ab10c22 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt @@ -9,6 +9,7 @@ object StudeezDestinations { const val TIMER_OVERVIEW_SCREEN = "timer_overview" const val TIMER_SELECTION_SCREEN = "timer_selection" const val SESSION_SCREEN = "session" + const val SESSION_RECAP = "session_recap" // const val TASKS_SCREEN = "tasks" // const val SESSIONS_SCREEN = "sessions" const val PROFILE_SCREEN = "profile" From 96795d0e18e41911956dde97030fedab5f82c473 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Tue, 25 Apr 2023 18:10:55 +0200 Subject: [PATCH 15/41] #76 session recap viewmodel en screen --- .../session_recap/SessionRecapScreen.kt | 63 +++++++++++++++++++ .../session_recap/SessionRecapViewModel.kt | 31 ++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapScreen.kt index 440e1d9..63878f7 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapScreen.kt @@ -1,2 +1,65 @@ package be.ugent.sel.studeez.screens.session_recap +import androidx.compose.foundation.layout.Column +import androidx.compose.material.ButtonDefaults +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.common.composable.BasicButton +import be.ugent.sel.studeez.common.ext.basicButton +import be.ugent.sel.studeez.data.local.models.SessionReport +import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds +import be.ugent.sel.studeez.data.local.models.timer_functional.Time + +data class SessionRecapActions( + val getSessionReport: () -> SessionReport, + val saveSession: () -> Unit, + val discardSession: () -> Unit +) + +fun getSessionRecapActions( + viewModel: SessionRecapViewModel, + openAndPopUp: (String, String) -> Unit, +): SessionRecapActions { + return SessionRecapActions( + viewModel::getSessionReport, + {viewModel.saveSession(openAndPopUp)}, + {viewModel.saveSession(openAndPopUp)} + ) +} + +@Composable +fun SessionRecapRoute( + openAndPopUp: (String, String) -> Unit, + modifier: Modifier = Modifier, + viewModel: SessionRecapViewModel, +) { + SessionRecapScreen( + modifier = modifier, + getSessionRecapActions(viewModel, openAndPopUp) + ) +} + +@Composable +fun SessionRecapScreen(modifier: Modifier, sessionRecapActions: SessionRecapActions) { + val sessionReport: SessionReport = sessionRecapActions.getSessionReport() + val studyTime: Int = sessionReport.studyTime + val hms: HoursMinutesSeconds = Time(studyTime).getAsHMS() + Column { + Text(text = "You studied: ${hms.hours} : ${hms.minutes} : ${hms.seconds}") + + BasicButton( + R.string.save, Modifier.basicButton() + ) { + sessionRecapActions.saveSession() + } + BasicButton( + R.string.discard, Modifier.basicButton(), + colors = ButtonDefaults.buttonColors(backgroundColor = Color.Red) + ) { + sessionRecapActions.discardSession() + } + } +} diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt index aaa77af..e9ad6b1 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt @@ -1,4 +1,33 @@ package be.ugent.sel.studeez.screens.session_recap -class SessionRecapViewModel { +import be.ugent.sel.studeez.data.SessionReportState +import be.ugent.sel.studeez.data.local.models.SessionReport +import be.ugent.sel.studeez.domain.LogService +import be.ugent.sel.studeez.domain.SessionDAO +import be.ugent.sel.studeez.navigation.StudeezDestinations +import be.ugent.sel.studeez.screens.StudeezViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class SessionRecapViewModel @Inject constructor( + private val sessionReportState: SessionReportState, + private val sessionDAO: SessionDAO, + logService: LogService +) : StudeezViewModel(logService) { + + private val report: SessionReport = sessionReportState.sessionReport!! + + fun getSessionReport(): SessionReport { + return report + } + + fun saveSession(open: (String, String) -> Unit) { + sessionDAO.saveSession(getSessionReport()) + open(StudeezDestinations.HOME_SCREEN, StudeezDestinations.SESSION_RECAP) + } + + fun discardSession(open: (String, String) -> Unit) { + open(StudeezDestinations.HOME_SCREEN, StudeezDestinations.SESSION_RECAP) + } } \ No newline at end of file From 4e35951850133c5444f72de0ca0aa76d586e28c4 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Tue, 25 Apr 2023 18:11:45 +0200 Subject: [PATCH 16/41] added ensession --- .../screens/session/sessionScreens/AbstractSessionScreen.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 index 9bb9d73..8042450 100644 --- 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 @@ -45,8 +45,7 @@ abstract class AbstractSessionScreen { TextButton( onClick = { sessionActions.releaseMediaPlayer - open(StudeezDestinations.HOME_SCREEN) - // Vanaf hier ook naar report gaan als "end session" knop word ingedrukt + sessionActions.endSession() }, modifier = Modifier .padding(horizontal = 20.dp) From 312fc3167ab275d0f56208c70adf572bd62832d6 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Tue, 25 Apr 2023 18:12:41 +0200 Subject: [PATCH 17/41] added openAndPopUp --- .../be/ugent/sel/studeez/screens/session/SessionRoute.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 index 0d930dc..10fca3f 100644 --- 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 @@ -13,23 +13,27 @@ data class SessionActions( val getTask: () -> String, val prepareMediaPlayer: () -> Unit, val releaseMediaPlayer: () -> Unit, + val endSession: () -> Unit ) private fun getSessionActions( viewModel: SessionViewModel, + openAndPopUp: (String, String) -> Unit, mediaplayer: MediaPlayer, ): SessionActions { return SessionActions( getTimer = viewModel::getTimer, getTask = viewModel::getTask, + endSession = { viewModel.endSession(openAndPopUp) }, prepareMediaPlayer = mediaplayer::prepareAsync, - releaseMediaPlayer = mediaplayer::release, + releaseMediaPlayer = mediaplayer::release ) } @Composable fun SessionRoute( open: (String) -> Unit, + openAndPopUp: (String, String) -> Unit, viewModel: SessionViewModel, ) { val sessionScreen: AbstractSessionScreen = viewModel.getTimer().getView() @@ -48,6 +52,6 @@ fun SessionRoute( } sessionScreen.SessionScreen( open = open, - sessionActions = getSessionActions(viewModel, mediaplayer), + sessionActions = getSessionActions(viewModel, openAndPopUp, mediaplayer), ) } From d381480c433249c839c143b0da35baa88d214291 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Tue, 25 Apr 2023 18:13:12 +0200 Subject: [PATCH 18/41] send sessionreport to state --- .../sel/studeez/screens/session/SessionViewModel.kt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt index b45364e..d5e2bab 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt @@ -1,20 +1,21 @@ package be.ugent.sel.studeez.screens.session +import be.ugent.sel.studeez.data.SelectedTimerState +import be.ugent.sel.studeez.data.SessionReportState import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer import be.ugent.sel.studeez.domain.LogService +import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.StudeezViewModel -import be.ugent.sel.studeez.data.SelectedTimerState -import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel class SessionViewModel @Inject constructor( private val selectedTimerState: SelectedTimerState, + private val sessionReportState: SessionReportState, logService: LogService ) : StudeezViewModel(logService) { - private val timer: FunctionalTimer = FunctionalPomodoroTimer(15, 5, 3) private val task : String = "No task selected" // placeholder for tasks implementation fun getTimer() : FunctionalTimer { @@ -24,4 +25,9 @@ class SessionViewModel @Inject constructor( fun getTask(): String { return task } + + fun endSession(openAndPopUp: (String, String) -> Unit) { + sessionReportState.sessionReport = getTimer().getSessionReport() + openAndPopUp(StudeezDestinations.SESSION_RECAP, StudeezDestinations.SESSION_SCREEN) + } } \ No newline at end of file From 5148d2de4e0ea40278cb82ad4540fa7badd42085 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Tue, 25 Apr 2023 18:14:07 +0200 Subject: [PATCH 19/41] session recap --- .idea/misc.xml | 3 ++- app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt | 10 +++++++++- app/src/main/res/values/strings.xml | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 8978d23..4412b1a 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,7 @@ + - + diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index a6830a5..6aade8f 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -31,6 +31,7 @@ import be.ugent.sel.studeez.screens.log_in.LoginRoute import be.ugent.sel.studeez.screens.profile.EditProfileRoute import be.ugent.sel.studeez.screens.profile.ProfileRoute import be.ugent.sel.studeez.screens.session.SessionRoute +import be.ugent.sel.studeez.screens.session_recap.SessionRecapRoute import be.ugent.sel.studeez.screens.sign_up.SignUpRoute import be.ugent.sel.studeez.screens.splash.SplashRoute import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute @@ -147,7 +148,7 @@ fun StudeezNavGraph( } composable(StudeezDestinations.SESSION_SCREEN) { - SessionRoute(open, viewModel = hiltViewModel()) + SessionRoute(open, openAndPopUp, viewModel = hiltViewModel()) } // TODO Timers screen @@ -167,5 +168,12 @@ fun StudeezNavGraph( navBarViewModel = navBarViewModel, ) } + + composable(StudeezDestinations.SESSION_RECAP) { + SessionRecapRoute( + openAndPopUp = openAndPopUp, + viewModel = hiltViewModel() + ) + } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 39abda6..bb643d3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -10,6 +10,7 @@ Confirm Save + Discard Cancel Go back Next From e73cc798f0764802a4cd30265deab2387634033d Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Tue, 25 Apr 2023 19:27:14 +0200 Subject: [PATCH 20/41] #42 highlight selected screen --- .../composable/PrimaryScreenComposable.kt | 2 +- .../navbar/NavigationBarComposable.kt | 32 ++++++++++++------- .../navbar/NavigationBarViewModel.kt | 15 +++++++++ .../sel/studeez/screens/home/HomeScreen.kt | 2 +- .../studeez/screens/profile/ProfileScreen.kt | 2 +- .../timer_selection/TimerSelectionScreen.kt | 2 +- 6 files changed, 39 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt index 5af2788..773c546 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt @@ -77,7 +77,7 @@ fun PrimaryScreenPreview() { PrimaryScreenTemplate( "Preview screen", DrawerActions({}, {}, {}, {}, {}), - NavigationBarActions({}, {}, {}, {}), + NavigationBarActions({ false }, {}, {}, {}, {}), { IconButton(onClick = { /*TODO*/ }) { Icon( diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt index 21311ef..27fb605 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt @@ -17,6 +17,7 @@ import be.ugent.sel.studeez.ui.theme.StudeezTheme import be.ugent.sel.studeez.R.string as AppText data class NavigationBarActions( + val selectedTab: (Int) -> Boolean, val onHomeClick: () -> Unit, val onTasksClick: () -> Unit, val onSessionsClick: () -> Unit, @@ -28,10 +29,19 @@ fun getNavigationBarActions( open: (String) -> Unit, ): NavigationBarActions { return NavigationBarActions( - onHomeClick = { navigationBarViewModel.onHomeClick(open) }, - onTasksClick = { navigationBarViewModel.onTasksClick(open) }, - onSessionsClick = { navigationBarViewModel.onSessionsClick(open) }, - onProfileClick = { navigationBarViewModel.onProfileClick(open) }, + selectedTab = { navigationBarViewModel.isSelected(it) }, + onHomeClick = { + navigationBarViewModel.onHomeClick(open) + }, + onTasksClick = { + navigationBarViewModel.onTasksClick(open) + }, + onSessionsClick = { + navigationBarViewModel.onSessionsClick(open) + }, + onProfileClick = { + navigationBarViewModel.onProfileClick(open) + }, ) } @@ -39,16 +49,14 @@ fun getNavigationBarActions( fun NavigationBar( navigationBarActions: NavigationBarActions, ) { - // TODO Pass functions and new screens. - // TODO Pass which screen is selected. - // TODO Disabled -> HIGH/MEDIUM_EMPHASIS if the page is implemented BottomNavigation( elevation = 10.dp ) { + BottomNavigationItem( icon = { Icon(imageVector = Icons.Default.List, resources().getString(AppText.home)) }, label = { Text(text = resources().getString(AppText.home)) }, - selected = false, // TODO + selected = navigationBarActions.selectedTab(0), onClick = navigationBarActions.onHomeClick ) @@ -59,7 +67,7 @@ fun NavigationBar( ) }, label = { Text(text = resources().getString(AppText.tasks)) }, - selected = false, // TODO + selected = navigationBarActions.selectedTab(1), onClick = navigationBarActions.onTasksClick ) @@ -73,7 +81,7 @@ fun NavigationBar( ) }, label = { Text(text = resources().getString(AppText.sessions)) }, - selected = false, // TODO + selected = navigationBarActions.selectedTab(2), onClick = navigationBarActions.onSessionsClick ) @@ -84,7 +92,7 @@ fun NavigationBar( ) }, label = { Text(text = resources().getString(AppText.profile)) }, - selected = false, // TODO + selected = navigationBarActions.selectedTab(3), onClick = navigationBarActions.onProfileClick ) @@ -95,6 +103,6 @@ fun NavigationBar( @Composable fun NavigationBarPreview() { StudeezTheme { - NavigationBar(NavigationBarActions({}, {}, {}, {})) + NavigationBar(NavigationBarActions({ false }, {}, {}, {}, {})) } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt index 1e4bd0d..58a75ef 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt @@ -7,26 +7,41 @@ import be.ugent.sel.studeez.navigation.StudeezDestinations.PROFILE_SCREEN import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject +import javax.inject.Singleton @HiltViewModel class NavigationBarViewModel @Inject constructor( private val accountDAO: AccountDAO, + var selectedTab: SelectedTabState, logService: LogService ) : StudeezViewModel(logService) { + fun isSelected(index: Int): Boolean { + return index == selectedTab.selectedTab + } + fun onHomeClick(open: (String) -> Unit) { + selectedTab.selectedTab = 0 open(HOME_SCREEN) } fun onTasksClick(open: (String) -> Unit) { // TODO + selectedTab.selectedTab = 1 } fun onSessionsClick(open: (String) -> Unit) { // TODO + selectedTab.selectedTab = 2 } fun onProfileClick(open: (String) -> Unit) { + selectedTab.selectedTab = 3 open(PROFILE_SCREEN) } +} + +@Singleton +class SelectedTabState @Inject constructor() { + var selectedTab: Int = 0 } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt index e318655..ba322d9 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt @@ -69,6 +69,6 @@ fun HomeScreenPreview() { HomeScreen( onStartSessionClick = {}, drawerActions = DrawerActions({}, {}, {}, {}, {}), - navigationBarActions = NavigationBarActions({}, {}, {}, {}) + navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}) ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt index a12dd08..af72010 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt @@ -90,6 +90,6 @@ fun ProfileScreenPreview() { ProfileScreen( profileActions = ProfileActions({ null }, {}), drawerActions = DrawerActions({}, {}, {}, {}, {}), - navigationBarActions = NavigationBarActions({}, {}, {}, {}) + navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}) ) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt index 47e7f91..007a656 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt @@ -86,6 +86,6 @@ fun TimerSelectionPreview() { TimerSelectionScreen( timerSelectionActions = TimerSelectionActions({ flowOf() }, {}), drawerActions = DrawerActions({}, {}, {}, {}, {}), - navigationBarActions = NavigationBarActions({}, {}, {}, {}), + navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), ) } \ No newline at end of file From f46063eba1f660f4bf5af1f43714abb60eea8baa Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Tue, 25 Apr 2023 20:58:14 +0200 Subject: [PATCH 21/41] isSession vervangend door null waaarden --- .../session/InvisibleSessionManager.kt | 34 +++++++++++++++++++ .../studeez/screens/session/SessionScreen.kt | 31 ++--------------- app/src/main/res/values/strings.xml | 1 + 3 files changed, 37 insertions(+), 29 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt new file mode 100644 index 0000000..c6def28 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt @@ -0,0 +1,34 @@ +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 var mediaplayer: MediaPlayer? = null + + fun setParameters(viewModel: SessionViewModel, mediaplayer: MediaPlayer) { + this.viewModel = viewModel + this.mediaplayer = mediaplayer + } + + suspend fun updateTimer() { + if (viewModel != null) { + while (true) { + delay(1.seconds) + viewModel!!.getTimer().tick() + if (viewModel!!.getTimer().hasCurrentCountdownEnded() && !viewModel!!.getTimer().hasEnded()) { + mediaplayer?.start() + } + } + } + } + + fun removeParameters() { + viewModel = null + mediaplayer = null + } +} \ No newline at end of file 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 index 3a32b37..4f9ada5 100644 --- 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 @@ -35,7 +35,6 @@ 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.resources import kotlinx.coroutines.delay -import javax.inject.Singleton import kotlin.time.Duration.Companion.seconds data class SessionActions( @@ -99,7 +98,7 @@ fun SessionScreen( TextButton( onClick = { sessionActions.releaseMediaPlayer - + InvisibleSessionManager.removeParameters() open(StudeezDestinations.HOME_SCREEN) // Vanaf hier ook naar report gaan als "end session" knop word ingedrukt }, @@ -109,7 +108,7 @@ fun SessionScreen( .background(Color.Transparent) ) { Text( - text = "End session", + text = resources().getString(R.string.end_session), color = Color.Red, fontWeight = FontWeight.Bold, fontSize = 18.sp, @@ -190,32 +189,6 @@ private fun Timer( } } - -@Singleton -object InvisibleSessionManager { - private lateinit var viewModel: SessionViewModel - private lateinit var mediaplayer: MediaPlayer - var isSession: Boolean = false - - fun setParameters(viewModel: SessionViewModel, mediaplayer: MediaPlayer) { - isSession = true - this.viewModel = viewModel - this.mediaplayer = mediaplayer - } - - suspend fun updateTimer() { - if (isSession) { - while (true) { - delay(1.seconds) - viewModel.getTimer().tick() - if (viewModel.getTimer().hasCurrentCountdownEnded() && !viewModel.getTimer().hasEnded()) { - mediaplayer.start() - } - } - } - } -} - @Preview @Composable fun TimerPreview() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 39abda6..03900b3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -44,6 +44,7 @@ Sessions + End session Profile From 05860345b6393ee7baf66167088898029dac80d0 Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Tue, 25 Apr 2023 21:17:57 +0200 Subject: [PATCH 22/41] less hardcoding --- .../composable/navbar/NavigationBarComposable.kt | 14 +++++++++----- .../composable/navbar/NavigationBarViewModel.kt | 14 +++++++------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt index 27fb605..e9b2b0e 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt @@ -12,12 +12,14 @@ import androidx.compose.material.icons.outlined.DateRange import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import be.ugent.sel.studeez.navigation.StudeezDestinations.HOME_SCREEN +import be.ugent.sel.studeez.navigation.StudeezDestinations.PROFILE_SCREEN import be.ugent.sel.studeez.resources import be.ugent.sel.studeez.ui.theme.StudeezTheme import be.ugent.sel.studeez.R.string as AppText data class NavigationBarActions( - val selectedTab: (Int) -> Boolean, + val selectedTab: (String) -> Boolean, val onHomeClick: () -> Unit, val onTasksClick: () -> Unit, val onSessionsClick: () -> Unit, @@ -56,7 +58,7 @@ fun NavigationBar( BottomNavigationItem( icon = { Icon(imageVector = Icons.Default.List, resources().getString(AppText.home)) }, label = { Text(text = resources().getString(AppText.home)) }, - selected = navigationBarActions.selectedTab(0), + selected = navigationBarActions.selectedTab(HOME_SCREEN), onClick = navigationBarActions.onHomeClick ) @@ -67,7 +69,8 @@ fun NavigationBar( ) }, label = { Text(text = resources().getString(AppText.tasks)) }, - selected = navigationBarActions.selectedTab(1), + // TODO selected = navigationBarActions.selectedTab(TASKS_SCREEN), + selected = false, onClick = navigationBarActions.onTasksClick ) @@ -81,7 +84,8 @@ fun NavigationBar( ) }, label = { Text(text = resources().getString(AppText.sessions)) }, - selected = navigationBarActions.selectedTab(2), + // TODO selected = navigationBarActions.selectedTab(SESSIONS_SCREEN), + selected = false, onClick = navigationBarActions.onSessionsClick ) @@ -92,7 +96,7 @@ fun NavigationBar( ) }, label = { Text(text = resources().getString(AppText.profile)) }, - selected = navigationBarActions.selectedTab(3), + selected = navigationBarActions.selectedTab(PROFILE_SCREEN), onClick = navigationBarActions.onProfileClick ) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt index 58a75ef..cadec72 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt @@ -16,32 +16,32 @@ class NavigationBarViewModel @Inject constructor( logService: LogService ) : StudeezViewModel(logService) { - fun isSelected(index: Int): Boolean { - return index == selectedTab.selectedTab + fun isSelected(screen: String): Boolean { + return screen == selectedTab.selectedTab } fun onHomeClick(open: (String) -> Unit) { - selectedTab.selectedTab = 0 + selectedTab.selectedTab = HOME_SCREEN open(HOME_SCREEN) } fun onTasksClick(open: (String) -> Unit) { // TODO - selectedTab.selectedTab = 1 + // selectedTab.selectedTab = TASKS_SCREEN } fun onSessionsClick(open: (String) -> Unit) { // TODO - selectedTab.selectedTab = 2 + // selectedTab.selectedTab = SESSIONS_SCREEN } fun onProfileClick(open: (String) -> Unit) { - selectedTab.selectedTab = 3 + selectedTab.selectedTab = PROFILE_SCREEN open(PROFILE_SCREEN) } } @Singleton class SelectedTabState @Inject constructor() { - var selectedTab: Int = 0 + var selectedTab: String = HOME_SCREEN } \ No newline at end of file From ce3261df076a065dad7999a21cb8c6c49020a11c Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Wed, 26 Apr 2023 10:29:14 +0200 Subject: [PATCH 23/41] Add DrawerScreen preview --- .../common/composable/DrawerScreenComposable.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/DrawerScreenComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/DrawerScreenComposable.kt index e6f55f7..3f43f3e 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/DrawerScreenComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/DrawerScreenComposable.kt @@ -7,9 +7,11 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Menu import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.tooling.preview.Preview import be.ugent.sel.studeez.common.composable.drawer.Drawer import be.ugent.sel.studeez.common.composable.drawer.DrawerActions import be.ugent.sel.studeez.resources +import be.ugent.sel.studeez.ui.theme.StudeezTheme import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import be.ugent.sel.studeez.R.string as AppText @@ -48,4 +50,15 @@ fun DrawerScreenTemplate( ) { content(it) } +} + +@Preview +@Composable +fun DrawerScreenPreview() { + StudeezTheme { DrawerScreenTemplate( + title = "Drawer screen preview", + drawerActions =DrawerActions({}, {}, {}, {}, {}) + ) { + Text(text = "Preview content") + } } } \ No newline at end of file From d268fcd389ae90738087bbc83e5a6540884f3202 Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Wed, 26 Apr 2023 10:33:35 +0200 Subject: [PATCH 24/41] Rename action to barAction --- .../studeez/common/composable/DrawerScreenComposable.kt | 4 ++-- .../studeez/common/composable/PrimaryScreenComposable.kt | 4 ++-- .../studeez/common/composable/SecondaryScreenComposable.kt | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/DrawerScreenComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/DrawerScreenComposable.kt index 3f43f3e..b0b1829 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/DrawerScreenComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/DrawerScreenComposable.kt @@ -20,7 +20,7 @@ import be.ugent.sel.studeez.R.string as AppText fun DrawerScreenTemplate( title: String, drawerActions: DrawerActions, - action: @Composable RowScope.() -> Unit = {}, + barAction: @Composable RowScope.() -> Unit = {}, content: @Composable (PaddingValues) -> Unit ) { val scaffoldState: ScaffoldState = rememberScaffoldState() @@ -41,7 +41,7 @@ fun DrawerScreenTemplate( ) } }, - actions = action + actions = barAction )}, drawerContent = { diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt index 773c546..f83e8d7 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt @@ -31,7 +31,7 @@ fun PrimaryScreenTemplate( title: String, drawerActions: DrawerActions, navigationBarActions: NavigationBarActions, - action: @Composable RowScope.() -> Unit = {}, + barAction: @Composable RowScope.() -> Unit = {}, content: @Composable (PaddingValues) -> Unit ) { val scaffoldState: ScaffoldState = rememberScaffoldState() @@ -53,7 +53,7 @@ fun PrimaryScreenTemplate( ) } }, - actions = action + actions = barAction ) }, diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/SecondaryScreenComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/SecondaryScreenComposable.kt index 5470566..5999072 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/SecondaryScreenComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/SecondaryScreenComposable.kt @@ -1,6 +1,7 @@ package be.ugent.sel.studeez.common.composable import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.RowScope import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack @@ -10,13 +11,12 @@ import be.ugent.sel.studeez.R import be.ugent.sel.studeez.resources import be.ugent.sel.studeez.ui.theme.StudeezTheme -// TODO Add option for button in top right corner as extra button - @Composable // Does not contain floatingActionButton and bottom bar, used in all the other screens fun SecondaryScreenTemplate( title: String, popUp: () -> Unit, + barAction: @Composable RowScope.() -> Unit = {}, content: @Composable (PaddingValues) -> Unit ) { Scaffold( @@ -30,7 +30,8 @@ fun SecondaryScreenTemplate( contentDescription = resources().getString(R.string.go_back) ) } - } + }, + actions = barAction ) }, ) { paddingValues -> content(paddingValues) From 04f61c751634fbc228f950e909831b209b05fce7 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Wed, 26 Apr 2023 11:00:06 +0200 Subject: [PATCH 25/41] Added test for CustomTimer when app isn't visible --- .../InvisibleSessionManagerTest.kt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt index 5649f46..fe0d1c2 100644 --- a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt +++ b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt @@ -2,6 +2,7 @@ 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.data.local.models.timer_functional.FunctionalTimer @@ -80,4 +81,25 @@ class InvisibleSessionManagerTest { 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 + } } \ No newline at end of file From c3a9826001aed884c23df606c013fd15317daceb Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Wed, 26 Apr 2023 11:05:08 +0200 Subject: [PATCH 26/41] remove getView from functional timer and add when in sessionRoute --- .../timer_functional/FunctionalCustomTimer.kt | 4 ---- .../FunctionalEndlessTimer.kt | 4 ---- .../FunctionalPomodoroTimer.kt | 4 ---- .../timer_functional/FunctionalTimer.kt | 3 --- .../studeez/screens/session/SessionRoute.kt | 20 +++++++++++++++---- .../sessionScreens/AbstractSessionScreen.kt | 2 +- 6 files changed, 17 insertions(+), 20 deletions(-) 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 15dd00c..822d3af 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 @@ -19,8 +19,4 @@ class FunctionalCustomTimer(studyTime: Int) : FunctionalTimer(studyTime) { 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 eb368f4..d9d3613 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 @@ -16,8 +16,4 @@ 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 931cbe6..f35c0f7 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 @@ -39,8 +39,4 @@ class FunctionalPomodoroTimer( 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 449b85c..71eb38a 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 @@ -13,7 +13,4 @@ abstract class FunctionalTimer(initialValue: Int) { abstract fun hasEnded(): Boolean abstract fun hasCurrentCountdownEnded(): Boolean - - 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 index 0d930dc..2511fde 100644 --- 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 @@ -5,8 +5,13 @@ 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.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.data.local.models.timer_functional.FunctionalTimer -import be.ugent.sel.studeez.screens.session.sessionScreens.AbstractSessionScreen +import be.ugent.sel.studeez.screens.session.sessionScreens.BreakSessionScreen +import be.ugent.sel.studeez.screens.session.sessionScreens.CustomSessionScreen +import be.ugent.sel.studeez.screens.session.sessionScreens.EndlessSessionScreen data class SessionActions( val getTimer: () -> FunctionalTimer, @@ -32,7 +37,6 @@ fun SessionRoute( open: (String) -> Unit, viewModel: SessionViewModel, ) { - val sessionScreen: AbstractSessionScreen = viewModel.getTimer().getView() val context = LocalContext.current val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) val mediaplayer = MediaPlayer() @@ -46,8 +50,16 @@ fun SessionRoute( mediaplayer.setOnPreparedListener { // mediaplayer.start() } - sessionScreen.SessionScreen( + + val sessionScreen = when (val timer = viewModel.getTimer()) { + is FunctionalCustomTimer -> CustomSessionScreen(timer) + is FunctionalPomodoroTimer -> BreakSessionScreen(timer) + is FunctionalEndlessTimer -> EndlessSessionScreen() + else -> throw java.lang.IllegalArgumentException("Unknown Timer") + } + + sessionScreen( open = open, - sessionActions = getSessionActions(viewModel, mediaplayer), + sessionActions = getSessionActions(viewModel, mediaplayer) ) } 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 index 9bb9d73..3db5b36 100644 --- 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 @@ -27,7 +27,7 @@ abstract class AbstractSessionScreen { var timerEnd = false @Composable - fun SessionScreen( + operator fun invoke( open: (String) -> Unit, sessionActions: SessionActions, ) { From 27526151b0cb0fc6cfbdc43bde6f88bad7571623 Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Wed, 26 Apr 2023 11:20:57 +0200 Subject: [PATCH 27/41] Cleanup show current tab --- .../java/be/ugent/sel/studeez/StudeezApp.kt | 23 +++++++++--------- .../composable/PrimaryScreenComposable.kt | 11 ++------- .../navbar/NavigationBarComposable.kt | 24 ++++++++++++------- .../navbar/NavigationBarViewModel.kt | 15 ------------ .../sel/studeez/screens/home/HomeScreen.kt | 5 ++-- .../studeez/screens/profile/ProfileScreen.kt | 14 ++++------- .../timer_selection/TimerSelectionScreen.kt | 3 ++- 7 files changed, 38 insertions(+), 57 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index c9b0963..0744b42 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -2,17 +2,8 @@ package be.ugent.sel.studeez import android.content.res.Resources import androidx.compose.foundation.layout.padding -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Scaffold -import androidx.compose.material.ScaffoldState -import androidx.compose.material.Snackbar -import androidx.compose.material.SnackbarHost -import androidx.compose.material.Surface -import androidx.compose.material.rememberScaffoldState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.ReadOnlyComposable -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.material.* +import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext @@ -21,6 +12,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable +import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import be.ugent.sel.studeez.common.composable.drawer.DrawerViewModel import be.ugent.sel.studeez.common.composable.navbar.NavigationBarViewModel @@ -89,6 +81,8 @@ fun StudeezNavGraph( val drawerViewModel: DrawerViewModel = hiltViewModel() val navBarViewModel: NavigationBarViewModel = hiltViewModel() + val backStackEntry by appState.navController.currentBackStackEntryAsState() + NavHost( navController = appState.navController, startDestination = StudeezDestinations.SPLASH_SCREEN, @@ -106,6 +100,9 @@ fun StudeezNavGraph( appState.navigateAndPopUp(route, popUp) } + val getCurrentScreen: () -> String? = { + backStackEntry?.destination?.route + } composable(StudeezDestinations.SPLASH_SCREEN) { SplashRoute(openAndPopUp, viewModel = hiltViewModel()) @@ -123,6 +120,7 @@ fun StudeezNavGraph( HomeRoute( open, openAndPopUp, + getCurrentScreen, viewModel = hiltViewModel(), drawerViewModel = drawerViewModel, navBarViewModel = navBarViewModel, @@ -133,7 +131,7 @@ fun StudeezNavGraph( // TODO Sessions screen composable(StudeezDestinations.PROFILE_SCREEN) { - ProfileRoute(open, openAndPopUp, viewModel = hiltViewModel()) + ProfileRoute(open, openAndPopUp, getCurrentScreen, viewModel = hiltViewModel()) } composable(StudeezDestinations.TIMER_OVERVIEW_SCREEN) { @@ -161,6 +159,7 @@ fun StudeezNavGraph( TimerSelectionRoute( open, openAndPopUp, + getCurrentScreen, viewModel = hiltViewModel(), drawerViewModel = drawerViewModel, navBarViewModel = navBarViewModel, diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt index f83e8d7..79dec41 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt @@ -2,26 +2,19 @@ package be.ugent.sel.studeez.common.composable import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.RowScope -import androidx.compose.material.FabPosition -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.Scaffold -import androidx.compose.material.ScaffoldState -import androidx.compose.material.Text -import androidx.compose.material.TopAppBar +import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Menu -import androidx.compose.material.rememberScaffoldState import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.tooling.preview.Preview import be.ugent.sel.studeez.R -import be.ugent.sel.studeez.resources import be.ugent.sel.studeez.common.composable.drawer.Drawer import be.ugent.sel.studeez.common.composable.drawer.DrawerActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBar import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions +import be.ugent.sel.studeez.resources import be.ugent.sel.studeez.ui.theme.StudeezTheme import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt index e9b2b0e..cdfd2d1 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt @@ -1,5 +1,6 @@ package be.ugent.sel.studeez.common.composable.navbar +import android.util.Log import androidx.compose.material.BottomNavigation import androidx.compose.material.BottomNavigationItem import androidx.compose.material.Icon @@ -19,7 +20,7 @@ import be.ugent.sel.studeez.ui.theme.StudeezTheme import be.ugent.sel.studeez.R.string as AppText data class NavigationBarActions( - val selectedTab: (String) -> Boolean, + val isSelectedTab: (String) -> Boolean, val onHomeClick: () -> Unit, val onTasksClick: () -> Unit, val onSessionsClick: () -> Unit, @@ -29,9 +30,13 @@ data class NavigationBarActions( fun getNavigationBarActions( navigationBarViewModel: NavigationBarViewModel, open: (String) -> Unit, + getCurrentScreen: () -> String? ): NavigationBarActions { return NavigationBarActions( - selectedTab = { navigationBarViewModel.isSelected(it) }, + isSelectedTab = { screen -> + Log.v("TEMP", getCurrentScreen().toString()) // TODO Remove + screen == getCurrentScreen() + }, onHomeClick = { navigationBarViewModel.onHomeClick(open) }, @@ -49,16 +54,15 @@ fun getNavigationBarActions( @Composable fun NavigationBar( - navigationBarActions: NavigationBarActions, + navigationBarActions: NavigationBarActions ) { BottomNavigation( elevation = 10.dp ) { - BottomNavigationItem( icon = { Icon(imageVector = Icons.Default.List, resources().getString(AppText.home)) }, label = { Text(text = resources().getString(AppText.home)) }, - selected = navigationBarActions.selectedTab(HOME_SCREEN), + selected = navigationBarActions.isSelectedTab(HOME_SCREEN), onClick = navigationBarActions.onHomeClick ) @@ -69,7 +73,7 @@ fun NavigationBar( ) }, label = { Text(text = resources().getString(AppText.tasks)) }, - // TODO selected = navigationBarActions.selectedTab(TASKS_SCREEN), + // TODO selected = navigationBarActions.isSelectedTab(TASKS_SCREEN), selected = false, onClick = navigationBarActions.onTasksClick ) @@ -84,7 +88,7 @@ fun NavigationBar( ) }, label = { Text(text = resources().getString(AppText.sessions)) }, - // TODO selected = navigationBarActions.selectedTab(SESSIONS_SCREEN), + // TODO selected = navigationBarActions.isSelectedTab(SESSIONS_SCREEN), selected = false, onClick = navigationBarActions.onSessionsClick ) @@ -96,7 +100,7 @@ fun NavigationBar( ) }, label = { Text(text = resources().getString(AppText.profile)) }, - selected = navigationBarActions.selectedTab(PROFILE_SCREEN), + selected = navigationBarActions.isSelectedTab(PROFILE_SCREEN), onClick = navigationBarActions.onProfileClick ) @@ -107,6 +111,8 @@ fun NavigationBar( @Composable fun NavigationBarPreview() { StudeezTheme { - NavigationBar(NavigationBarActions({ false }, {}, {}, {}, {})) + NavigationBar( + navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), + ) } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt index cadec72..1e4bd0d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt @@ -7,41 +7,26 @@ import be.ugent.sel.studeez.navigation.StudeezDestinations.PROFILE_SCREEN import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject -import javax.inject.Singleton @HiltViewModel class NavigationBarViewModel @Inject constructor( private val accountDAO: AccountDAO, - var selectedTab: SelectedTabState, logService: LogService ) : StudeezViewModel(logService) { - fun isSelected(screen: String): Boolean { - return screen == selectedTab.selectedTab - } - fun onHomeClick(open: (String) -> Unit) { - selectedTab.selectedTab = HOME_SCREEN open(HOME_SCREEN) } fun onTasksClick(open: (String) -> Unit) { // TODO - // selectedTab.selectedTab = TASKS_SCREEN } fun onSessionsClick(open: (String) -> Unit) { // TODO - // selectedTab.selectedTab = SESSIONS_SCREEN } fun onProfileClick(open: (String) -> Unit) { - selectedTab.selectedTab = PROFILE_SCREEN open(PROFILE_SCREEN) } -} - -@Singleton -class SelectedTabState @Inject constructor() { - var selectedTab: String = HOME_SCREEN } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt index ba322d9..0ea8e16 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt @@ -23,6 +23,7 @@ import be.ugent.sel.studeez.resources fun HomeRoute( open: (String) -> Unit, openAndPopUp: (String, String) -> Unit, + getCurrentScreen: () -> String?, viewModel: HomeViewModel, drawerViewModel: DrawerViewModel, navBarViewModel: NavigationBarViewModel, @@ -30,7 +31,7 @@ fun HomeRoute( HomeScreen( onStartSessionClick = { viewModel.onStartSessionClick(open) }, drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp), - navigationBarActions = getNavigationBarActions(navBarViewModel, open), + navigationBarActions = getNavigationBarActions(navBarViewModel, open, getCurrentScreen), ) } @@ -45,7 +46,7 @@ fun HomeScreen( title = resources().getString(R.string.home), drawerActions = drawerActions, navigationBarActions = navigationBarActions, - action = { FriendsAction() } + barAction = { FriendsAction() } ) { BasicButton(R.string.start_session, Modifier.basicButton()) { onStartSessionClick() diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt index af72010..d68f05e 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt @@ -4,22 +4,17 @@ import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit -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.runtime.* import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel import be.ugent.sel.studeez.R import be.ugent.sel.studeez.common.composable.Headline import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate -import be.ugent.sel.studeez.resources import be.ugent.sel.studeez.common.composable.drawer.DrawerActions import be.ugent.sel.studeez.common.composable.drawer.getDrawerActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions +import be.ugent.sel.studeez.resources import kotlinx.coroutines.CoroutineScope import be.ugent.sel.studeez.R.string as AppText @@ -42,12 +37,13 @@ fun getProfileActions( fun ProfileRoute( open: (String) -> Unit, openAndPopUp: (String, String) -> Unit, + getCurrentScreen: () -> String?, viewModel: ProfileViewModel, ) { ProfileScreen( profileActions = getProfileActions(viewModel, open), drawerActions = getDrawerActions(hiltViewModel(), open, openAndPopUp), - navigationBarActions = getNavigationBarActions(hiltViewModel(), open), + navigationBarActions = getNavigationBarActions(hiltViewModel(), open, getCurrentScreen), ) } @@ -65,7 +61,7 @@ fun ProfileScreen( title = resources().getString(AppText.profile), drawerActions = drawerActions, navigationBarActions = navigationBarActions, - action = { EditAction(onClick = profileActions.onEditProfileClick) } + barAction = { EditAction(onClick = profileActions.onEditProfileClick) } ) { Headline(text = (username ?: resources().getString(R.string.no_username))) } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt index 007a656..54fac0d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt @@ -41,6 +41,7 @@ fun getTimerSelectionActions( fun TimerSelectionRoute( open: (String) -> Unit, openAndPopUp: (String, String) -> Unit, + getCurrentScreen: () -> String?, viewModel: TimerSelectionViewModel, drawerViewModel: DrawerViewModel, navBarViewModel: NavigationBarViewModel, @@ -48,7 +49,7 @@ fun TimerSelectionRoute( TimerSelectionScreen( timerSelectionActions = getTimerSelectionActions(viewModel, open), drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp), - navigationBarActions = getNavigationBarActions(navBarViewModel, open), + navigationBarActions = getNavigationBarActions(navBarViewModel, open, getCurrentScreen), ) } From 351547f1110b028250f6f6346efa1d8c6035c057 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Wed, 26 Apr 2023 11:35:26 +0200 Subject: [PATCH 28/41] visitor --- .../timer_functional/FunctionalCustomTimer.kt | 4 ++++ .../FunctionalEndlessTimer.kt | 7 +++--- .../FunctionalPomodoroTimer.kt | 4 ++++ .../timer_functional/FunctionalTimer.kt | 3 ++- .../FunctionalTimerVisitor.kt | 11 ++++++++++ .../studeez/screens/session/SessionRoute.kt | 22 +++++++++---------- .../sessionScreens/GetSessionScreen.kt | 20 +++++++++++++++++ 7 files changed, 55 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimerVisitor.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.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 822d3af..412432b 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 @@ -19,4 +19,8 @@ class FunctionalCustomTimer(studyTime: Int) : FunctionalTimer(studyTime) { return hasEnded() } + override fun accept(visitor: FunctionalTimerVisitor): T { + return visitor.visitFunctionalCustomTimer(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 d9d3613..67ed4e1 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,8 +1,5 @@ package be.ugent.sel.studeez.data.local.models.timer_functional -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 { @@ -16,4 +13,8 @@ class FunctionalEndlessTimer : FunctionalTimer(0) { override fun tick() { time.plusOne() } + + override fun accept(visitor: FunctionalTimerVisitor): T { + return visitor.visitFunctionalEndlessTimer(this) + } } \ 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 f35c0f7..07f9a39 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 @@ -39,4 +39,8 @@ class FunctionalPomodoroTimer( override fun hasCurrentCountdownEnded(): Boolean { return time.time == 0 } + + override fun accept(visitor: FunctionalTimerVisitor): T { + return visitor.visitFunctionalBreakTimer(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 71eb38a..2d904d8 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,6 +1,5 @@ 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) @@ -13,4 +12,6 @@ abstract class FunctionalTimer(initialValue: Int) { abstract fun hasEnded(): Boolean abstract fun hasCurrentCountdownEnded(): Boolean + + abstract fun accept(visitor: FunctionalTimerVisitor): T } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimerVisitor.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimerVisitor.kt new file mode 100644 index 0000000..3acc805 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimerVisitor.kt @@ -0,0 +1,11 @@ +package be.ugent.sel.studeez.data.local.models.timer_functional + +interface FunctionalTimerVisitor { + + fun visitFunctionalCustomTimer(functionalCustomTimer: FunctionalCustomTimer): T + + fun visitFunctionalEndlessTimer(functionalEndlessTimer: FunctionalEndlessTimer): T + + fun visitFunctionalBreakTimer(functionalPomodoroTimer: FunctionalPomodoroTimer): T + +} \ 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 index 2511fde..57dd7af 100644 --- 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 @@ -5,13 +5,9 @@ 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.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.data.local.models.timer_functional.FunctionalTimer -import be.ugent.sel.studeez.screens.session.sessionScreens.BreakSessionScreen -import be.ugent.sel.studeez.screens.session.sessionScreens.CustomSessionScreen -import be.ugent.sel.studeez.screens.session.sessionScreens.EndlessSessionScreen +import be.ugent.sel.studeez.screens.session.sessionScreens.AbstractSessionScreen +import be.ugent.sel.studeez.screens.session.sessionScreens.GetSessionScreen data class SessionActions( val getTimer: () -> FunctionalTimer, @@ -51,12 +47,14 @@ fun SessionRoute( // mediaplayer.start() } - val sessionScreen = when (val timer = viewModel.getTimer()) { - is FunctionalCustomTimer -> CustomSessionScreen(timer) - is FunctionalPomodoroTimer -> BreakSessionScreen(timer) - is FunctionalEndlessTimer -> EndlessSessionScreen() - else -> throw java.lang.IllegalArgumentException("Unknown Timer") - } + val sessionScreen: AbstractSessionScreen = viewModel.getTimer().accept(GetSessionScreen()) + + //val sessionScreen = when (val timer = viewModel.getTimer()) { + // is FunctionalCustomTimer -> CustomSessionScreen(timer) + // is FunctionalPomodoroTimer -> BreakSessionScreen(timer) + // is FunctionalEndlessTimer -> EndlessSessionScreen() + // else -> throw java.lang.IllegalArgumentException("Unknown Timer") + //} sessionScreen( open = open, diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt new file mode 100644 index 0000000..e5ee42c --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt @@ -0,0 +1,20 @@ +package be.ugent.sel.studeez.screens.session.sessionScreens + +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.data.local.models.timer_functional.FunctionalTimerVisitor + +class GetSessionScreen : FunctionalTimerVisitor { + override fun visitFunctionalCustomTimer(functionalCustomTimer: FunctionalCustomTimer): AbstractSessionScreen { + return CustomSessionScreen(functionalCustomTimer) + } + + override fun visitFunctionalEndlessTimer(functionalEndlessTimer: FunctionalEndlessTimer): AbstractSessionScreen { + return EndlessSessionScreen() + } + + override fun visitFunctionalBreakTimer(functionalPomodoroTimer: FunctionalPomodoroTimer): AbstractSessionScreen { + return BreakSessionScreen(functionalPomodoroTimer) + } +} \ No newline at end of file From e898b6753d56984cfe8c41daa1a156f16d3a7104 Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Wed, 26 Apr 2023 11:36:54 +0200 Subject: [PATCH 29/41] Remove log --- .../studeez/common/composable/navbar/NavigationBarComposable.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt index cdfd2d1..7a3da18 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt @@ -34,7 +34,6 @@ fun getNavigationBarActions( ): NavigationBarActions { return NavigationBarActions( isSelectedTab = { screen -> - Log.v("TEMP", getCurrentScreen().toString()) // TODO Remove screen == getCurrentScreen() }, onHomeClick = { From 9a18bcc41467b29eb597c2e584925ff78dfa0afc Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Wed, 26 Apr 2023 14:34:44 +0200 Subject: [PATCH 30/41] preview + visitor refactor --- .../sessionScreens/AbstractSessionScreen.kt | 19 ++++++++++++++++--- .../sessionScreens/GetSessionScreen.kt | 15 ++++++--------- 2 files changed, 22 insertions(+), 12 deletions(-) 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 index 3db5b36..98a5871 100644 --- 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 @@ -15,8 +15,10 @@ 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.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +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 kotlinx.coroutines.delay @@ -66,7 +68,7 @@ abstract class AbstractSessionScreen { } @Composable - private fun Timer( + fun Timer( sessionActions: SessionActions, ) { var tikker by remember { mutableStateOf(false) } @@ -85,8 +87,8 @@ abstract class AbstractSessionScreen { if (!timerEnd && sessionActions.getTimer().hasEnded()) { // sessionActions.prepareMediaPlayer() - timerEnd = - true // Placeholder, vanaf hier moet het report opgestart worden en de sessie afgesloten + timerEnd = + true // Placeholder, vanaf hier moet het report opgestart worden en de sessie afgesloten } val hms = sessionActions.getTimer().getHoursMinutesSeconds() @@ -135,4 +137,15 @@ abstract class AbstractSessionScreen { @Composable abstract fun motivationString(): String +} + +@Preview +@Composable +fun TimerPreview() { + val sessionScreen = object : AbstractSessionScreen() { + @Composable + override fun motivationString(): String = "Test" + + } + sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {})) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt index e5ee42c..e378661 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt @@ -6,15 +6,12 @@ import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodor import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimerVisitor class GetSessionScreen : FunctionalTimerVisitor { - override fun visitFunctionalCustomTimer(functionalCustomTimer: FunctionalCustomTimer): AbstractSessionScreen { - return CustomSessionScreen(functionalCustomTimer) - } + override fun visitFunctionalCustomTimer(functionalCustomTimer: FunctionalCustomTimer): AbstractSessionScreen = + CustomSessionScreen(functionalCustomTimer) - override fun visitFunctionalEndlessTimer(functionalEndlessTimer: FunctionalEndlessTimer): AbstractSessionScreen { - return EndlessSessionScreen() - } + override fun visitFunctionalEndlessTimer(functionalEndlessTimer: FunctionalEndlessTimer): AbstractSessionScreen = + EndlessSessionScreen() - override fun visitFunctionalBreakTimer(functionalPomodoroTimer: FunctionalPomodoroTimer): AbstractSessionScreen { - return BreakSessionScreen(functionalPomodoroTimer) - } + override fun visitFunctionalBreakTimer(functionalPomodoroTimer: FunctionalPomodoroTimer): AbstractSessionScreen = + BreakSessionScreen(functionalPomodoroTimer) } \ No newline at end of file From 66a566b7794741361543e0e7373f007bd8b4b7ad Mon Sep 17 00:00:00 2001 From: lbarraga Date: Wed, 26 Apr 2023 19:07:26 +0200 Subject: [PATCH 31/41] remove state from tests --- .../FunctionalCustomTimerUnitTest.kt | 5 +---- .../FunctionalEndlessTimerUnitTest.kt | 4 ---- .../FunctionalPomodoroTimerUnitTest.kt | 20 ------------------- 3 files changed, 1 insertion(+), 28 deletions(-) diff --git a/app/src/test/java/be/ugent/sel/studeez/timer_functional/FunctionalCustomTimerUnitTest.kt b/app/src/test/java/be/ugent/sel/studeez/timer_functional/FunctionalCustomTimerUnitTest.kt index 2daa61e..6e51b4e 100644 --- a/app/src/test/java/be/ugent/sel/studeez/timer_functional/FunctionalCustomTimerUnitTest.kt +++ b/app/src/test/java/be/ugent/sel/studeez/timer_functional/FunctionalCustomTimerUnitTest.kt @@ -36,9 +36,6 @@ class FunctionalCustomTimerUnitTest : FunctionalTimerUnitTest() { timer = FunctionalCustomTimer(0) timer.tick() Assert.assertTrue(timer.hasEnded()) - Assert.assertEquals( - FunctionalTimer.StudyState.DONE, - timer.view - ) + Assert.assertTrue(timer.hasEnded()) } } \ No newline at end of file diff --git a/app/src/test/java/be/ugent/sel/studeez/timer_functional/FunctionalEndlessTimerUnitTest.kt b/app/src/test/java/be/ugent/sel/studeez/timer_functional/FunctionalEndlessTimerUnitTest.kt index b83d436..b99c901 100644 --- a/app/src/test/java/be/ugent/sel/studeez/timer_functional/FunctionalEndlessTimerUnitTest.kt +++ b/app/src/test/java/be/ugent/sel/studeez/timer_functional/FunctionalEndlessTimerUnitTest.kt @@ -37,10 +37,6 @@ class FunctionalEndlessTimerUnitTest : FunctionalTimerUnitTest() { for (i in 1..n) { timer.tick() Assert.assertFalse(timer.hasEnded()) - Assert.assertEquals( - FunctionalTimer.StudyState.FOCUS, - timer.view - ) } } } \ No newline at end of file diff --git a/app/src/test/java/be/ugent/sel/studeez/timer_functional/FunctionalPomodoroTimerUnitTest.kt b/app/src/test/java/be/ugent/sel/studeez/timer_functional/FunctionalPomodoroTimerUnitTest.kt index a49d2f7..3ff1499 100644 --- a/app/src/test/java/be/ugent/sel/studeez/timer_functional/FunctionalPomodoroTimerUnitTest.kt +++ b/app/src/test/java/be/ugent/sel/studeez/timer_functional/FunctionalPomodoroTimerUnitTest.kt @@ -29,10 +29,6 @@ class FunctionalPomodoroTimerUnitTest : FunctionalTimerUnitTest() { breaks, pomodoroTimer.breaksRemaining, ) - Assert.assertEquals( - FunctionalTimer.StudyState.FOCUS, - pomodoroTimer.view, - ) } @Test @@ -52,10 +48,6 @@ class FunctionalPomodoroTimerUnitTest : FunctionalTimerUnitTest() { pomodoroTimer = FunctionalPomodoroTimer(0, 0, 0) pomodoroTimer.tick() Assert.assertTrue(pomodoroTimer.hasEnded()) - Assert.assertEquals( - FunctionalTimer.StudyState.DONE, - pomodoroTimer.view, - ) } @Test @@ -65,10 +57,6 @@ class FunctionalPomodoroTimerUnitTest : FunctionalTimerUnitTest() { } Assert.assertFalse(pomodoroTimer.hasEnded()) Assert.assertTrue(pomodoroTimer.isInBreak) - Assert.assertEquals( - FunctionalTimer.StudyState.BREAK, - pomodoroTimer.view - ) } @Test @@ -77,10 +65,6 @@ class FunctionalPomodoroTimerUnitTest : FunctionalTimerUnitTest() { pomodoroTimer.tick() } Assert.assertTrue(pomodoroTimer.isInBreak) - Assert.assertEquals( - FunctionalTimer.StudyState.BREAK, - pomodoroTimer.view - ) for (i in 0..breakTime) { pomodoroTimer.tick() } @@ -90,9 +74,5 @@ class FunctionalPomodoroTimerUnitTest : FunctionalTimerUnitTest() { breaksRemaining, pomodoroTimer.breaksRemaining ) - Assert.assertEquals( - FunctionalTimer.StudyState.FOCUS_REMAINING, - pomodoroTimer.view - ) } } \ No newline at end of file From 71a6bce61c6f045bb913f6fb1084178601279251 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Wed, 26 Apr 2023 19:26:46 +0200 Subject: [PATCH 32/41] preview error fix --- .../screens/session/sessionScreens/AbstractSessionScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 98a5871..7844587 100644 --- 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 @@ -147,5 +147,5 @@ fun TimerPreview() { override fun motivationString(): String = "Test" } - sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {})) + sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {}, {})) } \ No newline at end of file From 18a055c5991e65febf3be5f15e9d2400346cd5e3 Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Thu, 27 Apr 2023 23:15:25 +0200 Subject: [PATCH 33/41] TimerSelection is now secondary --- .../java/be/ugent/sel/studeez/StudeezApp.kt | 1 + .../timer_selection/TimerSelectionScreen.kt | 21 +++++++------------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index 0744b42..bd915a3 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -159,6 +159,7 @@ fun StudeezNavGraph( TimerSelectionRoute( open, openAndPopUp, + goBack, getCurrentScreen, viewModel = hiltViewModel(), drawerViewModel = drawerViewModel, diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt index 54fac0d..b6e4711 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt @@ -8,15 +8,11 @@ import androidx.compose.runtime.collectAsState import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import be.ugent.sel.studeez.R -import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate +import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate import be.ugent.sel.studeez.common.composable.StealthButton import be.ugent.sel.studeez.common.composable.TimerEntry -import be.ugent.sel.studeez.common.composable.drawer.DrawerActions import be.ugent.sel.studeez.common.composable.drawer.DrawerViewModel -import be.ugent.sel.studeez.common.composable.drawer.getDrawerActions -import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarViewModel -import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo import be.ugent.sel.studeez.resources import kotlinx.coroutines.flow.Flow @@ -41,6 +37,7 @@ fun getTimerSelectionActions( fun TimerSelectionRoute( open: (String) -> Unit, openAndPopUp: (String, String) -> Unit, + popUp: () -> Unit, getCurrentScreen: () -> String?, viewModel: TimerSelectionViewModel, drawerViewModel: DrawerViewModel, @@ -48,22 +45,19 @@ fun TimerSelectionRoute( ) { TimerSelectionScreen( timerSelectionActions = getTimerSelectionActions(viewModel, open), - drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp), - navigationBarActions = getNavigationBarActions(navBarViewModel, open, getCurrentScreen), + popUp = popUp ) } @Composable fun TimerSelectionScreen( timerSelectionActions: TimerSelectionActions, - drawerActions: DrawerActions, - navigationBarActions: NavigationBarActions, + popUp: () -> Unit ) { val timers = timerSelectionActions.getAllTimers().collectAsState(initial = emptyList()) - PrimaryScreenTemplate( + SecondaryScreenTemplate( title = resources().getString(R.string.timers), - drawerActions = drawerActions, - navigationBarActions = navigationBarActions, + popUp = popUp ) { LazyColumn(verticalArrangement = Arrangement.spacedBy(7.dp)) { // All timers @@ -86,7 +80,6 @@ fun TimerSelectionScreen( fun TimerSelectionPreview() { TimerSelectionScreen( timerSelectionActions = TimerSelectionActions({ flowOf() }, {}), - drawerActions = DrawerActions({}, {}, {}, {}, {}), - navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), + popUp = {} ) } \ No newline at end of file From cf91d727a0adb6b953f7abe82b2ffe5532e2b50d Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Fri, 28 Apr 2023 00:15:09 +0200 Subject: [PATCH 34/41] Minor styling of timerentries --- .../common/composable/ButtonComposable.kt | 15 ++---- .../studeez/common/composable/TimerEntry.kt | 47 ++++++++++++------- .../timer_overview/TimerOverviewScreen.kt | 14 ++---- .../timer_selection/TimerSelectionScreen.kt | 19 ++++---- 4 files changed, 48 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt index b2568aa..3fa9bd2 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt @@ -3,15 +3,9 @@ package be.ugent.sel.studeez.common.composable import androidx.annotation.StringRes import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Button -import androidx.compose.material.ButtonColors -import androidx.compose.material.ButtonDefaults -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.material.TextButton +import androidx.compose.material.* import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -21,7 +15,6 @@ import be.ugent.sel.studeez.common.ext.basicButton import be.ugent.sel.studeez.common.ext.card @Composable - fun BasicTextButton(@StringRes text: Int, modifier: Modifier, action: () -> Unit) { TextButton(onClick = action, modifier = modifier) { Text(text = stringResource(text)) } } @@ -64,10 +57,10 @@ fun StealthButton( onClick = onClick, modifier = Modifier.card(), colors = ButtonDefaults.buttonColors( - backgroundColor = Color.Transparent, - contentColor = Color.DarkGray, + backgroundColor = MaterialTheme.colors.surface, + contentColor = MaterialTheme.colors.onSurface ), - border = BorderStroke(3.dp, Color.DarkGray), + border = BorderStroke(1.dp, MaterialTheme.colors.onSurface) ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/TimerEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/TimerEntry.kt index bfa2711..7dc105b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/TimerEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/TimerEntry.kt @@ -1,10 +1,6 @@ package be.ugent.sel.studeez.common.composable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.* import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -20,24 +16,39 @@ import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo @Composable fun TimerEntry( timerInfo: TimerInfo, - button: @Composable () -> Unit, + rightButton: @Composable () -> Unit = {}, + leftButton: @Composable () -> Unit = {} ) { Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween + modifier = Modifier.fillMaxWidth() ) { - Column( - Modifier.padding(horizontal = 10.dp) + Row( + modifier = Modifier.weight(1f) ) { - Text( - text = timerInfo.name, fontWeight = FontWeight.Bold, fontSize = 20.sp - ) - Text( - text = timerInfo.description, fontWeight = FontWeight.Light, fontSize = 15.sp - ) + Box(modifier = Modifier.align(alignment = Alignment.CenterVertically)) { + leftButton() + } + + Column( + Modifier.padding( + horizontal = 20.dp, + vertical = 11.dp + ) + ) { + Text( + text = timerInfo.name, + fontWeight = FontWeight.Medium, + fontSize = 20.sp + ) + Text( + text = timerInfo.description, fontWeight = FontWeight.Light, fontSize = 14.sp + ) + } + } + + Box(modifier = Modifier.align(alignment = Alignment.CenterVertically)) { + rightButton() } - button() } } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt index 9537965..ca38ba9 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt @@ -1,6 +1,5 @@ package be.ugent.sel.studeez.screens.timer_overview -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items @@ -8,15 +7,14 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import be.ugent.sel.studeez.R -import be.ugent.sel.studeez.common.composable.* +import be.ugent.sel.studeez.common.composable.BasicButton +import be.ugent.sel.studeez.common.composable.DrawerScreenTemplate +import be.ugent.sel.studeez.common.composable.StealthButton +import be.ugent.sel.studeez.common.composable.TimerEntry import be.ugent.sel.studeez.common.composable.drawer.DrawerActions import be.ugent.sel.studeez.common.composable.drawer.DrawerViewModel import be.ugent.sel.studeez.common.composable.drawer.getDrawerActions -import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions -import be.ugent.sel.studeez.common.composable.navbar.NavigationBarViewModel -import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions import be.ugent.sel.studeez.common.ext.basicButton import be.ugent.sel.studeez.data.local.models.timer_info.CustomTimerInfo import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo @@ -66,9 +64,7 @@ fun TimerOverviewScreen( drawerActions = drawerActions ) { Column { - LazyColumn( - verticalArrangement = Arrangement.spacedBy(7.dp) - ) { + LazyColumn { // Default Timers, cannot be edited items(timerOverviewActions.getDefaultTimers()) { TimerEntry(timerInfo = it) {} diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt index b6e4711..2e52b0b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt @@ -1,12 +1,12 @@ 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.material.Text +import androidx.compose.material.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import be.ugent.sel.studeez.R import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate import be.ugent.sel.studeez.common.composable.StealthButton @@ -59,17 +59,18 @@ fun TimerSelectionScreen( title = resources().getString(R.string.timers), popUp = popUp ) { - LazyColumn(verticalArrangement = Arrangement.spacedBy(7.dp)) { + LazyColumn { // All timers items(timers.value) { timerInfo -> TimerEntry( timerInfo = timerInfo, - ) { - StealthButton( - text = R.string.start, - onClick = { timerSelectionActions.startSession(timerInfo) } - ) - } + leftButton = { + StealthButton( + text = R.string.start, + onClick = { timerSelectionActions.startSession(timerInfo) } + ) + } + ) } } } From a2648509ac06b64fbf065fb146ad69e55fc1b73b Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Fri, 28 Apr 2023 11:43:53 +0200 Subject: [PATCH 35/41] remove bracket --- .../screens/session/sessionScreens/AbstractSessionScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 7844587..98a5871 100644 --- 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 @@ -147,5 +147,5 @@ fun TimerPreview() { override fun motivationString(): String = "Test" } - sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {}, {})) + sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {})) } \ No newline at end of file From 010c7cff5408968882c71fdc617ba7a239d0c2e2 Mon Sep 17 00:00:00 2001 From: brreynie Date: Fri, 28 Apr 2023 12:13:06 +0200 Subject: [PATCH 36/41] extract navbar and draweractions to StudeezNavGraph --- .../java/be/ugent/sel/studeez/StudeezApp.kt | 89 ++++++++++++------- .../sel/studeez/screens/home/HomeScreen.kt | 15 +--- .../studeez/screens/profile/ProfileScreen.kt | 18 ++-- .../studeez/screens/splash/SplashScreen.kt | 1 - .../timer_overview/TimerOverviewScreen.kt | 8 +- .../timer_selection/TimerSelectionScreen.kt | 8 -- 6 files changed, 72 insertions(+), 67 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index bd915a3..28e3785 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -2,8 +2,18 @@ package be.ugent.sel.studeez import android.content.res.Resources import androidx.compose.foundation.layout.padding -import androidx.compose.material.* -import androidx.compose.runtime.* +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Scaffold +import androidx.compose.material.ScaffoldState +import androidx.compose.material.Snackbar +import androidx.compose.material.SnackbarHost +import androidx.compose.material.Surface +import androidx.compose.material.rememberScaffoldState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext @@ -14,8 +24,12 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController +import be.ugent.sel.studeez.common.composable.drawer.DrawerActions import be.ugent.sel.studeez.common.composable.drawer.DrawerViewModel +import be.ugent.sel.studeez.common.composable.drawer.getDrawerActions +import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarViewModel +import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions import be.ugent.sel.studeez.common.snackbar.SnackbarManager import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.home.HomeRoute @@ -82,48 +96,51 @@ fun StudeezNavGraph( val navBarViewModel: NavigationBarViewModel = hiltViewModel() val backStackEntry by appState.navController.currentBackStackEntryAsState() + val getCurrentScreen: () -> String? = { backStackEntry?.destination?.route } + + val goBack: () -> Unit = { appState.popUp() } + val open: (String) -> Unit = { appState.navigate(it) } + val openAndPopUp: (String, String) -> Unit = + { route, popUp -> appState.navigateAndPopUp(route, popUp) } + + val drawerActions: DrawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp) + val navigationBarActions: NavigationBarActions = + getNavigationBarActions(navBarViewModel, open, getCurrentScreen) NavHost( navController = appState.navController, startDestination = StudeezDestinations.SPLASH_SCREEN, modifier = modifier, ) { - val goBack: () -> Unit = { - appState.popUp() - } - val open: (String) -> Unit = { route -> - appState.navigate(route) - } - - val openAndPopUp: (String, String) -> Unit = { route, popUp -> - appState.navigateAndPopUp(route, popUp) - } - - val getCurrentScreen: () -> String? = { - backStackEntry?.destination?.route - } composable(StudeezDestinations.SPLASH_SCREEN) { - SplashRoute(openAndPopUp, viewModel = hiltViewModel()) + SplashRoute( + openAndPopUp, + viewModel = hiltViewModel(), + ) } composable(StudeezDestinations.LOGIN_SCREEN) { - LoginRoute(openAndPopUp, viewModel = hiltViewModel()) + LoginRoute( + openAndPopUp, + viewModel = hiltViewModel(), + ) } composable(StudeezDestinations.SIGN_UP_SCREEN) { - SignUpRoute(openAndPopUp, viewModel = hiltViewModel()) + SignUpRoute( + openAndPopUp, + viewModel = hiltViewModel(), + ) } composable(StudeezDestinations.HOME_SCREEN) { HomeRoute( open, - openAndPopUp, - getCurrentScreen, viewModel = hiltViewModel(), - drawerViewModel = drawerViewModel, - navBarViewModel = navBarViewModel, + drawerActions = drawerActions, + navigationBarActions = navigationBarActions, ) } @@ -131,20 +148,26 @@ fun StudeezNavGraph( // TODO Sessions screen composable(StudeezDestinations.PROFILE_SCREEN) { - ProfileRoute(open, openAndPopUp, getCurrentScreen, viewModel = hiltViewModel()) + ProfileRoute( + open, + viewModel = hiltViewModel(), + drawerActions = drawerActions, + navigationBarActions = navigationBarActions, + ) } composable(StudeezDestinations.TIMER_OVERVIEW_SCREEN) { TimerOverviewRoute( - open, - openAndPopUp, viewModel = hiltViewModel(), - drawerViewModel = drawerViewModel + drawerActions = drawerActions, ) } composable(StudeezDestinations.SESSION_SCREEN) { - SessionRoute(open, viewModel = hiltViewModel()) + SessionRoute( + open, + viewModel = hiltViewModel() + ) } // TODO Timers screen @@ -152,18 +175,18 @@ fun StudeezNavGraph( // Edit screens composable(StudeezDestinations.EDIT_PROFILE_SCREEN) { - EditProfileRoute(goBack, openAndPopUp, viewModel = hiltViewModel()) + EditProfileRoute( + goBack, + openAndPopUp, + viewModel = hiltViewModel(), + ) } composable(StudeezDestinations.TIMER_SELECTION_SCREEN) { TimerSelectionRoute( open, - openAndPopUp, goBack, - getCurrentScreen, viewModel = hiltViewModel(), - drawerViewModel = drawerViewModel, - navBarViewModel = navBarViewModel, ) } } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt index 0ea8e16..1f760e5 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt @@ -11,27 +11,21 @@ import be.ugent.sel.studeez.R import be.ugent.sel.studeez.common.composable.BasicButton import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate import be.ugent.sel.studeez.common.composable.drawer.DrawerActions -import be.ugent.sel.studeez.common.composable.drawer.DrawerViewModel -import be.ugent.sel.studeez.common.composable.drawer.getDrawerActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions -import be.ugent.sel.studeez.common.composable.navbar.NavigationBarViewModel -import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions import be.ugent.sel.studeez.common.ext.basicButton import be.ugent.sel.studeez.resources @Composable fun HomeRoute( open: (String) -> Unit, - openAndPopUp: (String, String) -> Unit, - getCurrentScreen: () -> String?, viewModel: HomeViewModel, - drawerViewModel: DrawerViewModel, - navBarViewModel: NavigationBarViewModel, + drawerActions: DrawerActions, + navigationBarActions: NavigationBarActions, ) { HomeScreen( onStartSessionClick = { viewModel.onStartSessionClick(open) }, - drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp), - navigationBarActions = getNavigationBarActions(navBarViewModel, open, getCurrentScreen), + drawerActions = drawerActions, + navigationBarActions = navigationBarActions, ) } @@ -41,7 +35,6 @@ fun HomeScreen( drawerActions: DrawerActions, navigationBarActions: NavigationBarActions, ) { - PrimaryScreenTemplate( title = resources().getString(R.string.home), drawerActions = drawerActions, diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt index d68f05e..0b4a67f 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt @@ -4,16 +4,18 @@ import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit -import androidx.compose.runtime.* +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.tooling.preview.Preview -import androidx.hilt.navigation.compose.hiltViewModel import be.ugent.sel.studeez.R import be.ugent.sel.studeez.common.composable.Headline import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate import be.ugent.sel.studeez.common.composable.drawer.DrawerActions -import be.ugent.sel.studeez.common.composable.drawer.getDrawerActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions -import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions import be.ugent.sel.studeez.resources import kotlinx.coroutines.CoroutineScope import be.ugent.sel.studeez.R.string as AppText @@ -36,14 +38,14 @@ fun getProfileActions( @Composable fun ProfileRoute( open: (String) -> Unit, - openAndPopUp: (String, String) -> Unit, - getCurrentScreen: () -> String?, viewModel: ProfileViewModel, + drawerActions: DrawerActions, + navigationBarActions: NavigationBarActions, ) { ProfileScreen( profileActions = getProfileActions(viewModel, open), - drawerActions = getDrawerActions(hiltViewModel(), open, openAndPopUp), - navigationBarActions = getNavigationBarActions(hiltViewModel(), open, getCurrentScreen), + drawerActions = drawerActions, + navigationBarActions = navigationBarActions, ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/splash/SplashScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/splash/SplashScreen.kt index a5b0e81..e70c67b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/splash/SplashScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/splash/SplashScreen.kt @@ -1,6 +1,5 @@ package be.ugent.sel.studeez.screens.splash -import android.window.SplashScreen import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt index ca38ba9..9489a30 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt @@ -13,8 +13,6 @@ import be.ugent.sel.studeez.common.composable.DrawerScreenTemplate import be.ugent.sel.studeez.common.composable.StealthButton import be.ugent.sel.studeez.common.composable.TimerEntry import be.ugent.sel.studeez.common.composable.drawer.DrawerActions -import be.ugent.sel.studeez.common.composable.drawer.DrawerViewModel -import be.ugent.sel.studeez.common.composable.drawer.getDrawerActions import be.ugent.sel.studeez.common.ext.basicButton import be.ugent.sel.studeez.data.local.models.timer_info.CustomTimerInfo import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo @@ -40,14 +38,12 @@ fun getTimerOverviewActions( @Composable fun TimerOverviewRoute( - open: (String) -> Unit, - openAndPopUp: (String, String) -> Unit, viewModel: TimerOverviewViewModel, - drawerViewModel: DrawerViewModel + drawerActions: DrawerActions, ) { TimerOverviewScreen( timerOverviewActions = getTimerOverviewActions(viewModel), - drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp) + drawerActions = drawerActions, ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt index 2e52b0b..ac46b5c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt @@ -2,8 +2,6 @@ package be.ugent.sel.studeez.screens.timer_selection import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.Text -import androidx.compose.material.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.ui.tooling.preview.Preview @@ -11,8 +9,6 @@ import be.ugent.sel.studeez.R import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate import be.ugent.sel.studeez.common.composable.StealthButton import be.ugent.sel.studeez.common.composable.TimerEntry -import be.ugent.sel.studeez.common.composable.drawer.DrawerViewModel -import be.ugent.sel.studeez.common.composable.navbar.NavigationBarViewModel import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo import be.ugent.sel.studeez.resources import kotlinx.coroutines.flow.Flow @@ -36,12 +32,8 @@ fun getTimerSelectionActions( @Composable fun TimerSelectionRoute( open: (String) -> Unit, - openAndPopUp: (String, String) -> Unit, popUp: () -> Unit, - getCurrentScreen: () -> String?, viewModel: TimerSelectionViewModel, - drawerViewModel: DrawerViewModel, - navBarViewModel: NavigationBarViewModel, ) { TimerSelectionScreen( timerSelectionActions = getTimerSelectionActions(viewModel, open), From 2fb90b15c3d5aad67421b82199670c59c86494ba Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Fri, 28 Apr 2023 12:32:26 +0200 Subject: [PATCH 37/41] Update app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt --- .../data/local/models/timer_functional/FunctionalTimer.kt | 1 - 1 file changed, 1 deletion(-) 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 232b189..760d656 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 @@ -20,7 +20,6 @@ abstract class FunctionalTimer(initialValue: Int) { fun getSessionReport(): SessionReport { return SessionReport( - id = "", studyTime = totalStudyTime, endTime = Timestamp.now() ) From 76e69dd03c6fb75e89559a42b3c574b14cd49efb Mon Sep 17 00:00:00 2001 From: tdpeuter Date: Fri, 28 Apr 2023 12:42:36 +0200 Subject: [PATCH 38/41] Fix problems --- .../screens/session/sessionScreens/AbstractSessionScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 273e5dc..ca9d9c0 100644 --- 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 @@ -146,5 +146,5 @@ fun TimerPreview() { override fun motivationString(): String = "Test" } - sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {})) + sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {}, {})) } \ No newline at end of file From e421430f0bb9442b2507722af1739d51f9ae201f Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Fri, 28 Apr 2023 14:42:37 +0200 Subject: [PATCH 39/41] mediaplayer in AbstractSessionScreen + InvisibleSessionManagerTest.kt fixed --- .../timer_functional/FunctionalCustomTimer.kt | 6 ---- .../FunctionalPomodoroTimer.kt | 10 ++----- .../timer_functional/FunctionalTimer.kt | 3 -- .../session/InvisibleSessionManager.kt | 5 +++- .../studeez/screens/session/SessionRoute.kt | 7 ++--- .../sessionScreens/AbstractSessionScreen.kt | 4 +++ .../sessionScreens/BreakSessionScreen.kt | 15 +++++++++- .../sessionScreens/CustomSessionScreen.kt | 14 ++++++++- .../sessionScreens/EndlessSessionScreen.kt | 2 ++ .../sessionScreens/GetSessionScreen.kt | 7 +++-- .../InvisibleSessionManagerTest.kt | 30 ++++++++----------- 11 files changed, 59 insertions(+), 44 deletions(-) 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 0d1c4f5..94871ee 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 @@ -5,12 +5,6 @@ class FunctionalCustomTimer(studyTime: Int) : FunctionalTimer(studyTime) { override fun tick() { if (!hasEnded()) { time.minOne() - } else { - mediaPlayer?.setOnCompletionListener { - mediaPlayer!!.release() - mediaPlayer = null - } - mediaPlayer?.start() } } 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 8189559..6dac7c6 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 @@ -10,14 +10,10 @@ class FunctionalPomodoroTimer( override fun tick() { if (hasEnded()) { - mediaPlayer?.setOnCompletionListener { - mediaPlayer!!.release() - mediaPlayer = null - } - mediaPlayer?.start() return - } else if (hasCurrentCountdownEnded()) { - mediaPlayer?.start() + } + + if (hasCurrentCountdownEnded()) { if (isInBreak) { breaksRemaining-- time.time = studyTime 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 daec359..2d904d8 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,10 +1,7 @@ package be.ugent.sel.studeez.data.local.models.timer_functional -import android.media.MediaPlayer - abstract class FunctionalTimer(initialValue: Int) { val time: Time = Time(initialValue) - var mediaPlayer: MediaPlayer? = null fun getHoursMinutesSeconds(): HoursMinutesSeconds { return time.getAsHMS() diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt index 4c43d13..68fe703 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt @@ -1,5 +1,6 @@ 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 @@ -7,8 +8,9 @@ import kotlin.time.Duration.Companion.seconds @Singleton object InvisibleSessionManager { private var viewModel: SessionViewModel? = null + private var mediaPlayer: MediaPlayer? = null - fun setParameters(viewModel: SessionViewModel) { + fun setParameters(viewModel: SessionViewModel, mediaplayer: MediaPlayer) { this.viewModel = viewModel } @@ -17,6 +19,7 @@ object InvisibleSessionManager { while (true) { delay(1.seconds) viewModel!!.getTimer().tick() + } } } 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 index d13c6c1..680212d 100644 --- 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 @@ -38,13 +38,12 @@ fun SessionRoute( val mediaplayer = MediaPlayer.create(context, uri) mediaplayer.isLooping = false - viewModel.getTimer().mediaPlayer = mediaplayer - InvisibleSessionManager.setParameters( - viewModel = viewModel + viewModel = viewModel, + mediaplayer = mediaplayer ) - val sessionScreen: AbstractSessionScreen = viewModel.getTimer().accept(GetSessionScreen()) + val sessionScreen: AbstractSessionScreen = viewModel.getTimer().accept(GetSessionScreen(mediaplayer)) sessionScreen( open = open, 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 index 0804abf..f268edb 100644 --- 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 @@ -73,6 +73,7 @@ abstract class AbstractSessionScreen { LaunchedEffect(tikker) { delay(1.seconds) sessionActions.getTimer().tick() + callMediaPlayer() tikker = !tikker } @@ -122,6 +123,8 @@ abstract class AbstractSessionScreen { @Composable abstract fun motivationString(): String + abstract fun callMediaPlayer() + } @Preview @@ -130,6 +133,7 @@ fun TimerPreview() { val sessionScreen = object : AbstractSessionScreen() { @Composable override fun motivationString(): String = "Test" + override fun callMediaPlayer() {} } sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {})) 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 index edc8475..34927bc 100644 --- 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 @@ -1,5 +1,6 @@ package be.ugent.sel.studeez.screens.session.sessionScreens +import android.media.MediaPlayer import androidx.compose.runtime.Composable import be.ugent.sel.studeez.R 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 class BreakSessionScreen( - private val funPomoDoroTimer: FunctionalPomodoroTimer + private val funPomoDoroTimer: FunctionalPomodoroTimer, + private var mediaplayer: MediaPlayer? ): AbstractSessionScreen() { @Composable @@ -27,4 +29,15 @@ class BreakSessionScreen( ) } + override fun callMediaPlayer() { + if (funPomoDoroTimer.hasEnded()) { + mediaplayer?.setOnCompletionListener { + mediaplayer!!.release() + mediaplayer = null + } + mediaplayer?.start() + } else if (funPomoDoroTimer.hasCurrentCountdownEnded()) { + mediaplayer?.start() + } + } } \ 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 index 36ee492..e998645 100644 --- 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 @@ -1,5 +1,6 @@ package be.ugent.sel.studeez.screens.session.sessionScreens +import android.media.MediaPlayer import androidx.compose.runtime.Composable import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer import be.ugent.sel.studeez.resources @@ -7,7 +8,8 @@ import be.ugent.sel.studeez.R.string as AppText class CustomSessionScreen( - private val functionalTimer: FunctionalCustomTimer + private val functionalTimer: FunctionalCustomTimer, + private var mediaplayer: MediaPlayer? ): AbstractSessionScreen() { @Composable @@ -18,4 +20,14 @@ class CustomSessionScreen( return resources().getString(AppText.state_focus) } + override fun callMediaPlayer() { + if (functionalTimer.hasEnded()) { + mediaplayer?.setOnCompletionListener { + mediaplayer!!.release() + mediaplayer = null + } + mediaplayer?.start() + } + } + } \ 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 index fc46c9d..be67cff 100644 --- 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 @@ -11,4 +11,6 @@ class EndlessSessionScreen : AbstractSessionScreen() { override fun motivationString(): String { return resources().getString(AppText.state_focus) } + + override fun callMediaPlayer() {} } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt index e378661..98b2d5e 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/GetSessionScreen.kt @@ -1,17 +1,18 @@ 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.FunctionalEndlessTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimerVisitor -class GetSessionScreen : FunctionalTimerVisitor { +class GetSessionScreen(private val mediaplayer: MediaPlayer?) : FunctionalTimerVisitor { override fun visitFunctionalCustomTimer(functionalCustomTimer: FunctionalCustomTimer): AbstractSessionScreen = - CustomSessionScreen(functionalCustomTimer) + CustomSessionScreen(functionalCustomTimer, mediaplayer) override fun visitFunctionalEndlessTimer(functionalEndlessTimer: FunctionalEndlessTimer): AbstractSessionScreen = EndlessSessionScreen() override fun visitFunctionalBreakTimer(functionalPomodoroTimer: FunctionalPomodoroTimer): AbstractSessionScreen = - BreakSessionScreen(functionalPomodoroTimer) + BreakSessionScreen(functionalPomodoroTimer, mediaplayer) } \ No newline at end of file diff --git a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt index fe0d1c2..60740d9 100644 --- a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt +++ b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt @@ -5,7 +5,6 @@ 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.data.local.models.timer_functional.FunctionalTimer import be.ugent.sel.studeez.screens.session.InvisibleSessionManager import be.ugent.sel.studeez.screens.session.SessionViewModel import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -20,7 +19,7 @@ import org.mockito.kotlin.mock class InvisibleSessionManagerTest { private var timerState: SelectedTimerState = SelectedTimerState() private lateinit var viewModel: SessionViewModel - private val mediaPlayer = mock() + private var mediaPlayer: MediaPlayer = mock() @Test fun InvisibleEndlessTimerTest() = runTest { @@ -58,25 +57,20 @@ class InvisibleSessionManagerTest { advanceTimeBy(1_000) // start tikker advanceTimeBy(9_000) - Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.FOCUS) // Tijdens het focussen + Assert.assertEquals(viewModel.getTimer().time.time, 1) + // focus, 9 sec, 1 sec nog - advanceTimeBy(1_000) - Assert.assertEquals(viewModel.getTimer().time.time, 0) // Focussen gedaan + advanceTimeBy(2_000) + Assert.assertEquals(viewModel.getTimer().time.time, 4) + // pauze, 11 sec bezig, 4 seconden nog pauze - advanceTimeBy(4_000) - Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.BREAK) // Tijdens pauze + advanceTimeBy(5_000) + Assert.assertEquals(viewModel.getTimer().time.time, 9) + // 2e focus, 16 sec, 9 sec in 2e focus nog - advanceTimeBy(1_000) - Assert.assertEquals(viewModel.getTimer().time.time, 0) // Pauze gedaan - - advanceTimeBy(9_000) - Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.FOCUS_REMAINING) // Tijdens 2e focus - - advanceTimeBy(1_000) - Assert.assertEquals(viewModel.getTimer().time.time, 0) // 2e focus gedaan - - advanceTimeBy(4_000) - Assert.assertEquals(viewModel.getTimer().view, FunctionalTimer.StudyState.DONE) // Done + advanceTimeBy(13_000) + Assert.assertTrue(viewModel.getTimer().hasEnded()) + // Done test.cancel() return@runTest From 8eb199757ce5a857a2d13d56bb971fa0cfba5385 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Fri, 28 Apr 2023 15:30:57 +0200 Subject: [PATCH 40/41] InvisibleSessionManager.kt fixed --- .../screens/session/InvisibleSessionManager.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt index 68fe703..9051fa8 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/InvisibleSessionManager.kt @@ -8,18 +8,21 @@ import kotlin.time.Duration.Companion.seconds @Singleton object InvisibleSessionManager { private var viewModel: SessionViewModel? = null - private var mediaPlayer: MediaPlayer? = null + private lateinit var mediaPlayer: MediaPlayer fun setParameters(viewModel: SessionViewModel, mediaplayer: MediaPlayer) { this.viewModel = viewModel + this.mediaPlayer = mediaplayer } suspend fun updateTimer() { - if (viewModel != null) { - while (true) { + viewModel?.let { + while (!it.getTimer().hasEnded()) { delay(1.seconds) - viewModel!!.getTimer().tick() - + it.getTimer().tick() + if (it.getTimer().hasCurrentCountdownEnded()) { + mediaPlayer.start() + } } } } From 2ca7d062f30d84ef3ef481f62737f619ce6c5221 Mon Sep 17 00:00:00 2001 From: Rune Dyselinck Date: Fri, 28 Apr 2023 19:02:10 +0200 Subject: [PATCH 41/41] mediaplayer null safe listeners --- .../session/sessionScreens/BreakSessionScreen.kt | 10 ++++++---- .../session/sessionScreens/CustomSessionScreen.kt | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) 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 index 34927bc..8fa45ff 100644 --- 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 @@ -31,11 +31,13 @@ class BreakSessionScreen( override fun callMediaPlayer() { if (funPomoDoroTimer.hasEnded()) { - mediaplayer?.setOnCompletionListener { - mediaplayer!!.release() - mediaplayer = null + mediaplayer?.let { it: MediaPlayer -> + it.setOnCompletionListener { + it.release() + mediaplayer = null + } + it.start() } - mediaplayer?.start() } else if (funPomoDoroTimer.hasCurrentCountdownEnded()) { mediaplayer?.start() } 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 index e998645..7fc60bc 100644 --- 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 @@ -22,11 +22,13 @@ class CustomSessionScreen( override fun callMediaPlayer() { if (functionalTimer.hasEnded()) { - mediaplayer?.setOnCompletionListener { - mediaplayer!!.release() - mediaplayer = null + mediaplayer?.let { it: MediaPlayer -> + it.setOnCompletionListener { + it.release() + mediaplayer = null + } + it.start() } - mediaplayer?.start() } }