diff --git a/app/src/main/java/ru/myitschool/work/core/Constants.kt b/app/src/main/java/ru/myitschool/work/core/Constants.kt index f229fb7..3852103 100644 --- a/app/src/main/java/ru/myitschool/work/core/Constants.kt +++ b/app/src/main/java/ru/myitschool/work/core/Constants.kt @@ -1,10 +1,9 @@ package ru.myitschool.work.core object Constants { - const val HOST = "http://10.0.0.14:49182" // "http://10.0.0.14:49182" or "http://10.0.2.2:8080" + const val HOST = "http://10.0.0.172:49182" // "http://10.0.0.14:49182" or "http://10.0.2.2:8080" const val AUTH_URL = "/auth" const val INFO_URL = "/info" const val BOOKING_URL = "/booking" const val BOOK_URL = "/book" - const val GET_TOKEN = "/getToken" } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/data/repo/AuthRepository.kt b/app/src/main/java/ru/myitschool/work/data/repo/AuthRepository.kt index 0f29fc1..7a5a893 100644 --- a/app/src/main/java/ru/myitschool/work/data/repo/AuthRepository.kt +++ b/app/src/main/java/ru/myitschool/work/data/repo/AuthRepository.kt @@ -1,6 +1,7 @@ package ru.myitschool.work.data.repo import android.content.Context +import android.util.Log import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.edit @@ -25,6 +26,10 @@ object AuthRepository { } } } + + /** + * Из памяти + */ suspend fun getToken(): String? { if (tokenCache == null) { tokenCache = App.context.userDataStore.data @@ -33,10 +38,15 @@ object AuthRepository { preferences[stringPreferencesKey(TOKEN_KEY)] } } + Log.e("getTokenCache", tokenCache.toString()) return tokenCache } + /** + * При обращении к серверу + */ suspend fun getToken(login : String, password : String) : Result { + Log.e("getTokenNDSInAR", NetworkDataSource.getToken(login, password).toString()) return NetworkDataSource.getToken(login, password) } diff --git a/app/src/main/java/ru/myitschool/work/data/source/NetworkDataSource.kt b/app/src/main/java/ru/myitschool/work/data/source/NetworkDataSource.kt index 06a934e..c2de735 100644 --- a/app/src/main/java/ru/myitschool/work/data/source/NetworkDataSource.kt +++ b/app/src/main/java/ru/myitschool/work/data/source/NetworkDataSource.kt @@ -42,22 +42,29 @@ object NetworkDataSource { } suspend fun getToken(login: String, password: String): Result = withContext(Dispatchers.IO) { return@withContext runCatching { - val response = client.post("${Constants.HOST}/api${Constants.GET_TOKEN}") { + val response = client.post("${Constants.HOST}/api${Constants.AUTH_URL}") { contentType(ContentType.Application.Json) - setBody( - """ + Log.d("bodyInToken", + """ { "login" : "$login", "password" : "$password" - """.trimIndent() + } """.trimIndent() + ) + setBody( + """{ + "login" : "${login}", + "password" : "${password}" + } """.trimIndent() ) } + Log.e("getTokenInNDS", response.body()) if (response.status != HttpStatusCode.OK) { - error(response.status) + Log.e("getToken", response.status.toString()) + throw Exception("Неизвестная ошибка ${response.status}") } else if (response.status == HttpStatusCode.Unauthorized) { - error("Неверный логин или пароль") + throw Exception("Неверный логин или пароль") } - Log.e("getToken", response.status.toString()) response.body() } } diff --git a/app/src/main/java/ru/myitschool/work/domain/auth/GetTokenNetworkUseCase.kt b/app/src/main/java/ru/myitschool/work/domain/auth/GetTokenNetworkUseCase.kt index d1edf62..87a0754 100644 --- a/app/src/main/java/ru/myitschool/work/domain/auth/GetTokenNetworkUseCase.kt +++ b/app/src/main/java/ru/myitschool/work/domain/auth/GetTokenNetworkUseCase.kt @@ -1,11 +1,13 @@ package ru.myitschool.work.domain.auth +import android.util.Log import ru.myitschool.work.data.repo.AuthRepository class GetTokenNetworkUseCase( private val repository: AuthRepository ) { suspend operator fun invoke(login : String, password: String): Result { + Log.e("GetTokenNetworkUseCase", repository.getToken(login, password).toString()) return repository.getToken(login, password) } } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthScreen.kt b/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthScreen.kt index 703c25f..f8965c0 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthScreen.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthScreen.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.size import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.SecureTextField import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.Composable @@ -25,10 +26,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController +import io.ktor.http.HttpStatusCode import ru.myitschool.work.R import ru.myitschool.work.core.TestIds import ru.myitschool.work.ui.custom.component.CustomButon @@ -71,10 +74,10 @@ fun AuthScreen( } } } -@Composable -fun SecureScreen(enabled: Boolean = true) { - -} +//@Composable +//fun SecureScreen(enabled: Boolean = true) { +// +//} @Composable private fun Content( viewModel: AuthViewModel, @@ -112,14 +115,30 @@ private fun Content( ) { Text(stringResource(R.string.auth_sign_in)) } - if (state.error != "Connection refused" && state.error != null) { +// if (state.error != null) { +// Text( +// modifier = Modifier.testTag(TestIds.Auth.ERROR), +// text = state.error, +// style = MaterialTheme.typography.bodyMedium, +// color = Color.Red, +// ) +// } + if (state.error != null && !state.error.contains("401") && state.error.contains("Network")) { Text( modifier = Modifier.testTag(TestIds.Auth.ERROR), - text = "Неизвестная ошибка: ${state.error}", + text = state.error, style = MaterialTheme.typography.bodyMedium, color = Color.Red, ) - } else if (state.error == "Connection refused") { + } + if (state.error.toString().contains("401")) { + Text( + modifier = Modifier.testTag(TestIds.Auth.ERROR), + text = "Неверный логин или пароль", + style = MaterialTheme.typography.bodyMedium, + color = Color.Red, + ) + } else if (state.error.toString().contains("Network")) { Text( modifier = Modifier.testTag(TestIds.Auth.ERROR), text = "Отсутствует интернет-соединение", diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthViewModel.kt index 93abbb0..92fd117 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthViewModel.kt @@ -30,10 +30,10 @@ class AuthViewModel : ViewModel() { private val _actionFlow: MutableSharedFlow = MutableSharedFlow() val actionFlow: SharedFlow = _actionFlow - fun onIntent(intent: AuthIntent) { when (intent) { is AuthIntent.Send -> { + Log.e("onIntent", intent.login) viewModelScope.launch { getTokenNetworkUseCase.invoke(intent.login, intent.password).fold( onSuccess = { diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/main/MeetingResult.kt b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingResult.kt similarity index 61% rename from app/src/main/java/ru/myitschool/work/ui/screen/main/MeetingResult.kt rename to app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingResult.kt index 07779e2..b520f4c 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/main/MeetingResult.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingResult.kt @@ -1,4 +1,4 @@ -package ru.myitschool.work.ui.screen.main +package ru.myitschool.work.ui.screen.meetings object MeetingResult { const val REFRESH_STATUS = "refresh_status" diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsAction.kt b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsAction.kt index 2be688d..8affe18 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsAction.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsAction.kt @@ -1,4 +1,10 @@ package ru.myitschool.work.ui.screen.meetings -class MeetingsAction { +import ru.myitschool.work.ui.nav.AppDestination + +sealed interface MeetingsAction { + class Open( + val destination: AppDestination, + val clearBackStack: Boolean = false + ): MeetingsAction } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsViewModel.kt index ffdbda5..d3c27ba 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/meetings/MeetingsViewModel.kt @@ -1,18 +1,66 @@ package ru.myitschool.work.ui.screen.meetings +import android.provider.Settings.System.DATE_FORMAT import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import ru.myitschool.work.data.repo.AuthRepository +import ru.myitschool.work.data.repo.BookRepository +import ru.myitschool.work.domain.auth.LogoutUseCase +import ru.myitschool.work.domain.main.GetMainDataUseCase +import ru.myitschool.work.ui.nav.AuthScreenDestination +import ru.myitschool.work.ui.screen.main.MainAction +import ru.myitschool.work.ui.screen.main.MainState +import java.time.LocalDate +import java.time.format.DateTimeFormatter -class MeetingsViewModel : ViewModel() { +class MeetingsViewModel: ViewModel() { private val _uiState = MutableStateFlow(MeetingsState.Loading) val uiState: StateFlow = _uiState.asStateFlow() + private val _actionFlow: MutableSharedFlow = MutableSharedFlow() + val actionFlow: SharedFlow = _actionFlow + private val logoutUseCase by lazy { + LogoutUseCase(AuthRepository) + } + private val getMeetingsDataUseCase by lazy { + GetMainDataUseCase(BookRepository(AuthRepository)) + } + init { - private val _actionFlow: MutableSharedFlow = MutableSharedFlow() - val actionFlow: SharedFlow = _actionFlow - - + } +// fun onIntent(intent: MeetingIntent) { +// when(intent) { +// is MeetingIntent.Logout -> { +// viewModelScope.launch { +// logoutUseCase.invoke() +// _actionFlow.emit(/*TODo*/) +// } +// } +// is MeetingIntent.Refresh -> { +// /*TODO("обновляться автоматически с заданной периодичностью")*/ +// } +// } +// } + fun refresh() { + viewModelScope.launch { + _uiState.update { MeetingsState.Loading } + _uiState.update { + getMeetingsDataUseCase.invoke().fold( + onFailure = { error -> + MeetingsState.Error( + error = error.message?.takeIf { it.isNotBlank() } ?: "Unknown error" + ) + }, + onSuccess = TODO() + ) + } + } + } } \ No newline at end of file