main #8

Open
student-m-kuchergin wants to merge 17 commits from KHBGPU-org/NTO-2026-Android-TeamTask-Template:main into main
5 changed files with 82 additions and 19 deletions
Showing only changes of commit 62bcfe6291 - Show all commits

View File

@ -34,6 +34,7 @@ android {
} }
dependencies { dependencies {
implementation("androidx.compose.foundation:foundation:1.10.3")
defaultComposeLibrary() defaultComposeLibrary()
implementation("androidx.datastore:datastore-preferences:1.1.7") implementation("androidx.datastore:datastore-preferences:1.1.7")
implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.4.0") implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.4.0")
@ -47,4 +48,8 @@ dependencies {
implementation("io.ktor:ktor-client-content-negotiation:$ktor") implementation("io.ktor:ktor-client-content-negotiation:$ktor")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor") implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0")
implementation("androidx.compose.ui:ui-tooling-preview:1.10.3")
implementation("androidx.compose.runtime:runtime-tracing:1.10.3")
implementation("androidx.compose.runtime:runtime-tracing:1.10.3")
debugImplementation ("androidx.compose.ui:ui-tooling:1.10.3")
} }

View File

@ -11,12 +11,16 @@ import androidx.compose.material3.Scaffold
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import ru.myitschool.work.ui.screen.AppNavHost import ru.myitschool.work.ui.screen.AppNavHost
import ru.myitschool.work.ui.theme.WorkTheme import ru.myitschool.work.ui.theme.WorkTheme
import android.view.View
class RootActivity : ComponentActivity() { class RootActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
// Hide the status bar.
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
actionBar?.hide()
setContent { setContent {
WorkTheme { WorkTheme {

View File

@ -11,13 +11,11 @@ import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -29,8 +27,18 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import ru.myitschool.work.R import ru.myitschool.work.R
import ru.myitschool.work.core.TestIds import ru.myitschool.work.core.TestIds
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.material3.OutlinedTextField
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.unit.sp
@Composable @Composable
fun AuthScreen( fun AuthScreen(
@ -39,6 +47,7 @@ fun AuthScreen(
) { ) {
val state by viewModel.uiState.collectAsState() val state by viewModel.uiState.collectAsState()
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
viewModel.actionFlow.collect { action -> viewModel.actionFlow.collect { action ->
when (action) { when (action) {
@ -52,15 +61,11 @@ fun AuthScreen(
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(all = 24.dp), .padding(all = 44.dp),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center verticalArrangement = Arrangement.Center
) { ) {
Text(
text = stringResource(R.string.auth_title),
style = MaterialTheme.typography.headlineSmall,
textAlign = TextAlign.Center
)
when (val currentState = state) { when (val currentState = state) {
is AuthState.Data -> Content(viewModel, currentState) is AuthState.Data -> Content(viewModel, currentState)
is AuthState.Loading -> { is AuthState.Loading -> {
@ -79,34 +84,70 @@ private fun Content
state: AuthState.Data state: AuthState.Data
) { ) {
var inputLogin by rememberSaveable { mutableStateOf("") } var inputLogin by rememberSaveable { mutableStateOf("") }
Spacer(modifier = Modifier.size(16.dp)) val googleSans = FontFamily(
TextField( Font(R.font.googlesans_regular, FontWeight.Medium, FontStyle.Normal)
)
Spacer(modifier = Modifier.size(0.dp))
Text(
text = stringResource(R.string.auth_title),
fontFamily = googleSans,
color = Color(0xFF284777),
fontSize = 35.sp,
textAlign = TextAlign.Center,
fontWeight = FontWeight.Medium,
fontStyle = FontStyle.Normal,
modifier = Modifier.fillMaxWidth(1f)
)
Spacer(modifier = Modifier.size(106.dp))
Text(
text = stringResource(R.string.auth_label_login),
fontFamily = googleSans,
color = Color(0xFF74777f),
textAlign = TextAlign.Start,
fontWeight = FontWeight.Medium,
fontStyle = FontStyle.Normal,
modifier = Modifier.fillMaxWidth(1f)
)
Spacer(modifier = Modifier.size(10.dp))
OutlinedTextField(
modifier = Modifier.testTag(TestIds.Auth.LOGIN_INPUT).fillMaxWidth(), modifier = Modifier.testTag(TestIds.Auth.LOGIN_INPUT).fillMaxWidth(),
value = inputLogin, value = inputLogin,
shape = RoundedCornerShape(12.dp),
colors = TextFieldDefaults.colors(unfocusedContainerColor = Color(0xFFededf4)),
onValueChange = { onValueChange = {
inputLogin = it inputLogin = it
viewModel.onIntent(AuthIntent.TextInput( viewModel.onIntent(AuthIntent.TextInput(
it, it,
textPassword = "" textPassword = ""
)) ))
}, }
label = { Text(stringResource(R.string.auth_label_login)) }
) )
var inputPassword by rememberSaveable { mutableStateOf("") } var inputPassword by rememberSaveable { mutableStateOf("") }
Spacer(modifier = Modifier.size(16.dp)) Spacer(modifier = Modifier.size(20.dp))
TextField( Text(
text = stringResource(R.string.auth_label_password),
fontFamily = googleSans,
color = Color(0xFF74777f),
textAlign = TextAlign.Start,
fontWeight = FontWeight.Medium,
fontStyle = FontStyle.Normal,
modifier = Modifier.fillMaxWidth(1f)
)
Spacer(modifier = Modifier.size(10.dp))
OutlinedTextField(
modifier = Modifier.testTag(TestIds.Auth.PASSWORD_INPUT).fillMaxWidth(), modifier = Modifier.testTag(TestIds.Auth.PASSWORD_INPUT).fillMaxWidth(),
value = inputPassword, value = inputPassword,
shape = RoundedCornerShape(12.dp),
colors = TextFieldDefaults.colors(unfocusedContainerColor = Color(0xFFededf4)),
onValueChange = { onValueChange = {
inputPassword = it inputPassword = it
viewModel.onIntent(AuthIntent.TextInput( viewModel.onIntent(AuthIntent.TextInput(
inputLogin, inputLogin,
textPassword = it textPassword = it
)) ))
}, }
label = { Text(stringResource(R.string.auth_label_password)) }
) )
Spacer(modifier = Modifier.size(16.dp)) Spacer(modifier = Modifier.size(35.dp))
Button( Button(
modifier = Modifier.testTag(TestIds.Auth.SIGN_BUTTON).fillMaxWidth(), modifier = Modifier.testTag(TestIds.Auth.SIGN_BUTTON).fillMaxWidth(),
onClick = { onClick = {
@ -114,7 +155,14 @@ private fun Content
}, },
enabled = state.isEnabledSend enabled = state.isEnabledSend
) { ) {
Text(stringResource(R.string.auth_sign_in)) Text(
text = "Войти",
modifier = Modifier.padding(10.dp),
fontFamily = googleSans,
fontWeight = FontWeight.Medium,
fontStyle = FontStyle.Normal,
fontSize = 18.sp
)
} }
if (state.error != null) { if (state.error != null) {
Text( Text(
@ -128,4 +176,10 @@ private fun Content
color = Color.Red, color = Color.Red,
) )
} }
}
@Preview
@Composable
fun AuthView() {
AuthScreen(navController = rememberNavController())
} }

Binary file not shown.

View File

@ -1,7 +1,7 @@
<resources> <resources>
<string name="app_name">Work</string> <string name="app_name">Work</string>
<string name="title_activity_root">Приложение</string> <string name="title_activity_root">Приложение</string>
<string name="auth_title">Привет! Введи код для авторизации</string> <string name="auth_title">Авторизация</string>
<string name="auth_label_login">Логин</string> <string name="auth_label_login">Логин</string>
<string name="auth_label_password">Пароль</string> <string name="auth_label_password">Пароль</string>
<string name="auth_sign_in">Войти</string> <string name="auth_sign_in">Войти</string>