#67 working popup, not styled
This commit is contained in:
		
							parent
							
								
									0a409421a8
								
							
						
					
					
						commit
						da79195e8d
					
				
					 8 changed files with 141 additions and 36 deletions
				
			
		|  | @ -2,18 +2,8 @@ package be.ugent.sel.studeez | ||||||
| 
 | 
 | ||||||
| import android.content.res.Resources | import android.content.res.Resources | ||||||
| import androidx.compose.foundation.layout.padding | import androidx.compose.foundation.layout.padding | ||||||
| import androidx.compose.material.MaterialTheme | import androidx.compose.material.* | ||||||
| import androidx.compose.material.Scaffold | import androidx.compose.runtime.* | ||||||
| import androidx.compose.material.ScaffoldState |  | ||||||
| import androidx.compose.material.Snackbar |  | ||||||
| import androidx.compose.material.SnackbarHost |  | ||||||
| import androidx.compose.material.Surface |  | ||||||
| import androidx.compose.material.rememberScaffoldState |  | ||||||
| import androidx.compose.runtime.Composable |  | ||||||
| import androidx.compose.runtime.ReadOnlyComposable |  | ||||||
| import androidx.compose.runtime.getValue |  | ||||||
| import androidx.compose.runtime.remember |  | ||||||
| import androidx.compose.runtime.rememberCoroutineScope |  | ||||||
| import androidx.compose.ui.Modifier | import androidx.compose.ui.Modifier | ||||||
| import androidx.compose.ui.platform.LocalConfiguration | import androidx.compose.ui.platform.LocalConfiguration | ||||||
| import androidx.compose.ui.platform.LocalContext | import androidx.compose.ui.platform.LocalContext | ||||||
|  | @ -119,7 +109,7 @@ fun StudeezNavGraph( | ||||||
|                 open, |                 open, | ||||||
|                 viewModel = hiltViewModel(), |                 viewModel = hiltViewModel(), | ||||||
|                 drawerActions = drawerActions, |                 drawerActions = drawerActions, | ||||||
|                 navigationBarActions = navigationBarActions, |                 navigationBarActions = navigationBarActions | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -136,7 +126,7 @@ fun StudeezNavGraph( | ||||||
|                 open, |                 open, | ||||||
|                 viewModel = hiltViewModel(), |                 viewModel = hiltViewModel(), | ||||||
|                 drawerActions = drawerActions, |                 drawerActions = drawerActions, | ||||||
|                 navigationBarActions = navigationBarActions, |                 navigationBarActions = navigationBarActions | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -198,7 +188,20 @@ fun StudeezNavGraph( | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Edit screens |         // Friends flow | ||||||
|  |         composable(StudeezDestinations.SEARCH_FRIENDS_SCREEN) { | ||||||
|  |             // TODO | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Create & edit screens | ||||||
|  |         composable(StudeezDestinations.CREATE_TASK_SCREEN) { | ||||||
|  |             // TODO | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         composable(StudeezDestinations.CREATE_SESSION_SCREEN) { | ||||||
|  |             // TODO | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         composable(StudeezDestinations.EDIT_PROFILE_SCREEN) { |         composable(StudeezDestinations.EDIT_PROFILE_SCREEN) { | ||||||
|             EditProfileRoute( |             EditProfileRoute( | ||||||
|                 goBack, |                 goBack, | ||||||
|  |  | ||||||
|  | @ -1,5 +1,8 @@ | ||||||
| package be.ugent.sel.studeez.common.composable | package be.ugent.sel.studeez.common.composable | ||||||
| 
 | 
 | ||||||
|  | import androidx.compose.animation.core.animateFloat | ||||||
|  | import androidx.compose.animation.core.updateTransition | ||||||
|  | import androidx.compose.foundation.layout.Arrangement | ||||||
| import androidx.compose.foundation.layout.Column | import androidx.compose.foundation.layout.Column | ||||||
| import androidx.compose.foundation.layout.Row | import androidx.compose.foundation.layout.Row | ||||||
| import androidx.compose.material.FloatingActionButton | import androidx.compose.material.FloatingActionButton | ||||||
|  | @ -11,36 +14,88 @@ import androidx.compose.material.icons.filled.Add | ||||||
| import androidx.compose.material.icons.filled.Check | import androidx.compose.material.icons.filled.Check | ||||||
| import androidx.compose.material.icons.filled.DateRange | import androidx.compose.material.icons.filled.DateRange | ||||||
| import androidx.compose.material.icons.filled.Person | import androidx.compose.material.icons.filled.Person | ||||||
| import androidx.compose.runtime.Composable | import androidx.compose.runtime.* | ||||||
| import androidx.compose.ui.Alignment | import androidx.compose.ui.Alignment | ||||||
|  | import androidx.compose.ui.Modifier | ||||||
|  | import androidx.compose.ui.draw.rotate | ||||||
| import androidx.compose.ui.tooling.preview.Preview | import androidx.compose.ui.tooling.preview.Preview | ||||||
| import be.ugent.sel.studeez.ui.theme.StudeezTheme | import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||||
| 
 | 
 | ||||||
|  | const val TRANSITION = "transition" | ||||||
|  | enum class MultiFloatingState { | ||||||
|  |     Expanded, | ||||||
|  |     Collapsed | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | data class AddButtonActions( | ||||||
|  |     val onTaskClick: () -> Unit, | ||||||
|  |     val onFriendClick: () -> Unit, | ||||||
|  |     val onSessionClick: () -> Unit | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| @Composable | @Composable | ||||||
| fun CollapsedAddButton() { | fun AddButton( | ||||||
|     FloatingActionButton( |     addButtonActions: AddButtonActions | ||||||
|         onClick = { /* TODO popup add options */ } |  | ||||||
| ) { | ) { | ||||||
|         Icon(imageVector = Icons.Default.Add, contentDescription = "fab") |     var multiFloatingState by remember { | ||||||
|  |         mutableStateOf(MultiFloatingState.Collapsed) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Rotate the button when expanded, normal when collapsed. | ||||||
|  |     val transition = updateTransition(targetState = multiFloatingState, label = TRANSITION) | ||||||
|  |     val rotate by transition.animateFloat(label = TRANSITION) { | ||||||
|  |         when (it) { | ||||||
|  |             MultiFloatingState.Expanded -> 315f | ||||||
|  |             MultiFloatingState.Collapsed -> 0f | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Column( | ||||||
|  |         horizontalAlignment = Alignment.CenterHorizontally, | ||||||
|  |         verticalArrangement = Arrangement.Top | ||||||
|  |     ) { | ||||||
|  |         // Show minis when expanded. | ||||||
|  |         if (multiFloatingState == MultiFloatingState.Expanded) { | ||||||
|  |             ExpandedAddButton(addButtonActions = addButtonActions) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // The base add button | ||||||
|  |         FloatingActionButton( | ||||||
|  |             onClick = { | ||||||
|  |                 // Toggle expanded/collapsed. | ||||||
|  |                 multiFloatingState = when (transition.currentState) { | ||||||
|  |                     MultiFloatingState.Collapsed -> MultiFloatingState.Expanded | ||||||
|  |                     MultiFloatingState.Expanded -> MultiFloatingState.Collapsed | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ) { | ||||||
|  |             Icon( | ||||||
|  |                 imageVector = Icons.Default.Add, | ||||||
|  |                 contentDescription = "fab", | ||||||
|  |                 modifier = Modifier.rotate(rotate) // The rotation | ||||||
|  |             ) | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| fun ExpandedAddButton() { | fun ExpandedAddButton( | ||||||
|     Row() { |     addButtonActions: AddButtonActions | ||||||
|         IconButton(onClick = { /* TODO Go to next step */ }) { | ) { | ||||||
|  |     Row { | ||||||
|  |         IconButton(onClick = addButtonActions.onTaskClick) { | ||||||
|             Column (horizontalAlignment = Alignment.CenterHorizontally) { |             Column (horizontalAlignment = Alignment.CenterHorizontally) { | ||||||
|                 Icon(imageVector = Icons.Default.Check, contentDescription = "Task") |                 Icon(imageVector = Icons.Default.Check, contentDescription = "Task") | ||||||
|                 Text(text = "Task") |                 Text(text = "Task") | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         IconButton(onClick = { /* TODO Go to next step */ }) { |         IconButton(onClick = addButtonActions.onFriendClick) { | ||||||
|             Column (horizontalAlignment = Alignment.CenterHorizontally) { |             Column (horizontalAlignment = Alignment.CenterHorizontally) { | ||||||
|                 Icon(imageVector = Icons.Default.Person, contentDescription = "Friend") |                 Icon(imageVector = Icons.Default.Person, contentDescription = "Friend") | ||||||
|                 Text(text = "Friend") |                 Text(text = "Friend") | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         IconButton(onClick = { /* TODO Go to next step */ }) { |         IconButton(onClick = addButtonActions.onSessionClick) { | ||||||
|             Column (horizontalAlignment = Alignment.CenterHorizontally) { |             Column (horizontalAlignment = Alignment.CenterHorizontally) { | ||||||
|                 Icon(imageVector = Icons.Default.DateRange, contentDescription = "Session") |                 Icon(imageVector = Icons.Default.DateRange, contentDescription = "Session") | ||||||
|                 Text(text = "Session") |                 Text(text = "Session") | ||||||
|  | @ -51,12 +106,16 @@ fun ExpandedAddButton() { | ||||||
| 
 | 
 | ||||||
| @Preview | @Preview | ||||||
| @Composable | @Composable | ||||||
| fun CollapsedAddButtonPreview() { | fun AddButtonPreview() { | ||||||
|     StudeezTheme { CollapsedAddButton() } |     StudeezTheme { AddButton( | ||||||
|  |         addButtonActions = AddButtonActions({}, {}, {}) | ||||||
|  |     )} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Preview | @Preview | ||||||
| @Composable | @Composable | ||||||
| fun ExpandedAddButtonPreview() { | fun ExpandedAddButtonPreview() { | ||||||
|     StudeezTheme { ExpandedAddButton() } |     StudeezTheme { ExpandedAddButton( | ||||||
|  |         addButtonActions = AddButtonActions({}, {}, {}) | ||||||
|  |     ) } | ||||||
| } | } | ||||||
|  | @ -56,8 +56,12 @@ fun PrimaryScreenTemplate( | ||||||
| 
 | 
 | ||||||
|         bottomBar = { NavigationBar(navigationBarActions) }, |         bottomBar = { NavigationBar(navigationBarActions) }, | ||||||
|         floatingActionButtonPosition = FabPosition.Center, |         floatingActionButtonPosition = FabPosition.Center, | ||||||
|         isFloatingActionButtonDocked = true, |         isFloatingActionButtonDocked = false, | ||||||
|         floatingActionButton = { CollapsedAddButton() } |         floatingActionButton = { AddButton(AddButtonActions( | ||||||
|  |             onTaskClick = navigationBarActions.onAddTaskClick, | ||||||
|  |             onFriendClick = navigationBarActions.onAddFriendClick, | ||||||
|  |             onSessionClick = navigationBarActions.onAddSessionClick | ||||||
|  |         )) } | ||||||
|     ) { |     ) { | ||||||
|         content(it) |         content(it) | ||||||
|     } |     } | ||||||
|  | @ -70,7 +74,7 @@ fun PrimaryScreenPreview() { | ||||||
|         PrimaryScreenTemplate( |         PrimaryScreenTemplate( | ||||||
|             "Preview screen", |             "Preview screen", | ||||||
|             DrawerActions({}, {}, {}, {}, {}), |             DrawerActions({}, {}, {}, {}, {}), | ||||||
|             NavigationBarActions({ false }, {}, {}, {}, {}), |             NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), | ||||||
|             { |             { | ||||||
|                 IconButton(onClick = { /*TODO*/ }) { |                 IconButton(onClick = { /*TODO*/ }) { | ||||||
|                     Icon( |                     Icon( | ||||||
|  |  | ||||||
|  | @ -22,10 +22,16 @@ import be.ugent.sel.studeez.R.string as AppText | ||||||
| 
 | 
 | ||||||
| data class NavigationBarActions( | data class NavigationBarActions( | ||||||
|     val isSelectedTab: (String) -> Boolean, |     val isSelectedTab: (String) -> Boolean, | ||||||
|  | 
 | ||||||
|     val onHomeClick: () -> Unit, |     val onHomeClick: () -> Unit, | ||||||
|     val onTasksClick: () -> Unit, |     val onTasksClick: () -> Unit, | ||||||
|     val onSessionsClick: () -> Unit, |     val onSessionsClick: () -> Unit, | ||||||
|     val onProfileClick: () -> Unit, |     val onProfileClick: () -> Unit, | ||||||
|  | 
 | ||||||
|  |     // AddButton | ||||||
|  |     val onAddTaskClick: () -> Unit, | ||||||
|  |     val onAddFriendClick: () -> Unit, | ||||||
|  |     val onAddSessionClick: () -> Unit | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| fun getNavigationBarActions( | fun getNavigationBarActions( | ||||||
|  | @ -37,6 +43,7 @@ fun getNavigationBarActions( | ||||||
|         isSelectedTab = { screen -> |         isSelectedTab = { screen -> | ||||||
|             screen == getCurrentScreen() |             screen == getCurrentScreen() | ||||||
|         }, |         }, | ||||||
|  | 
 | ||||||
|         onHomeClick = { |         onHomeClick = { | ||||||
|             navigationBarViewModel.onHomeClick(open) |             navigationBarViewModel.onHomeClick(open) | ||||||
|         }, |         }, | ||||||
|  | @ -49,6 +56,18 @@ fun getNavigationBarActions( | ||||||
|         onProfileClick = { |         onProfileClick = { | ||||||
|             navigationBarViewModel.onProfileClick(open) |             navigationBarViewModel.onProfileClick(open) | ||||||
|         }, |         }, | ||||||
|  | 
 | ||||||
|  |         onAddTaskClick = { | ||||||
|  |             navigationBarViewModel.onAddTaskClick(open) | ||||||
|  |         }, | ||||||
|  | 
 | ||||||
|  |         onAddFriendClick = { | ||||||
|  |             navigationBarViewModel.onAddFriendClick(open) | ||||||
|  |         }, | ||||||
|  | 
 | ||||||
|  |         onAddSessionClick = { | ||||||
|  |             navigationBarViewModel.onAddSessionClick(open) | ||||||
|  |         } | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -110,7 +129,7 @@ fun NavigationBar( | ||||||
| fun NavigationBarPreview() { | fun NavigationBarPreview() { | ||||||
|     StudeezTheme { |     StudeezTheme { | ||||||
|         NavigationBar( |         NavigationBar( | ||||||
|             navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), |             navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -2,8 +2,11 @@ package be.ugent.sel.studeez.common.composable.navbar | ||||||
| 
 | 
 | ||||||
| import be.ugent.sel.studeez.domain.AccountDAO | import be.ugent.sel.studeez.domain.AccountDAO | ||||||
| import be.ugent.sel.studeez.domain.LogService | import be.ugent.sel.studeez.domain.LogService | ||||||
|  | import be.ugent.sel.studeez.navigation.StudeezDestinations.CREATE_SESSION_SCREEN | ||||||
|  | import be.ugent.sel.studeez.navigation.StudeezDestinations.CREATE_TASK_SCREEN | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations.HOME_SCREEN | import be.ugent.sel.studeez.navigation.StudeezDestinations.HOME_SCREEN | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations.PROFILE_SCREEN | import be.ugent.sel.studeez.navigation.StudeezDestinations.PROFILE_SCREEN | ||||||
|  | import be.ugent.sel.studeez.navigation.StudeezDestinations.SEARCH_FRIENDS_SCREEN | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations.SESSIONS_SCREEN | import be.ugent.sel.studeez.navigation.StudeezDestinations.SESSIONS_SCREEN | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations.TASKS_SCREEN | import be.ugent.sel.studeez.navigation.StudeezDestinations.TASKS_SCREEN | ||||||
| import be.ugent.sel.studeez.screens.StudeezViewModel | import be.ugent.sel.studeez.screens.StudeezViewModel | ||||||
|  | @ -31,4 +34,16 @@ class NavigationBarViewModel @Inject constructor( | ||||||
|     fun onProfileClick(open: (String) -> Unit) { |     fun onProfileClick(open: (String) -> Unit) { | ||||||
|         open(PROFILE_SCREEN) |         open(PROFILE_SCREEN) | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     fun onAddTaskClick(open: (String) -> Unit) { | ||||||
|  |         open(CREATE_TASK_SCREEN) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun onAddFriendClick(open: (String) -> Unit) { | ||||||
|  |         open(SEARCH_FRIENDS_SCREEN) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun onAddSessionClick(open: (String) -> Unit) { | ||||||
|  |         open(CREATE_SESSION_SCREEN) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -21,6 +21,11 @@ object StudeezDestinations { | ||||||
|     const val SESSION_SCREEN = "session" |     const val SESSION_SCREEN = "session" | ||||||
|     const val SESSION_RECAP = "session_recap" |     const val SESSION_RECAP = "session_recap" | ||||||
| 
 | 
 | ||||||
|     // Edit screens |     // Friends flow | ||||||
|  |     const val SEARCH_FRIENDS_SCREEN = "search_friends" | ||||||
|  | 
 | ||||||
|  |     // Create & edit screens | ||||||
|  |     const val CREATE_TASK_SCREEN = "create_task" | ||||||
|  |     const val CREATE_SESSION_SCREEN = "create_session" | ||||||
|     const val EDIT_PROFILE_SCREEN = "edit_profile" |     const val EDIT_PROFILE_SCREEN = "edit_profile" | ||||||
| } | } | ||||||
|  | @ -33,7 +33,7 @@ fun HomeRoute( | ||||||
| fun HomeScreen( | fun HomeScreen( | ||||||
|     onStartSessionClick: () -> Unit, |     onStartSessionClick: () -> Unit, | ||||||
|     drawerActions: DrawerActions, |     drawerActions: DrawerActions, | ||||||
|     navigationBarActions: NavigationBarActions, |     navigationBarActions: NavigationBarActions | ||||||
| ) { | ) { | ||||||
|     PrimaryScreenTemplate( |     PrimaryScreenTemplate( | ||||||
|         title = resources().getString(R.string.home), |         title = resources().getString(R.string.home), | ||||||
|  | @ -63,6 +63,6 @@ fun HomeScreenPreview() { | ||||||
|     HomeScreen( |     HomeScreen( | ||||||
|         onStartSessionClick = {}, |         onStartSessionClick = {}, | ||||||
|         drawerActions = DrawerActions({}, {}, {}, {}, {}), |         drawerActions = DrawerActions({}, {}, {}, {}, {}), | ||||||
|         navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}) |         navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}) | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -88,6 +88,6 @@ fun ProfileScreenPreview() { | ||||||
|     ProfileScreen( |     ProfileScreen( | ||||||
|         profileActions = ProfileActions({ null }, {}), |         profileActions = ProfileActions({ null }, {}), | ||||||
|         drawerActions = DrawerActions({}, {}, {}, {}, {}), |         drawerActions = DrawerActions({}, {}, {}, {}, {}), | ||||||
|         navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}) |         navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}) | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
		Reference in a new issue