Add basic sidemenu
This commit is contained in:
		
							parent
							
								
									d9a96e92ca
								
							
						
					
					
						commit
						18d8108779
					
				
					 5 changed files with 111 additions and 30 deletions
				
			
		|  | @ -16,6 +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.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 | ||||||
|  | @ -31,6 +32,10 @@ fun StudeezApp() { | ||||||
|         Surface(color = MaterialTheme.colors.background) { |         Surface(color = MaterialTheme.colors.background) { | ||||||
|             val appState = rememberAppState() |             val appState = rememberAppState() | ||||||
| 
 | 
 | ||||||
|  |             ModalDrawer( | ||||||
|  |                 drawerContent = { Drawer() }, | ||||||
|  |                 drawerState = appState.drawerState | ||||||
|  |             ) { | ||||||
|                 Scaffold( |                 Scaffold( | ||||||
|                     snackbarHost = { |                     snackbarHost = { | ||||||
|                         SnackbarHost( |                         SnackbarHost( | ||||||
|  | @ -53,18 +58,20 @@ 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, navController, snackbarManager, resources, coroutineScope) |         StudeezAppstate(scaffoldState, drawerState, navController, snackbarManager, resources, coroutineScope) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
|  | @ -89,6 +96,9 @@ fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     composable(StudeezDestinations.HOME_SCREEN) { |     composable(StudeezDestinations.HOME_SCREEN) { | ||||||
|         HomeScreen(openAndPopUp = { route, popUp -> appState.navigateAndPopUp(route, popUp) }) |         HomeScreen( | ||||||
|  |             openAndPopUp = { route, popUp -> appState.navigateAndPopUp(route, popUp) }, | ||||||
|  |             openDrawer = { appState.openDrawer() } | ||||||
|  |         ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| 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 | ||||||
|  | @ -13,11 +14,14 @@ 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 -> | ||||||
|  | @ -48,4 +52,8 @@ class StudeezAppstate( | ||||||
|             popUpTo(0) { inclusive = true } |             popUpTo(0) { inclusive = true } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     fun openDrawer() { | ||||||
|  |         coroutineScope.launch { drawerState.open() } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -0,0 +1,60 @@ | ||||||
|  | package be.ugent.sel.studeez.common.composable | ||||||
|  | 
 | ||||||
|  | import android.graphics.drawable.Icon | ||||||
|  | import androidx.compose.foundation.layout.* | ||||||
|  | import androidx.compose.material.Button | ||||||
|  | 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.Home | ||||||
|  | import androidx.compose.runtime.Composable | ||||||
|  | import androidx.compose.ui.Modifier | ||||||
|  | import androidx.compose.ui.graphics.vector.ImageVector | ||||||
|  | import androidx.compose.ui.tooling.preview.Preview | ||||||
|  | import androidx.compose.ui.unit.dp | ||||||
|  | 
 | ||||||
|  | @Composable | ||||||
|  | fun Drawer() { | ||||||
|  |     Column(modifier = Modifier.fillMaxSize()) { | ||||||
|  |         Text(text = "Studeez") | ||||||
|  |         Divider() | ||||||
|  |         Text(text = "Logout") | ||||||
|  |         IconTextButton(icon = Icons.Default.Home, text = "Home") { | ||||||
|  |              | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Composable | ||||||
|  | fun IconTextButton(icon: ImageVector, text: String, onClick: () -> Unit) { | ||||||
|  |     Button( | ||||||
|  |         onClick = onClick | ||||||
|  |     ) { | ||||||
|  |         Row( | ||||||
|  |             horizontalArrangement = Arrangement.Center | ||||||
|  |         ) { | ||||||
|  |             Icon(imageVector = icon, contentDescription = text) | ||||||
|  |             Spacer(modifier = Modifier.width(8.dp)) | ||||||
|  |             Text(text = text) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Preview | ||||||
|  | @Composable | ||||||
|  | fun DrawerPreview() { | ||||||
|  |     Drawer() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Preview | ||||||
|  | @Composable | ||||||
|  | fun DrawerEntryPreview() { | ||||||
|  |     IconTextButton( | ||||||
|  |         icon = Icons.Default.Home, | ||||||
|  |         text = "Home", | ||||||
|  |         onClick = { | ||||||
|  |             // Do something when the button is clicked | ||||||
|  |         } | ||||||
|  |     ) | ||||||
|  | } | ||||||
|  | @ -3,6 +3,7 @@ package be.ugent.sel.studeez.common.composable | ||||||
| import androidx.compose.foundation.layout.PaddingValues | import androidx.compose.foundation.layout.PaddingValues | ||||||
| import androidx.compose.material.* | import androidx.compose.material.* | ||||||
| import androidx.compose.material.icons.Icons | import androidx.compose.material.icons.Icons | ||||||
|  | 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.ui.tooling.preview.Preview | import androidx.compose.ui.tooling.preview.Preview | ||||||
|  | @ -14,6 +15,7 @@ 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, | ||||||
|     content: @Composable (PaddingValues) -> Unit |     content: @Composable (PaddingValues) -> Unit | ||||||
| ) { | ) { | ||||||
|     Scaffold( |     Scaffold( | ||||||
|  | @ -21,7 +23,7 @@ fun PrimaryScreenToolbar( | ||||||
|         topBar = { TopAppBar( |         topBar = { TopAppBar( | ||||||
|             title = { Text(text = title) }, |             title = { Text(text = title) }, | ||||||
|             navigationIcon = { |             navigationIcon = { | ||||||
|                 IconButton(onClick = { /* TODO open sidemenu */ }) { |                 IconButton(onClick = { openDrawer() }) { | ||||||
|                     Icon(imageVector = Icons.Default.Menu, contentDescription = "Menu") |                     Icon(imageVector = Icons.Default.Menu, contentDescription = "Menu") | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | @ -48,8 +50,8 @@ fun SecondaryScreenToolbar( | ||||||
|         topBar = { TopAppBar( |         topBar = { TopAppBar( | ||||||
|             title = { Text(text = title) }, |             title = { Text(text = title) }, | ||||||
|             navigationIcon = { |             navigationIcon = { | ||||||
|                 IconButton(onClick = { /* TODO open sidemenu */ }) { |                 IconButton(onClick = { /* TODO Go back */ }) { | ||||||
|                     Icon(imageVector = Icons.Default.Menu, contentDescription = "Menu") |                     Icon(imageVector = Icons.Default.ArrowBack, contentDescription = "Go back") | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         ) }, |         ) }, | ||||||
|  | @ -64,14 +66,13 @@ fun PrimaryScreenToolbarPreview() { | ||||||
|     StudeezTheme { PrimaryScreenToolbar( |     StudeezTheme { PrimaryScreenToolbar( | ||||||
|         "Preview screen", |         "Preview screen", | ||||||
|         {} |         {} | ||||||
|     ) } |     ) {} } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Preview | @Preview | ||||||
| @Composable | @Composable | ||||||
| fun SecondaryScreenToolbarPreview() { | fun SecondaryScreenToolbarPreview() { | ||||||
|     StudeezTheme { SecondaryScreenToolbar( |     StudeezTheme { SecondaryScreenToolbar( | ||||||
|         "Preview screen", |         "Preview screen" | ||||||
|         {} |     ) {} } | ||||||
|     )} |  | ||||||
| } | } | ||||||
|  | @ -6,18 +6,20 @@ 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.PrimaryScreenToolbar | import be.ugent.sel.studeez.common.composable.PrimaryScreenToolbar | ||||||
| import be.ugent.sel.studeez.common.composable.SecondaryScreenToolbar |  | ||||||
| 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 HomeScreen( | ||||||
|     openAndPopUp: (String, String) -> Unit, |     openAndPopUp: (String, String) -> Unit, | ||||||
|  |     openDrawer: () -> Unit, | ||||||
|     viewModel: HomeViewModel = hiltViewModel() |     viewModel: HomeViewModel = hiltViewModel() | ||||||
| ) { | ) { | ||||||
| 
 | 
 | ||||||
|     PrimaryScreenToolbar(title = resources().getString(R.string.home)) { |     PrimaryScreenToolbar( | ||||||
|         // "Start session" button |         title = resources().getString(R.string.home), | ||||||
|  |         openDrawer = { openDrawer() } | ||||||
|  |     ) { | ||||||
|         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