Add a navigation drawer

master
Lonami Exo 2022-10-24 13:58:47 +02:00
parent 35ed8e12c6
commit da136a1990
1 changed files with 165 additions and 26 deletions

View File

@ -1,13 +1,19 @@
package dev.lonami.talaria package dev.lonami.talaria
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
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.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.currentBackStackEntryAsState
@ -16,6 +22,7 @@ import dev.lonami.talaria.bindings.Native
import dev.lonami.talaria.ui.screens.ChatScreen import dev.lonami.talaria.ui.screens.ChatScreen
import dev.lonami.talaria.ui.screens.DialogScreen import dev.lonami.talaria.ui.screens.DialogScreen
import dev.lonami.talaria.ui.screens.LoginScreen import dev.lonami.talaria.ui.screens.LoginScreen
import kotlinx.coroutines.launch
enum class TalariaScreen(@StringRes val title: Int) { enum class TalariaScreen(@StringRes val title: Int) {
Login(title = R.string.app_name), Login(title = R.string.app_name),
@ -23,8 +30,93 @@ enum class TalariaScreen(@StringRes val title: Int) {
Chat(title = R.string.chat), Chat(title = R.string.chat),
} }
enum class DrawerAction {
SelectAccount,
AddAccount,
SavedMessages,
Contacts,
NewChat,
Settings,
Help,
}
@Composable @Composable
fun TalariaAppBar(currentScreen: TalariaScreen, canNavigateBack: Boolean, navigateUp: () -> Unit) { fun DrawerAction(
icon: ImageVector,
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier
.clickable(onClick = onClick)
.fillMaxWidth()
.padding(0.dp, 8.dp)
) {
Icon(imageVector = icon, contentDescription = null)
Spacer(modifier = Modifier.width(8.dp))
Text(text)
}
}
@Composable
fun Drawer(modifier: Modifier = Modifier, onSelect: (DrawerAction) -> Unit) {
Column(
modifier = modifier
.fillMaxSize()
.padding(24.dp, 48.dp)
) {
Image(
painter = painterResource(R.drawable.ic_launcher_foreground),
contentDescription = "App Icon"
)
DrawerAction(
icon = Icons.Filled.AccountBox,
text = "Main Account",
onClick = { onSelect(DrawerAction.SelectAccount) }
)
DrawerAction(
icon = Icons.Filled.Add,
text = "Add Account",
onClick = { onSelect(DrawerAction.AddAccount) }
)
Divider()
DrawerAction(
icon = Icons.Filled.Star,
text = "Saved Messages",
onClick = { onSelect(DrawerAction.SavedMessages) }
)
DrawerAction(
icon = Icons.Filled.Call,
text = "Contacts",
onClick = { onSelect(DrawerAction.Contacts) }
)
DrawerAction(
icon = Icons.Filled.Create,
text = "New Chat",
onClick = { onSelect(DrawerAction.NewChat) }
)
Divider()
DrawerAction(
icon = Icons.Filled.Settings,
text = "Settings",
onClick = { onSelect(DrawerAction.Settings) }
)
DrawerAction(
icon = Icons.Filled.Info,
text = "Help",
onClick = { onSelect(DrawerAction.Help) }
)
}
}
@Composable
fun TalariaAppBar(
currentScreen: TalariaScreen,
canNavigateBack: Boolean,
navigateUp: () -> Unit,
openDrawer: () -> Unit
) {
TopAppBar( TopAppBar(
title = { Text(stringResource(currentScreen.title)) }, title = { Text(stringResource(currentScreen.title)) },
navigationIcon = { navigationIcon = {
@ -35,6 +127,13 @@ fun TalariaAppBar(currentScreen: TalariaScreen, canNavigateBack: Boolean, naviga
contentDescription = stringResource(R.string.back_button) contentDescription = stringResource(R.string.back_button)
) )
} }
} else {
IconButton(onClick = openDrawer) {
Icon(
imageVector = Icons.Filled.Menu,
contentDescription = stringResource(androidx.compose.ui.R.string.navigation_menu)
)
}
} }
} }
) )
@ -50,38 +149,78 @@ fun TalariaApp() {
val loggedIn by remember { mutableStateOf(!Native.needLogin()) } val loggedIn by remember { mutableStateOf(!Native.needLogin()) }
var selectedDialog by remember { mutableStateOf("") } var selectedDialog by remember { mutableStateOf("") }
val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()
val toggleDrawer = { open: Boolean ->
scope.launch {
if (open) {
drawerState.open()
} else {
drawerState.close()
}
}
}
Scaffold( Scaffold(
topBar = { topBar = {
TalariaAppBar( TalariaAppBar(
currentScreen, currentScreen,
canNavigateBack = navController.previousBackStackEntry != null, canNavigateBack = navController.previousBackStackEntry != null,
navigateUp = { navController.navigateUp() } navigateUp = { navController.navigateUp() },
openDrawer = { toggleDrawer(drawerState.isClosed) }
) )
} }
) { innerPadding -> ) { innerPadding ->
NavHost( ModalDrawer(
navController = navController, drawerState = drawerState,
startDestination = if (loggedIn) { gesturesEnabled = drawerState.isOpen,
TalariaScreen.Login.name drawerContent = {
} else { Drawer(onSelect = {})
TalariaScreen.Dialog.name }) {
},
Modifier.padding(innerPadding) NavHost(
) { navController = navController,
composable(route = TalariaScreen.Dialog.name) { startDestination = if (loggedIn) {
DialogScreen(onDialogSelected = { TalariaScreen.Login.name
selectedDialog = it } else {
navController.navigate(TalariaScreen.Chat.name) TalariaScreen.Dialog.name
}) },
} Modifier.padding(innerPadding)
composable(route = TalariaScreen.Chat.name) { ) {
ChatScreen(selectedDialog) composable(route = TalariaScreen.Dialog.name) {
} DialogScreen(onDialogSelected = {
composable(route = TalariaScreen.Login.name) { selectedDialog = it
LoginScreen(onConfirmOtp = { navController.navigate(TalariaScreen.Chat.name)
navController.navigate(TalariaScreen.Dialog.name) })
}) }
composable(route = TalariaScreen.Chat.name) {
ChatScreen(selectedDialog)
}
composable(route = TalariaScreen.Login.name) {
LoginScreen(onConfirmOtp = {
navController.navigate(TalariaScreen.Dialog.name)
})
}
} }
} }
} }
} }
@Preview
@Composable
fun TopBarPreview() {
TalariaAppBar(
currentScreen = TalariaScreen.Dialog,
canNavigateBack = false,
navigateUp = {},
openDrawer = {},
)
}
@Preview
@Composable
fun NavDrawerPreview() {
Surface {
Drawer(onSelect = {})
}
}