#52 Move drawer to toolbar
This commit is contained in:
		
							parent
							
								
									85e1b55507
								
							
						
					
					
						commit
						307f9e0d70
					
				
					 7 changed files with 88 additions and 51 deletions
				
			
		|  | @ -16,7 +16,7 @@ import androidx.navigation.NavHostController | |||
| import androidx.navigation.compose.NavHost | ||||
| import androidx.navigation.compose.composable | ||||
| import androidx.navigation.compose.rememberNavController | ||||
| import be.ugent.sel.studeez.common.composable.Drawer | ||||
| import be.ugent.sel.studeez.screens.drawer.Drawer | ||||
| import be.ugent.sel.studeez.common.snackbar.SnackbarManager | ||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations | ||||
| import be.ugent.sel.studeez.screens.home.HomeScreen | ||||
|  | @ -32,29 +32,24 @@ fun StudeezApp() { | |||
|         Surface(color = MaterialTheme.colors.background) { | ||||
|             val appState = rememberAppState() | ||||
| 
 | ||||
|             ModalDrawer( | ||||
|                 drawerContent = { Drawer({ route, popUp -> appState.navigateAndPopUp(route, popUp) }) }, | ||||
|                 drawerState = appState.drawerState | ||||
|             ) { | ||||
|                 Scaffold( | ||||
|                     snackbarHost = { | ||||
|                         SnackbarHost( | ||||
|                             hostState = it, | ||||
|                             modifier = Modifier.padding(8.dp), | ||||
|                             snackbar = { snackbarData -> | ||||
|                                 Snackbar(snackbarData, contentColor = MaterialTheme.colors.onPrimary) | ||||
|                             } | ||||
|                         ) | ||||
|                     }, | ||||
|                     scaffoldState = appState.scaffoldState | ||||
|                 ) { innerPaddingModifier -> | ||||
|                     NavHost( | ||||
|                         navController = appState.navController, | ||||
|                         startDestination = StudeezDestinations.SPLASH_SCREEN, | ||||
|                         modifier = Modifier.padding(innerPaddingModifier) | ||||
|                     ) { | ||||
|                         studeezGraph(appState) | ||||
|                     } | ||||
|             Scaffold( | ||||
|                 snackbarHost = { | ||||
|                     SnackbarHost( | ||||
|                         hostState = it, | ||||
|                         modifier = Modifier.padding(8.dp), | ||||
|                         snackbar = { snackbarData -> | ||||
|                             Snackbar(snackbarData, contentColor = MaterialTheme.colors.onPrimary) | ||||
|                         } | ||||
|                     ) | ||||
|                 }, | ||||
|                 scaffoldState = appState.scaffoldState | ||||
|             ) { innerPaddingModifier -> | ||||
|                 NavHost( | ||||
|                     navController = appState.navController, | ||||
|                     startDestination = StudeezDestinations.SPLASH_SCREEN, | ||||
|                     modifier = Modifier.padding(innerPaddingModifier) | ||||
|                 ) { | ||||
|                     studeezGraph(appState) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | @ -64,14 +59,13 @@ fun StudeezApp() { | |||
| @Composable | ||||
| fun rememberAppState( | ||||
|     scaffoldState: ScaffoldState = rememberScaffoldState(), | ||||
|     drawerState: DrawerState = rememberDrawerState(initialValue = DrawerValue.Closed), | ||||
|     navController: NavHostController = rememberNavController(), | ||||
|     snackbarManager: SnackbarManager = SnackbarManager, | ||||
|     resources: Resources = resources(), | ||||
|     coroutineScope: CoroutineScope = rememberCoroutineScope() | ||||
| ) = | ||||
|     remember(scaffoldState, navController, snackbarManager, resources, coroutineScope) { | ||||
|         StudeezAppstate(scaffoldState, drawerState, navController, snackbarManager, resources, coroutineScope) | ||||
|         StudeezAppstate(scaffoldState, navController, snackbarManager, resources, coroutineScope) | ||||
|     } | ||||
| 
 | ||||
| @Composable | ||||
|  | @ -97,8 +91,7 @@ fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) { | |||
| 
 | ||||
|     composable(StudeezDestinations.HOME_SCREEN) { | ||||
|         HomeScreen( | ||||
|             openAndPopUp = { route, popUp -> appState.navigateAndPopUp(route, popUp) }, | ||||
|             openDrawer = { appState.openDrawer() } | ||||
|             openAndPopUp = { route, popUp -> appState.navigateAndPopUp(route, popUp) } | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|  | @ -1,7 +1,6 @@ | |||
| package be.ugent.sel.studeez | ||||
| 
 | ||||
| import android.content.res.Resources | ||||
| import androidx.compose.material.DrawerState | ||||
| import androidx.compose.material.ScaffoldState | ||||
| import androidx.compose.runtime.Stable | ||||
| import androidx.navigation.NavHostController | ||||
|  | @ -14,14 +13,11 @@ import kotlinx.coroutines.launch | |||
| @Stable | ||||
| class StudeezAppstate( | ||||
|     val scaffoldState: ScaffoldState, | ||||
|     val drawerState: DrawerState, | ||||
|     val navController: NavHostController, | ||||
|     private val snackbarManager: SnackbarManager, | ||||
|     private val resources: Resources, | ||||
|     coroutineScope: CoroutineScope | ||||
| ) { | ||||
|     val coroutineScope: CoroutineScope = coroutineScope | ||||
| 
 | ||||
|     init { | ||||
|         coroutineScope.launch { | ||||
|             snackbarManager.snackbarMessages.filterNotNull().collect { snackbarMessage -> | ||||
|  | @ -52,8 +48,4 @@ class StudeezAppstate( | |||
|             popUpTo(0) { inclusive = true } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fun openDrawer() { | ||||
|         coroutineScope.launch { drawerState.open() } | ||||
|     } | ||||
| } | ||||
|  | @ -6,8 +6,13 @@ import androidx.compose.material.icons.Icons | |||
| import androidx.compose.material.icons.filled.ArrowBack | ||||
| import androidx.compose.material.icons.filled.Menu | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.runtime.remember | ||||
| import androidx.compose.runtime.rememberCoroutineScope | ||||
| 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 kotlinx.coroutines.CoroutineScope | ||||
| 
 | ||||
| // 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. | ||||
| fun PrimaryScreenToolbar( | ||||
|     title: String, | ||||
|     openDrawer: () -> Unit, | ||||
|     openAndPopUp: (String, String) -> Unit, | ||||
|     content: @Composable (PaddingValues) -> Unit | ||||
| ) { | ||||
|     val primaryScreenToolbarState = rememberPrimaryScreenToolbarState() | ||||
| 
 | ||||
|     Scaffold( | ||||
|         scaffoldState = primaryScreenToolbarState.scaffoldState, | ||||
| 
 | ||||
|         // Everything at the top of the screen | ||||
|         topBar = { TopAppBar( | ||||
|             title = { Text(text = title) }, | ||||
|             navigationIcon = { | ||||
|                 IconButton(onClick = { openDrawer() }) { | ||||
|                 IconButton(onClick = { primaryScreenToolbarState.openDrawer() }) { | ||||
|                     Icon(imageVector = Icons.Default.Menu, contentDescription = "Menu") | ||||
|                 } | ||||
|             } | ||||
|         ) }, | ||||
| 
 | ||||
|         // Drawer | ||||
|         drawerContent = @Composable { | ||||
|             Drawer(openAndPopUp) | ||||
|         }, | ||||
| 
 | ||||
|         // Everything at the bottom of the screen | ||||
|         bottomBar = { NavigationBar() }, // TODO Pass arguments so that the current tab etc can be shown | ||||
|         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 | ||||
| // Does not contain floatingActionButton and bottom bar, used in all the other screens | ||||
| fun SecondaryScreenToolbar( | ||||
|     title: String, | ||||
|     popUp: () -> Unit, | ||||
|     content: @Composable (PaddingValues) -> Unit | ||||
| ) { | ||||
|     Scaffold( | ||||
|  |  | |||
|  | @ -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.clickable | ||||
|  | @ -7,17 +7,19 @@ import androidx.compose.material.Divider | |||
| import androidx.compose.material.Icon | ||||
| import androidx.compose.material.Text | ||||
| 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.ui.Modifier | ||||
| import androidx.compose.ui.graphics.vector.ImageVector | ||||
| import androidx.compose.ui.res.painterResource | ||||
| import androidx.compose.ui.res.stringResource | ||||
| import androidx.compose.ui.res.vectorResource | ||||
| import androidx.compose.ui.tooling.preview.Preview | ||||
| import androidx.hilt.navigation.compose.hiltViewModel | ||||
| import be.ugent.sel.studeez.R | ||||
| import be.ugent.sel.studeez.resources | ||||
| import be.ugent.sel.studeez.screens.drawer.DrawerViewModel | ||||
| import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||
| 
 | ||||
| 
 | ||||
|  | @ -27,7 +29,7 @@ fun Drawer( | |||
|     viewModel: DrawerViewModel = hiltViewModel() | ||||
| ) { | ||||
|     Column(modifier = Modifier.fillMaxSize()) { | ||||
|         LoggedInUserCard() | ||||
|         LoggedInUserCard(viewModel.currentUser) | ||||
| 
 | ||||
|         Divider() | ||||
| 
 | ||||
|  | @ -38,7 +40,7 @@ fun Drawer( | |||
|             // TODO Go to home | ||||
|         } | ||||
|         DrawerEntry( | ||||
|             icon = Icons.Default.LocationOn, // TODO Fix icon | ||||
|             icon = ImageVector.vectorResource(id = R.drawable.ic_timer), | ||||
|             text = resources().getString(R.string.timers) | ||||
|         ) { | ||||
|             // TODO Go to timers | ||||
|  | @ -50,14 +52,14 @@ fun Drawer( | |||
|             // TODO Go to settings | ||||
|         } | ||||
|         DrawerEntry( | ||||
|             icon = Icons.Default.AccountBox, // TODO Fix icon | ||||
|             icon = ImageVector.vectorResource(id = R.drawable.ic_logout), | ||||
|             text = resources().getString(R.string.log_out) | ||||
|         ) { | ||||
|             viewModel.onLogoutClick(openAndPopup) | ||||
|         } | ||||
| 
 | ||||
|         DrawerEntry( | ||||
|             icon = Icons.Default.Info, | ||||
|             icon = Icons.Outlined.Info, | ||||
|             text = resources().getString(R.string.about) | ||||
|         ) { | ||||
|             // TODO Go to about | ||||
|  | @ -87,7 +89,9 @@ fun DrawerEntry( | |||
| } | ||||
| 
 | ||||
| @Composable | ||||
| fun LoggedInUserCard() { | ||||
| fun LoggedInUserCard( | ||||
|     username: String | ||||
| ) { | ||||
|     Column() { | ||||
|         // TODO Profile picture of current user | ||||
|         Image( | ||||
|  | @ -95,8 +99,7 @@ fun LoggedInUserCard() { | |||
|             contentDescription = stringResource(R.string.profile_picture_description) | ||||
|         ) | ||||
| 
 | ||||
|         // TODO Username | ||||
|         Text(text = "Username todo") | ||||
|         Text(text = username) | ||||
| 
 | ||||
|         // TODO Description of user (normal user or something else?) | ||||
|         Text(text = stringResource(id = R.string.user_description)) | ||||
|  | @ -115,6 +118,6 @@ fun DrawerPreview() { | |||
| @Composable | ||||
| fun LoggedInUserCardPreview() { | ||||
|     StudeezTheme { | ||||
|         LoggedInUserCard() | ||||
|         LoggedInUserCard("John Doe") | ||||
|     } | ||||
| } | ||||
|  | @ -13,6 +13,8 @@ class DrawerViewModel @Inject constructor( | |||
|     private val accountDAO: AccountDAO, | ||||
|     logService: LogService | ||||
| ): StudeezViewModel(logService) { | ||||
|     val currentUser: String = accountDAO.currentUserId | ||||
| 
 | ||||
|     fun onLogoutClick(openAndPopup: (String, String) -> Unit) { | ||||
|         launchCatching { | ||||
|             accountDAO.signOut() | ||||
|  |  | |||
|  | @ -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() } | ||||
|     } | ||||
| } | ||||
|  | @ -12,13 +12,12 @@ import be.ugent.sel.studeez.resources | |||
| @Composable | ||||
| fun HomeScreen( | ||||
|     openAndPopUp: (String, String) -> Unit, | ||||
|     openDrawer: () -> Unit, | ||||
|     viewModel: HomeViewModel = hiltViewModel() | ||||
| ) { | ||||
| 
 | ||||
|     PrimaryScreenToolbar( | ||||
|         title = resources().getString(R.string.home), | ||||
|         openDrawer = { openDrawer() } | ||||
|         openAndPopUp = openAndPopUp | ||||
|     ) { | ||||
|         BasicButton(R.string.start_session, Modifier.basicButton()) { | ||||
|             viewModel.onStartSessionClick(openAndPopUp) | ||||
|  |  | |||
		Reference in a new issue