#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.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,29 +32,24 @@ fun StudeezApp() { | ||||||
|         Surface(color = MaterialTheme.colors.background) { |         Surface(color = MaterialTheme.colors.background) { | ||||||
|             val appState = rememberAppState() |             val appState = rememberAppState() | ||||||
| 
 | 
 | ||||||
|             ModalDrawer( |             Scaffold( | ||||||
|                 drawerContent = { Drawer({ route, popUp -> appState.navigateAndPopUp(route, popUp) }) }, |                 snackbarHost = { | ||||||
|                 drawerState = appState.drawerState |                     SnackbarHost( | ||||||
|             ) { |                         hostState = it, | ||||||
|                 Scaffold( |                         modifier = Modifier.padding(8.dp), | ||||||
|                     snackbarHost = { |                         snackbar = { snackbarData -> | ||||||
|                         SnackbarHost( |                             Snackbar(snackbarData, contentColor = MaterialTheme.colors.onPrimary) | ||||||
|                             hostState = it, |                         } | ||||||
|                             modifier = Modifier.padding(8.dp), |                     ) | ||||||
|                             snackbar = { snackbarData -> |                 }, | ||||||
|                                 Snackbar(snackbarData, contentColor = MaterialTheme.colors.onPrimary) |                 scaffoldState = appState.scaffoldState | ||||||
|                             } |             ) { innerPaddingModifier -> | ||||||
|                         ) |                 NavHost( | ||||||
|                     }, |                     navController = appState.navController, | ||||||
|                     scaffoldState = appState.scaffoldState |                     startDestination = StudeezDestinations.SPLASH_SCREEN, | ||||||
|                 ) { innerPaddingModifier -> |                     modifier = Modifier.padding(innerPaddingModifier) | ||||||
|                     NavHost( |                 ) { | ||||||
|                         navController = appState.navController, |                     studeezGraph(appState) | ||||||
|                         startDestination = StudeezDestinations.SPLASH_SCREEN, |  | ||||||
|                         modifier = Modifier.padding(innerPaddingModifier) |  | ||||||
|                     ) { |  | ||||||
|                         studeezGraph(appState) |  | ||||||
|                     } |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | @ -64,14 +59,13 @@ 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() } |  | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -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() } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  | @ -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( | ||||||
|  |  | ||||||
|  | @ -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") | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -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() | ||||||
|  |  | ||||||
|  | @ -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 | @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) | ||||||
|  |  | ||||||
		Reference in a new issue