package dev.lonami.talaria import androidx.annotation.StringRes 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.* 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 import androidx.navigation.compose.rememberNavController import dev.lonami.talaria.ui.screens.ChatScreen import dev.lonami.talaria.ui.screens.DialogScreen import dev.lonami.talaria.ui.screens.LoginScreen import dev.lonami.talaria.ui.state.ChatViewModel import kotlinx.coroutines.launch import uniffi.talaria.needLogin enum class TalariaScreen(@StringRes val title: Int) { Login(title = R.string.app_name), Dialog(title = R.string.dialog), Chat(title = R.string.chat), } enum class DrawerAction { SelectAccount, AddAccount, SavedMessages, Contacts, NewChat, Settings, Help, } @Composable 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(onSelect: (DrawerAction) -> Unit, modifier: Modifier = Modifier) { 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, modifier: Modifier = Modifier, ) { TopAppBar( modifier = modifier, title = { Text(stringResource(currentScreen.title)) }, navigationIcon = { if (canNavigateBack) { IconButton(onClick = navigateUp) { Icon( imageVector = Icons.Filled.ArrowBack, contentDescription = stringResource(R.string.back_button) ) } } else { IconButton(onClick = openDrawer) { Icon( imageVector = Icons.Filled.Menu, contentDescription = stringResource(androidx.compose.ui.R.string.navigation_menu) ) } } } ) } @Composable fun TalariaApp(modifier: Modifier = Modifier) { val navController = rememberNavController() val backStackEntry by navController.currentBackStackEntryAsState() val currentScreen = TalariaScreen.valueOf(backStackEntry?.destination?.route ?: TalariaScreen.Login.name) val loggedIn by remember { mutableStateOf(!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() } } } val chatViewModel = remember { ChatViewModel() } Scaffold( modifier = modifier, topBar = { TalariaAppBar( currentScreen, canNavigateBack = navController.previousBackStackEntry != null, navigateUp = { navController.navigateUp() }, openDrawer = { toggleDrawer(drawerState.isClosed) } ) } ) { innerPadding -> 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 chatViewModel.loadMessages(it) navController.navigate(TalariaScreen.Chat.name) }) } composable(route = TalariaScreen.Chat.name) { ChatScreen(selectedDialog, chatViewModel = chatViewModel) } 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 = {}) } }