forked from student-25326/NTO-2025-Android-TeamTask
yo
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package ru.myitschool.work.data.dto
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class AvailableBookingResponse(
|
||||
val dates: Map<String, List<AvailablePlace>> = emptyMap()
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class AvailablePlace(
|
||||
val id: Int,
|
||||
val place: String
|
||||
)
|
||||
@@ -0,0 +1,9 @@
|
||||
package ru.myitschool.work.data.dto
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class BookRequest(
|
||||
val date: String,
|
||||
val placeID: Int
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package ru.myitschool.work.data.dto
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class UserInfoResponse(
|
||||
val name: String,
|
||||
val photoUrl: String,
|
||||
val booking: Map<String, BookingItem> = emptyMap()
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class BookingItem(
|
||||
val id: Int,
|
||||
val place: String
|
||||
)
|
||||
@@ -1,16 +1,13 @@
|
||||
package ru.myitschool.work.data.repo
|
||||
|
||||
import ru.myitschool.work.data.source.NetworkDataSource
|
||||
import ru.myitschool.work.domain.MyResult
|
||||
|
||||
object AuthRepository {
|
||||
|
||||
private var codeCache: String? = null
|
||||
|
||||
suspend fun checkAndSave(text: String): Result<Boolean> {
|
||||
return NetworkDataSource.checkAuth(text).onSuccess { success ->
|
||||
if (success) {
|
||||
codeCache = text
|
||||
}
|
||||
}
|
||||
suspend fun checkAndSave(code: String): MyResult<Boolean> {
|
||||
return NetworkDataSource.checkAuth(code)
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,18 @@
|
||||
package ru.myitschool.work.data.source
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.engine.cio.CIO
|
||||
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.statement.bodyAsText
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.serialization.kotlinx.json.json
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.json.Json
|
||||
import ru.myitschool.work.core.Constants
|
||||
import ru.myitschool.work.data.dto.UserInfoResponse
|
||||
import ru.myitschool.work.domain.MyResult
|
||||
|
||||
object NetworkDataSource {
|
||||
private val client by lazy {
|
||||
@@ -28,15 +30,35 @@ object NetworkDataSource {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun checkAuth(code: String): Result<Boolean> = withContext(Dispatchers.IO) {
|
||||
return@withContext runCatching {
|
||||
suspend fun checkAuth(code: String): MyResult<Boolean> = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
val response = client.get(getUrl(code, Constants.AUTH_URL))
|
||||
when (response.status) {
|
||||
HttpStatusCode.OK -> true
|
||||
else -> error(response.bodyAsText())
|
||||
HttpStatusCode.OK -> MyResult.Success(true)
|
||||
else -> {
|
||||
MyResult.Error("Неверный код или ошибка сервера")
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
MyResult.Error("Сетевая ошибка")
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getUserInfo(code: String): MyResult<UserInfoResponse> = withContext(Dispatchers.IO){
|
||||
try {
|
||||
val response = client.get(getUrl(code, Constants.INFO_URL))
|
||||
when (response.status) {
|
||||
HttpStatusCode.OK -> {
|
||||
val userInfo: UserInfoResponse = response.body()
|
||||
MyResult.Success(userInfo)
|
||||
}
|
||||
else -> {
|
||||
MyResult.Error("Ошибка получения данных пользователя")
|
||||
}
|
||||
}
|
||||
} catch (e: Exception){
|
||||
MyResult.Error("Сетевая ошибка")
|
||||
}
|
||||
}
|
||||
private fun getUrl(code: String, targetUrl: String) = "${Constants.HOST}/api/$code$targetUrl"
|
||||
}
|
||||
6
app/src/main/java/ru/myitschool/work/domain/MyResult.kt
Normal file
6
app/src/main/java/ru/myitschool/work/domain/MyResult.kt
Normal file
@@ -0,0 +1,6 @@
|
||||
package ru.myitschool.work.domain
|
||||
|
||||
sealed class MyResult<out T> {
|
||||
data class Success<T>(val data: T): MyResult<T>()
|
||||
data class Error(val error: String): MyResult<Nothing>()
|
||||
}
|
||||
@@ -1,23 +1,25 @@
|
||||
package ru.myitschool.work.domain.auth
|
||||
|
||||
import androidx.datastore.dataStore
|
||||
import ru.myitschool.work.data.repo.AuthRepository
|
||||
import ru.myitschool.work.domain.MyResult
|
||||
import ru.myitschool.work.util.DataStoreManager
|
||||
|
||||
class CheckAndSaveAuthCodeUseCase(
|
||||
private val repository: AuthRepository,
|
||||
) {
|
||||
suspend operator fun invoke(
|
||||
code: String
|
||||
): Result<Unit> = try {
|
||||
val response = repository.checkAndSave(code)
|
||||
if (response.isSuccess) {
|
||||
suspend operator fun invoke(code: String): MyResult<Unit> {
|
||||
return when (val repoResult = repository.checkAndSave(code)) {
|
||||
is MyResult.Success -> {
|
||||
if (repoResult.data) {
|
||||
DataStoreManager.saveAuthCode(code)
|
||||
Result.success(Unit)
|
||||
MyResult.Success(Unit)
|
||||
} else {
|
||||
Result.failure(Exception("Неверный код"))
|
||||
}
|
||||
} catch (e: Exception){
|
||||
Result.failure(e)
|
||||
MyResult.Error("Неверный код")
|
||||
}
|
||||
}
|
||||
is MyResult.Error -> {
|
||||
MyResult.Error(repoResult.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package ru.myitschool.work.domain.user
|
||||
|
||||
class GetUserUseCase {
|
||||
}
|
||||
6
app/src/main/java/ru/myitschool/work/domain/user/User.kt
Normal file
6
app/src/main/java/ru/myitschool/work/domain/user/User.kt
Normal file
@@ -0,0 +1,6 @@
|
||||
package ru.myitschool.work.domain.user
|
||||
|
||||
data class User(
|
||||
val name: String,
|
||||
val imageUrl: String
|
||||
)
|
||||
@@ -8,6 +8,7 @@ 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.domain.MyResult
|
||||
import ru.myitschool.work.domain.auth.CheckAndSaveAuthCodeUseCase
|
||||
|
||||
class AuthViewModel : ViewModel() {
|
||||
@@ -17,42 +18,49 @@ class AuthViewModel : ViewModel() {
|
||||
|
||||
fun onIntent(intent: AuthIntent) {
|
||||
when (intent) {
|
||||
is AuthIntent.Send -> {
|
||||
viewModelScope.launch {
|
||||
_uiState.update {
|
||||
it.copy(isLoading = true)
|
||||
AuthIntent.Send -> sendCode()
|
||||
is AuthIntent.TextInput -> updateCode(intent.text)
|
||||
}
|
||||
}
|
||||
|
||||
checkAndSaveAuthCodeUseCase(_uiState.value.code).fold(
|
||||
onSuccess = {
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
isLoading = false,
|
||||
isAuthenticated = true
|
||||
)
|
||||
}
|
||||
|
||||
},
|
||||
onFailure = { error ->
|
||||
private fun updateCode(newCode: String) {
|
||||
val trimmed = newCode.trim()
|
||||
val isValid = trimmed.length == 4 && trimmed.matches(Regex("^[a-zA-Z0-9]{4}$"))
|
||||
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
isLoading = false,
|
||||
error = error.message ?: "Ошибка",
|
||||
isAuthenticated = false
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
is AuthIntent.TextInput -> _uiState.update {
|
||||
it.copy(
|
||||
code = intent.text,
|
||||
isButtonEnabled = intent.text.length == 4 &&
|
||||
uiState.value.code.matches(Regex("^[a-zA-Z0-9]+$")),
|
||||
code = trimmed,
|
||||
isButtonEnabled = isValid,
|
||||
error = null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendCode() {
|
||||
val currentCode = _uiState.value.code
|
||||
if (currentCode.length != 4 || !currentCode.matches(Regex("^[a-zA-Z0-9]{4}$"))) return
|
||||
|
||||
viewModelScope.launch {
|
||||
_uiState.update { it.copy(isLoading = true, error = null) }
|
||||
|
||||
when (val result = checkAndSaveAuthCodeUseCase(currentCode)){
|
||||
is MyResult.Success<*> -> {
|
||||
_uiState.update {
|
||||
it.copy(isLoading = false, isAuthenticated = true)
|
||||
}
|
||||
}
|
||||
|
||||
is MyResult.Error -> {
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
isLoading = false,
|
||||
error = result.error,
|
||||
isAuthenticated = false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user