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
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.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.*
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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
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.DialogScreen
import dev.lonami.talaria.ui.screens.LoginScreen
import kotlinx.coroutines.launch
enum class TalariaScreen(@StringRes val title: Int) {
Login(title = R.string.app_name),
@ -23,8 +30,93 @@ enum class TalariaScreen(@StringRes val title: Int) {
Chat(title = R.string.chat),
}
enum class DrawerAction {
SelectAccount,
AddAccount,
SavedMessages,
Contacts,
NewChat,
Settings,
Help,
}
@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(
title = { Text(stringResource(currentScreen.title)) },
navigationIcon = {
@ -35,6 +127,13 @@ fun TalariaAppBar(currentScreen: TalariaScreen, canNavigateBack: Boolean, naviga
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()) }
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(
topBar = {
TalariaAppBar(
currentScreen,
canNavigateBack = navController.previousBackStackEntry != null,
navigateUp = { navController.navigateUp() }
navigateUp = { navController.navigateUp() },
openDrawer = { toggleDrawer(drawerState.isClosed) }
)
}
) { innerPadding ->
NavHost(
navController = navController,
startDestination = if (loggedIn) {
TalariaScreen.Login.name
} else {
TalariaScreen.Dialog.name
},
Modifier.padding(innerPadding)
) {
composable(route = TalariaScreen.Dialog.name) {
DialogScreen(onDialogSelected = {
selectedDialog = it
navController.navigate(TalariaScreen.Chat.name)
})
}
composable(route = TalariaScreen.Chat.name) {
ChatScreen(selectedDialog)
}
composable(route = TalariaScreen.Login.name) {
LoginScreen(onConfirmOtp = {
navController.navigate(TalariaScreen.Dialog.name)
})
ModalDrawer(
drawerState = drawerState,
gesturesEnabled = drawerState.isOpen,
drawerContent = {
Drawer(onSelect = {})
}) {
NavHost(
navController = navController,
startDestination = if (loggedIn) {
TalariaScreen.Login.name
} else {
TalariaScreen.Dialog.name
},
Modifier.padding(innerPadding)
) {
composable(route = TalariaScreen.Dialog.name) {
DialogScreen(onDialogSelected = {
selectedDialog = it
navController.navigate(TalariaScreen.Chat.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 = {})
}
}