Compare commits
No commits in common. "ea53d3cb1dfcdef5e341de07a4ffe3f37ffb2113" and "35ed8e12c6cdaa9cc9443e4d18288cedee07a3f5" have entirely different histories.
ea53d3cb1d
...
35ed8e12c6
|
@ -1,19 +1,13 @@
|
||||||
package dev.lonami.talaria
|
package dev.lonami.talaria
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.layout.padding
|
||||||
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.*
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
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
|
||||||
|
@ -22,7 +16,6 @@ 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),
|
||||||
|
@ -30,94 +23,8 @@ 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 DrawerAction(
|
fun TalariaAppBar(currentScreen: TalariaScreen, canNavigateBack: Boolean, navigateUp: () -> Unit) {
|
||||||
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(
|
TopAppBar(
|
||||||
title = { Text(stringResource(currentScreen.title)) },
|
title = { Text(stringResource(currentScreen.title)) },
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
|
@ -128,20 +35,13 @@ fun TalariaAppBar(
|
||||||
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)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TalariaApp(modifier: Modifier = Modifier) {
|
fun TalariaApp() {
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
val backStackEntry by navController.currentBackStackEntryAsState()
|
val backStackEntry by navController.currentBackStackEntryAsState()
|
||||||
val currentScreen =
|
val currentScreen =
|
||||||
|
@ -150,36 +50,15 @@ fun TalariaApp(modifier: Modifier = Modifier) {
|
||||||
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(
|
||||||
modifier = modifier,
|
|
||||||
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 ->
|
||||||
ModalDrawer(
|
|
||||||
drawerState = drawerState,
|
|
||||||
gesturesEnabled = drawerState.isOpen,
|
|
||||||
drawerContent = {
|
|
||||||
Drawer(onSelect = {})
|
|
||||||
}) {
|
|
||||||
|
|
||||||
NavHost(
|
NavHost(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
startDestination = if (loggedIn) {
|
startDestination = if (loggedIn) {
|
||||||
|
@ -205,24 +84,4 @@ fun TalariaApp(modifier: Modifier = Modifier) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun TopBarPreview() {
|
|
||||||
TalariaAppBar(
|
|
||||||
currentScreen = TalariaScreen.Dialog,
|
|
||||||
canNavigateBack = false,
|
|
||||||
navigateUp = {},
|
|
||||||
openDrawer = {},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun NavDrawerPreview() {
|
|
||||||
Surface {
|
|
||||||
Drawer(onSelect = {})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,10 @@ import dev.lonami.talaria.ui.theme.TalariaTheme
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MessageCard(message: Message, modifier: Modifier = Modifier) {
|
fun MessageCard(message: Message) {
|
||||||
Card(
|
Card(
|
||||||
elevation = 4.dp,
|
elevation = 4.dp,
|
||||||
modifier = modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
) {
|
) {
|
||||||
|
@ -44,8 +44,8 @@ fun MessageCard(message: Message, modifier: Modifier = Modifier) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MessageList(messages: List<Message>, listState: LazyListState, modifier: Modifier = Modifier) {
|
fun MessageList(messages: List<Message>, modifier: Modifier, listState: LazyListState) {
|
||||||
LazyColumn(modifier = modifier, state = listState) {
|
LazyColumn(modifier, state = listState) {
|
||||||
items(messages.size) { MessageCard(messages[it]) }
|
items(messages.size) { MessageCard(messages[it]) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,9 @@ fun MessageList(messages: List<Message>, listState: LazyListState, modifier: Mod
|
||||||
fun MessageInputField(
|
fun MessageInputField(
|
||||||
messageText: String,
|
messageText: String,
|
||||||
onMessageChanged: (String) -> Unit,
|
onMessageChanged: (String) -> Unit,
|
||||||
onSendMessage: () -> Unit,
|
onSendMessage: () -> Unit
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
Row(modifier = modifier) {
|
Row {
|
||||||
TextField(
|
TextField(
|
||||||
messageText,
|
messageText,
|
||||||
placeholder = { Text(stringResource(R.string.write_message)) },
|
placeholder = { Text(stringResource(R.string.write_message)) },
|
||||||
|
@ -79,17 +78,13 @@ fun MessageInputField(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ChatScreen(
|
fun ChatScreen(selectedDialog: String, chatViewModel: ChatViewModel = viewModel()) {
|
||||||
selectedDialog: String,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
chatViewModel: ChatViewModel = viewModel(),
|
|
||||||
) {
|
|
||||||
val chatUiState by chatViewModel.uiState.collectAsState()
|
val chatUiState by chatViewModel.uiState.collectAsState()
|
||||||
var messageText by remember { mutableStateOf("") }
|
var messageText by remember { mutableStateOf("") }
|
||||||
val messageListState = rememberLazyListState()
|
val messageListState = rememberLazyListState()
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
Column(modifier = modifier.fillMaxSize()) {
|
Column(modifier = Modifier.fillMaxSize()) {
|
||||||
MessageList(
|
MessageList(
|
||||||
chatUiState.messages,
|
chatUiState.messages,
|
||||||
modifier = Modifier.weight(1.0f),
|
modifier = Modifier.weight(1.0f),
|
||||||
|
|
|
@ -31,9 +31,9 @@ import java.time.format.DateTimeFormatter
|
||||||
import java.time.format.FormatStyle
|
import java.time.format.FormatStyle
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Dialog(dialog: Dialog, onDialogSelected: () -> Unit, modifier: Modifier = Modifier) {
|
fun Dialog(dialog: Dialog, onDialogSelected: () -> Unit) {
|
||||||
Row(
|
Row(
|
||||||
modifier = modifier
|
modifier = Modifier
|
||||||
.padding(4.dp)
|
.padding(4.dp)
|
||||||
.clickable(onClick = onDialogSelected)
|
.clickable(onClick = onDialogSelected)
|
||||||
) {
|
) {
|
||||||
|
@ -98,12 +98,8 @@ fun Dialog(dialog: Dialog, onDialogSelected: () -> Unit, modifier: Modifier = Mo
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DialogList(
|
fun DialogList(dialogs: List<Dialog>, onDialogSelected: (String) -> Unit) {
|
||||||
dialogs: List<Dialog>,
|
LazyColumn {
|
||||||
onDialogSelected: (String) -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
LazyColumn(modifier = modifier) {
|
|
||||||
items(dialogs.size) {
|
items(dialogs.size) {
|
||||||
Dialog(dialogs[it], onDialogSelected = {
|
Dialog(dialogs[it], onDialogSelected = {
|
||||||
onDialogSelected(dialogs[it].id)
|
onDialogSelected(dialogs[it].id)
|
||||||
|
@ -116,11 +112,10 @@ fun DialogList(
|
||||||
@Composable
|
@Composable
|
||||||
fun DialogScreen(
|
fun DialogScreen(
|
||||||
onDialogSelected: (String) -> Unit,
|
onDialogSelected: (String) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
dialogViewModel: DialogViewModel = viewModel()
|
||||||
dialogViewModel: DialogViewModel = viewModel(),
|
|
||||||
) {
|
) {
|
||||||
val dialogUiState by dialogViewModel.uiState.collectAsState()
|
val dialogUiState by dialogViewModel.uiState.collectAsState()
|
||||||
Surface(modifier = modifier) {
|
Surface {
|
||||||
DialogList(dialogUiState.dialogs, onDialogSelected = onDialogSelected)
|
DialogList(dialogUiState.dialogs, onDialogSelected = onDialogSelected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,15 +30,9 @@ fun isPhoneValid(phone: String): Boolean = phone.trim('+', ' ').isNotEmpty()
|
||||||
fun isLoginCodeValid(code: String): Boolean = code.trim().count { it.isDigit() } == 5
|
fun isLoginCodeValid(code: String): Boolean = code.trim().count { it.isDigit() } == 5
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PhoneInput(
|
fun PhoneInput(phone: String, onPhoneChanged: (String) -> Unit, onSendCode: () -> Unit) {
|
||||||
phone: String,
|
|
||||||
onPhoneChanged: (String) -> Unit,
|
|
||||||
onSendCode: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
val focusManager = LocalFocusManager.current
|
val focusManager = LocalFocusManager.current
|
||||||
|
|
||||||
Column(modifier = modifier) {
|
|
||||||
Text(stringResource(R.string.enter_phone))
|
Text(stringResource(R.string.enter_phone))
|
||||||
TextField(
|
TextField(
|
||||||
phone,
|
phone,
|
||||||
|
@ -61,19 +55,12 @@ fun PhoneInput(
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.send_otp))
|
Text(stringResource(R.string.send_otp))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun OtpInput(
|
fun OtpInput(otp: String, onOtpChanged: (String) -> Unit, onConfirmOtp: () -> Unit) {
|
||||||
otp: String,
|
|
||||||
onOtpChanged: (String) -> Unit,
|
|
||||||
onConfirmOtp: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
val focusManager = LocalFocusManager.current
|
val focusManager = LocalFocusManager.current
|
||||||
|
|
||||||
Column(modifier = modifier) {
|
|
||||||
Text(stringResource(R.string.enter_otp))
|
Text(stringResource(R.string.enter_otp))
|
||||||
TextField(
|
TextField(
|
||||||
otp,
|
otp,
|
||||||
|
@ -96,11 +83,10 @@ fun OtpInput(
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.do_login))
|
Text(stringResource(R.string.do_login))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LoginScreen(onConfirmOtp: () -> Unit, modifier: Modifier = Modifier) {
|
fun LoginScreen(onConfirmOtp: () -> Unit) {
|
||||||
var stage by remember { mutableStateOf(LoginStage.ASK_PHONE) }
|
var stage by remember { mutableStateOf(LoginStage.ASK_PHONE) }
|
||||||
var phone by remember { mutableStateOf("") }
|
var phone by remember { mutableStateOf("") }
|
||||||
var otp by remember { mutableStateOf("") }
|
var otp by remember { mutableStateOf("") }
|
||||||
|
@ -108,7 +94,7 @@ fun LoginScreen(onConfirmOtp: () -> Unit, modifier: Modifier = Modifier) {
|
||||||
var tokenPtr by remember { mutableStateOf(0L) }
|
var tokenPtr by remember { mutableStateOf(0L) }
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(16.dp),
|
.padding(16.dp),
|
||||||
verticalArrangement = Arrangement.Center
|
verticalArrangement = Arrangement.Center
|
||||||
|
|
Loading…
Reference in New Issue