diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index fb7f4a8..b589d56 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index 7e42cec..ff9696e 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index bdd9278..8978d23 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,7 +1,6 @@
-
-
+
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 04b4914..a6830a5 100644
--- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt
+++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt
@@ -2,7 +2,13 @@ package be.ugent.sel.studeez
import android.content.res.Resources
import androidx.compose.foundation.layout.padding
-import androidx.compose.material.*
+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
@@ -11,22 +17,24 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
-import androidx.navigation.NavGraphBuilder
+import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
+import be.ugent.sel.studeez.common.composable.drawer.DrawerViewModel
+import be.ugent.sel.studeez.common.composable.navbar.NavigationBarViewModel
import be.ugent.sel.studeez.common.snackbar.SnackbarManager
import be.ugent.sel.studeez.navigation.StudeezDestinations
-import be.ugent.sel.studeez.screens.home.HomeScreen
-import be.ugent.sel.studeez.screens.log_in.LoginScreen
-import be.ugent.sel.studeez.screens.session.SessionScreen
-import be.ugent.sel.studeez.screens.profile.EditProfileScreen
-import be.ugent.sel.studeez.screens.profile.ProfileScreen
-import be.ugent.sel.studeez.screens.sign_up.SignUpScreen
-import be.ugent.sel.studeez.screens.splash.SplashScreen
-import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewScreen
-import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionScreen
+import be.ugent.sel.studeez.screens.home.HomeRoute
+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.sign_up.SignUpRoute
+import be.ugent.sel.studeez.screens.splash.SplashRoute
+import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute
+import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute
import be.ugent.sel.studeez.ui.theme.StudeezTheme
import kotlinx.coroutines.CoroutineScope
@@ -48,13 +56,7 @@ fun StudeezApp() {
},
scaffoldState = appState.scaffoldState
) { innerPaddingModifier ->
- NavHost(
- navController = appState.navController,
- startDestination = StudeezDestinations.SPLASH_SCREEN,
- modifier = Modifier.padding(innerPaddingModifier)
- ) {
- studeezGraph(appState)
- }
+ StudeezNavGraph(appState, Modifier.padding(innerPaddingModifier))
}
}
}
@@ -79,60 +81,91 @@ fun resources(): Resources {
return LocalContext.current.resources
}
-fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) {
+@Composable
+fun StudeezNavGraph(
+ appState: StudeezAppstate,
+ modifier: Modifier,
+) {
+ val drawerViewModel: DrawerViewModel = hiltViewModel()
+ val navBarViewModel: NavigationBarViewModel = hiltViewModel()
- val goBack: () -> Unit = {
- appState.popUp()
+ 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)
+ }
+
+
+ composable(StudeezDestinations.SPLASH_SCREEN) {
+ SplashRoute(openAndPopUp, viewModel = hiltViewModel())
+ }
+
+ composable(StudeezDestinations.LOGIN_SCREEN) {
+ LoginRoute(openAndPopUp, viewModel = hiltViewModel())
+ }
+
+ composable(StudeezDestinations.SIGN_UP_SCREEN) {
+ SignUpRoute(openAndPopUp, viewModel = hiltViewModel())
+ }
+
+ composable(StudeezDestinations.HOME_SCREEN) {
+ HomeRoute(
+ open,
+ openAndPopUp,
+ viewModel = hiltViewModel(),
+ drawerViewModel = drawerViewModel,
+ navBarViewModel = navBarViewModel,
+ )
+ }
+
+ // TODO Tasks screen
+ // TODO Sessions screen
+
+ composable(StudeezDestinations.PROFILE_SCREEN) {
+ ProfileRoute(open, openAndPopUp, viewModel = hiltViewModel())
+ }
+
+ composable(StudeezDestinations.TIMER_OVERVIEW_SCREEN) {
+ TimerOverviewRoute(
+ open,
+ openAndPopUp,
+ viewModel = hiltViewModel(),
+ drawerViewModel = drawerViewModel,
+ navBarViewModel = navBarViewModel,
+ )
+ }
+
+ composable(StudeezDestinations.SESSION_SCREEN) {
+ SessionRoute(open, viewModel = hiltViewModel())
+ }
+
+ // TODO Timers screen
+ // TODO Settings screen
+
+ // Edit screens
+ composable(StudeezDestinations.EDIT_PROFILE_SCREEN) {
+ EditProfileRoute(goBack, openAndPopUp, viewModel = hiltViewModel())
+ }
+
+ composable(StudeezDestinations.TIMER_SELECTION_SCREEN) {
+ TimerSelectionRoute(
+ open,
+ openAndPopUp,
+ viewModel = hiltViewModel(),
+ drawerViewModel = drawerViewModel,
+ navBarViewModel = navBarViewModel,
+ )
+ }
}
-
- val open: (String) -> Unit = {
- route -> appState.navigate(route)
- }
-
- val openAndPopUp: (String, String) -> Unit = {
- route, popUp -> appState.navigateAndPopUp(route, popUp)
- }
-
- composable(StudeezDestinations.SPLASH_SCREEN) {
- SplashScreen(openAndPopUp)
- }
-
- composable(StudeezDestinations.LOGIN_SCREEN) {
- LoginScreen(openAndPopUp)
- }
-
- composable(StudeezDestinations.SIGN_UP_SCREEN) {
- SignUpScreen(openAndPopUp)
- }
-
- composable(StudeezDestinations.HOME_SCREEN) {
- HomeScreen(open, openAndPopUp)
- }
-
- // TODO Tasks screen
- // TODO Sessions screen
-
- composable(StudeezDestinations.PROFILE_SCREEN) {
- ProfileScreen(open, openAndPopUp)
- }
-
- composable(StudeezDestinations.TIMER_OVERVIEW_SCREEN) {
- TimerOverviewScreen(open, openAndPopUp)
- }
-
- composable(StudeezDestinations.SESSION_SCREEN) {
- SessionScreen(open, openAndPopUp)
- }
-
- // TODO Timers screen
- // TODO Settings screen
-
- // Edit screens
- composable(StudeezDestinations.EDIT_PROFILE_SCREEN) {
- EditProfileScreen(goBack, openAndPopUp)
- }
-
- composable(StudeezDestinations.TIMER_SELECTION_SCREEN) {
- TimerSelectionScreen(open, openAndPopUp)
- }
-}
\ No newline at end of file
+}
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 02656bd..b020cc8 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,8 +1,5 @@
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
@@ -25,13 +22,7 @@ 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 {
@@ -54,16 +45,9 @@ class MainActivity : ComponentActivity() {
}
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/common/composable/PrimaryScreenComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt
index df9b346..5af2788 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,17 +2,26 @@ 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.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.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.screens.drawer.Drawer
-import be.ugent.sel.studeez.screens.navbar.NavigationBar
+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.ui.theme.StudeezTheme
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@@ -20,8 +29,8 @@ import kotlinx.coroutines.launch
@Composable
fun PrimaryScreenTemplate(
title: String,
- open: (String) -> Unit,
- openAndPopUp: (String, String) -> Unit,
+ drawerActions: DrawerActions,
+ navigationBarActions: NavigationBarActions,
action: @Composable RowScope.() -> Unit = {},
content: @Composable (PaddingValues) -> Unit
) {
@@ -31,26 +40,28 @@ fun PrimaryScreenTemplate(
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(R.string.menu)
- )
- }
- },
- actions = action
- ) },
-
- drawerContent = {
- Drawer(open, openAndPopUp)
+ topBar = {
+ TopAppBar(
+ title = { Text(text = title) },
+ navigationIcon = {
+ IconButton(onClick = {
+ coroutineScope.launch { scaffoldState.drawerState.open() }
+ }) {
+ Icon(
+ imageVector = Icons.Default.Menu,
+ contentDescription = resources().getString(R.string.menu)
+ )
+ }
+ },
+ actions = action
+ )
},
- bottomBar = { NavigationBar(open) },
+ drawerContent = {
+ Drawer(drawerActions)
+ },
+
+ bottomBar = { NavigationBar(navigationBarActions) },
floatingActionButtonPosition = FabPosition.Center,
isFloatingActionButtonDocked = true,
floatingActionButton = { CollapsedAddButton() }
@@ -65,14 +76,16 @@ fun PrimaryScreenPreview() {
StudeezTheme {
PrimaryScreenTemplate(
"Preview screen",
- { _ -> {}},
- { _, _ -> {}},
- { IconButton(onClick = { /*TODO*/ }) {
- Icon(
- imageVector = Icons.Default.Edit,
- contentDescription = "Edit"
- )
- }}
+ DrawerActions({}, {}, {}, {}, {}),
+ NavigationBarActions({}, {}, {}, {}),
+ {
+ IconButton(onClick = { /*TODO*/ }) {
+ Icon(
+ imageVector = Icons.Default.Edit,
+ contentDescription = "Edit"
+ )
+ }
+ },
) {}
}
}
\ No newline at end of file
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
new file mode 100644
index 0000000..bfa2711
--- /dev/null
+++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/TimerEntry.kt
@@ -0,0 +1,62 @@
+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.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.font.FontWeight
+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_info.CustomTimerInfo
+import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
+
+@Composable
+fun TimerEntry(
+ timerInfo: TimerInfo,
+ button: @Composable () -> Unit,
+) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween
+ ) {
+ Column(
+ Modifier.padding(horizontal = 10.dp)
+ ) {
+ Text(
+ text = timerInfo.name, fontWeight = FontWeight.Bold, fontSize = 20.sp
+ )
+ Text(
+ text = timerInfo.description, fontWeight = FontWeight.Light, fontSize = 15.sp
+ )
+ }
+ button()
+ }
+}
+
+@Preview
+@Composable
+fun TimerEntryPreview() {
+ val timerInfo = CustomTimerInfo(
+ "my preview timer", "This is the description of the timer", 60
+ )
+ TimerEntry(timerInfo = timerInfo) {
+ StealthButton(text = R.string.edit) {}
+ }
+}
+
+@Preview
+@Composable
+fun TimerDefaultEntryPreview() {
+ val timerInfo = CustomTimerInfo(
+ "Default preview timer", "This is the description of the timer", 60
+ )
+ TimerEntry(timerInfo = timerInfo) {}
+}
\ No newline at end of file
diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/drawer/DrawerComposable.kt
similarity index 51%
rename from app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerComposable.kt
rename to app/src/main/java/be/ugent/sel/studeez/common/composable/drawer/DrawerComposable.kt
index 296fd94..47571f5 100644
--- a/app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerComposable.kt
+++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/drawer/DrawerComposable.kt
@@ -1,7 +1,12 @@
-package be.ugent.sel.studeez.screens.drawer
+package be.ugent.sel.studeez.common.composable.drawer
import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+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.Icon
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
@@ -14,57 +19,71 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import androidx.hilt.navigation.compose.hiltViewModel
-import androidx.lifecycle.viewmodel.compose.viewModel
import be.ugent.sel.studeez.R
import be.ugent.sel.studeez.resources
import be.ugent.sel.studeez.ui.theme.StudeezTheme
+data class DrawerActions(
+ val onHomeButtonClick: () -> Unit,
+ val onTimersClick: () -> Unit,
+ val onSettingsClick: () -> Unit,
+ val onLogoutClick: () -> Unit,
+ val onAboutClick: () -> Unit,
+)
+
+fun getDrawerActions(
+ drawerViewModel: DrawerViewModel,
+ open: (String) -> Unit,
+ openAndPopUp: (String, String) -> Unit,
+): DrawerActions {
+ return DrawerActions(
+ onHomeButtonClick = { drawerViewModel.onHomeButtonClick(open) },
+ onTimersClick = { drawerViewModel.onTimersClick(open) },
+ onSettingsClick = { drawerViewModel.onSettingsClick(open) },
+ onLogoutClick = { drawerViewModel.onLogoutClick(openAndPopUp) },
+ onAboutClick = { drawerViewModel.onAboutClick(open) },
+ )
+}
@Composable
fun Drawer(
- open: (String) -> Unit,
- openAndPopUp: (String, String) -> Unit,
- viewModel: DrawerViewModel = hiltViewModel()
+ drawerActions: DrawerActions,
) {
- Column (
+ Column(
modifier = Modifier.fillMaxWidth()
) {
- Column (
- modifier = Modifier.fillMaxWidth().weight(1f)
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .weight(1f)
) {
DrawerEntry(
icon = Icons.Default.Home,
- text = resources().getString(R.string.home)
- ) {
- viewModel.onHomeButtonClick(open)
- }
+ text = resources().getString(R.string.home),
+ onClick = drawerActions.onHomeButtonClick,
+ )
DrawerEntry(
icon = ImageVector.vectorResource(id = R.drawable.ic_timer),
- text = resources().getString(R.string.timers)
- ) {
- viewModel.onTimersClick(open)
- }
+ text = resources().getString(R.string.timers),
+ onClick = drawerActions.onTimersClick,
+ )
DrawerEntry(
icon = Icons.Default.Settings,
- text = resources().getString(R.string.settings)
- ) {
- viewModel.onSettingsClick(open)
- }
+ text = resources().getString(R.string.settings),
+ onClick = drawerActions.onSettingsClick,
+ )
DrawerEntry(
icon = ImageVector.vectorResource(id = R.drawable.ic_logout),
- text = resources().getString(R.string.log_out)
- ) {
- viewModel.onLogoutClick(openAndPopUp)
- }
+ text = resources().getString(R.string.log_out),
+ onClick = drawerActions.onLogoutClick,
+ )
}
DrawerEntry(
icon = Icons.Outlined.Info,
- text = resources().getString(R.string.about)
- ) {
- viewModel.onAboutClick(open)
- }
+ text = resources().getString(R.string.about),
+ onClick = drawerActions.onAboutClick,
+ )
}
}
@@ -100,11 +119,8 @@ fun DrawerEntry(
@Preview
@Composable
fun DrawerPreview() {
+ val drawerActions = DrawerActions({}, {}, {}, {}, {})
StudeezTheme {
- Drawer(
- { _, -> {} },
- { _, _ -> {} },
- hiltViewModel()
- )
+ Drawer(drawerActions)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/drawer/DrawerViewModel.kt
similarity index 95%
rename from app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt
rename to app/src/main/java/be/ugent/sel/studeez/common/composable/drawer/DrawerViewModel.kt
index 7e03b9b..d16d930 100644
--- a/app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt
+++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/drawer/DrawerViewModel.kt
@@ -1,4 +1,4 @@
-package be.ugent.sel.studeez.screens.drawer
+package be.ugent.sel.studeez.common.composable.drawer
import be.ugent.sel.studeez.domain.AccountDAO
import be.ugent.sel.studeez.domain.LogService
diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/navbar/NavigationBarComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt
similarity index 56%
rename from app/src/main/java/be/ugent/sel/studeez/screens/navbar/NavigationBarComposable.kt
rename to app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt
index 5c5dee1..21311ef 100644
--- a/app/src/main/java/be/ugent/sel/studeez/screens/navbar/NavigationBarComposable.kt
+++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt
@@ -1,4 +1,4 @@
-package be.ugent.sel.studeez.screens.navbar
+package be.ugent.sel.studeez.common.composable.navbar
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
@@ -12,16 +12,32 @@ 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 androidx.hilt.navigation.compose.hiltViewModel
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 onHomeClick: () -> Unit,
+ val onTasksClick: () -> Unit,
+ val onSessionsClick: () -> Unit,
+ val onProfileClick: () -> Unit,
+)
+
+fun getNavigationBarActions(
+ navigationBarViewModel: NavigationBarViewModel,
+ open: (String) -> Unit,
+): NavigationBarActions {
+ return NavigationBarActions(
+ onHomeClick = { navigationBarViewModel.onHomeClick(open) },
+ onTasksClick = { navigationBarViewModel.onTasksClick(open) },
+ onSessionsClick = { navigationBarViewModel.onSessionsClick(open) },
+ onProfileClick = { navigationBarViewModel.onProfileClick(open) },
+ )
+}
@Composable
fun NavigationBar(
- open: (String) -> Unit,
- viewModel: NavigationBarViewModel = hiltViewModel()
+ navigationBarActions: NavigationBarActions,
) {
// TODO Pass functions and new screens.
// TODO Pass which screen is selected.
@@ -33,31 +49,43 @@ fun NavigationBar(
icon = { Icon(imageVector = Icons.Default.List, resources().getString(AppText.home)) },
label = { Text(text = resources().getString(AppText.home)) },
selected = false, // TODO
- onClick = { viewModel.onHomeClick(open) }
+ onClick = navigationBarActions.onHomeClick
)
BottomNavigationItem(
- icon = { Icon(imageVector = Icons.Default.Check, resources().getString(AppText.tasks)) },
+ icon = {
+ Icon(
+ imageVector = Icons.Default.Check, resources().getString(AppText.tasks)
+ )
+ },
label = { Text(text = resources().getString(AppText.tasks)) },
selected = false, // TODO
- onClick = { viewModel.onTasksClick(open) }
+ onClick = navigationBarActions.onTasksClick
)
// Hack to space the entries in the navigation bar, make space for fab
BottomNavigationItem(icon = {}, onClick = {}, selected = false)
BottomNavigationItem(
- icon = { Icon(imageVector = Icons.Outlined.DateRange, resources().getString(AppText.sessions)) },
+ icon = {
+ Icon(
+ imageVector = Icons.Outlined.DateRange, resources().getString(AppText.sessions)
+ )
+ },
label = { Text(text = resources().getString(AppText.sessions)) },
selected = false, // TODO
- onClick = { viewModel.onSessionsClick(open) }
+ onClick = navigationBarActions.onSessionsClick
)
BottomNavigationItem(
- icon = { Icon(imageVector = Icons.Default.Person, resources().getString(AppText.profile)) },
+ icon = {
+ Icon(
+ imageVector = Icons.Default.Person, resources().getString(AppText.profile)
+ )
+ },
label = { Text(text = resources().getString(AppText.profile)) },
selected = false, // TODO
- onClick = { viewModel.onProfileClick(open) }
+ onClick = navigationBarActions.onProfileClick
)
}
@@ -67,9 +95,6 @@ fun NavigationBar(
@Composable
fun NavigationBarPreview() {
StudeezTheme {
- NavigationBar(
- { _ -> {} },
- hiltViewModel()
- )
+ NavigationBar(NavigationBarActions({}, {}, {}, {}))
}
}
\ No newline at end of file
diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/navbar/NavigationBarViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt
similarity index 93%
rename from app/src/main/java/be/ugent/sel/studeez/screens/navbar/NavigationBarViewModel.kt
rename to app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt
index 75613d5..1e4bd0d 100644
--- a/app/src/main/java/be/ugent/sel/studeez/screens/navbar/NavigationBarViewModel.kt
+++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt
@@ -1,4 +1,4 @@
-package be.ugent.sel.studeez.screens.navbar
+package be.ugent.sel.studeez.common.composable.navbar
import be.ugent.sel.studeez.domain.AccountDAO
import be.ugent.sel.studeez.domain.LogService
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 7ca2559..e318655 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
@@ -6,37 +6,69 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Person
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.hilt.navigation.compose.hiltViewModel
+import androidx.compose.ui.tooling.preview.Preview
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 HomeScreen(
+fun HomeRoute(
open: (String) -> Unit,
openAndPopUp: (String, String) -> Unit,
- viewModel: HomeViewModel = hiltViewModel()
+ viewModel: HomeViewModel,
+ drawerViewModel: DrawerViewModel,
+ navBarViewModel: NavigationBarViewModel,
) {
+ HomeScreen(
+ onStartSessionClick = { viewModel.onStartSessionClick(open) },
+ drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp),
+ navigationBarActions = getNavigationBarActions(navBarViewModel, open),
+ )
+}
+
+@Composable
+fun HomeScreen(
+ onStartSessionClick: () -> Unit,
+ drawerActions: DrawerActions,
+ navigationBarActions: NavigationBarActions,
+) {
+
PrimaryScreenTemplate(
title = resources().getString(R.string.home),
- open = open,
- openAndPopUp = openAndPopUp,
+ drawerActions = drawerActions,
+ navigationBarActions = navigationBarActions,
action = { FriendsAction() }
) {
BasicButton(R.string.start_session, Modifier.basicButton()) {
- viewModel.onStartSessionClick(open)
+ onStartSessionClick()
}
}
}
@Composable
-fun FriendsAction () {
+fun FriendsAction() {
IconButton(onClick = { /*TODO*/ }) {
Icon(
imageVector = Icons.Default.Person,
contentDescription = resources().getString(R.string.friends)
)
}
-}
\ No newline at end of file
+}
+
+@Preview
+@Composable
+fun HomeScreenPreview() {
+ HomeScreen(
+ onStartSessionClick = {},
+ drawerActions = DrawerActions({}, {}, {}, {}, {}),
+ navigationBarActions = NavigationBarActions({}, {}, {}, {})
+ )
+}
diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/log_in/LoginScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/log_in/LoginScreen.kt
index 2762abc..fe7524b 100644
--- a/app/src/main/java/be/ugent/sel/studeez/screens/log_in/LoginScreen.kt
+++ b/app/src/main/java/be/ugent/sel/studeez/screens/log_in/LoginScreen.kt
@@ -10,7 +10,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.hilt.navigation.compose.hiltViewModel
+import androidx.compose.ui.tooling.preview.Preview
import be.ugent.sel.studeez.common.composable.*
import be.ugent.sel.studeez.common.ext.basicButton
import be.ugent.sel.studeez.common.ext.fieldModifier
@@ -18,14 +18,48 @@ import be.ugent.sel.studeez.common.ext.textButton
import be.ugent.sel.studeez.resources
import be.ugent.sel.studeez.R.string as AppText
+data class LoginScreenActions(
+ val onEmailChange: (String) -> Unit,
+ val onPasswordChange: (String) -> Unit,
+ val onSignUpClick: () -> Unit,
+ val onSignInClick: () -> Unit,
+ val onForgotPasswordClick: () -> Unit,
+)
+
+fun getLoginScreenActions(
+ viewModel: LoginViewModel,
+ openAndPopUp: (String, String) -> Unit,
+): LoginScreenActions {
+ return LoginScreenActions(
+ onEmailChange = { viewModel.onEmailChange(it) },
+ onPasswordChange = { viewModel.onPasswordChange(it) },
+ onSignUpClick = { viewModel.onSignUpClick(openAndPopUp) },
+ onSignInClick = { viewModel.onSignInClick(openAndPopUp) },
+ onForgotPasswordClick = { viewModel.onForgotPasswordClick() }
+ )
+}
+
@Composable
-fun LoginScreen(
+fun LoginRoute(
openAndPopUp: (String, String) -> Unit,
modifier: Modifier = Modifier,
- viewModel: LoginViewModel = hiltViewModel()
+ viewModel: LoginViewModel,
) {
val uiState by viewModel.uiState
+ LoginScreen(
+ modifier = modifier,
+ uiState = uiState,
+ loginScreenActions = getLoginScreenActions(viewModel = viewModel, openAndPopUp)
+ )
+}
+
+@Composable
+fun LoginScreen(
+ modifier: Modifier = Modifier,
+ uiState: LoginUiState,
+ loginScreenActions: LoginScreenActions,
+) {
SimpleScreenTemplate(title = resources().getString(AppText.sign_in)) {
Column(
modifier = modifier
@@ -35,18 +69,42 @@ fun LoginScreen(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
- EmailField(uiState.email, viewModel::onEmailChange, Modifier.fieldModifier())
- PasswordField(uiState.password, viewModel::onPasswordChange, Modifier.fieldModifier())
+ EmailField(
+ uiState.email,
+ loginScreenActions.onEmailChange,
+ Modifier.fieldModifier()
+ )
+ PasswordField(
+ uiState.password,
+ loginScreenActions.onPasswordChange,
+ Modifier.fieldModifier()
+ )
+ BasicButton(
+ AppText.sign_in,
+ Modifier.basicButton(),
+ onClick = loginScreenActions.onSignInClick,
+ )
- BasicButton(AppText.sign_in, Modifier.basicButton()) { viewModel.onSignInClick(openAndPopUp) }
+ BasicTextButton(
+ AppText.not_already_user,
+ Modifier.textButton(),
+ action = loginScreenActions.onSignUpClick,
+ )
- BasicTextButton(AppText.not_already_user, Modifier.textButton()) {
- viewModel.onNotAlreadyUser(openAndPopUp)
- }
-
- BasicTextButton(AppText.forgot_password, Modifier.textButton()) {
- viewModel.onForgotPasswordClick()
- }
+ BasicTextButton(
+ AppText.forgot_password,
+ Modifier.textButton(),
+ action = loginScreenActions.onForgotPasswordClick,
+ )
}
}
+}
+
+@Preview
+@Composable
+fun LoginScreenPreview() {
+ LoginScreen(
+ uiState = LoginUiState(),
+ loginScreenActions = LoginScreenActions({}, {}, {}, {}, {})
+ )
}
\ No newline at end of file
diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/log_in/LoginViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/log_in/LoginViewModel.kt
index cf3a72d..c7e88fa 100644
--- a/app/src/main/java/be/ugent/sel/studeez/screens/log_in/LoginViewModel.kt
+++ b/app/src/main/java/be/ugent/sel/studeez/screens/log_in/LoginViewModel.kt
@@ -63,7 +63,7 @@ class LoginViewModel @Inject constructor(
}
}
- fun onNotAlreadyUser(openAndPopUp: (String, String) -> Unit) {
+ fun onSignUpClick(openAndPopUp: (String, String) -> Unit) {
openAndPopUp(SIGN_UP_SCREEN, LOGIN_SCREEN)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt
index eb12ac7..3dbe270 100644
--- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt
+++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileEditScreen.kt
@@ -5,7 +5,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
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.BasicTextButton
import be.ugent.sel.studeez.common.composable.LabelledInputField
@@ -14,14 +13,43 @@ import be.ugent.sel.studeez.common.ext.textButton
import be.ugent.sel.studeez.resources
import be.ugent.sel.studeez.ui.theme.StudeezTheme
+data class EditProfileActions(
+ val onUserNameChange: (String) -> Unit,
+ val onSaveClick: () -> Unit,
+ val onDeleteClick: () -> Unit
+)
+
+fun getEditProfileActions(
+ viewModel: ProfileEditViewModel,
+ openAndPopUp: (String, String) -> Unit,
+): EditProfileActions {
+ return EditProfileActions(
+ onUserNameChange = { viewModel.onUsernameChange(it) },
+ onSaveClick = { viewModel.onSaveClick() },
+ onDeleteClick = { viewModel.onDeleteClick(openAndPopUp) },
+ )
+}
+
+@Composable
+fun EditProfileRoute(
+ goBack: () -> Unit,
+ openAndPopUp: (String, String) -> Unit,
+ viewModel: ProfileEditViewModel,
+) {
+ val uiState by viewModel.uiState
+ EditProfileScreen(
+ goBack = goBack,
+ uiState = uiState,
+ editProfileActions = getEditProfileActions(viewModel, openAndPopUp)
+ )
+}
+
@Composable
fun EditProfileScreen(
goBack: () -> Unit,
- openAndPopUp: (String, String) -> Unit,
- viewModel: ProfileEditViewModel = hiltViewModel()
+ uiState: ProfileEditUiState,
+ editProfileActions: EditProfileActions,
) {
- val uiState by viewModel.uiState
-
SecondaryScreenTemplate(
title = resources().getString(R.string.editing_profile),
popUp = goBack
@@ -29,16 +57,19 @@ fun EditProfileScreen(
Column {
LabelledInputField(
value = uiState.username,
- onNewValue = viewModel::onUsernameChange,
+ onNewValue = editProfileActions.onUserNameChange,
label = R.string.username
)
-
- BasicTextButton(text = R.string.save, Modifier.textButton()) {
- viewModel.onSaveClick()
- }
- BasicTextButton(text = R.string.delete_profile, Modifier.textButton()) {
- viewModel.onDeleteClick(openAndPopUp)
- }
+ BasicTextButton(
+ text = R.string.save,
+ Modifier.textButton(),
+ action = editProfileActions.onSaveClick
+ )
+ BasicTextButton(
+ text = R.string.delete_profile,
+ Modifier.textButton(),
+ action = editProfileActions.onDeleteClick
+ )
}
}
}
@@ -47,9 +78,6 @@ fun EditProfileScreen(
@Composable
fun EditProfileScreenComposable() {
StudeezTheme {
- EditProfileScreen (
- {},
- {_, _ -> {}}
- )
+ EditProfileScreen({}, ProfileEditUiState(), EditProfileActions({}, {}, {}))
}
}
\ No newline at end of file
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 6ec4a01..a12dd08 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,30 +4,68 @@ 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.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 kotlinx.coroutines.CoroutineScope
import be.ugent.sel.studeez.R.string as AppText
+data class ProfileActions(
+ val getUsername: suspend CoroutineScope.() -> String?,
+ val onEditProfileClick: () -> Unit,
+)
+
+fun getProfileActions(
+ viewModel: ProfileViewModel,
+ open: (String) -> Unit,
+): ProfileActions {
+ return ProfileActions(
+ getUsername = { viewModel.getUsername() },
+ onEditProfileClick = { viewModel.onEditProfileClick(open) },
+ )
+}
+
+@Composable
+fun ProfileRoute(
+ open: (String) -> Unit,
+ openAndPopUp: (String, String) -> Unit,
+ viewModel: ProfileViewModel,
+) {
+ ProfileScreen(
+ profileActions = getProfileActions(viewModel, open),
+ drawerActions = getDrawerActions(hiltViewModel(), open, openAndPopUp),
+ navigationBarActions = getNavigationBarActions(hiltViewModel(), open),
+ )
+}
+
@Composable
fun ProfileScreen(
- open: (String) -> Unit,
- openAndPopUp: (String, String) -> Unit,
- viewModel: ProfileViewModel = hiltViewModel()
+ profileActions: ProfileActions,
+ drawerActions: DrawerActions,
+ navigationBarActions: NavigationBarActions,
) {
var username: String? by remember { mutableStateOf("") }
LaunchedEffect(key1 = Unit) {
- username = viewModel.getUsername()
+ username = profileActions.getUsername(this)
}
-
PrimaryScreenTemplate(
title = resources().getString(AppText.profile),
- open = open,
- openAndPopUp = openAndPopUp,
- action = { EditAction { viewModel.onEditProfileClick(open) } }
+ drawerActions = drawerActions,
+ navigationBarActions = navigationBarActions,
+ action = { EditAction(onClick = profileActions.onEditProfileClick) }
) {
Headline(text = (username ?: resources().getString(R.string.no_username)))
}
@@ -44,4 +82,14 @@ fun EditAction(
)
}
+}
+
+@Preview
+@Composable
+fun ProfileScreenPreview() {
+ ProfileScreen(
+ profileActions = ProfileActions({ null }, {}),
+ drawerActions = DrawerActions({}, {}, {}, {}, {}),
+ navigationBarActions = NavigationBarActions({}, {}, {}, {})
+ )
}
\ 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 ac2d225..3a32b37 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
@@ -24,34 +24,71 @@ 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 be.ugent.sel.studeez.navigation.StudeezDestinations
import androidx.compose.ui.unit.sp
-import androidx.hilt.navigation.compose.hiltViewModel
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.resources
import kotlinx.coroutines.delay
+import javax.inject.Singleton
import kotlin.time.Duration.Companion.seconds
+data class SessionActions(
+ val getTimer: () -> FunctionalTimer,
+ val getTask: () -> String,
+ val releaseMediaPlayer: () -> Unit,
+ val startMediaPlayer: () -> Unit,
+)
+
+fun getSessionActions(
+ viewModel: SessionViewModel,
+ mediaplayer: MediaPlayer,
+): SessionActions {
+ return SessionActions(
+ getTimer = viewModel::getTimer,
+ getTask = viewModel::getTask,
+ releaseMediaPlayer = mediaplayer::release,
+ startMediaPlayer = mediaplayer::start,
+ )
+}
+
@Composable
-fun SessionScreen(
+fun SessionRoute(
open: (String) -> Unit,
- openAndPopUp: (String, String) -> Unit,
- viewModel: SessionViewModel = hiltViewModel()
+ viewModel: SessionViewModel,
) {
val context = LocalContext.current
val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val mediaplayer = MediaPlayer.create(context, uri)
mediaplayer.isLooping = false
- InvisibleSessionManager.setParameters(viewModel = viewModel, mediaplayer = mediaplayer)
+ InvisibleSessionManager.setParameters(
+ viewModel = viewModel,
+ mediaplayer = mediaplayer
+ )
+ SessionScreen(
+ open = open,
+ sessionActions = getSessionActions(viewModel, mediaplayer)
+ )
+}
+
+@Composable
+fun SessionScreen(
+ open: (String) -> Unit,
+ sessionActions: SessionActions
+) {
Column(
- modifier = Modifier.padding(10.dp)
- ) {
- Timer(viewModel, mediaplayer)
+ modifier = Modifier.padding(10.dp)
+ ) {
+ Timer(
+ sessionActions = sessionActions
+ )
Box(
contentAlignment = Alignment.Center,
@@ -61,12 +98,11 @@ fun SessionScreen(
) {
TextButton(
onClick = {
- mediaplayer.stop()
- mediaplayer.release()
+ sessionActions.releaseMediaPlayer
+
open(StudeezDestinations.HOME_SCREEN)
- InvisibleSessionManager.isSession = false
// 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))
@@ -77,7 +113,8 @@ fun SessionScreen(
color = Color.Red,
fontWeight = FontWeight.Bold,
fontSize = 18.sp,
- modifier = Modifier.padding(1.dp)
+ modifier = Modifier
+ .padding(1.dp)
)
}
}
@@ -85,19 +122,21 @@ fun SessionScreen(
}
@Composable
-private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: MediaPlayer) {
+private fun Timer(
+ sessionActions: SessionActions
+) {
var tikker by remember { mutableStateOf(false) }
LaunchedEffect(tikker) {
delay(1.seconds)
- viewModel.getTimer().tick()
+ sessionActions.getTimer().tick()
tikker = !tikker
}
- if (viewModel.getTimer().hasCurrentCountdownEnded() && !viewModel.getTimer().hasEnded()) {
- mediaplayer.start()
+ if (sessionActions.getTimer().hasCurrentCountdownEnded() && !sessionActions.getTimer().hasEnded()) {
+ sessionActions.startMediaPlayer
}
- val hms = viewModel.getTimer().getHoursMinutesSeconds()
+ val hms = sessionActions.getTimer().getHoursMinutesSeconds()
Column {
Text(
text = "${hms.hours} : ${hms.minutes} : ${hms.seconds}",
@@ -108,14 +147,14 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me
fontWeight = FontWeight.Bold,
fontSize = 40.sp,
)
- val stateString: String = when (viewModel.getTimer().view) {
+ 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 ->
- (viewModel.getTimer() as FunctionalPomodoroTimer?)?.breaksRemaining?.let {
+ (sessionActions.getTimer() as FunctionalPomodoroTimer?)?.breaksRemaining?.let {
resources().getQuantityString(R.plurals.state_focus_remaining, it, it)
- }.toString()
+ }.toString()
}
Text(
@@ -139,7 +178,7 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me
.background(Color.Blue, RoundedCornerShape(32.dp))
) {
Text(
- text = viewModel.getTask(),
+ text = sessionActions.getTask(),
color = Color.White,
fontSize = 18.sp,
fontWeight = FontWeight.Bold,
@@ -151,6 +190,8 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me
}
}
+
+@Singleton
object InvisibleSessionManager {
private lateinit var viewModel: SessionViewModel
private lateinit var mediaplayer: MediaPlayer
@@ -174,3 +215,19 @@ object InvisibleSessionManager {
}
}
}
+
+@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/sign_up/SignUpScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/sign_up/SignUpScreen.kt
index 7515117..038bee2 100644
--- a/app/src/main/java/be/ugent/sel/studeez/screens/sign_up/SignUpScreen.kt
+++ b/app/src/main/java/be/ugent/sel/studeez/screens/sign_up/SignUpScreen.kt
@@ -10,23 +10,64 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.hilt.navigation.compose.hiltViewModel
-import be.ugent.sel.studeez.common.composable.*
+import androidx.compose.ui.tooling.preview.Preview
+import be.ugent.sel.studeez.common.composable.BasicButton
+import be.ugent.sel.studeez.common.composable.BasicTextButton
+import be.ugent.sel.studeez.common.composable.EmailField
+import be.ugent.sel.studeez.common.composable.PasswordField
+import be.ugent.sel.studeez.common.composable.RepeatPasswordField
+import be.ugent.sel.studeez.common.composable.SimpleScreenTemplate
+import be.ugent.sel.studeez.common.composable.UsernameField
import be.ugent.sel.studeez.common.ext.basicButton
import be.ugent.sel.studeez.common.ext.fieldModifier
import be.ugent.sel.studeez.common.ext.textButton
import be.ugent.sel.studeez.resources
import be.ugent.sel.studeez.R.string as AppText
+data class SignUpActions(
+ val onUserNameChange: (String) -> Unit,
+ val onEmailChange: (String) -> Unit,
+ val onPasswordChange: (String) -> Unit,
+ val onRepeatPasswordChange: (String) -> Unit,
+ val onSignUpClick: () -> Unit,
+ val onLoginClick: () -> Unit,
+)
+
+fun getSignUpActions(
+ viewModel: SignUpViewModel,
+ openAndPopUp: (String, String) -> Unit,
+): SignUpActions {
+ return SignUpActions(
+ onUserNameChange = { viewModel.onUsernameChange(it) },
+ onEmailChange = { viewModel.onEmailChange(it) },
+ onPasswordChange = { viewModel.onPasswordChange(it) },
+ onRepeatPasswordChange = { viewModel.onRepeatPasswordChange(it) },
+ onSignUpClick = { viewModel.onSignUpClick(openAndPopUp) },
+ onLoginClick = { viewModel.onLoginClick(openAndPopUp) },
+ )
+}
+
@Composable
-fun SignUpScreen(
+fun SignUpRoute(
openAndPopUp: (String, String) -> Unit,
modifier: Modifier = Modifier,
- viewModel: SignUpViewModel = hiltViewModel()
+ viewModel: SignUpViewModel,
) {
val uiState by viewModel.uiState
- val fieldModifier = Modifier.fieldModifier()
+ SignUpScreen(
+ modifier = modifier,
+ uiState,
+ getSignUpActions(viewModel, openAndPopUp)
+ )
+}
+@Composable
+fun SignUpScreen(
+ modifier: Modifier = Modifier,
+ uiState: SignUpUiState,
+ signUpActions: SignUpActions,
+) {
+ val fieldModifier = Modifier.fieldModifier()
SimpleScreenTemplate(title = resources().getString(AppText.create_account)) {
Column(
modifier = modifier
@@ -36,40 +77,45 @@ fun SignUpScreen(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
-
UsernameField(
uiState.username,
- viewModel::onUsernameChange,
+ signUpActions.onUserNameChange,
fieldModifier
)
-
EmailField(
uiState.email,
- viewModel::onEmailChange,
+ signUpActions.onEmailChange,
fieldModifier
)
-
PasswordField(
uiState.password,
- viewModel::onPasswordChange,
+ signUpActions.onPasswordChange,
fieldModifier
)
-
RepeatPasswordField(
uiState.repeatPassword,
- viewModel::onRepeatPasswordChange,
+ signUpActions.onRepeatPasswordChange,
fieldModifier
)
-
- BasicButton(AppText.create_account, Modifier.basicButton()) {
- viewModel.onSignUpClick(openAndPopUp)
- }
-
- BasicTextButton(AppText.already_user, Modifier.textButton()) {
- viewModel.onLoginScreenClick(openAndPopUp)
- }
+ BasicButton(
+ AppText.create_account,
+ Modifier.basicButton(),
+ onClick = signUpActions.onSignUpClick
+ )
+ BasicTextButton(
+ AppText.already_user,
+ Modifier.textButton(),
+ action = signUpActions.onLoginClick
+ )
}
}
+}
-
+@Preview
+@Composable
+fun SignUpPreview() {
+ SignUpScreen(
+ uiState = SignUpUiState(),
+ signUpActions = SignUpActions({}, {}, {}, {}, {}, {})
+ )
}
\ No newline at end of file
diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/sign_up/SignUpViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/sign_up/SignUpViewModel.kt
index 91dde13..a08d063 100644
--- a/app/src/main/java/be/ugent/sel/studeez/screens/sign_up/SignUpViewModel.kt
+++ b/app/src/main/java/be/ugent/sel/studeez/screens/sign_up/SignUpViewModel.kt
@@ -71,7 +71,7 @@ class SignUpViewModel @Inject constructor(
}
}
- fun onLoginScreenClick(openAndPopUp: (String, String) -> Unit) {
+ fun onLoginClick(openAndPopUp: (String, String) -> Unit) {
openAndPopUp(LOGIN_SCREEN, SIGN_UP_SCREEN)
}
}
\ No newline at end of file
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 38146c0..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
@@ -15,7 +15,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
-import androidx.hilt.navigation.compose.hiltViewModel
+import androidx.compose.ui.tooling.preview.Preview
import be.ugent.sel.studeez.common.composable.BasicButton
import be.ugent.sel.studeez.common.ext.basicButton
import kotlinx.coroutines.delay
@@ -24,14 +24,26 @@ import be.ugent.sel.studeez.R.string as AppText
private const val SPLASH_TIMEOUT = 500L
@Composable
-fun SplashScreen(
+fun SplashRoute(
openAndPopUp: (String, String) -> Unit,
modifier: Modifier = Modifier,
- viewModel: SplashViewModel = hiltViewModel()
+ viewModel: SplashViewModel,
+) {
+ SplashScreen(
+ modifier = modifier,
+ onAppStart = { viewModel.onAppStart(openAndPopUp) },
+ showError = viewModel.showError.value
+ )
+}
+
+@Composable
+fun SplashScreen(
+ modifier: Modifier = Modifier,
+ onAppStart: () -> Unit,
+ showError: Boolean,
) {
Column(
- modifier =
- modifier
+ modifier = modifier
.fillMaxWidth()
.fillMaxHeight()
.background(color = MaterialTheme.colors.background)
@@ -39,17 +51,37 @@ fun SplashScreen(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
- if (viewModel.showError.value) {
+ if (showError) {
Text(text = stringResource(AppText.generic_error))
-
- BasicButton(AppText.try_again, Modifier.basicButton()) { viewModel.onAppStart(openAndPopUp) }
+ BasicButton(
+ AppText.try_again,
+ Modifier.basicButton(),
+ onClick = onAppStart,
+ )
} else {
CircularProgressIndicator(color = MaterialTheme.colors.onBackground)
}
}
-
LaunchedEffect(true) {
delay(SPLASH_TIMEOUT)
- viewModel.onAppStart(openAndPopUp)
+ onAppStart()
}
+}
+
+@Preview
+@Composable
+fun SplashPreview() {
+ SplashScreen(
+ onAppStart = {},
+ showError = false,
+ )
+}
+
+@Preview
+@Composable
+fun SplashErrorPreview() {
+ SplashScreen(
+ onAppStart = {},
+ showError = true,
+ )
}
\ 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 fcff7fe..fafdf02 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,122 +1,118 @@
package be.ugent.sel.studeez.screens.timer_overview
-import android.annotation.SuppressLint
-import androidx.annotation.StringRes
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.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
-import androidx.compose.material.Scaffold
-import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import androidx.hilt.navigation.compose.hiltViewModel
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.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
import be.ugent.sel.studeez.resources
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
+
+data class TimerOverviewActions(
+ val getUserTimers: () -> Flow>,
+ val getDefaultTimers: () -> List,
+ val onEditClick: (TimerInfo) -> Unit,
+)
+
+fun getTimerOverviewActions(
+ viewModel: TimerOverviewViewModel,
+): TimerOverviewActions {
+ return TimerOverviewActions(
+ getUserTimers = viewModel::getUserTimers,
+ getDefaultTimers = viewModel::getDefaultTimers,
+ onEditClick = { viewModel.update(it) },
+ )
+}
+
+@Composable
+fun TimerOverviewRoute(
+ open: (String) -> Unit,
+ openAndPopUp: (String, String) -> Unit,
+ viewModel: TimerOverviewViewModel,
+ drawerViewModel: DrawerViewModel,
+ navBarViewModel: NavigationBarViewModel,
+) {
+ TimerOverviewScreen(
+ timerOverviewActions = getTimerOverviewActions(viewModel),
+ drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp),
+ navigationBarActions = getNavigationBarActions(navBarViewModel, open),
+ )
+}
@Composable
fun TimerOverviewScreen(
- open: (String) -> Unit,
- openAndPopUp: (String, String) -> Unit,
- viewModel: TimerOverviewViewModel = hiltViewModel()
+ timerOverviewActions: TimerOverviewActions,
+ drawerActions: DrawerActions,
+ navigationBarActions: NavigationBarActions,
) {
- val timers = viewModel.getUserTimers().collectAsState(initial = emptyList())
+ val timers = timerOverviewActions.getUserTimers().collectAsState(initial = emptyList())
+ // TODO moet geen primary screen zijn: geen navbar nodig
PrimaryScreenTemplate(
title = resources().getString(R.string.timers),
- open = open,
- openAndPopUp = openAndPopUp
+ drawerActions = drawerActions,
+ navigationBarActions = navigationBarActions,
) {
-
Column {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(7.dp)
) {
// Default Timers, cannot be edited
- items(viewModel.getDefaultTimers()) {
- TimerEntry(timerInfo = it, canDisplay = false)
+ items(timerOverviewActions.getDefaultTimers()) {
+ TimerEntry(timerInfo = it) {}
}
-
// User timers, can be edited
- items(timers.value) {
- TimerEntry(timerInfo = it, true, R.string.edit) { timerInfo ->
- viewModel.update(timerInfo)
+ items(timers.value) { timerInfo ->
+ TimerEntry(
+ timerInfo = timerInfo,
+ ) {
+ StealthButton(
+ text = R.string.edit,
+ onClick = { timerOverviewActions.onEditClick(timerInfo) }
+ )
}
+
}
}
BasicButton(R.string.add_timer, Modifier.basicButton()) {
// TODO
}
}
-
}
}
-@Composable
-fun TimerEntry(
- timerInfo: TimerInfo,
- canDisplay: Boolean,
- @StringRes buttonName: Int = -1,
- buttonFunction: (TimerInfo) -> Unit = {}
-) {
- Row(
- verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.SpaceBetween
- ) {
- Column(
- Modifier.padding(horizontal = 10.dp)
- ) {
- Text(
- text = timerInfo.name,
- fontWeight = FontWeight.Bold,
- fontSize = 20.sp
- )
- Text(
- text = timerInfo.description,
- fontWeight = FontWeight.Light,
- fontSize = 15.sp
- )
- }
- if (canDisplay) {
- StealthButton(buttonName) {
- buttonFunction(timerInfo)
- }
- }
-
- }
-}
-
-@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Preview
@Composable
-fun TimerEntryPreview() {
- val timerInfo = CustomTimerInfo(
- "my preview timer",
- "This is the description of the timer",
- 60
+fun TimerOverviewPreview() {
+ val customTimer = CustomTimerInfo(
+ "my preview timer", "This is the description of the timer", 60
)
- Scaffold() {
- Column() {
- TimerEntry(timerInfo = timerInfo, true, buttonName = R.string.edit) { }
- TimerEntry(timerInfo = timerInfo, true, buttonName = R.string.edit) { }
- TimerEntry(timerInfo = timerInfo, true, buttonName = R.string.edit) { }
- }
- }
-}
\ No newline at end of file
+ TimerOverviewScreen(
+ timerOverviewActions = TimerOverviewActions(
+ { flowOf() },
+ { listOf(customTimer, customTimer) },
+ {}),
+ drawerActions = DrawerActions({}, {}, {}, {}, {}),
+ navigationBarActions = NavigationBarActions({}, {}, {}, {})
+ )
+}
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 8e8df37..47e7f91 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
@@ -3,42 +3,89 @@ 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.runtime.*
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import androidx.hilt.navigation.compose.hiltViewModel
import be.ugent.sel.studeez.R
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.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 be.ugent.sel.studeez.screens.timer_overview.TimerEntry
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
+
+data class TimerSelectionActions(
+ val getAllTimers: () -> Flow>,
+ val startSession: (TimerInfo) -> Unit,
+)
+
+fun getTimerSelectionActions(
+ viewModel: TimerSelectionViewModel,
+ open: (String) -> Unit,
+): TimerSelectionActions {
+ return TimerSelectionActions(
+ getAllTimers = viewModel::getAllTimers,
+ startSession = { viewModel.startSession(open, it) },
+ )
+}
+
+@Composable
+fun TimerSelectionRoute(
+ open: (String) -> Unit,
+ openAndPopUp: (String, String) -> Unit,
+ viewModel: TimerSelectionViewModel,
+ drawerViewModel: DrawerViewModel,
+ navBarViewModel: NavigationBarViewModel,
+) {
+ TimerSelectionScreen(
+ timerSelectionActions = getTimerSelectionActions(viewModel, open),
+ drawerActions = getDrawerActions(drawerViewModel, open, openAndPopUp),
+ navigationBarActions = getNavigationBarActions(navBarViewModel, open),
+ )
+}
@Composable
fun TimerSelectionScreen(
- open: (String) -> Unit,
- openAndPopUp: (String, String) -> Unit,
- viewModel: TimerSelectionViewModel = hiltViewModel()
+ timerSelectionActions: TimerSelectionActions,
+ drawerActions: DrawerActions,
+ navigationBarActions: NavigationBarActions,
) {
-
- val timers = viewModel.getAllTimers().collectAsState(initial = emptyList())
-
+ val timers = timerSelectionActions.getAllTimers().collectAsState(initial = emptyList())
PrimaryScreenTemplate(
title = resources().getString(R.string.timers),
- open = open,
- openAndPopUp = openAndPopUp,
+ drawerActions = drawerActions,
+ navigationBarActions = navigationBarActions,
) {
-
LazyColumn(verticalArrangement = Arrangement.spacedBy(7.dp)) {
-
// All timers
- items(timers.value) {
+ items(timers.value) { timerInfo ->
TimerEntry(
- timerInfo = it,
- canDisplay = true,
- buttonName = R.string.start
- ) { timerInfo ->
- viewModel.startSession(open, timerInfo)
+ timerInfo = timerInfo,
+ ) {
+ StealthButton(
+ text = R.string.start,
+ onClick = { timerSelectionActions.startSession(timerInfo) }
+ )
}
}
}
-
}
+}
+
+@Preview
+@Composable
+fun TimerSelectionPreview() {
+ TimerSelectionScreen(
+ timerSelectionActions = TimerSelectionActions({ flowOf() }, {}),
+ drawerActions = DrawerActions({}, {}, {}, {}, {}),
+ navigationBarActions = NavigationBarActions({}, {}, {}, {}),
+ )
}
\ No newline at end of file