merge dev

This commit is contained in:
Rune Dyselinck 2023-04-28 15:50:44 +02:00
commit 94336348c5
24 changed files with 377 additions and 166 deletions

1
.idea/misc.xml generated
View file

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">

View file

@ -11,6 +11,7 @@ import androidx.compose.material.Surface
import androidx.compose.material.rememberScaffoldState import androidx.compose.material.rememberScaffoldState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -21,9 +22,14 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController 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.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.NavigationBarViewModel
import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions
import be.ugent.sel.studeez.common.snackbar.SnackbarManager import be.ugent.sel.studeez.common.snackbar.SnackbarManager
import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.navigation.StudeezDestinations
import be.ugent.sel.studeez.screens.home.HomeRoute import be.ugent.sel.studeez.screens.home.HomeRoute
@ -31,6 +37,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.EditProfileRoute
import be.ugent.sel.studeez.screens.profile.ProfileRoute import be.ugent.sel.studeez.screens.profile.ProfileRoute
import be.ugent.sel.studeez.screens.session.SessionRoute 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.sign_up.SignUpRoute
import be.ugent.sel.studeez.screens.splash.SplashRoute import be.ugent.sel.studeez.screens.splash.SplashRoute
import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute
@ -89,43 +96,52 @@ fun StudeezNavGraph(
val drawerViewModel: DrawerViewModel = hiltViewModel() val drawerViewModel: DrawerViewModel = hiltViewModel()
val navBarViewModel: NavigationBarViewModel = hiltViewModel() 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( NavHost(
navController = appState.navController, navController = appState.navController,
startDestination = StudeezDestinations.SPLASH_SCREEN, startDestination = StudeezDestinations.SPLASH_SCREEN,
modifier = modifier, 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)
}
composable(StudeezDestinations.SPLASH_SCREEN) { composable(StudeezDestinations.SPLASH_SCREEN) {
SplashRoute(openAndPopUp, viewModel = hiltViewModel()) SplashRoute(
openAndPopUp,
viewModel = hiltViewModel(),
)
} }
composable(StudeezDestinations.LOGIN_SCREEN) { composable(StudeezDestinations.LOGIN_SCREEN) {
LoginRoute(openAndPopUp, viewModel = hiltViewModel()) LoginRoute(
openAndPopUp,
viewModel = hiltViewModel(),
)
} }
composable(StudeezDestinations.SIGN_UP_SCREEN) { composable(StudeezDestinations.SIGN_UP_SCREEN) {
SignUpRoute(openAndPopUp, viewModel = hiltViewModel()) SignUpRoute(
openAndPopUp,
viewModel = hiltViewModel(),
)
} }
composable(StudeezDestinations.HOME_SCREEN) { composable(StudeezDestinations.HOME_SCREEN) {
HomeRoute( HomeRoute(
open, open,
openAndPopUp,
viewModel = hiltViewModel(), viewModel = hiltViewModel(),
drawerViewModel = drawerViewModel, drawerActions = drawerActions,
navBarViewModel = navBarViewModel, navigationBarActions = navigationBarActions,
) )
} }
@ -133,21 +149,27 @@ fun StudeezNavGraph(
// TODO Sessions screen // TODO Sessions screen
composable(StudeezDestinations.PROFILE_SCREEN) { composable(StudeezDestinations.PROFILE_SCREEN) {
ProfileRoute(open, openAndPopUp, viewModel = hiltViewModel()) ProfileRoute(
open,
viewModel = hiltViewModel(),
drawerActions = drawerActions,
navigationBarActions = navigationBarActions,
)
} }
composable(StudeezDestinations.TIMER_OVERVIEW_SCREEN) { composable(StudeezDestinations.TIMER_OVERVIEW_SCREEN) {
TimerOverviewRoute( TimerOverviewRoute(
open,
openAndPopUp,
viewModel = hiltViewModel(), viewModel = hiltViewModel(),
drawerViewModel = drawerViewModel, drawerActions = drawerActions,
navBarViewModel = navBarViewModel,
) )
} }
composable(StudeezDestinations.SESSION_SCREEN) { composable(StudeezDestinations.SESSION_SCREEN) {
SessionRoute(open, viewModel = hiltViewModel()) SessionRoute(
open,
openAndPopUp,
viewModel = hiltViewModel()
)
} }
// TODO Timers screen // TODO Timers screen
@ -155,16 +177,25 @@ fun StudeezNavGraph(
// Edit screens // Edit screens
composable(StudeezDestinations.EDIT_PROFILE_SCREEN) { composable(StudeezDestinations.EDIT_PROFILE_SCREEN) {
EditProfileRoute(goBack, openAndPopUp, viewModel = hiltViewModel()) EditProfileRoute(
goBack,
openAndPopUp,
viewModel = hiltViewModel(),
)
} }
composable(StudeezDestinations.TIMER_SELECTION_SCREEN) { composable(StudeezDestinations.TIMER_SELECTION_SCREEN) {
TimerSelectionRoute( TimerSelectionRoute(
open, open,
openAndPopUp, goBack,
viewModel = hiltViewModel(), viewModel = hiltViewModel(),
drawerViewModel = drawerViewModel, )
navBarViewModel = navBarViewModel, }
composable(StudeezDestinations.SESSION_RECAP) {
SessionRecapRoute(
openAndPopUp = openAndPopUp,
viewModel = hiltViewModel()
) )
} }
} }

View file

@ -3,15 +3,9 @@ package be.ugent.sel.studeez.common.composable
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button import androidx.compose.material.*
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.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp 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 import be.ugent.sel.studeez.common.ext.card
@Composable @Composable
fun BasicTextButton(@StringRes text: Int, modifier: Modifier, action: () -> Unit) { fun BasicTextButton(@StringRes text: Int, modifier: Modifier, action: () -> Unit) {
TextButton(onClick = action, modifier = modifier) { Text(text = stringResource(text)) } TextButton(onClick = action, modifier = modifier) { Text(text = stringResource(text)) }
} }
@ -64,10 +57,10 @@ fun StealthButton(
onClick = onClick, onClick = onClick,
modifier = Modifier.card(), modifier = Modifier.card(),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
backgroundColor = Color.Transparent, backgroundColor = MaterialTheme.colors.surface,
contentColor = Color.DarkGray, contentColor = MaterialTheme.colors.onSurface
), ),
border = BorderStroke(3.dp, Color.DarkGray), border = BorderStroke(1.dp, MaterialTheme.colors.onSurface)
) )
} }

View file

@ -0,0 +1,64 @@
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 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
@Composable
fun DrawerScreenTemplate(
title: String,
drawerActions: DrawerActions,
barAction: @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 = barAction
)},
drawerContent = {
Drawer(drawerActions)
}
) {
content(it)
}
}
@Preview
@Composable
fun DrawerScreenPreview() {
StudeezTheme { DrawerScreenTemplate(
title = "Drawer screen preview",
drawerActions =DrawerActions({}, {}, {}, {}, {})
) {
Text(text = "Preview content")
} }
}

View file

@ -2,26 +2,19 @@ package be.ugent.sel.studeez.common.composable
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.material.FabPosition import androidx.compose.material.*
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.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.Menu import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.rememberScaffoldState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import be.ugent.sel.studeez.R 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.Drawer
import be.ugent.sel.studeez.common.composable.drawer.DrawerActions 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.NavigationBar
import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions
import be.ugent.sel.studeez.resources
import be.ugent.sel.studeez.ui.theme.StudeezTheme import be.ugent.sel.studeez.ui.theme.StudeezTheme
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -31,7 +24,7 @@ fun PrimaryScreenTemplate(
title: String, title: String,
drawerActions: DrawerActions, drawerActions: DrawerActions,
navigationBarActions: NavigationBarActions, navigationBarActions: NavigationBarActions,
action: @Composable RowScope.() -> Unit = {}, barAction: @Composable RowScope.() -> Unit = {},
content: @Composable (PaddingValues) -> Unit content: @Composable (PaddingValues) -> Unit
) { ) {
val scaffoldState: ScaffoldState = rememberScaffoldState() val scaffoldState: ScaffoldState = rememberScaffoldState()
@ -53,7 +46,7 @@ fun PrimaryScreenTemplate(
) )
} }
}, },
actions = action actions = barAction
) )
}, },
@ -77,7 +70,7 @@ fun PrimaryScreenPreview() {
PrimaryScreenTemplate( PrimaryScreenTemplate(
"Preview screen", "Preview screen",
DrawerActions({}, {}, {}, {}, {}), DrawerActions({}, {}, {}, {}, {}),
NavigationBarActions({}, {}, {}, {}), NavigationBarActions({ false }, {}, {}, {}, {}),
{ {
IconButton(onClick = { /*TODO*/ }) { IconButton(onClick = { /*TODO*/ }) {
Icon( Icon(

View file

@ -1,6 +1,7 @@
package be.ugent.sel.studeez.common.composable package be.ugent.sel.studeez.common.composable
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.RowScope
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack 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.resources
import be.ugent.sel.studeez.ui.theme.StudeezTheme import be.ugent.sel.studeez.ui.theme.StudeezTheme
// TODO Add option for button in top right corner as extra button
@Composable @Composable
// Does not contain floatingActionButton and bottom bar, used in all the other screens // Does not contain floatingActionButton and bottom bar, used in all the other screens
fun SecondaryScreenTemplate( fun SecondaryScreenTemplate(
title: String, title: String,
popUp: () -> Unit, popUp: () -> Unit,
barAction: @Composable RowScope.() -> Unit = {},
content: @Composable (PaddingValues) -> Unit content: @Composable (PaddingValues) -> Unit
) { ) {
Scaffold( Scaffold(
@ -30,7 +30,8 @@ fun SecondaryScreenTemplate(
contentDescription = resources().getString(R.string.go_back) contentDescription = resources().getString(R.string.go_back)
) )
} }
} },
actions = barAction
) }, ) },
) { paddingValues -> ) { paddingValues ->
content(paddingValues) content(paddingValues)

View file

@ -1,10 +1,6 @@
package be.ugent.sel.studeez.common.composable package be.ugent.sel.studeez.common.composable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.*
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.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -20,24 +16,39 @@ import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
@Composable @Composable
fun TimerEntry( fun TimerEntry(
timerInfo: TimerInfo, timerInfo: TimerInfo,
button: @Composable () -> Unit, rightButton: @Composable () -> Unit = {},
leftButton: @Composable () -> Unit = {}
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) { ) {
Row(
modifier = Modifier.weight(1f)
) {
Box(modifier = Modifier.align(alignment = Alignment.CenterVertically)) {
leftButton()
}
Column( Column(
Modifier.padding(horizontal = 10.dp) Modifier.padding(
horizontal = 20.dp,
vertical = 11.dp
)
) { ) {
Text( Text(
text = timerInfo.name, fontWeight = FontWeight.Bold, fontSize = 20.sp text = timerInfo.name,
fontWeight = FontWeight.Medium,
fontSize = 20.sp
) )
Text( Text(
text = timerInfo.description, fontWeight = FontWeight.Light, fontSize = 15.sp text = timerInfo.description, fontWeight = FontWeight.Light, fontSize = 14.sp
) )
} }
button() }
Box(modifier = Modifier.align(alignment = Alignment.CenterVertically)) {
rightButton()
}
} }
} }

View file

@ -12,11 +12,14 @@ import androidx.compose.material.icons.outlined.DateRange
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp 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.resources
import be.ugent.sel.studeez.ui.theme.StudeezTheme import be.ugent.sel.studeez.ui.theme.StudeezTheme
import be.ugent.sel.studeez.R.string as AppText import be.ugent.sel.studeez.R.string as AppText
data class NavigationBarActions( data class NavigationBarActions(
val isSelectedTab: (String) -> Boolean,
val onHomeClick: () -> Unit, val onHomeClick: () -> Unit,
val onTasksClick: () -> Unit, val onTasksClick: () -> Unit,
val onSessionsClick: () -> Unit, val onSessionsClick: () -> Unit,
@ -26,29 +29,38 @@ data class NavigationBarActions(
fun getNavigationBarActions( fun getNavigationBarActions(
navigationBarViewModel: NavigationBarViewModel, navigationBarViewModel: NavigationBarViewModel,
open: (String) -> Unit, open: (String) -> Unit,
getCurrentScreen: () -> String?
): NavigationBarActions { ): NavigationBarActions {
return NavigationBarActions( return NavigationBarActions(
onHomeClick = { navigationBarViewModel.onHomeClick(open) }, isSelectedTab = { screen ->
onTasksClick = { navigationBarViewModel.onTasksClick(open) }, screen == getCurrentScreen()
onSessionsClick = { navigationBarViewModel.onSessionsClick(open) }, },
onProfileClick = { navigationBarViewModel.onProfileClick(open) }, onHomeClick = {
navigationBarViewModel.onHomeClick(open)
},
onTasksClick = {
navigationBarViewModel.onTasksClick(open)
},
onSessionsClick = {
navigationBarViewModel.onSessionsClick(open)
},
onProfileClick = {
navigationBarViewModel.onProfileClick(open)
},
) )
} }
@Composable @Composable
fun NavigationBar( fun NavigationBar(
navigationBarActions: NavigationBarActions, 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( BottomNavigation(
elevation = 10.dp elevation = 10.dp
) { ) {
BottomNavigationItem( BottomNavigationItem(
icon = { Icon(imageVector = Icons.Default.List, resources().getString(AppText.home)) }, icon = { Icon(imageVector = Icons.Default.List, resources().getString(AppText.home)) },
label = { Text(text = resources().getString(AppText.home)) }, label = { Text(text = resources().getString(AppText.home)) },
selected = false, // TODO selected = navigationBarActions.isSelectedTab(HOME_SCREEN),
onClick = navigationBarActions.onHomeClick onClick = navigationBarActions.onHomeClick
) )
@ -59,7 +71,8 @@ fun NavigationBar(
) )
}, },
label = { Text(text = resources().getString(AppText.tasks)) }, label = { Text(text = resources().getString(AppText.tasks)) },
selected = false, // TODO // TODO selected = navigationBarActions.isSelectedTab(TASKS_SCREEN),
selected = false,
onClick = navigationBarActions.onTasksClick onClick = navigationBarActions.onTasksClick
) )
@ -73,7 +86,8 @@ fun NavigationBar(
) )
}, },
label = { Text(text = resources().getString(AppText.sessions)) }, label = { Text(text = resources().getString(AppText.sessions)) },
selected = false, // TODO // TODO selected = navigationBarActions.isSelectedTab(SESSIONS_SCREEN),
selected = false,
onClick = navigationBarActions.onSessionsClick onClick = navigationBarActions.onSessionsClick
) )
@ -84,7 +98,7 @@ fun NavigationBar(
) )
}, },
label = { Text(text = resources().getString(AppText.profile)) }, label = { Text(text = resources().getString(AppText.profile)) },
selected = false, // TODO selected = navigationBarActions.isSelectedTab(PROFILE_SCREEN),
onClick = navigationBarActions.onProfileClick onClick = navigationBarActions.onProfileClick
) )
@ -95,6 +109,8 @@ fun NavigationBar(
@Composable @Composable
fun NavigationBarPreview() { fun NavigationBarPreview() {
StudeezTheme { StudeezTheme {
NavigationBar(NavigationBarActions({}, {}, {}, {})) NavigationBar(
navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}),
)
} }
} }

View file

@ -0,0 +1,14 @@
package be.ugent.sel.studeez.data
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
}

View file

@ -5,6 +5,7 @@ class FunctionalCustomTimer(studyTime: Int) : FunctionalTimer(studyTime) {
override fun tick() { override fun tick() {
if (!hasEnded()) { if (!hasEnded()) {
time.minOne() time.minOne()
totalStudyTime++
} }
} }

View file

@ -12,6 +12,7 @@ class FunctionalEndlessTimer : FunctionalTimer(0) {
override fun tick() { override fun tick() {
time.plusOne() time.plusOne()
totalStudyTime++
} }
override fun <T> accept(visitor: FunctionalTimerVisitor<T>): T { override fun <T> accept(visitor: FunctionalTimerVisitor<T>): T {

View file

@ -23,6 +23,10 @@ class FunctionalPomodoroTimer(
isInBreak = !isInBreak isInBreak = !isInBreak
} }
time.minOne() time.minOne()
if (!isInBreak) {
totalStudyTime++
}
} }
override fun hasEnded(): Boolean { override fun hasEnded(): Boolean {

View file

@ -1,7 +1,11 @@
package be.ugent.sel.studeez.data.local.models.timer_functional package be.ugent.sel.studeez.data.local.models.timer_functional
import be.ugent.sel.studeez.data.local.models.SessionReport
import com.google.firebase.Timestamp
abstract class FunctionalTimer(initialValue: Int) { abstract class FunctionalTimer(initialValue: Int) {
val time: Time = Time(initialValue) val time: Time = Time(initialValue)
var totalStudyTime: Int = 0
fun getHoursMinutesSeconds(): HoursMinutesSeconds { fun getHoursMinutesSeconds(): HoursMinutesSeconds {
return time.getAsHMS() return time.getAsHMS()
@ -13,5 +17,12 @@ abstract class FunctionalTimer(initialValue: Int) {
abstract fun hasCurrentCountdownEnded(): Boolean abstract fun hasCurrentCountdownEnded(): Boolean
fun getSessionReport(): SessionReport {
return SessionReport(
studyTime = totalStudyTime,
endTime = Timestamp.now()
)
}
abstract fun <T> accept(visitor: FunctionalTimerVisitor<T>): T abstract fun <T> accept(visitor: FunctionalTimerVisitor<T>): T
} }

View file

@ -9,6 +9,7 @@ object StudeezDestinations {
const val TIMER_OVERVIEW_SCREEN = "timer_overview" const val TIMER_OVERVIEW_SCREEN = "timer_overview"
const val TIMER_SELECTION_SCREEN = "timer_selection" const val TIMER_SELECTION_SCREEN = "timer_selection"
const val SESSION_SCREEN = "session" const val SESSION_SCREEN = "session"
const val SESSION_RECAP = "session_recap"
// const val TASKS_SCREEN = "tasks" // const val TASKS_SCREEN = "tasks"
// const val SESSIONS_SCREEN = "sessions" // const val SESSIONS_SCREEN = "sessions"
const val PROFILE_SCREEN = "profile" const val PROFILE_SCREEN = "profile"

View file

@ -11,26 +11,21 @@ import be.ugent.sel.studeez.R
import be.ugent.sel.studeez.common.composable.BasicButton import be.ugent.sel.studeez.common.composable.BasicButton
import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate 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.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.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.common.ext.basicButton
import be.ugent.sel.studeez.resources import be.ugent.sel.studeez.resources
@Composable @Composable
fun HomeRoute( fun HomeRoute(
open: (String) -> Unit, open: (String) -> Unit,
openAndPopUp: (String, String) -> Unit,
viewModel: HomeViewModel, viewModel: HomeViewModel,
drawerViewModel: DrawerViewModel, drawerActions: DrawerActions,
navBarViewModel: NavigationBarViewModel, navigationBarActions: NavigationBarActions,
) { ) {
HomeScreen( HomeScreen(
onStartSessionClick = { viewModel.onStartSessionClick(open) }, onStartSessionClick = { viewModel.onStartSessionClick(open) },
drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp), drawerActions = drawerActions,
navigationBarActions = getNavigationBarActions(navBarViewModel, open), navigationBarActions = navigationBarActions,
) )
} }
@ -40,12 +35,11 @@ fun HomeScreen(
drawerActions: DrawerActions, drawerActions: DrawerActions,
navigationBarActions: NavigationBarActions, navigationBarActions: NavigationBarActions,
) { ) {
PrimaryScreenTemplate( PrimaryScreenTemplate(
title = resources().getString(R.string.home), title = resources().getString(R.string.home),
drawerActions = drawerActions, drawerActions = drawerActions,
navigationBarActions = navigationBarActions, navigationBarActions = navigationBarActions,
action = { FriendsAction() } barAction = { FriendsAction() }
) { ) {
BasicButton(R.string.start_session, Modifier.basicButton()) { BasicButton(R.string.start_session, Modifier.basicButton()) {
onStartSessionClick() onStartSessionClick()
@ -69,6 +63,6 @@ fun HomeScreenPreview() {
HomeScreen( HomeScreen(
onStartSessionClick = {}, onStartSessionClick = {},
drawerActions = DrawerActions({}, {}, {}, {}, {}), drawerActions = DrawerActions({}, {}, {}, {}, {}),
navigationBarActions = NavigationBarActions({}, {}, {}, {}) navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {})
) )
} }

View file

@ -11,15 +11,12 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import be.ugent.sel.studeez.R import be.ugent.sel.studeez.R
import be.ugent.sel.studeez.common.composable.Headline import be.ugent.sel.studeez.common.composable.Headline
import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate 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.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.NavigationBarActions
import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions import be.ugent.sel.studeez.resources
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import be.ugent.sel.studeez.R.string as AppText import be.ugent.sel.studeez.R.string as AppText
@ -41,13 +38,14 @@ fun getProfileActions(
@Composable @Composable
fun ProfileRoute( fun ProfileRoute(
open: (String) -> Unit, open: (String) -> Unit,
openAndPopUp: (String, String) -> Unit,
viewModel: ProfileViewModel, viewModel: ProfileViewModel,
drawerActions: DrawerActions,
navigationBarActions: NavigationBarActions,
) { ) {
ProfileScreen( ProfileScreen(
profileActions = getProfileActions(viewModel, open), profileActions = getProfileActions(viewModel, open),
drawerActions = getDrawerActions(hiltViewModel(), open, openAndPopUp), drawerActions = drawerActions,
navigationBarActions = getNavigationBarActions(hiltViewModel(), open), navigationBarActions = navigationBarActions,
) )
} }
@ -65,7 +63,7 @@ fun ProfileScreen(
title = resources().getString(AppText.profile), title = resources().getString(AppText.profile),
drawerActions = drawerActions, drawerActions = drawerActions,
navigationBarActions = navigationBarActions, navigationBarActions = navigationBarActions,
action = { EditAction(onClick = profileActions.onEditProfileClick) } barAction = { EditAction(onClick = profileActions.onEditProfileClick) }
) { ) {
Headline(text = (username ?: resources().getString(R.string.no_username))) Headline(text = (username ?: resources().getString(R.string.no_username)))
} }
@ -90,6 +88,6 @@ fun ProfileScreenPreview() {
ProfileScreen( ProfileScreen(
profileActions = ProfileActions({ null }, {}), profileActions = ProfileActions({ null }, {}),
drawerActions = DrawerActions({}, {}, {}, {}, {}), drawerActions = DrawerActions({}, {}, {}, {}, {}),
navigationBarActions = NavigationBarActions({}, {}, {}, {}) navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {})
) )
} }

View file

@ -14,15 +14,18 @@ data class SessionActions(
val getTask: () -> String, val getTask: () -> String,
val startMediaPlayer: () -> Unit, val startMediaPlayer: () -> Unit,
val releaseMediaPlayer: () -> Unit, val releaseMediaPlayer: () -> Unit,
val endSession: () -> Unit
) )
private fun getSessionActions( private fun getSessionActions(
viewModel: SessionViewModel, viewModel: SessionViewModel,
openAndPopUp: (String, String) -> Unit,
mediaplayer: MediaPlayer, mediaplayer: MediaPlayer,
): SessionActions { ): SessionActions {
return SessionActions( return SessionActions(
getTimer = viewModel::getTimer, getTimer = viewModel::getTimer,
getTask = viewModel::getTask, getTask = viewModel::getTask,
endSession = { viewModel.endSession(openAndPopUp) },
startMediaPlayer = mediaplayer::start, startMediaPlayer = mediaplayer::start,
releaseMediaPlayer = mediaplayer::release, releaseMediaPlayer = mediaplayer::release,
) )
@ -31,6 +34,7 @@ private fun getSessionActions(
@Composable @Composable
fun SessionRoute( fun SessionRoute(
open: (String) -> Unit, open: (String) -> Unit,
openAndPopUp: (String, String) -> Unit,
viewModel: SessionViewModel, viewModel: SessionViewModel,
) { ) {
val context = LocalContext.current val context = LocalContext.current
@ -47,6 +51,6 @@ fun SessionRoute(
sessionScreen( sessionScreen(
open = open, open = open,
sessionActions = getSessionActions(viewModel, mediaplayer) sessionActions = getSessionActions(viewModel, openAndPopUp, mediaplayer)
) )
} }

View file

@ -1,20 +1,21 @@
package be.ugent.sel.studeez.screens.session 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.data.local.models.timer_functional.FunctionalTimer
import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.domain.LogService
import be.ugent.sel.studeez.navigation.StudeezDestinations
import be.ugent.sel.studeez.screens.StudeezViewModel 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 dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class SessionViewModel @Inject constructor( class SessionViewModel @Inject constructor(
private val selectedTimerState: SelectedTimerState, private val selectedTimerState: SelectedTimerState,
private val sessionReportState: SessionReportState,
logService: LogService logService: LogService
) : StudeezViewModel(logService) { ) : StudeezViewModel(logService) {
private val timer: FunctionalTimer = FunctionalPomodoroTimer(15, 5, 3)
private val task : String = "No task selected" // placeholder for tasks implementation private val task : String = "No task selected" // placeholder for tasks implementation
fun getTimer() : FunctionalTimer { fun getTimer() : FunctionalTimer {
@ -24,4 +25,9 @@ class SessionViewModel @Inject constructor(
fun getTask(): String { fun getTask(): String {
return task return task
} }
fun endSession(openAndPopUp: (String, String) -> Unit) {
sessionReportState.sessionReport = getTimer().getSessionReport()
openAndPopUp(StudeezDestinations.SESSION_RECAP, StudeezDestinations.SESSION_SCREEN)
}
} }

View file

@ -19,7 +19,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer
import be.ugent.sel.studeez.navigation.StudeezDestinations
import be.ugent.sel.studeez.screens.session.SessionActions import be.ugent.sel.studeez.screens.session.SessionActions
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
@ -45,8 +44,7 @@ abstract class AbstractSessionScreen {
TextButton( TextButton(
onClick = { onClick = {
sessionActions.releaseMediaPlayer sessionActions.releaseMediaPlayer
open(StudeezDestinations.HOME_SCREEN) sessionActions.endSession()
// Vanaf hier ook naar report gaan als "end session" knop word ingedrukt
}, },
modifier = Modifier modifier = Modifier
.padding(horizontal = 20.dp) .padding(horizontal = 20.dp)
@ -136,5 +134,5 @@ fun TimerPreview() {
override fun callMediaPlayer() {} override fun callMediaPlayer() {}
} }
sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {})) sessionScreen.Timer(sessionActions = SessionActions({ FunctionalEndlessTimer() }, { "Preview" }, {}, {}, {}))
} }

View file

@ -0,0 +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.discardSession(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()
}
}
}

View file

@ -0,0 +1,33 @@
package be.ugent.sel.studeez.screens.session_recap
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)
}
}

View file

@ -1,6 +1,5 @@
package be.ugent.sel.studeez.screens.timer_overview package be.ugent.sel.studeez.screens.timer_overview
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
@ -8,18 +7,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import be.ugent.sel.studeez.R import be.ugent.sel.studeez.R
import be.ugent.sel.studeez.common.composable.BasicButton import be.ugent.sel.studeez.common.composable.BasicButton
import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate import be.ugent.sel.studeez.common.composable.DrawerScreenTemplate
import be.ugent.sel.studeez.common.composable.StealthButton import be.ugent.sel.studeez.common.composable.StealthButton
import be.ugent.sel.studeez.common.composable.TimerEntry 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.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.common.ext.basicButton
import be.ugent.sel.studeez.data.local.models.timer_info.CustomTimerInfo import be.ugent.sel.studeez.data.local.models.timer_info.CustomTimerInfo
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
@ -45,38 +38,29 @@ fun getTimerOverviewActions(
@Composable @Composable
fun TimerOverviewRoute( fun TimerOverviewRoute(
open: (String) -> Unit,
openAndPopUp: (String, String) -> Unit,
viewModel: TimerOverviewViewModel, viewModel: TimerOverviewViewModel,
drawerViewModel: DrawerViewModel, drawerActions: DrawerActions,
navBarViewModel: NavigationBarViewModel,
) { ) {
TimerOverviewScreen( TimerOverviewScreen(
timerOverviewActions = getTimerOverviewActions(viewModel), timerOverviewActions = getTimerOverviewActions(viewModel),
drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp), drawerActions = drawerActions,
navigationBarActions = getNavigationBarActions(navBarViewModel, open),
) )
} }
@Composable @Composable
fun TimerOverviewScreen( fun TimerOverviewScreen(
timerOverviewActions: TimerOverviewActions, timerOverviewActions: TimerOverviewActions,
drawerActions: DrawerActions, drawerActions: DrawerActions
navigationBarActions: NavigationBarActions,
) { ) {
val timers = timerOverviewActions.getUserTimers().collectAsState(initial = emptyList()) val timers = timerOverviewActions.getUserTimers().collectAsState(initial = emptyList())
// TODO moet geen primary screen zijn: geen navbar nodig DrawerScreenTemplate(
PrimaryScreenTemplate(
title = resources().getString(R.string.timers), title = resources().getString(R.string.timers),
drawerActions = drawerActions, drawerActions = drawerActions
navigationBarActions = navigationBarActions,
) { ) {
Column { Column {
LazyColumn( LazyColumn {
verticalArrangement = Arrangement.spacedBy(7.dp)
) {
// Default Timers, cannot be edited // Default Timers, cannot be edited
items(timerOverviewActions.getDefaultTimers()) { items(timerOverviewActions.getDefaultTimers()) {
TimerEntry(timerInfo = it) {} TimerEntry(timerInfo = it) {}
@ -112,7 +96,6 @@ fun TimerOverviewPreview() {
{ flowOf() }, { flowOf() },
{ listOf(customTimer, customTimer) }, { listOf(customTimer, customTimer) },
{}), {}),
drawerActions = DrawerActions({}, {}, {}, {}, {}), drawerActions = DrawerActions({}, {}, {}, {}, {})
navigationBarActions = NavigationBarActions({}, {}, {}, {})
) )
} }

View file

@ -1,22 +1,14 @@
package be.ugent.sel.studeez.screens.timer_selection 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.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import be.ugent.sel.studeez.R import be.ugent.sel.studeez.R
import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate
import be.ugent.sel.studeez.common.composable.StealthButton import be.ugent.sel.studeez.common.composable.StealthButton
import be.ugent.sel.studeez.common.composable.TimerEntry 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.data.local.models.timer_info.TimerInfo
import be.ugent.sel.studeez.resources import be.ugent.sel.studeez.resources
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -40,41 +32,37 @@ fun getTimerSelectionActions(
@Composable @Composable
fun TimerSelectionRoute( fun TimerSelectionRoute(
open: (String) -> Unit, open: (String) -> Unit,
openAndPopUp: (String, String) -> Unit, popUp: () -> Unit,
viewModel: TimerSelectionViewModel, viewModel: TimerSelectionViewModel,
drawerViewModel: DrawerViewModel,
navBarViewModel: NavigationBarViewModel,
) { ) {
TimerSelectionScreen( TimerSelectionScreen(
timerSelectionActions = getTimerSelectionActions(viewModel, open), timerSelectionActions = getTimerSelectionActions(viewModel, open),
drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp), popUp = popUp
navigationBarActions = getNavigationBarActions(navBarViewModel, open),
) )
} }
@Composable @Composable
fun TimerSelectionScreen( fun TimerSelectionScreen(
timerSelectionActions: TimerSelectionActions, timerSelectionActions: TimerSelectionActions,
drawerActions: DrawerActions, popUp: () -> Unit
navigationBarActions: NavigationBarActions,
) { ) {
val timers = timerSelectionActions.getAllTimers().collectAsState(initial = emptyList()) val timers = timerSelectionActions.getAllTimers().collectAsState(initial = emptyList())
PrimaryScreenTemplate( SecondaryScreenTemplate(
title = resources().getString(R.string.timers), title = resources().getString(R.string.timers),
drawerActions = drawerActions, popUp = popUp
navigationBarActions = navigationBarActions,
) { ) {
LazyColumn(verticalArrangement = Arrangement.spacedBy(7.dp)) { LazyColumn {
// All timers // All timers
items(timers.value) { timerInfo -> items(timers.value) { timerInfo ->
TimerEntry( TimerEntry(
timerInfo = timerInfo, timerInfo = timerInfo,
) { leftButton = {
StealthButton( StealthButton(
text = R.string.start, text = R.string.start,
onClick = { timerSelectionActions.startSession(timerInfo) } onClick = { timerSelectionActions.startSession(timerInfo) }
) )
} }
)
} }
} }
} }
@ -85,7 +73,6 @@ fun TimerSelectionScreen(
fun TimerSelectionPreview() { fun TimerSelectionPreview() {
TimerSelectionScreen( TimerSelectionScreen(
timerSelectionActions = TimerSelectionActions({ flowOf() }, {}), timerSelectionActions = TimerSelectionActions({ flowOf() }, {}),
drawerActions = DrawerActions({}, {}, {}, {}, {}), popUp = {}
navigationBarActions = NavigationBarActions({}, {}, {}, {}),
) )
} }

View file

@ -10,6 +10,7 @@
<!-- Actions --> <!-- Actions -->
<string name="confirm">Confirm</string> <string name="confirm">Confirm</string>
<string name="save">Save</string> <string name="save">Save</string>
<string name="discard">Discard</string>
<string name="cancel">Cancel</string> <string name="cancel">Cancel</string>
<string name="go_back">Go back</string> <string name="go_back">Go back</string>
<string name="next">Next</string> <string name="next">Next</string>