merged with current dev
This commit is contained in:
commit
b30edf6538
22 changed files with 849 additions and 373 deletions
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<bytecodeTargetLevel target="11" />
|
<bytecodeTargetLevel target="17" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
2
.idea/kotlinc.xml
generated
2
.idea/kotlinc.xml
generated
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="KotlinJpsPluginSettings">
|
<component name="KotlinJpsPluginSettings">
|
||||||
<option name="version" value="1.8.0-release" />
|
<option name="version" value="1.7.0" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
|
@ -1,7 +1,6 @@
|
||||||
<?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_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|
|
@ -2,7 +2,13 @@ package be.ugent.sel.studeez
|
||||||
|
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import androidx.compose.foundation.layout.padding
|
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.Composable
|
||||||
import androidx.compose.runtime.ReadOnlyComposable
|
import androidx.compose.runtime.ReadOnlyComposable
|
||||||
import androidx.compose.runtime.remember
|
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.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavGraphBuilder
|
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.rememberNavController
|
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.common.snackbar.SnackbarManager
|
||||||
import be.ugent.sel.studeez.navigation.StudeezDestinations
|
import be.ugent.sel.studeez.navigation.StudeezDestinations
|
||||||
import be.ugent.sel.studeez.screens.home.HomeScreen
|
import be.ugent.sel.studeez.screens.home.HomeRoute
|
||||||
import be.ugent.sel.studeez.screens.log_in.LoginScreen
|
import be.ugent.sel.studeez.screens.log_in.LoginRoute
|
||||||
import be.ugent.sel.studeez.screens.session.SessionScreen
|
import be.ugent.sel.studeez.screens.profile.EditProfileRoute
|
||||||
import be.ugent.sel.studeez.screens.profile.EditProfileScreen
|
import be.ugent.sel.studeez.screens.profile.ProfileRoute
|
||||||
import be.ugent.sel.studeez.screens.profile.ProfileScreen
|
import be.ugent.sel.studeez.screens.session.SessionRoute
|
||||||
import be.ugent.sel.studeez.screens.sign_up.SignUpScreen
|
import be.ugent.sel.studeez.screens.sign_up.SignUpRoute
|
||||||
import be.ugent.sel.studeez.screens.splash.SplashScreen
|
import be.ugent.sel.studeez.screens.splash.SplashRoute
|
||||||
import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewScreen
|
import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute
|
||||||
import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionScreen
|
import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute
|
||||||
import be.ugent.sel.studeez.ui.theme.StudeezTheme
|
import be.ugent.sel.studeez.ui.theme.StudeezTheme
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
|
||||||
|
@ -48,13 +56,7 @@ fun StudeezApp() {
|
||||||
},
|
},
|
||||||
scaffoldState = appState.scaffoldState
|
scaffoldState = appState.scaffoldState
|
||||||
) { innerPaddingModifier ->
|
) { innerPaddingModifier ->
|
||||||
NavHost(
|
StudeezNavGraph(appState, Modifier.padding(innerPaddingModifier))
|
||||||
navController = appState.navController,
|
|
||||||
startDestination = StudeezDestinations.SPLASH_SCREEN,
|
|
||||||
modifier = Modifier.padding(innerPaddingModifier)
|
|
||||||
) {
|
|
||||||
studeezGraph(appState)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,49 +81,73 @@ fun resources(): Resources {
|
||||||
return LocalContext.current.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()
|
||||||
|
|
||||||
|
NavHost(
|
||||||
|
navController = appState.navController,
|
||||||
|
startDestination = StudeezDestinations.SPLASH_SCREEN,
|
||||||
|
modifier = modifier,
|
||||||
|
) {
|
||||||
val goBack: () -> Unit = {
|
val goBack: () -> Unit = {
|
||||||
appState.popUp()
|
appState.popUp()
|
||||||
}
|
}
|
||||||
|
|
||||||
val open: (String) -> Unit = {
|
val open: (String) -> Unit = { route ->
|
||||||
route -> appState.navigate(route)
|
appState.navigate(route)
|
||||||
}
|
}
|
||||||
|
|
||||||
val openAndPopUp: (String, String) -> Unit = {
|
val openAndPopUp: (String, String) -> Unit = { route, popUp ->
|
||||||
route, popUp -> appState.navigateAndPopUp(route, popUp)
|
appState.navigateAndPopUp(route, popUp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
composable(StudeezDestinations.SPLASH_SCREEN) {
|
composable(StudeezDestinations.SPLASH_SCREEN) {
|
||||||
SplashScreen(openAndPopUp)
|
SplashRoute(openAndPopUp, viewModel = hiltViewModel())
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(StudeezDestinations.LOGIN_SCREEN) {
|
composable(StudeezDestinations.LOGIN_SCREEN) {
|
||||||
LoginScreen(openAndPopUp)
|
LoginRoute(openAndPopUp, viewModel = hiltViewModel())
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(StudeezDestinations.SIGN_UP_SCREEN) {
|
composable(StudeezDestinations.SIGN_UP_SCREEN) {
|
||||||
SignUpScreen(openAndPopUp)
|
SignUpRoute(openAndPopUp, viewModel = hiltViewModel())
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(StudeezDestinations.HOME_SCREEN) {
|
composable(StudeezDestinations.HOME_SCREEN) {
|
||||||
HomeScreen(open, openAndPopUp)
|
HomeRoute(
|
||||||
|
open,
|
||||||
|
openAndPopUp,
|
||||||
|
viewModel = hiltViewModel(),
|
||||||
|
drawerViewModel = drawerViewModel,
|
||||||
|
navBarViewModel = navBarViewModel,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Tasks screen
|
// TODO Tasks screen
|
||||||
// TODO Sessions screen
|
// TODO Sessions screen
|
||||||
|
|
||||||
composable(StudeezDestinations.PROFILE_SCREEN) {
|
composable(StudeezDestinations.PROFILE_SCREEN) {
|
||||||
ProfileScreen(open, openAndPopUp)
|
ProfileRoute(open, openAndPopUp, viewModel = hiltViewModel())
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(StudeezDestinations.TIMER_OVERVIEW_SCREEN) {
|
composable(StudeezDestinations.TIMER_OVERVIEW_SCREEN) {
|
||||||
TimerOverviewScreen(open, openAndPopUp)
|
TimerOverviewRoute(
|
||||||
|
open,
|
||||||
|
openAndPopUp,
|
||||||
|
viewModel = hiltViewModel(),
|
||||||
|
drawerViewModel = drawerViewModel,
|
||||||
|
navBarViewModel = navBarViewModel,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(StudeezDestinations.SESSION_SCREEN) {
|
composable(StudeezDestinations.SESSION_SCREEN) {
|
||||||
SessionScreen(open, openAndPopUp)
|
SessionRoute(open, viewModel = hiltViewModel())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Timers screen
|
// TODO Timers screen
|
||||||
|
@ -129,10 +155,17 @@ fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) {
|
||||||
|
|
||||||
// Edit screens
|
// Edit screens
|
||||||
composable(StudeezDestinations.EDIT_PROFILE_SCREEN) {
|
composable(StudeezDestinations.EDIT_PROFILE_SCREEN) {
|
||||||
EditProfileScreen(goBack, openAndPopUp)
|
EditProfileRoute(goBack, openAndPopUp, viewModel = hiltViewModel())
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(StudeezDestinations.TIMER_SELECTION_SCREEN) {
|
composable(StudeezDestinations.TIMER_SELECTION_SCREEN) {
|
||||||
TimerSelectionScreen(open, openAndPopUp)
|
TimerSelectionRoute(
|
||||||
|
open,
|
||||||
|
openAndPopUp,
|
||||||
|
viewModel = hiltViewModel(),
|
||||||
|
drawerViewModel = drawerViewModel,
|
||||||
|
navBarViewModel = navBarViewModel,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,5 @@
|
||||||
package be.ugent.sel.studeez.activities
|
package be.ugent.sel.studeez.activities
|
||||||
|
|
||||||
import android.media.MediaPlayer
|
|
||||||
import android.media.RingtoneManager
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
|
@ -25,13 +22,7 @@ var onTimerInvisible: Job? = null
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
private var mediaPlayer: MediaPlayer? = null
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
|
||||||
mediaPlayer = MediaPlayer.create(this, uri)
|
|
||||||
mediaPlayer?.isLooping = false
|
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContent {
|
setContent {
|
||||||
StudeezTheme {
|
StudeezTheme {
|
||||||
|
@ -54,16 +45,9 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
mediaPlayer?.stop()
|
|
||||||
onTimerInvisible?.cancel()
|
onTimerInvisible?.cancel()
|
||||||
super.onStart()
|
super.onStart()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
mediaPlayer?.stop()
|
|
||||||
mediaPlayer?.release()
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
@ -2,17 +2,26 @@ 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.*
|
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.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.resources
|
||||||
import be.ugent.sel.studeez.screens.drawer.Drawer
|
import be.ugent.sel.studeez.common.composable.drawer.Drawer
|
||||||
import be.ugent.sel.studeez.screens.navbar.NavigationBar
|
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 be.ugent.sel.studeez.ui.theme.StudeezTheme
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -20,8 +29,8 @@ import kotlinx.coroutines.launch
|
||||||
@Composable
|
@Composable
|
||||||
fun PrimaryScreenTemplate(
|
fun PrimaryScreenTemplate(
|
||||||
title: String,
|
title: String,
|
||||||
open: (String) -> Unit,
|
drawerActions: DrawerActions,
|
||||||
openAndPopUp: (String, String) -> Unit,
|
navigationBarActions: NavigationBarActions,
|
||||||
action: @Composable RowScope.() -> Unit = {},
|
action: @Composable RowScope.() -> Unit = {},
|
||||||
content: @Composable (PaddingValues) -> Unit
|
content: @Composable (PaddingValues) -> Unit
|
||||||
) {
|
) {
|
||||||
|
@ -31,7 +40,8 @@ fun PrimaryScreenTemplate(
|
||||||
Scaffold(
|
Scaffold(
|
||||||
scaffoldState = scaffoldState,
|
scaffoldState = scaffoldState,
|
||||||
|
|
||||||
topBar = { TopAppBar(
|
topBar = {
|
||||||
|
TopAppBar(
|
||||||
title = { Text(text = title) },
|
title = { Text(text = title) },
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = {
|
IconButton(onClick = {
|
||||||
|
@ -44,13 +54,14 @@ fun PrimaryScreenTemplate(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = action
|
actions = action
|
||||||
) },
|
)
|
||||||
|
|
||||||
drawerContent = {
|
|
||||||
Drawer(open, openAndPopUp)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
bottomBar = { NavigationBar(open) },
|
drawerContent = {
|
||||||
|
Drawer(drawerActions)
|
||||||
|
},
|
||||||
|
|
||||||
|
bottomBar = { NavigationBar(navigationBarActions) },
|
||||||
floatingActionButtonPosition = FabPosition.Center,
|
floatingActionButtonPosition = FabPosition.Center,
|
||||||
isFloatingActionButtonDocked = true,
|
isFloatingActionButtonDocked = true,
|
||||||
floatingActionButton = { CollapsedAddButton() }
|
floatingActionButton = { CollapsedAddButton() }
|
||||||
|
@ -65,14 +76,16 @@ fun PrimaryScreenPreview() {
|
||||||
StudeezTheme {
|
StudeezTheme {
|
||||||
PrimaryScreenTemplate(
|
PrimaryScreenTemplate(
|
||||||
"Preview screen",
|
"Preview screen",
|
||||||
{ _ -> {}},
|
DrawerActions({}, {}, {}, {}, {}),
|
||||||
{ _, _ -> {}},
|
NavigationBarActions({}, {}, {}, {}),
|
||||||
{ IconButton(onClick = { /*TODO*/ }) {
|
{
|
||||||
|
IconButton(onClick = { /*TODO*/ }) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Edit,
|
imageVector = Icons.Default.Edit,
|
||||||
contentDescription = "Edit"
|
contentDescription = "Edit"
|
||||||
)
|
)
|
||||||
}}
|
}
|
||||||
|
},
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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) {}
|
||||||
|
}
|
|
@ -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.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.Icon
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.icons.Icons
|
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.res.vectorResource
|
||||||
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 androidx.hilt.navigation.compose.hiltViewModel
|
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
||||||
import be.ugent.sel.studeez.R
|
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
|
||||||
|
|
||||||
|
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
|
@Composable
|
||||||
fun Drawer(
|
fun Drawer(
|
||||||
open: (String) -> Unit,
|
drawerActions: DrawerActions,
|
||||||
openAndPopUp: (String, String) -> Unit,
|
|
||||||
viewModel: DrawerViewModel = hiltViewModel()
|
|
||||||
) {
|
) {
|
||||||
Column (
|
Column(
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
Column (
|
Column(
|
||||||
modifier = Modifier.fillMaxWidth().weight(1f)
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(1f)
|
||||||
) {
|
) {
|
||||||
DrawerEntry(
|
DrawerEntry(
|
||||||
icon = Icons.Default.Home,
|
icon = Icons.Default.Home,
|
||||||
text = resources().getString(R.string.home)
|
text = resources().getString(R.string.home),
|
||||||
) {
|
onClick = drawerActions.onHomeButtonClick,
|
||||||
viewModel.onHomeButtonClick(open)
|
)
|
||||||
}
|
|
||||||
DrawerEntry(
|
DrawerEntry(
|
||||||
icon = ImageVector.vectorResource(id = R.drawable.ic_timer),
|
icon = ImageVector.vectorResource(id = R.drawable.ic_timer),
|
||||||
text = resources().getString(R.string.timers)
|
text = resources().getString(R.string.timers),
|
||||||
) {
|
onClick = drawerActions.onTimersClick,
|
||||||
viewModel.onTimersClick(open)
|
)
|
||||||
}
|
|
||||||
DrawerEntry(
|
DrawerEntry(
|
||||||
icon = Icons.Default.Settings,
|
icon = Icons.Default.Settings,
|
||||||
text = resources().getString(R.string.settings)
|
text = resources().getString(R.string.settings),
|
||||||
) {
|
onClick = drawerActions.onSettingsClick,
|
||||||
viewModel.onSettingsClick(open)
|
)
|
||||||
}
|
|
||||||
DrawerEntry(
|
DrawerEntry(
|
||||||
icon = ImageVector.vectorResource(id = R.drawable.ic_logout),
|
icon = ImageVector.vectorResource(id = R.drawable.ic_logout),
|
||||||
text = resources().getString(R.string.log_out)
|
text = resources().getString(R.string.log_out),
|
||||||
) {
|
onClick = drawerActions.onLogoutClick,
|
||||||
viewModel.onLogoutClick(openAndPopUp)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawerEntry(
|
DrawerEntry(
|
||||||
icon = Icons.Outlined.Info,
|
icon = Icons.Outlined.Info,
|
||||||
text = resources().getString(R.string.about)
|
text = resources().getString(R.string.about),
|
||||||
) {
|
onClick = drawerActions.onAboutClick,
|
||||||
viewModel.onAboutClick(open)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,11 +119,8 @@ fun DrawerEntry(
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun DrawerPreview() {
|
fun DrawerPreview() {
|
||||||
|
val drawerActions = DrawerActions({}, {}, {}, {}, {})
|
||||||
StudeezTheme {
|
StudeezTheme {
|
||||||
Drawer(
|
Drawer(drawerActions)
|
||||||
{ _, -> {} },
|
|
||||||
{ _, _ -> {} },
|
|
||||||
hiltViewModel()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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.AccountDAO
|
||||||
import be.ugent.sel.studeez.domain.LogService
|
import be.ugent.sel.studeez.domain.LogService
|
|
@ -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.BottomNavigation
|
||||||
import androidx.compose.material.BottomNavigationItem
|
import androidx.compose.material.BottomNavigationItem
|
||||||
|
@ -12,16 +12,32 @@ 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 androidx.hilt.navigation.compose.hiltViewModel
|
|
||||||
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(
|
||||||
|
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
|
@Composable
|
||||||
fun NavigationBar(
|
fun NavigationBar(
|
||||||
open: (String) -> Unit,
|
navigationBarActions: NavigationBarActions,
|
||||||
viewModel: NavigationBarViewModel = hiltViewModel()
|
|
||||||
) {
|
) {
|
||||||
// TODO Pass functions and new screens.
|
// TODO Pass functions and new screens.
|
||||||
// TODO Pass which screen is selected.
|
// TODO Pass which screen is selected.
|
||||||
|
@ -33,31 +49,43 @@ fun NavigationBar(
|
||||||
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 = false, // TODO
|
||||||
onClick = { viewModel.onHomeClick(open) }
|
onClick = navigationBarActions.onHomeClick
|
||||||
)
|
)
|
||||||
|
|
||||||
BottomNavigationItem(
|
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)) },
|
label = { Text(text = resources().getString(AppText.tasks)) },
|
||||||
selected = false, // TODO
|
selected = false, // TODO
|
||||||
onClick = { viewModel.onTasksClick(open) }
|
onClick = navigationBarActions.onTasksClick
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hack to space the entries in the navigation bar, make space for fab
|
// Hack to space the entries in the navigation bar, make space for fab
|
||||||
BottomNavigationItem(icon = {}, onClick = {}, selected = false)
|
BottomNavigationItem(icon = {}, onClick = {}, selected = false)
|
||||||
|
|
||||||
BottomNavigationItem(
|
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)) },
|
label = { Text(text = resources().getString(AppText.sessions)) },
|
||||||
selected = false, // TODO
|
selected = false, // TODO
|
||||||
onClick = { viewModel.onSessionsClick(open) }
|
onClick = navigationBarActions.onSessionsClick
|
||||||
)
|
)
|
||||||
|
|
||||||
BottomNavigationItem(
|
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)) },
|
label = { Text(text = resources().getString(AppText.profile)) },
|
||||||
selected = false, // TODO
|
selected = false, // TODO
|
||||||
onClick = { viewModel.onProfileClick(open) }
|
onClick = navigationBarActions.onProfileClick
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -67,9 +95,6 @@ fun NavigationBar(
|
||||||
@Composable
|
@Composable
|
||||||
fun NavigationBarPreview() {
|
fun NavigationBarPreview() {
|
||||||
StudeezTheme {
|
StudeezTheme {
|
||||||
NavigationBar(
|
NavigationBar(NavigationBarActions({}, {}, {}, {}))
|
||||||
{ _ -> {} },
|
|
||||||
hiltViewModel()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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.AccountDAO
|
||||||
import be.ugent.sel.studeez.domain.LogService
|
import be.ugent.sel.studeez.domain.LogService
|
|
@ -6,33 +6,55 @@ import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Person
|
import androidx.compose.material.icons.filled.Person
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
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.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.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.resources
|
import be.ugent.sel.studeez.resources
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HomeScreen(
|
fun HomeRoute(
|
||||||
open: (String) -> Unit,
|
open: (String) -> Unit,
|
||||||
openAndPopUp: (String, 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(
|
PrimaryScreenTemplate(
|
||||||
title = resources().getString(R.string.home),
|
title = resources().getString(R.string.home),
|
||||||
open = open,
|
drawerActions = drawerActions,
|
||||||
openAndPopUp = openAndPopUp,
|
navigationBarActions = navigationBarActions,
|
||||||
action = { FriendsAction() }
|
action = { FriendsAction() }
|
||||||
) {
|
) {
|
||||||
BasicButton(R.string.start_session, Modifier.basicButton()) {
|
BasicButton(R.string.start_session, Modifier.basicButton()) {
|
||||||
viewModel.onStartSessionClick(open)
|
onStartSessionClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun FriendsAction () {
|
fun FriendsAction() {
|
||||||
IconButton(onClick = { /*TODO*/ }) {
|
IconButton(onClick = { /*TODO*/ }) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Person,
|
imageVector = Icons.Default.Person,
|
||||||
|
@ -40,3 +62,13 @@ fun FriendsAction () {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun HomeScreenPreview() {
|
||||||
|
HomeScreen(
|
||||||
|
onStartSessionClick = {},
|
||||||
|
drawerActions = DrawerActions({}, {}, {}, {}, {}),
|
||||||
|
navigationBarActions = NavigationBarActions({}, {}, {}, {})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
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.composable.*
|
||||||
import be.ugent.sel.studeez.common.ext.basicButton
|
import be.ugent.sel.studeez.common.ext.basicButton
|
||||||
import be.ugent.sel.studeez.common.ext.fieldModifier
|
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.resources
|
||||||
import be.ugent.sel.studeez.R.string as AppText
|
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
|
@Composable
|
||||||
fun LoginScreen(
|
fun LoginRoute(
|
||||||
openAndPopUp: (String, String) -> Unit,
|
openAndPopUp: (String, String) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
viewModel: LoginViewModel = hiltViewModel()
|
viewModel: LoginViewModel,
|
||||||
) {
|
) {
|
||||||
val uiState by viewModel.uiState
|
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)) {
|
SimpleScreenTemplate(title = resources().getString(AppText.sign_in)) {
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
@ -35,18 +69,42 @@ fun LoginScreen(
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.Center,
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
EmailField(uiState.email, viewModel::onEmailChange, Modifier.fieldModifier())
|
EmailField(
|
||||||
PasswordField(uiState.password, viewModel::onPasswordChange, Modifier.fieldModifier())
|
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()) {
|
BasicTextButton(
|
||||||
viewModel.onNotAlreadyUser(openAndPopUp)
|
AppText.forgot_password,
|
||||||
}
|
Modifier.textButton(),
|
||||||
|
action = loginScreenActions.onForgotPasswordClick,
|
||||||
BasicTextButton(AppText.forgot_password, Modifier.textButton()) {
|
)
|
||||||
viewModel.onForgotPasswordClick()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun LoginScreenPreview() {
|
||||||
|
LoginScreen(
|
||||||
|
uiState = LoginUiState(),
|
||||||
|
loginScreenActions = LoginScreenActions({}, {}, {}, {}, {})
|
||||||
|
)
|
||||||
|
}
|
|
@ -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)
|
openAndPopUp(SIGN_UP_SCREEN, LOGIN_SCREEN)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,6 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
|
||||||
import be.ugent.sel.studeez.R
|
import be.ugent.sel.studeez.R
|
||||||
import be.ugent.sel.studeez.common.composable.BasicTextButton
|
import be.ugent.sel.studeez.common.composable.BasicTextButton
|
||||||
import be.ugent.sel.studeez.common.composable.LabelledInputField
|
import be.ugent.sel.studeez.common.composable.LabelledInputField
|
||||||
|
@ -14,14 +13,43 @@ import be.ugent.sel.studeez.common.ext.textButton
|
||||||
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
|
||||||
|
|
||||||
|
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
|
@Composable
|
||||||
fun EditProfileScreen(
|
fun EditProfileScreen(
|
||||||
goBack: () -> Unit,
|
goBack: () -> Unit,
|
||||||
openAndPopUp: (String, String) -> Unit,
|
uiState: ProfileEditUiState,
|
||||||
viewModel: ProfileEditViewModel = hiltViewModel()
|
editProfileActions: EditProfileActions,
|
||||||
) {
|
) {
|
||||||
val uiState by viewModel.uiState
|
|
||||||
|
|
||||||
SecondaryScreenTemplate(
|
SecondaryScreenTemplate(
|
||||||
title = resources().getString(R.string.editing_profile),
|
title = resources().getString(R.string.editing_profile),
|
||||||
popUp = goBack
|
popUp = goBack
|
||||||
|
@ -29,16 +57,19 @@ fun EditProfileScreen(
|
||||||
Column {
|
Column {
|
||||||
LabelledInputField(
|
LabelledInputField(
|
||||||
value = uiState.username,
|
value = uiState.username,
|
||||||
onNewValue = viewModel::onUsernameChange,
|
onNewValue = editProfileActions.onUserNameChange,
|
||||||
label = R.string.username
|
label = R.string.username
|
||||||
)
|
)
|
||||||
|
BasicTextButton(
|
||||||
BasicTextButton(text = R.string.save, Modifier.textButton()) {
|
text = R.string.save,
|
||||||
viewModel.onSaveClick()
|
Modifier.textButton(),
|
||||||
}
|
action = editProfileActions.onSaveClick
|
||||||
BasicTextButton(text = R.string.delete_profile, Modifier.textButton()) {
|
)
|
||||||
viewModel.onDeleteClick(openAndPopUp)
|
BasicTextButton(
|
||||||
}
|
text = R.string.delete_profile,
|
||||||
|
Modifier.textButton(),
|
||||||
|
action = editProfileActions.onDeleteClick
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,9 +78,6 @@ fun EditProfileScreen(
|
||||||
@Composable
|
@Composable
|
||||||
fun EditProfileScreenComposable() {
|
fun EditProfileScreenComposable() {
|
||||||
StudeezTheme {
|
StudeezTheme {
|
||||||
EditProfileScreen (
|
EditProfileScreen({}, ProfileEditUiState(), EditProfileActions({}, {}, {}))
|
||||||
{},
|
|
||||||
{_, _ -> {}}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,30 +4,68 @@ import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.IconButton
|
import androidx.compose.material.IconButton
|
||||||
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.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 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.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
|
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
|
@Composable
|
||||||
fun ProfileScreen(
|
fun ProfileScreen(
|
||||||
open: (String) -> Unit,
|
profileActions: ProfileActions,
|
||||||
openAndPopUp: (String, String) -> Unit,
|
drawerActions: DrawerActions,
|
||||||
viewModel: ProfileViewModel = hiltViewModel()
|
navigationBarActions: NavigationBarActions,
|
||||||
) {
|
) {
|
||||||
var username: String? by remember { mutableStateOf("") }
|
var username: String? by remember { mutableStateOf("") }
|
||||||
LaunchedEffect(key1 = Unit) {
|
LaunchedEffect(key1 = Unit) {
|
||||||
username = viewModel.getUsername()
|
username = profileActions.getUsername(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
PrimaryScreenTemplate(
|
PrimaryScreenTemplate(
|
||||||
title = resources().getString(AppText.profile),
|
title = resources().getString(AppText.profile),
|
||||||
open = open,
|
drawerActions = drawerActions,
|
||||||
openAndPopUp = openAndPopUp,
|
navigationBarActions = navigationBarActions,
|
||||||
action = { EditAction { viewModel.onEditProfileClick(open) } }
|
action = { EditAction(onClick = profileActions.onEditProfileClick) }
|
||||||
) {
|
) {
|
||||||
Headline(text = (username ?: resources().getString(R.string.no_username)))
|
Headline(text = (username ?: resources().getString(R.string.no_username)))
|
||||||
}
|
}
|
||||||
|
@ -45,3 +83,13 @@ fun EditAction(
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun ProfileScreenPreview() {
|
||||||
|
ProfileScreen(
|
||||||
|
profileActions = ProfileActions({ null }, {}),
|
||||||
|
drawerActions = DrawerActions({}, {}, {}, {}, {}),
|
||||||
|
navigationBarActions = NavigationBarActions({}, {}, {}, {})
|
||||||
|
)
|
||||||
|
}
|
|
@ -24,34 +24,71 @@ import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import be.ugent.sel.studeez.navigation.StudeezDestinations
|
import be.ugent.sel.studeez.navigation.StudeezDestinations
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
|
||||||
import be.ugent.sel.studeez.R
|
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.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.data.local.models.timer_functional.FunctionalTimer.StudyState
|
||||||
import be.ugent.sel.studeez.resources
|
import be.ugent.sel.studeez.resources
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
import javax.inject.Singleton
|
||||||
import kotlin.time.Duration.Companion.seconds
|
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
|
@Composable
|
||||||
fun SessionScreen(
|
fun SessionRoute(
|
||||||
open: (String) -> Unit,
|
open: (String) -> Unit,
|
||||||
openAndPopUp: (String, String) -> Unit,
|
viewModel: SessionViewModel,
|
||||||
viewModel: SessionViewModel = hiltViewModel()
|
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
||||||
val mediaplayer = MediaPlayer.create(context, uri)
|
val mediaplayer = MediaPlayer.create(context, uri)
|
||||||
mediaplayer.isLooping = false
|
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(
|
Column(
|
||||||
modifier = Modifier.padding(10.dp)
|
modifier = Modifier.padding(10.dp)
|
||||||
) {
|
) {
|
||||||
Timer(viewModel, mediaplayer)
|
Timer(
|
||||||
|
sessionActions = sessionActions
|
||||||
|
)
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
|
@ -61,10 +98,9 @@ fun SessionScreen(
|
||||||
) {
|
) {
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
mediaplayer.stop()
|
sessionActions.releaseMediaPlayer
|
||||||
mediaplayer.release()
|
|
||||||
open(StudeezDestinations.HOME_SCREEN)
|
open(StudeezDestinations.HOME_SCREEN)
|
||||||
InvisibleSessionManager.isSession = false
|
|
||||||
// Vanaf hier ook naar report gaan als "end session" knop word ingedrukt
|
// Vanaf hier ook naar report gaan als "end session" knop word ingedrukt
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -77,7 +113,8 @@ fun SessionScreen(
|
||||||
color = Color.Red,
|
color = Color.Red,
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
fontSize = 18.sp,
|
fontSize = 18.sp,
|
||||||
modifier = Modifier.padding(1.dp)
|
modifier = Modifier
|
||||||
|
.padding(1.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,19 +122,21 @@ fun SessionScreen(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: MediaPlayer) {
|
private fun Timer(
|
||||||
|
sessionActions: SessionActions
|
||||||
|
) {
|
||||||
var tikker by remember { mutableStateOf(false) }
|
var tikker by remember { mutableStateOf(false) }
|
||||||
LaunchedEffect(tikker) {
|
LaunchedEffect(tikker) {
|
||||||
delay(1.seconds)
|
delay(1.seconds)
|
||||||
viewModel.getTimer().tick()
|
sessionActions.getTimer().tick()
|
||||||
tikker = !tikker
|
tikker = !tikker
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewModel.getTimer().hasCurrentCountdownEnded() && !viewModel.getTimer().hasEnded()) {
|
if (sessionActions.getTimer().hasCurrentCountdownEnded() && !sessionActions.getTimer().hasEnded()) {
|
||||||
mediaplayer.start()
|
sessionActions.startMediaPlayer
|
||||||
}
|
}
|
||||||
|
|
||||||
val hms = viewModel.getTimer().getHoursMinutesSeconds()
|
val hms = sessionActions.getTimer().getHoursMinutesSeconds()
|
||||||
Column {
|
Column {
|
||||||
Text(
|
Text(
|
||||||
text = "${hms.hours} : ${hms.minutes} : ${hms.seconds}",
|
text = "${hms.hours} : ${hms.minutes} : ${hms.seconds}",
|
||||||
|
@ -108,12 +147,12 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
fontSize = 40.sp,
|
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.DONE -> resources().getString(R.string.state_done)
|
||||||
StudyState.FOCUS -> resources().getString(R.string.state_focus)
|
StudyState.FOCUS -> resources().getString(R.string.state_focus)
|
||||||
StudyState.BREAK -> resources().getString(R.string.state_take_a_break)
|
StudyState.BREAK -> resources().getString(R.string.state_take_a_break)
|
||||||
StudyState.FOCUS_REMAINING ->
|
StudyState.FOCUS_REMAINING ->
|
||||||
(viewModel.getTimer() as FunctionalPomodoroTimer?)?.breaksRemaining?.let {
|
(sessionActions.getTimer() as FunctionalPomodoroTimer?)?.breaksRemaining?.let {
|
||||||
resources().getQuantityString(R.plurals.state_focus_remaining, it, it)
|
resources().getQuantityString(R.plurals.state_focus_remaining, it, it)
|
||||||
}.toString()
|
}.toString()
|
||||||
}
|
}
|
||||||
|
@ -139,7 +178,7 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me
|
||||||
.background(Color.Blue, RoundedCornerShape(32.dp))
|
.background(Color.Blue, RoundedCornerShape(32.dp))
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = viewModel.getTask(),
|
text = sessionActions.getTask(),
|
||||||
color = Color.White,
|
color = Color.White,
|
||||||
fontSize = 18.sp,
|
fontSize = 18.sp,
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
|
@ -151,6 +190,8 @@ private fun Timer(viewModel: SessionViewModel = hiltViewModel(), mediaplayer: Me
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Singleton
|
||||||
object InvisibleSessionManager {
|
object InvisibleSessionManager {
|
||||||
private lateinit var viewModel: SessionViewModel
|
private lateinit var viewModel: SessionViewModel
|
||||||
private lateinit var mediaplayer: MediaPlayer
|
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" }, {}, {})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,23 +10,64 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
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.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.basicButton
|
||||||
import be.ugent.sel.studeez.common.ext.fieldModifier
|
import be.ugent.sel.studeez.common.ext.fieldModifier
|
||||||
import be.ugent.sel.studeez.common.ext.textButton
|
import be.ugent.sel.studeez.common.ext.textButton
|
||||||
import be.ugent.sel.studeez.resources
|
import be.ugent.sel.studeez.resources
|
||||||
import be.ugent.sel.studeez.R.string as AppText
|
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
|
@Composable
|
||||||
fun SignUpScreen(
|
fun SignUpRoute(
|
||||||
openAndPopUp: (String, String) -> Unit,
|
openAndPopUp: (String, String) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
viewModel: SignUpViewModel = hiltViewModel()
|
viewModel: SignUpViewModel,
|
||||||
) {
|
) {
|
||||||
val uiState by viewModel.uiState
|
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)) {
|
SimpleScreenTemplate(title = resources().getString(AppText.create_account)) {
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
@ -36,40 +77,45 @@ fun SignUpScreen(
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.Center,
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
|
|
||||||
UsernameField(
|
UsernameField(
|
||||||
uiState.username,
|
uiState.username,
|
||||||
viewModel::onUsernameChange,
|
signUpActions.onUserNameChange,
|
||||||
fieldModifier
|
fieldModifier
|
||||||
)
|
)
|
||||||
|
|
||||||
EmailField(
|
EmailField(
|
||||||
uiState.email,
|
uiState.email,
|
||||||
viewModel::onEmailChange,
|
signUpActions.onEmailChange,
|
||||||
fieldModifier
|
fieldModifier
|
||||||
)
|
)
|
||||||
|
|
||||||
PasswordField(
|
PasswordField(
|
||||||
uiState.password,
|
uiState.password,
|
||||||
viewModel::onPasswordChange,
|
signUpActions.onPasswordChange,
|
||||||
fieldModifier
|
fieldModifier
|
||||||
)
|
)
|
||||||
|
|
||||||
RepeatPasswordField(
|
RepeatPasswordField(
|
||||||
uiState.repeatPassword,
|
uiState.repeatPassword,
|
||||||
viewModel::onRepeatPasswordChange,
|
signUpActions.onRepeatPasswordChange,
|
||||||
fieldModifier
|
fieldModifier
|
||||||
)
|
)
|
||||||
|
BasicButton(
|
||||||
BasicButton(AppText.create_account, Modifier.basicButton()) {
|
AppText.create_account,
|
||||||
viewModel.onSignUpClick(openAndPopUp)
|
Modifier.basicButton(),
|
||||||
}
|
onClick = signUpActions.onSignUpClick
|
||||||
|
)
|
||||||
BasicTextButton(AppText.already_user, Modifier.textButton()) {
|
BasicTextButton(
|
||||||
viewModel.onLoginScreenClick(openAndPopUp)
|
AppText.already_user,
|
||||||
|
Modifier.textButton(),
|
||||||
|
action = signUpActions.onLoginClick
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun SignUpPreview() {
|
||||||
|
SignUpScreen(
|
||||||
|
uiState = SignUpUiState(),
|
||||||
|
signUpActions = SignUpActions({}, {}, {}, {}, {}, {})
|
||||||
|
)
|
||||||
}
|
}
|
|
@ -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)
|
openAndPopUp(LOGIN_SCREEN, SIGN_UP_SCREEN)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -15,7 +15,7 @@ import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
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.composable.BasicButton
|
||||||
import be.ugent.sel.studeez.common.ext.basicButton
|
import be.ugent.sel.studeez.common.ext.basicButton
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
@ -24,14 +24,26 @@ import be.ugent.sel.studeez.R.string as AppText
|
||||||
private const val SPLASH_TIMEOUT = 500L
|
private const val SPLASH_TIMEOUT = 500L
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SplashScreen(
|
fun SplashRoute(
|
||||||
openAndPopUp: (String, String) -> Unit,
|
openAndPopUp: (String, String) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
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(
|
Column(
|
||||||
modifier =
|
modifier = modifier
|
||||||
modifier
|
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.background(color = MaterialTheme.colors.background)
|
.background(color = MaterialTheme.colors.background)
|
||||||
|
@ -39,17 +51,37 @@ fun SplashScreen(
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.Center,
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
if (viewModel.showError.value) {
|
if (showError) {
|
||||||
Text(text = stringResource(AppText.generic_error))
|
Text(text = stringResource(AppText.generic_error))
|
||||||
|
BasicButton(
|
||||||
BasicButton(AppText.try_again, Modifier.basicButton()) { viewModel.onAppStart(openAndPopUp) }
|
AppText.try_again,
|
||||||
|
Modifier.basicButton(),
|
||||||
|
onClick = onAppStart,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
CircularProgressIndicator(color = MaterialTheme.colors.onBackground)
|
CircularProgressIndicator(color = MaterialTheme.colors.onBackground)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(true) {
|
LaunchedEffect(true) {
|
||||||
delay(SPLASH_TIMEOUT)
|
delay(SPLASH_TIMEOUT)
|
||||||
viewModel.onAppStart(openAndPopUp)
|
onAppStart()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun SplashPreview() {
|
||||||
|
SplashScreen(
|
||||||
|
onAppStart = {},
|
||||||
|
showError = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun SplashErrorPreview() {
|
||||||
|
SplashScreen(
|
||||||
|
onAppStart = {},
|
||||||
|
showError = true,
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,122 +1,118 @@
|
||||||
package be.ugent.sel.studeez.screens.timer_overview
|
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.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
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.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
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.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
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 androidx.compose.ui.unit.sp
|
|
||||||
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.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.StealthButton
|
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.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
|
||||||
import be.ugent.sel.studeez.resources
|
import be.ugent.sel.studeez.resources
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
|
||||||
|
data class TimerOverviewActions(
|
||||||
|
val getUserTimers: () -> Flow<List<TimerInfo>>,
|
||||||
|
val getDefaultTimers: () -> List<TimerInfo>,
|
||||||
|
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
|
@Composable
|
||||||
fun TimerOverviewScreen(
|
fun TimerOverviewScreen(
|
||||||
open: (String) -> Unit,
|
timerOverviewActions: TimerOverviewActions,
|
||||||
openAndPopUp: (String, String) -> Unit,
|
drawerActions: DrawerActions,
|
||||||
viewModel: TimerOverviewViewModel = hiltViewModel()
|
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(
|
PrimaryScreenTemplate(
|
||||||
title = resources().getString(R.string.timers),
|
title = resources().getString(R.string.timers),
|
||||||
open = open,
|
drawerActions = drawerActions,
|
||||||
openAndPopUp = openAndPopUp
|
navigationBarActions = navigationBarActions,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
verticalArrangement = Arrangement.spacedBy(7.dp)
|
verticalArrangement = Arrangement.spacedBy(7.dp)
|
||||||
) {
|
) {
|
||||||
// Default Timers, cannot be edited
|
// Default Timers, cannot be edited
|
||||||
items(viewModel.getDefaultTimers()) {
|
items(timerOverviewActions.getDefaultTimers()) {
|
||||||
TimerEntry(timerInfo = it, canDisplay = false)
|
TimerEntry(timerInfo = it) {}
|
||||||
|
}
|
||||||
|
// User timers, can be edited
|
||||||
|
items(timers.value) { timerInfo ->
|
||||||
|
TimerEntry(
|
||||||
|
timerInfo = timerInfo,
|
||||||
|
) {
|
||||||
|
StealthButton(
|
||||||
|
text = R.string.edit,
|
||||||
|
onClick = { timerOverviewActions.onEditClick(timerInfo) }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// User timers, can be edited
|
|
||||||
items(timers.value) {
|
|
||||||
TimerEntry(timerInfo = it, true, R.string.edit) { timerInfo ->
|
|
||||||
viewModel.update(timerInfo)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BasicButton(R.string.add_timer, Modifier.basicButton()) {
|
BasicButton(R.string.add_timer, Modifier.basicButton()) {
|
||||||
// TODO
|
// 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
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun TimerEntryPreview() {
|
fun TimerOverviewPreview() {
|
||||||
val timerInfo = CustomTimerInfo(
|
val customTimer = CustomTimerInfo(
|
||||||
"my preview timer",
|
"my preview timer", "This is the description of the timer", 60
|
||||||
"This is the description of the timer",
|
)
|
||||||
60
|
TimerOverviewScreen(
|
||||||
|
timerOverviewActions = TimerOverviewActions(
|
||||||
|
{ flowOf() },
|
||||||
|
{ listOf(customTimer, customTimer) },
|
||||||
|
{}),
|
||||||
|
drawerActions = DrawerActions({}, {}, {}, {}, {}),
|
||||||
|
navigationBarActions = NavigationBarActions({}, {}, {}, {})
|
||||||
)
|
)
|
||||||
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) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -3,42 +3,89 @@ package be.ugent.sel.studeez.screens.timer_selection
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
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.*
|
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.compose.ui.unit.dp
|
||||||
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.PrimaryScreenTemplate
|
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.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<List<TimerInfo>>,
|
||||||
|
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
|
@Composable
|
||||||
fun TimerSelectionScreen(
|
fun TimerSelectionScreen(
|
||||||
open: (String) -> Unit,
|
timerSelectionActions: TimerSelectionActions,
|
||||||
openAndPopUp: (String, String) -> Unit,
|
drawerActions: DrawerActions,
|
||||||
viewModel: TimerSelectionViewModel = hiltViewModel()
|
navigationBarActions: NavigationBarActions,
|
||||||
) {
|
) {
|
||||||
|
val timers = timerSelectionActions.getAllTimers().collectAsState(initial = emptyList())
|
||||||
val timers = viewModel.getAllTimers().collectAsState(initial = emptyList())
|
|
||||||
|
|
||||||
PrimaryScreenTemplate(
|
PrimaryScreenTemplate(
|
||||||
title = resources().getString(R.string.timers),
|
title = resources().getString(R.string.timers),
|
||||||
open = open,
|
drawerActions = drawerActions,
|
||||||
openAndPopUp = openAndPopUp,
|
navigationBarActions = navigationBarActions,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
LazyColumn(verticalArrangement = Arrangement.spacedBy(7.dp)) {
|
LazyColumn(verticalArrangement = Arrangement.spacedBy(7.dp)) {
|
||||||
|
|
||||||
// All timers
|
// All timers
|
||||||
items(timers.value) {
|
items(timers.value) { timerInfo ->
|
||||||
TimerEntry(
|
TimerEntry(
|
||||||
timerInfo = it,
|
timerInfo = timerInfo,
|
||||||
canDisplay = true,
|
) {
|
||||||
buttonName = R.string.start
|
StealthButton(
|
||||||
) { timerInfo ->
|
text = R.string.start,
|
||||||
viewModel.startSession(open, timerInfo)
|
onClick = { timerSelectionActions.startSession(timerInfo) }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun TimerSelectionPreview() {
|
||||||
|
TimerSelectionScreen(
|
||||||
|
timerSelectionActions = TimerSelectionActions({ flowOf() }, {}),
|
||||||
|
drawerActions = DrawerActions({}, {}, {}, {}, {}),
|
||||||
|
navigationBarActions = NavigationBarActions({}, {}, {}, {}),
|
||||||
|
)
|
||||||
|
}
|
Reference in a new issue