diff --git a/app/src/main/java/dev/lonami/talaria/MainActivity.kt b/app/src/main/java/dev/lonami/talaria/MainActivity.kt index d376475..edb7a29 100644 --- a/app/src/main/java/dev/lonami/talaria/MainActivity.kt +++ b/app/src/main/java/dev/lonami/talaria/MainActivity.kt @@ -3,28 +3,11 @@ package dev.lonami.talaria import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Surface import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import dev.lonami.talaria.data.DialogSource -import dev.lonami.talaria.data.MessageSource -import dev.lonami.talaria.model.Dialog -import dev.lonami.talaria.model.Message +import dev.lonami.talaria.ui.LoginScreen import dev.lonami.talaria.ui.theme.TalariaTheme class MainActivity : ComponentActivity() { @@ -37,186 +20,9 @@ class MainActivity : ComponentActivity() { modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background ) { - Login() + LoginScreen() } } } } } - -enum class LoginStage { - ASK_PHONE, - ASK_CODE, -} - -fun isPhoneValid(phone: String): Boolean = phone.trim('+', ' ').isNotEmpty() -fun isLoginCodeValid(code: String): Boolean = code.trim().count { it.isDigit() } == 5 - -@Composable -fun PhoneInput(phone: String, onPhoneChanged: (String) -> Unit, onSendCode: () -> Unit) { - val focusManager = LocalFocusManager.current - - Text(stringResource(R.string.enter_phone)) - TextField( - phone, - label = { Text(stringResource(R.string.phone_international)) }, - placeholder = { Text(stringResource(R.string.phone_example)) }, - singleLine = true, - keyboardOptions = KeyboardOptions( - keyboardType = KeyboardType.Phone, - imeAction = ImeAction.Done - ), - keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), - modifier = Modifier.fillMaxWidth(), - onValueChange = onPhoneChanged - ) - Spacer(Modifier.height(16.dp)) - Button( - enabled = isPhoneValid(phone), - modifier = Modifier.fillMaxWidth(), - onClick = onSendCode - ) { - Text(stringResource(R.string.send_otp)) - } -} - -@Composable -fun OtpInput(otp: String, onOtpChanged: (String) -> Unit, onConfirmOtp: () -> Unit) { - val focusManager = LocalFocusManager.current - - Text(stringResource(R.string.enter_otp)) - TextField( - otp, - label = { Text(stringResource(R.string.otp)) }, - placeholder = { Text(stringResource(R.string.otp_example)) }, - singleLine = true, - keyboardOptions = KeyboardOptions( - keyboardType = KeyboardType.Number, - imeAction = ImeAction.Done - ), - keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), - modifier = Modifier.fillMaxWidth(), - onValueChange = onOtpChanged - ) - Spacer(Modifier.height(16.dp)) - Button( - enabled = isLoginCodeValid(otp), - modifier = Modifier.fillMaxWidth(), - onClick = onConfirmOtp - ) { - Text(stringResource(R.string.do_login)) - } -} - -@Composable -fun DialogCard(dialog: Dialog) { - Card( - modifier = Modifier - .fillMaxWidth() - .padding(8.dp, 16.dp) - ) { - Row { - Image( - painter = painterResource(R.drawable.ic_launcher_foreground), - contentDescription = stringResource(R.string.profile_photo), - ) - Column(modifier = Modifier.weight(1.0f)) { - Text(dialog.title, fontWeight = FontWeight.Bold) - Text(dialog.lastMessage) - } - Switch(dialog.pinned, enabled = false, onCheckedChange = null) - } - } -} - -@Composable -fun DialogList(dialogs: List) { - LazyColumn { - items(dialogs.size) { DialogCard(dialogs[it]) } - } -} - -@Composable -fun MessageCard(message: Message) { - Card( - elevation = 4.dp, - modifier = Modifier - .fillMaxWidth() - .padding(8.dp) - ) { - Column(modifier = Modifier - .fillMaxWidth() - .padding(8.dp)) { - Text(message.sender, fontWeight = FontWeight.Bold) - Text(message.text) - } - } -} - -@Composable -fun MessageList(messages: List) { - LazyColumn { - items(messages.size) { MessageCard(messages[it]) } - } -} - -@Composable -fun Login() { - var stage by remember { mutableStateOf(LoginStage.ASK_PHONE) } - var phone by remember { mutableStateOf("") } - var otp by remember { mutableStateOf("") } - - Column( - modifier = Modifier - .fillMaxSize() - .padding(16.dp), - verticalArrangement = Arrangement.Center - ) { - Text( - stringResource(R.string.welcome_to, stringResource(R.string.app_name)), - fontSize = 24.sp, - fontWeight = FontWeight.Bold, - modifier = Modifier - .fillMaxWidth() - .wrapContentWidth(Alignment.CenterHorizontally) - .padding(16.dp) - ) - when (stage) { - LoginStage.ASK_PHONE -> PhoneInput( - phone, - onPhoneChanged = { phone = it }, - onSendCode = { stage = LoginStage.ASK_CODE }) - LoginStage.ASK_CODE -> OtpInput(otp, onOtpChanged = { otp = it }, onConfirmOtp = { - - }) - } - } -} - -@Preview(showBackground = true) -@Composable -fun LoginPreview() { - TalariaTheme { - Login() - } -} - -@Preview -@Composable -fun DialogPreview() { - TalariaTheme { - DialogList( - DialogSource.loadDialogs() - ) - } -} - -@Preview -@Composable -fun ChatPreview() { - TalariaTheme { - MessageList( - MessageSource.loadMessages() - ) - } -} diff --git a/app/src/main/java/dev/lonami/talaria/ui/ChatScreen.kt b/app/src/main/java/dev/lonami/talaria/ui/ChatScreen.kt new file mode 100644 index 0000000..ed283eb --- /dev/null +++ b/app/src/main/java/dev/lonami/talaria/ui/ChatScreen.kt @@ -0,0 +1,52 @@ +package dev.lonami.talaria.ui + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material.Card +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import dev.lonami.talaria.data.MessageSource +import dev.lonami.talaria.model.Message +import dev.lonami.talaria.ui.theme.TalariaTheme + +@Composable +fun MessageCard(message: Message) { + Card( + elevation = 4.dp, + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + ) { + Text(message.sender, fontWeight = FontWeight.Bold) + Text(message.text) + } + } +} + +@Composable +fun MessageList(messages: List) { + LazyColumn { + items(messages.size) { MessageCard(messages[it]) } + } +} + +@Preview +@Composable +fun ChatPreview() { + TalariaTheme { + MessageList( + MessageSource.loadMessages() + ) + } +} diff --git a/app/src/main/java/dev/lonami/talaria/ui/DialogScreen.kt b/app/src/main/java/dev/lonami/talaria/ui/DialogScreen.kt new file mode 100644 index 0000000..8cb298b --- /dev/null +++ b/app/src/main/java/dev/lonami/talaria/ui/DialogScreen.kt @@ -0,0 +1,60 @@ +package dev.lonami.talaria.ui + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material.Card +import androidx.compose.material.Switch +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import dev.lonami.talaria.R +import dev.lonami.talaria.data.DialogSource +import dev.lonami.talaria.model.Dialog +import dev.lonami.talaria.ui.theme.TalariaTheme + +@Composable +fun DialogCard(dialog: Dialog) { + Card( + modifier = Modifier + .fillMaxWidth() + .padding(8.dp, 16.dp) + ) { + Row { + Image( + painter = painterResource(R.drawable.ic_launcher_foreground), + contentDescription = stringResource(R.string.profile_photo), + ) + Column(modifier = Modifier.weight(1.0f)) { + Text(dialog.title, fontWeight = FontWeight.Bold) + Text(dialog.lastMessage) + } + Switch(dialog.pinned, enabled = false, onCheckedChange = null) + } + } +} + +@Composable +fun DialogList(dialogs: List) { + LazyColumn { + items(dialogs.size) { DialogCard(dialogs[it]) } + } +} + +@Preview +@Composable +fun DialogPreview() { + TalariaTheme { + DialogList( + DialogSource.loadDialogs() + ) + } +} diff --git a/app/src/main/java/dev/lonami/talaria/ui/LoginScreen.kt b/app/src/main/java/dev/lonami/talaria/ui/LoginScreen.kt new file mode 100644 index 0000000..5313d08 --- /dev/null +++ b/app/src/main/java/dev/lonami/talaria/ui/LoginScreen.kt @@ -0,0 +1,126 @@ +package dev.lonami.talaria.ui + +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.Button +import androidx.compose.material.Text +import androidx.compose.material.TextField +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import dev.lonami.talaria.R +import dev.lonami.talaria.ui.theme.TalariaTheme + +enum class LoginStage { + ASK_PHONE, + ASK_CODE, +} + +fun isPhoneValid(phone: String): Boolean = phone.trim('+', ' ').isNotEmpty() +fun isLoginCodeValid(code: String): Boolean = code.trim().count { it.isDigit() } == 5 + +@Composable +fun PhoneInput(phone: String, onPhoneChanged: (String) -> Unit, onSendCode: () -> Unit) { + val focusManager = LocalFocusManager.current + + Text(stringResource(R.string.enter_phone)) + TextField( + phone, + label = { Text(stringResource(R.string.phone_international)) }, + placeholder = { Text(stringResource(R.string.phone_example)) }, + singleLine = true, + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Phone, + imeAction = ImeAction.Done + ), + keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), + modifier = Modifier.fillMaxWidth(), + onValueChange = onPhoneChanged + ) + Spacer(Modifier.height(16.dp)) + Button( + enabled = isPhoneValid(phone), + modifier = Modifier.fillMaxWidth(), + onClick = onSendCode + ) { + Text(stringResource(R.string.send_otp)) + } +} + +@Composable +fun OtpInput(otp: String, onOtpChanged: (String) -> Unit, onConfirmOtp: () -> Unit) { + val focusManager = LocalFocusManager.current + + Text(stringResource(R.string.enter_otp)) + TextField( + otp, + label = { Text(stringResource(R.string.otp)) }, + placeholder = { Text(stringResource(R.string.otp_example)) }, + singleLine = true, + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Number, + imeAction = ImeAction.Done + ), + keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), + modifier = Modifier.fillMaxWidth(), + onValueChange = onOtpChanged + ) + Spacer(Modifier.height(16.dp)) + Button( + enabled = isLoginCodeValid(otp), + modifier = Modifier.fillMaxWidth(), + onClick = onConfirmOtp + ) { + Text(stringResource(R.string.do_login)) + } +} + +@Composable +fun LoginScreen() { + var stage by remember { mutableStateOf(LoginStage.ASK_PHONE) } + var phone by remember { mutableStateOf("") } + var otp by remember { mutableStateOf("") } + + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp), + verticalArrangement = Arrangement.Center + ) { + Text( + stringResource(R.string.welcome_to, stringResource(R.string.app_name)), + fontSize = 24.sp, + fontWeight = FontWeight.Bold, + modifier = Modifier + .fillMaxWidth() + .wrapContentWidth(Alignment.CenterHorizontally) + .padding(16.dp) + ) + when (stage) { + LoginStage.ASK_PHONE -> PhoneInput( + phone, + onPhoneChanged = { phone = it }, + onSendCode = { stage = LoginStage.ASK_CODE }) + LoginStage.ASK_CODE -> OtpInput(otp, onOtpChanged = { otp = it }, onConfirmOtp = { + + }) + } + } +} + +@Preview(showBackground = true) +@Composable +fun LoginPreview() { + TalariaTheme { + LoginScreen() + } +} \ No newline at end of file