#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 */ }
|
) {
|
||||||
|
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
|
@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