Merge pull request #61 from SELab1/drawer_navbar_refactor
Drawer navbar refactor
This commit is contained in:
		
						commit
						66e68493e4
					
				
					 8 changed files with 215 additions and 124 deletions
				
			
		|  | @ -76,21 +76,23 @@ fun resources(): Resources { | ||||||
| 
 | 
 | ||||||
| fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) { | fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) { | ||||||
| 
 | 
 | ||||||
|  |     val openAndPopUp: (String, String) -> Unit = { | ||||||
|  |             route, popUp -> appState.navigateAndPopUp(route, popUp) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     composable(StudeezDestinations.SPLASH_SCREEN) { |     composable(StudeezDestinations.SPLASH_SCREEN) { | ||||||
|         SplashScreen(openAndPopUp = { route, popUp -> appState.navigateAndPopUp(route, popUp) }) |         SplashScreen(openAndPopUp) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     composable(StudeezDestinations.LOGIN_SCREEN) { |     composable(StudeezDestinations.LOGIN_SCREEN) { | ||||||
|         LoginScreen(openAndPopUp = { route, popUp -> appState.navigateAndPopUp(route, popUp) }) |         LoginScreen(openAndPopUp) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     composable(StudeezDestinations.SIGN_UP_SCREEN) { |     composable(StudeezDestinations.SIGN_UP_SCREEN) { | ||||||
|         SignUpScreen(openAndPopUp = { route, popUp -> appState.navigateAndPopUp(route, popUp) }) |         SignUpScreen(openAndPopUp) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     composable(StudeezDestinations.HOME_SCREEN) { |     composable(StudeezDestinations.HOME_SCREEN) { | ||||||
|         HomeScreen( |         HomeScreen(openAndPopUp) | ||||||
|             openAndPopUp = { route, popUp -> appState.navigateAndPopUp(route, popUp) } |  | ||||||
|         ) |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -1,89 +0,0 @@ | ||||||
| package be.ugent.sel.studeez.common.composable |  | ||||||
| 
 |  | ||||||
| import androidx.compose.foundation.clickable |  | ||||||
| import androidx.compose.foundation.layout.* |  | ||||||
| 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.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.vectorResource |  | ||||||
| import androidx.compose.ui.tooling.preview.Preview |  | ||||||
| import be.ugent.sel.studeez.R |  | ||||||
| import be.ugent.sel.studeez.resources |  | ||||||
| import be.ugent.sel.studeez.ui.theme.StudeezTheme |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @Composable |  | ||||||
| fun Drawer( |  | ||||||
|     onLogoutClick: () -> Unit |  | ||||||
| ) { |  | ||||||
|     Column(modifier = Modifier.fillMaxSize()) { |  | ||||||
|         DrawerEntry( |  | ||||||
|             icon = Icons.Default.Home, |  | ||||||
|             text = resources().getString(R.string.home) |  | ||||||
|         ) { |  | ||||||
|             // TODO Go to home |  | ||||||
|         } |  | ||||||
|         DrawerEntry( |  | ||||||
|             icon = ImageVector.vectorResource(id = R.drawable.ic_timer), |  | ||||||
|             text = resources().getString(R.string.timers) |  | ||||||
|         ) { |  | ||||||
|             // TODO Go to timers |  | ||||||
|         } |  | ||||||
|         DrawerEntry( |  | ||||||
|             icon = Icons.Default.Settings, |  | ||||||
|             text = resources().getString(R.string.settings) |  | ||||||
|         ) { |  | ||||||
|             // TODO Go to settings |  | ||||||
|         } |  | ||||||
|         DrawerEntry( |  | ||||||
|             icon = ImageVector.vectorResource(id = R.drawable.ic_logout), |  | ||||||
|             text = resources().getString(R.string.log_out) |  | ||||||
|         ) { |  | ||||||
|             onLogoutClick() |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         DrawerEntry( |  | ||||||
|             icon = Icons.Outlined.Info, |  | ||||||
|             text = resources().getString(R.string.about) |  | ||||||
|         ) { |  | ||||||
|             // TODO Go to about |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @Composable |  | ||||||
| fun DrawerEntry( |  | ||||||
|     icon: ImageVector, |  | ||||||
|     text: String, |  | ||||||
|     onClick: () -> Unit |  | ||||||
| ) { |  | ||||||
|     Row( |  | ||||||
|         horizontalArrangement = Arrangement.Center, |  | ||||||
|         modifier = Modifier |  | ||||||
|             .clickable(onClick = { onClick() }) |  | ||||||
|             .fillMaxWidth() |  | ||||||
|     ) { |  | ||||||
|         Box(modifier = Modifier.fillMaxWidth(0.25f)) { |  | ||||||
|             Icon(imageVector = icon, contentDescription = text) |  | ||||||
|         } |  | ||||||
|         Box(modifier = Modifier.fillMaxWidth(0.75f)) { |  | ||||||
|             Text(text = text) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @Preview |  | ||||||
| @Composable |  | ||||||
| fun DrawerPreview() { |  | ||||||
|     StudeezTheme { |  | ||||||
|         Drawer( |  | ||||||
|             {} |  | ||||||
|         ) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | @ -6,17 +6,17 @@ import androidx.compose.material.icons.Icons | ||||||
| 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.rememberCoroutineScope | import androidx.compose.runtime.rememberCoroutineScope | ||||||
| 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.ui.theme.StudeezTheme | import be.ugent.sel.studeez.screens.drawer.Drawer | ||||||
|  | import be.ugent.sel.studeez.screens.navbar.NavigationBar | ||||||
| import kotlinx.coroutines.CoroutineScope | import kotlinx.coroutines.CoroutineScope | ||||||
| import kotlinx.coroutines.launch | import kotlinx.coroutines.launch | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| fun PrimaryScreenTemplate( | fun PrimaryScreenTemplate( | ||||||
|     title: String, |     title: String, | ||||||
|     onLogoutClick: () -> Unit, |     openAndPopUp: (String, String) -> Unit, | ||||||
|     content: @Composable (PaddingValues) -> Unit |     content: @Composable (PaddingValues) -> Unit | ||||||
| ) { | ) { | ||||||
|     val scaffoldState: ScaffoldState = rememberScaffoldState() |     val scaffoldState: ScaffoldState = rememberScaffoldState() | ||||||
|  | @ -40,12 +40,10 @@ fun PrimaryScreenTemplate( | ||||||
|         ) }, |         ) }, | ||||||
| 
 | 
 | ||||||
|         drawerContent = { |         drawerContent = { | ||||||
|             Drawer( |             Drawer(openAndPopUp) | ||||||
|                 onLogoutClick = { onLogoutClick() } |  | ||||||
|             ) |  | ||||||
|         }, |         }, | ||||||
| 
 | 
 | ||||||
|         bottomBar = { NavigationBar() }, // TODO Pass arguments so that the current tab etc can be shown |         bottomBar = { NavigationBar(openAndPopUp) }, | ||||||
|         floatingActionButtonPosition = FabPosition.Center, |         floatingActionButtonPosition = FabPosition.Center, | ||||||
|         isFloatingActionButtonDocked = true, |         isFloatingActionButtonDocked = true, | ||||||
|         floatingActionButton = { CollapsedAddButton() } |         floatingActionButton = { CollapsedAddButton() } | ||||||
|  | @ -54,13 +52,13 @@ fun PrimaryScreenTemplate( | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Preview | //@Preview | ||||||
| @Composable | //@Composable | ||||||
| fun PrimaryScreenPreview() { | //fun PrimaryScreenPreview() { | ||||||
|     StudeezTheme { | //    StudeezTheme { | ||||||
|         PrimaryScreenTemplate( | //        PrimaryScreenTemplate( | ||||||
|             "Preview screen", | //            "Preview screen", | ||||||
|             {} | //            {} | ||||||
|         ) {} | //        ) {} | ||||||
|     } | //    } | ||||||
| } | //} | ||||||
|  | @ -0,0 +1,107 @@ | ||||||
|  | package be.ugent.sel.studeez.screens.drawer | ||||||
|  | 
 | ||||||
|  | import androidx.compose.foundation.clickable | ||||||
|  | import androidx.compose.foundation.layout.* | ||||||
|  | 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.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.vectorResource | ||||||
|  | import androidx.compose.ui.tooling.preview.Preview | ||||||
|  | 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.resources | ||||||
|  | import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @Composable | ||||||
|  | fun Drawer( | ||||||
|  |     openAndPopUp: (String, String) -> Unit, | ||||||
|  |     viewModel: DrawerViewModel = hiltViewModel() | ||||||
|  | ) { | ||||||
|  |     Column ( | ||||||
|  |         modifier = Modifier.fillMaxWidth() | ||||||
|  |     ) { | ||||||
|  |         Column ( | ||||||
|  |             modifier = Modifier.fillMaxWidth().weight(1f) | ||||||
|  |         ) { | ||||||
|  |             DrawerEntry( | ||||||
|  |                 icon = Icons.Default.Home, | ||||||
|  |                 text = resources().getString(R.string.home) | ||||||
|  |             ) { | ||||||
|  |                 // TODO Go to home | ||||||
|  |             } | ||||||
|  |             DrawerEntry( | ||||||
|  |                 icon = ImageVector.vectorResource(id = R.drawable.ic_timer), | ||||||
|  |                 text = resources().getString(R.string.timers) | ||||||
|  |             ) { | ||||||
|  |                 viewModel.onTimersClick(openAndPopUp) | ||||||
|  |             } | ||||||
|  |             DrawerEntry( | ||||||
|  |                 icon = Icons.Default.Settings, | ||||||
|  |                 text = resources().getString(R.string.settings) | ||||||
|  |             ) { | ||||||
|  |                 viewModel.onSettingsClick(openAndPopUp) | ||||||
|  |             } | ||||||
|  |             DrawerEntry( | ||||||
|  |                 icon = ImageVector.vectorResource(id = R.drawable.ic_logout), | ||||||
|  |                 text = resources().getString(R.string.log_out) | ||||||
|  |             ) { | ||||||
|  |                 viewModel.onLogoutClick(openAndPopUp) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         DrawerEntry( | ||||||
|  |             icon = Icons.Outlined.Info, | ||||||
|  |             text = resources().getString(R.string.about) | ||||||
|  |         ) { | ||||||
|  |             viewModel.onAboutClick(openAndPopUp) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Composable | ||||||
|  | fun DrawerEntry( | ||||||
|  |     icon: ImageVector, | ||||||
|  |     text: String, | ||||||
|  |     onClick: () -> Unit | ||||||
|  | ) { | ||||||
|  |     Row( | ||||||
|  |         horizontalArrangement = Arrangement.Center, | ||||||
|  |         modifier = Modifier | ||||||
|  |             .clickable(onClick = { onClick() }) | ||||||
|  |             .fillMaxWidth() | ||||||
|  |     ) { | ||||||
|  |         Box( | ||||||
|  |             modifier = Modifier | ||||||
|  |                 .padding(vertical = 12.dp) | ||||||
|  |                 .fillMaxWidth(0.15f) | ||||||
|  |         ) { | ||||||
|  |             Icon(imageVector = icon, contentDescription = text) | ||||||
|  |         } | ||||||
|  |         Box( | ||||||
|  |             modifier = Modifier | ||||||
|  |                 .padding(vertical = 12.dp) | ||||||
|  |                 .fillMaxWidth(0.85f) | ||||||
|  |         ) { | ||||||
|  |             Text(text = text) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Preview | ||||||
|  | @Composable | ||||||
|  | fun DrawerPreview() { | ||||||
|  |     StudeezTheme { | ||||||
|  |         Drawer( | ||||||
|  |             {a, b -> {}}, hiltViewModel() | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,38 @@ | ||||||
|  | package be.ugent.sel.studeez.screens.drawer | ||||||
|  | 
 | ||||||
|  | import be.ugent.sel.studeez.domain.AccountDAO | ||||||
|  | import be.ugent.sel.studeez.domain.LogService | ||||||
|  | import be.ugent.sel.studeez.navigation.StudeezDestinations | ||||||
|  | import be.ugent.sel.studeez.screens.StudeezViewModel | ||||||
|  | import dagger.hilt.android.lifecycle.HiltViewModel | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | @HiltViewModel | ||||||
|  | class DrawerViewModel @Inject constructor( | ||||||
|  |     private val accountDAO: AccountDAO, | ||||||
|  |     logService: LogService | ||||||
|  | ) : StudeezViewModel(logService) { | ||||||
|  | 
 | ||||||
|  |     fun onLogoutClick(openAndPopup: (String, String) -> Unit) { | ||||||
|  |         launchCatching { | ||||||
|  |             accountDAO.signOut() | ||||||
|  |             openAndPopup(StudeezDestinations.LOGIN_SCREEN, StudeezDestinations.HOME_SCREEN) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun onHomeButtonClick(openAndPopup: (String, String) -> Unit) { | ||||||
|  |         // TODO | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun onTimersClick(openAndPopup: (String, String) -> Unit) { | ||||||
|  |         // TODO | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun onSettingsClick(openAndPopup: (String, String) -> Unit) { | ||||||
|  |         // TODO | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun onAboutClick(openAndPopup: (String, String) -> Unit) { | ||||||
|  |         // TODO | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -16,7 +16,7 @@ fun HomeScreen( | ||||||
| ) { | ) { | ||||||
|     PrimaryScreenTemplate( |     PrimaryScreenTemplate( | ||||||
|         title = resources().getString(R.string.home), |         title = resources().getString(R.string.home), | ||||||
|         onLogoutClick = { viewModel.onLogoutClick(openAndPopUp) } |         openAndPopUp = openAndPopUp | ||||||
|     ) { |     ) { | ||||||
|         BasicButton(R.string.start_session, Modifier.basicButton()) { |         BasicButton(R.string.start_session, Modifier.basicButton()) { | ||||||
|             viewModel.onStartSessionClick(openAndPopUp) |             viewModel.onStartSessionClick(openAndPopUp) | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| package be.ugent.sel.studeez.common.composable | package be.ugent.sel.studeez.screens.navbar | ||||||
| 
 | 
 | ||||||
| import androidx.compose.material.BottomNavigation | import androidx.compose.material.BottomNavigation | ||||||
| import androidx.compose.material.BottomNavigationItem | import androidx.compose.material.BottomNavigationItem | ||||||
|  | @ -12,10 +12,14 @@ 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.ui.theme.StudeezTheme | import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| fun NavigationBar() { | fun NavigationBar( | ||||||
|  |     popUpAndOpen: (String, String) -> Unit, | ||||||
|  |     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. | ||||||
|     // TODO Disabled -> HIGH/MEDIUM_EMPHASIS if the page is implemented |     // TODO Disabled -> HIGH/MEDIUM_EMPHASIS if the page is implemented | ||||||
|  | @ -26,14 +30,14 @@ fun NavigationBar() { | ||||||
|             icon = { Icon(imageVector = Icons.Default.List, "Home") }, |             icon = { Icon(imageVector = Icons.Default.List, "Home") }, | ||||||
|             label = { Text(text = "Home") }, |             label = { Text(text = "Home") }, | ||||||
|             selected = false, // TODO |             selected = false, // TODO | ||||||
|             onClick = { /* TODO */ } |             onClick = { viewModel.onHomeClick(popUpAndOpen) } | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         BottomNavigationItem( |         BottomNavigationItem( | ||||||
|             icon = { Icon(imageVector = Icons.Default.Check, "Tasks") }, |             icon = { Icon(imageVector = Icons.Default.Check, "Tasks") }, | ||||||
|             label = { Text(text = "Tasks") }, |             label = { Text(text = "Tasks") }, | ||||||
|             selected = false, // TODO |             selected = false, // TODO | ||||||
|             onClick = { /* TODO */ } |             onClick = { viewModel.onTasksClick(popUpAndOpen) } | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         // 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 | ||||||
|  | @ -43,21 +47,21 @@ fun NavigationBar() { | ||||||
|             icon = { Icon(imageVector = Icons.Outlined.DateRange, "Sessions") }, |             icon = { Icon(imageVector = Icons.Outlined.DateRange, "Sessions") }, | ||||||
|             label = { Text(text = "Sessions") }, |             label = { Text(text = "Sessions") }, | ||||||
|             selected = false, // TODO |             selected = false, // TODO | ||||||
|             onClick = { /* TODO */ } |             onClick = { viewModel.onSessionsClick(popUpAndOpen) } | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         BottomNavigationItem( |         BottomNavigationItem( | ||||||
|             icon = { Icon(imageVector = Icons.Default.Person, "Profile") }, |             icon = { Icon(imageVector = Icons.Default.Person, "Profile") }, | ||||||
|             label = { Text(text = "Profile") }, |             label = { Text(text = "Profile") }, | ||||||
|             selected = false, // TODO |             selected = false, // TODO | ||||||
|             onClick = { /* TODO */ } |             onClick = { viewModel.onProfileClick(popUpAndOpen) } | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Preview(showBackground = true) | //@Preview(showBackground = true) | ||||||
| @Composable | //@Composable | ||||||
| fun NavigationBarPreview() { | //fun NavigationBarPreview() { | ||||||
|     StudeezTheme { NavigationBar() } | //    StudeezTheme { NavigationBar() } | ||||||
| } | //} | ||||||
|  | @ -0,0 +1,31 @@ | ||||||
|  | package be.ugent.sel.studeez.screens.navbar | ||||||
|  | 
 | ||||||
|  | import be.ugent.sel.studeez.domain.AccountDAO | ||||||
|  | import be.ugent.sel.studeez.domain.LogService | ||||||
|  | import be.ugent.sel.studeez.navigation.StudeezDestinations | ||||||
|  | import be.ugent.sel.studeez.screens.StudeezViewModel | ||||||
|  | import dagger.hilt.android.lifecycle.HiltViewModel | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | @HiltViewModel | ||||||
|  | class NavigationBarViewModel @Inject constructor( | ||||||
|  |     private val accountDAO: AccountDAO, | ||||||
|  |     logService: LogService | ||||||
|  | ) : StudeezViewModel(logService) { | ||||||
|  | 
 | ||||||
|  |     fun onHomeClick(openAndPopup: (String, String) -> Unit) { | ||||||
|  |         // TODO | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun onTasksClick(openAndPopup: (String, String) -> Unit) { | ||||||
|  |         // TODO | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun onSessionsClick(openAndPopup: (String, String) -> Unit) { | ||||||
|  |         // TODO | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun onProfileClick(openAndPopup: (String, String) -> Unit) { | ||||||
|  |         // TODO | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in a new issue
	
	 lbarraga
						lbarraga