diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index ae460ff..584649f 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -2,18 +2,8 @@ package be.ugent.sel.studeez import android.content.res.Resources import androidx.compose.foundation.layout.padding -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Scaffold -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.material.* +import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext @@ -119,7 +109,7 @@ fun StudeezNavGraph( open, viewModel = hiltViewModel(), drawerActions = drawerActions, - navigationBarActions = navigationBarActions, + navigationBarActions = navigationBarActions ) } @@ -136,7 +126,7 @@ fun StudeezNavGraph( open, viewModel = hiltViewModel(), 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) { EditProfileRoute( goBack, diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/FloatingActionButtonComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/FloatingActionButtonComposable.kt index 15005fa..078d6fb 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/FloatingActionButtonComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/FloatingActionButtonComposable.kt @@ -1,5 +1,8 @@ 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.Row 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.DateRange 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.Modifier +import androidx.compose.ui.draw.rotate import androidx.compose.ui.tooling.preview.Preview 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 -fun CollapsedAddButton() { - FloatingActionButton( - onClick = { /* TODO popup add options */ } +fun AddButton( + addButtonActions: AddButtonActions +) { + 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 ) { - Icon(imageVector = Icons.Default.Add, contentDescription = "fab") + // 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 -fun ExpandedAddButton() { - Row() { - IconButton(onClick = { /* TODO Go to next step */ }) { +fun ExpandedAddButton( + addButtonActions: AddButtonActions +) { + Row { + IconButton(onClick = addButtonActions.onTaskClick) { Column (horizontalAlignment = Alignment.CenterHorizontally) { Icon(imageVector = Icons.Default.Check, contentDescription = "Task") Text(text = "Task") } } - IconButton(onClick = { /* TODO Go to next step */ }) { + IconButton(onClick = addButtonActions.onFriendClick) { Column (horizontalAlignment = Alignment.CenterHorizontally) { Icon(imageVector = Icons.Default.Person, contentDescription = "Friend") Text(text = "Friend") } } - IconButton(onClick = { /* TODO Go to next step */ }) { + IconButton(onClick = addButtonActions.onSessionClick) { Column (horizontalAlignment = Alignment.CenterHorizontally) { Icon(imageVector = Icons.Default.DateRange, contentDescription = "Session") Text(text = "Session") @@ -51,12 +106,16 @@ fun ExpandedAddButton() { @Preview @Composable -fun CollapsedAddButtonPreview() { - StudeezTheme { CollapsedAddButton() } +fun AddButtonPreview() { + StudeezTheme { AddButton( + addButtonActions = AddButtonActions({}, {}, {}) + )} } @Preview @Composable fun ExpandedAddButtonPreview() { - StudeezTheme { ExpandedAddButton() } + StudeezTheme { ExpandedAddButton( + addButtonActions = AddButtonActions({}, {}, {}) + ) } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt index 79dec41..0cbfb0b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/PrimaryScreenComposable.kt @@ -56,8 +56,12 @@ fun PrimaryScreenTemplate( bottomBar = { NavigationBar(navigationBarActions) }, floatingActionButtonPosition = FabPosition.Center, - isFloatingActionButtonDocked = true, - floatingActionButton = { CollapsedAddButton() } + isFloatingActionButtonDocked = false, + floatingActionButton = { AddButton(AddButtonActions( + onTaskClick = navigationBarActions.onAddTaskClick, + onFriendClick = navigationBarActions.onAddFriendClick, + onSessionClick = navigationBarActions.onAddSessionClick + )) } ) { content(it) } @@ -70,7 +74,7 @@ fun PrimaryScreenPreview() { PrimaryScreenTemplate( "Preview screen", DrawerActions({}, {}, {}, {}, {}), - NavigationBarActions({ false }, {}, {}, {}, {}), + NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), { IconButton(onClick = { /*TODO*/ }) { Icon( diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt index d84910e..b2393d8 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt @@ -22,10 +22,16 @@ import be.ugent.sel.studeez.R.string as AppText data class NavigationBarActions( val isSelectedTab: (String) -> Boolean, + val onHomeClick: () -> Unit, val onTasksClick: () -> Unit, val onSessionsClick: () -> Unit, val onProfileClick: () -> Unit, + + // AddButton + val onAddTaskClick: () -> Unit, + val onAddFriendClick: () -> Unit, + val onAddSessionClick: () -> Unit ) fun getNavigationBarActions( @@ -37,6 +43,7 @@ fun getNavigationBarActions( isSelectedTab = { screen -> screen == getCurrentScreen() }, + onHomeClick = { navigationBarViewModel.onHomeClick(open) }, @@ -49,6 +56,18 @@ fun getNavigationBarActions( onProfileClick = { navigationBarViewModel.onProfileClick(open) }, + + onAddTaskClick = { + navigationBarViewModel.onAddTaskClick(open) + }, + + onAddFriendClick = { + navigationBarViewModel.onAddFriendClick(open) + }, + + onAddSessionClick = { + navigationBarViewModel.onAddSessionClick(open) + } ) } @@ -110,7 +129,7 @@ fun NavigationBar( fun NavigationBarPreview() { StudeezTheme { NavigationBar( - navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), + navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), ) } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt index 8c68832..ab9256b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt @@ -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.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.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.TASKS_SCREEN import be.ugent.sel.studeez.screens.StudeezViewModel @@ -31,4 +34,16 @@ class NavigationBarViewModel @Inject constructor( fun onProfileClick(open: (String) -> Unit) { 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) + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt index bb78b0b..0d55dec 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt @@ -21,6 +21,11 @@ object StudeezDestinations { const val SESSION_SCREEN = "session" 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" } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt index 1e9be33..f02852e 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt @@ -33,7 +33,7 @@ fun HomeRoute( fun HomeScreen( onStartSessionClick: () -> Unit, drawerActions: DrawerActions, - navigationBarActions: NavigationBarActions, + navigationBarActions: NavigationBarActions ) { PrimaryScreenTemplate( title = resources().getString(R.string.home), @@ -63,6 +63,6 @@ fun HomeScreenPreview() { HomeScreen( onStartSessionClick = {}, drawerActions = DrawerActions({}, {}, {}, {}, {}), - navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}) + navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}) ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt index 0b4a67f..9c76337 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/profile/ProfileScreen.kt @@ -88,6 +88,6 @@ fun ProfileScreenPreview() { ProfileScreen( profileActions = ProfileActions({ null }, {}), drawerActions = DrawerActions({}, {}, {}, {}, {}), - navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}) + navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}) ) } \ No newline at end of file