#52 Move drawer to toolbar

This commit is contained in:
Tibo De Peuter 2023-04-12 15:08:26 +02:00
parent 85e1b55507
commit 307f9e0d70
7 changed files with 88 additions and 51 deletions

View file

@ -16,7 +16,7 @@ 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 import be.ugent.sel.studeez.screens.drawer.Drawer
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.HomeScreen
@ -32,10 +32,6 @@ fun StudeezApp() {
Surface(color = MaterialTheme.colors.background) { Surface(color = MaterialTheme.colors.background) {
val appState = rememberAppState() val appState = rememberAppState()
ModalDrawer(
drawerContent = { Drawer({ route, popUp -> appState.navigateAndPopUp(route, popUp) }) },
drawerState = appState.drawerState
) {
Scaffold( Scaffold(
snackbarHost = { snackbarHost = {
SnackbarHost( SnackbarHost(
@ -59,19 +55,17 @@ fun StudeezApp() {
} }
} }
} }
}
@Composable @Composable
fun rememberAppState( fun rememberAppState(
scaffoldState: ScaffoldState = rememberScaffoldState(), scaffoldState: ScaffoldState = rememberScaffoldState(),
drawerState: DrawerState = rememberDrawerState(initialValue = DrawerValue.Closed),
navController: NavHostController = rememberNavController(), navController: NavHostController = rememberNavController(),
snackbarManager: SnackbarManager = SnackbarManager, snackbarManager: SnackbarManager = SnackbarManager,
resources: Resources = resources(), resources: Resources = resources(),
coroutineScope: CoroutineScope = rememberCoroutineScope() coroutineScope: CoroutineScope = rememberCoroutineScope()
) = ) =
remember(scaffoldState, navController, snackbarManager, resources, coroutineScope) { remember(scaffoldState, navController, snackbarManager, resources, coroutineScope) {
StudeezAppstate(scaffoldState, drawerState, navController, snackbarManager, resources, coroutineScope) StudeezAppstate(scaffoldState, navController, snackbarManager, resources, coroutineScope)
} }
@Composable @Composable
@ -97,8 +91,7 @@ fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) {
composable(StudeezDestinations.HOME_SCREEN) { composable(StudeezDestinations.HOME_SCREEN) {
HomeScreen( HomeScreen(
openAndPopUp = { route, popUp -> appState.navigateAndPopUp(route, popUp) }, openAndPopUp = { route, popUp -> appState.navigateAndPopUp(route, popUp) }
openDrawer = { appState.openDrawer() }
) )
} }
} }

View file

@ -1,7 +1,6 @@
package be.ugent.sel.studeez package be.ugent.sel.studeez
import android.content.res.Resources import android.content.res.Resources
import androidx.compose.material.DrawerState
import androidx.compose.material.ScaffoldState import androidx.compose.material.ScaffoldState
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
@ -14,14 +13,11 @@ import kotlinx.coroutines.launch
@Stable @Stable
class StudeezAppstate( class StudeezAppstate(
val scaffoldState: ScaffoldState, val scaffoldState: ScaffoldState,
val drawerState: DrawerState,
val navController: NavHostController, val navController: NavHostController,
private val snackbarManager: SnackbarManager, private val snackbarManager: SnackbarManager,
private val resources: Resources, private val resources: Resources,
coroutineScope: CoroutineScope coroutineScope: CoroutineScope
) { ) {
val coroutineScope: CoroutineScope = coroutineScope
init { init {
coroutineScope.launch { coroutineScope.launch {
snackbarManager.snackbarMessages.filterNotNull().collect { snackbarMessage -> snackbarManager.snackbarMessages.filterNotNull().collect { snackbarMessage ->
@ -52,8 +48,4 @@ class StudeezAppstate(
popUpTo(0) { inclusive = true } popUpTo(0) { inclusive = true }
} }
} }
fun openDrawer() {
coroutineScope.launch { drawerState.open() }
}
} }

View file

@ -6,8 +6,13 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Menu import androidx.compose.material.icons.filled.Menu
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import be.ugent.sel.studeez.screens.drawer.Drawer
import be.ugent.sel.studeez.screens.drawer.StudeezDrawerState
import be.ugent.sel.studeez.ui.theme.StudeezTheme import be.ugent.sel.studeez.ui.theme.StudeezTheme
import kotlinx.coroutines.CoroutineScope
// TODO Add option for button in top right corner as extra button // TODO Add option for button in top right corner as extra button
@ -15,20 +20,29 @@ import be.ugent.sel.studeez.ui.theme.StudeezTheme
// Contains floatingActionButton and bottom bar, used in the main four screens. // Contains floatingActionButton and bottom bar, used in the main four screens.
fun PrimaryScreenToolbar( fun PrimaryScreenToolbar(
title: String, title: String,
openDrawer: () -> Unit, openAndPopUp: (String, String) -> Unit,
content: @Composable (PaddingValues) -> Unit content: @Composable (PaddingValues) -> Unit
) { ) {
val primaryScreenToolbarState = rememberPrimaryScreenToolbarState()
Scaffold( Scaffold(
scaffoldState = primaryScreenToolbarState.scaffoldState,
// Everything at the top of the screen // Everything at the top of the screen
topBar = { TopAppBar( topBar = { TopAppBar(
title = { Text(text = title) }, title = { Text(text = title) },
navigationIcon = { navigationIcon = {
IconButton(onClick = { openDrawer() }) { IconButton(onClick = { primaryScreenToolbarState.openDrawer() }) {
Icon(imageVector = Icons.Default.Menu, contentDescription = "Menu") Icon(imageVector = Icons.Default.Menu, contentDescription = "Menu")
} }
} }
) }, ) },
// Drawer
drawerContent = @Composable {
Drawer(openAndPopUp)
},
// Everything at the bottom of the screen // Everything at the bottom of the screen
bottomBar = { NavigationBar() }, // TODO Pass arguments so that the current tab etc can be shown bottomBar = { NavigationBar() }, // TODO Pass arguments so that the current tab etc can be shown
floatingActionButtonPosition = FabPosition.Center, floatingActionButtonPosition = FabPosition.Center,
@ -39,10 +53,28 @@ fun PrimaryScreenToolbar(
} }
} }
@Composable
fun rememberPrimaryScreenToolbarState(
scaffoldState: ScaffoldState = rememberScaffoldState(),
coroutineScope: CoroutineScope = rememberCoroutineScope()
) = remember(scaffoldState, coroutineScope) {
StudeezDrawerState(scaffoldState, coroutineScope)
}
@Preview
@Composable
fun PrimaryScreenToolbarPreview() {
StudeezTheme { PrimaryScreenToolbar(
"Preview screen",
{ a, b -> {}}
) {} }
}
@Composable @Composable
// Does not contain floatingActionButton and bottom bar, used in all the other screens // Does not contain floatingActionButton and bottom bar, used in all the other screens
fun SecondaryScreenToolbar( fun SecondaryScreenToolbar(
title: String, title: String,
popUp: () -> Unit,
content: @Composable (PaddingValues) -> Unit content: @Composable (PaddingValues) -> Unit
) { ) {
Scaffold( Scaffold(

View file

@ -1,4 +1,4 @@
package be.ugent.sel.studeez.common.composable package be.ugent.sel.studeez.screens.drawer
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -7,17 +7,19 @@ import androidx.compose.material.Divider
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
import androidx.compose.material.icons.filled.* import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.outlined.Info
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview 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.resources import be.ugent.sel.studeez.resources
import be.ugent.sel.studeez.screens.drawer.DrawerViewModel
import be.ugent.sel.studeez.ui.theme.StudeezTheme import be.ugent.sel.studeez.ui.theme.StudeezTheme
@ -27,7 +29,7 @@ fun Drawer(
viewModel: DrawerViewModel = hiltViewModel() viewModel: DrawerViewModel = hiltViewModel()
) { ) {
Column(modifier = Modifier.fillMaxSize()) { Column(modifier = Modifier.fillMaxSize()) {
LoggedInUserCard() LoggedInUserCard(viewModel.currentUser)
Divider() Divider()
@ -38,7 +40,7 @@ fun Drawer(
// TODO Go to home // TODO Go to home
} }
DrawerEntry( DrawerEntry(
icon = Icons.Default.LocationOn, // TODO Fix icon icon = ImageVector.vectorResource(id = R.drawable.ic_timer),
text = resources().getString(R.string.timers) text = resources().getString(R.string.timers)
) { ) {
// TODO Go to timers // TODO Go to timers
@ -50,14 +52,14 @@ fun Drawer(
// TODO Go to settings // TODO Go to settings
} }
DrawerEntry( DrawerEntry(
icon = Icons.Default.AccountBox, // TODO Fix icon icon = ImageVector.vectorResource(id = R.drawable.ic_logout),
text = resources().getString(R.string.log_out) text = resources().getString(R.string.log_out)
) { ) {
viewModel.onLogoutClick(openAndPopup) viewModel.onLogoutClick(openAndPopup)
} }
DrawerEntry( DrawerEntry(
icon = Icons.Default.Info, icon = Icons.Outlined.Info,
text = resources().getString(R.string.about) text = resources().getString(R.string.about)
) { ) {
// TODO Go to about // TODO Go to about
@ -87,7 +89,9 @@ fun DrawerEntry(
} }
@Composable @Composable
fun LoggedInUserCard() { fun LoggedInUserCard(
username: String
) {
Column() { Column() {
// TODO Profile picture of current user // TODO Profile picture of current user
Image( Image(
@ -95,8 +99,7 @@ fun LoggedInUserCard() {
contentDescription = stringResource(R.string.profile_picture_description) contentDescription = stringResource(R.string.profile_picture_description)
) )
// TODO Username Text(text = username)
Text(text = "Username todo")
// TODO Description of user (normal user or something else?) // TODO Description of user (normal user or something else?)
Text(text = stringResource(id = R.string.user_description)) Text(text = stringResource(id = R.string.user_description))
@ -115,6 +118,6 @@ fun DrawerPreview() {
@Composable @Composable
fun LoggedInUserCardPreview() { fun LoggedInUserCardPreview() {
StudeezTheme { StudeezTheme {
LoggedInUserCard() LoggedInUserCard("John Doe")
} }
} }

View file

@ -13,6 +13,8 @@ class DrawerViewModel @Inject constructor(
private val accountDAO: AccountDAO, private val accountDAO: AccountDAO,
logService: LogService logService: LogService
): StudeezViewModel(logService) { ): StudeezViewModel(logService) {
val currentUser: String = accountDAO.currentUserId
fun onLogoutClick(openAndPopup: (String, String) -> Unit) { fun onLogoutClick(openAndPopup: (String, String) -> Unit) {
launchCatching { launchCatching {
accountDAO.signOut() accountDAO.signOut()

View file

@ -0,0 +1,16 @@
package be.ugent.sel.studeez.screens.drawer
import androidx.compose.material.ScaffoldState
import androidx.compose.runtime.Stable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@Stable
class StudeezDrawerState(
val scaffoldState: ScaffoldState,
private val coroutineScope: CoroutineScope
) {
fun openDrawer() {
coroutineScope.launch { scaffoldState.drawerState.open() }
}
}

View file

@ -12,13 +12,12 @@ import be.ugent.sel.studeez.resources
@Composable @Composable
fun HomeScreen( fun HomeScreen(
openAndPopUp: (String, String) -> Unit, openAndPopUp: (String, String) -> Unit,
openDrawer: () -> Unit,
viewModel: HomeViewModel = hiltViewModel() viewModel: HomeViewModel = hiltViewModel()
) { ) {
PrimaryScreenToolbar( PrimaryScreenToolbar(
title = resources().getString(R.string.home), title = resources().getString(R.string.home),
openDrawer = { openDrawer() } openAndPopUp = openAndPopUp
) { ) {
BasicButton(R.string.start_session, Modifier.basicButton()) { BasicButton(R.string.start_session, Modifier.basicButton()) {
viewModel.onStartSessionClick(openAndPopUp) viewModel.onStartSessionClick(openAndPopUp)