First request #5
@@ -6,6 +6,7 @@ object TestIds {
|
|||||||
const val SIGN_BUTTON = "auth_sign_button"
|
const val SIGN_BUTTON = "auth_sign_button"
|
||||||
const val CODE_INPUT = "auth_code_input"
|
const val CODE_INPUT = "auth_code_input"
|
||||||
}
|
}
|
||||||
|
|
||||||
object Main {
|
object Main {
|
||||||
const val ERROR = "main_error"
|
const val ERROR = "main_error"
|
||||||
const val ADD_BUTTON = "main_add_button"
|
const val ADD_BUTTON = "main_add_button"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package ru.myitschool.work.data.repo
|
package ru.myitschool.work.data.repo
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import ru.myitschool.work.data.source.NetworkDataSource
|
import ru.myitschool.work.data.source.NetworkDataSource
|
||||||
|
|
||||||
object AuthRepository {
|
object AuthRepository {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class RootActivity : ComponentActivity() {
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
|
actionBar?.hide()
|
||||||
setContent {
|
setContent {
|
||||||
WorkTheme {
|
WorkTheme {
|
||||||
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
||||||
|
|||||||
@@ -35,14 +35,14 @@ fun AppNavHost(
|
|||||||
Box(
|
Box(
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Text(text = "Hello")
|
Text(text = "MAIN")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
composable<BookScreenDestination> {
|
composable<BookScreenDestination> {
|
||||||
Box(
|
Box(
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Text(text = "Hello")
|
Text(text = "BOOK")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package ru.myitschool.work.ui.screen.auth
|
package ru.myitschool.work.ui.screen.auth
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@@ -10,6 +11,7 @@ import androidx.compose.foundation.layout.size
|
|||||||
import androidx.compose.material3.Button
|
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.OutlinedTextField
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
import androidx.compose.material3.TextField
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -22,6 +24,7 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.layout.onGloballyPositioned
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
@@ -54,16 +57,16 @@ fun AuthScreen(
|
|||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.auth_title),
|
text = stringResource(R.string.auth_title),
|
||||||
style = MaterialTheme.typography.headlineSmall,
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
textAlign = TextAlign.Center
|
textAlign = TextAlign.Center
|
||||||
)
|
)
|
||||||
when (val currentState = state) {
|
when (val currentState = state) {
|
||||||
is AuthState.Data -> Content(viewModel, currentState)
|
|
||||||
is AuthState.Loading -> {
|
is AuthState.Loading -> {
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
modifier = Modifier.size(64.dp)
|
modifier = Modifier.size(64.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
else -> Content(viewModel, currentState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,11 +74,14 @@ fun AuthScreen(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun Content(
|
private fun Content(
|
||||||
viewModel: AuthViewModel,
|
viewModel: AuthViewModel,
|
||||||
state: AuthState.Data
|
state: AuthState,
|
||||||
) {
|
) {
|
||||||
var inputText by remember { mutableStateOf("") }
|
var inputText by remember { mutableStateOf("") }
|
||||||
|
val err by viewModel.errorFlow.collectAsState()
|
||||||
|
val isButtonEnabled by viewModel.isButtonEnabled.collectAsState()
|
||||||
|
|
||||||
Spacer(modifier = Modifier.size(16.dp))
|
Spacer(modifier = Modifier.size(16.dp))
|
||||||
TextField(
|
OutlinedTextField(
|
||||||
modifier = Modifier.testTag(TestIds.Auth.CODE_INPUT).fillMaxWidth(),
|
modifier = Modifier.testTag(TestIds.Auth.CODE_INPUT).fillMaxWidth(),
|
||||||
value = inputText,
|
value = inputText,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
@@ -85,12 +91,22 @@ private fun Content(
|
|||||||
label = { Text(stringResource(R.string.auth_label)) }
|
label = { Text(stringResource(R.string.auth_label)) }
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.size(16.dp))
|
Spacer(modifier = Modifier.size(16.dp))
|
||||||
|
if (state == AuthState.Error) {
|
||||||
|
Text(
|
||||||
|
text = err,
|
||||||
|
color = MaterialTheme.colorScheme.error,
|
||||||
|
modifier = Modifier.testTag(TestIds.Auth.ERROR)
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.size(16.dp))
|
||||||
|
}
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.testTag(TestIds.Auth.SIGN_BUTTON).fillMaxWidth(),
|
modifier = Modifier
|
||||||
|
.testTag(TestIds.Auth.SIGN_BUTTON)
|
||||||
|
.fillMaxWidth(),
|
||||||
onClick = {
|
onClick = {
|
||||||
viewModel.onIntent(AuthIntent.Send(inputText))
|
viewModel.onIntent(AuthIntent.Send(inputText))
|
||||||
},
|
},
|
||||||
enabled = true
|
enabled = isButtonEnabled
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.auth_sign_in))
|
Text(stringResource(R.string.auth_sign_in))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,6 @@ package ru.myitschool.work.ui.screen.auth
|
|||||||
sealed interface AuthState {
|
sealed interface AuthState {
|
||||||
object Loading: AuthState
|
object Loading: AuthState
|
||||||
object Data: AuthState
|
object Data: AuthState
|
||||||
|
|
||||||
|
object Error: AuthState
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package ru.myitschool.work.ui.screen.auth
|
package ru.myitschool.work.ui.screen.auth
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -18,26 +19,40 @@ class AuthViewModel : ViewModel() {
|
|||||||
private val _uiState = MutableStateFlow<AuthState>(AuthState.Data)
|
private val _uiState = MutableStateFlow<AuthState>(AuthState.Data)
|
||||||
val uiState: StateFlow<AuthState> = _uiState.asStateFlow()
|
val uiState: StateFlow<AuthState> = _uiState.asStateFlow()
|
||||||
|
|
||||||
|
private val _errorFlow = MutableStateFlow<String>("")
|
||||||
|
val errorFlow: StateFlow<String> = _errorFlow.asStateFlow()
|
||||||
|
|
||||||
|
private val _isButtonEnabled = MutableStateFlow<Boolean>(false)
|
||||||
|
val isButtonEnabled: StateFlow<Boolean> = _isButtonEnabled.asStateFlow()
|
||||||
|
|
||||||
private val _actionFlow: MutableSharedFlow<Unit> = MutableSharedFlow()
|
private val _actionFlow: MutableSharedFlow<Unit> = MutableSharedFlow()
|
||||||
val actionFlow: SharedFlow<Unit> = _actionFlow
|
val actionFlow: SharedFlow<Unit> = _actionFlow
|
||||||
|
|
||||||
fun onIntent(intent: AuthIntent) {
|
fun onIntent(intent: AuthIntent) {
|
||||||
when (intent) {
|
when (intent) {
|
||||||
is AuthIntent.Send -> {
|
is AuthIntent.Send -> {
|
||||||
|
onIntent(AuthIntent.TextInput(""))
|
||||||
viewModelScope.launch(Dispatchers.Default) {
|
viewModelScope.launch(Dispatchers.Default) {
|
||||||
_uiState.update { AuthState.Loading }
|
_uiState.update { AuthState.Loading }
|
||||||
checkAndSaveAuthCodeUseCase.invoke("9999").fold(
|
checkAndSaveAuthCodeUseCase.invoke(intent.text).fold(
|
||||||
onSuccess = {
|
onSuccess = {
|
||||||
_actionFlow.emit(Unit)
|
_actionFlow.emit(Unit)
|
||||||
},
|
},
|
||||||
onFailure = { error ->
|
onFailure = { error ->
|
||||||
error.printStackTrace()
|
error.printStackTrace()
|
||||||
_actionFlow.emit(Unit)
|
_errorFlow.update { error.message.toString() }
|
||||||
|
_uiState.update { AuthState.Error }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is AuthIntent.TextInput -> Unit
|
|
||||||
|
is AuthIntent.TextInput -> {
|
||||||
|
if (_uiState.value == AuthState.Error) _uiState.update { AuthState.Data }
|
||||||
|
if (intent.text.matches("[a-zA-Z0-9]{4}".toRegex())) {
|
||||||
|
_isButtonEnabled.update { true }
|
||||||
|
} else _isButtonEnabled.update { false }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,6 +52,6 @@ fun WorkTheme(
|
|||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colorScheme = colorScheme,
|
colorScheme = colorScheme,
|
||||||
typography = Typography,
|
typography = Typography,
|
||||||
content = content
|
content = content,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user