Add retrofit

Integrate login endpoint
This commit is contained in:
Nymos 2025-02-19 11:38:13 +03:00
parent b319718ac6
commit 507e076eca
9 changed files with 49 additions and 37 deletions

View File

@ -1,6 +1,6 @@
package com.nto.data.models package com.nto.data.models
data class LoginData( data class LoginResult(
val successful: Boolean, val successful: Boolean,
val message: String? val message: String?
) )

View File

@ -1,7 +1,7 @@
package com.nto.data.repository package com.nto.data.repository
import com.nto.data.models.LoginData import com.nto.data.models.LoginResult
interface DataRepository { interface DataRepository {
suspend fun login(email: String, password: String): LoginData suspend fun auth(login: String, password: String): LoginResult
} }

View File

@ -1,21 +1,17 @@
package com.nto.data.repository package com.nto.data.repository
import com.nto.data.models.LoginData import com.nto.data.models.LoginResult
import com.nto.data.utils.Provider import com.nto.data.utils.Provider
import okhttp3.Credentials
import javax.inject.Inject import javax.inject.Inject
class DataRepositoryImpl @Inject constructor() : DataRepository { class DataRepositoryImpl @Inject constructor() : DataRepository {
override suspend fun login(email: String, password: String): LoginData { override suspend fun auth(login: String, password: String): LoginResult {
val result = Provider.provideRetrofit().login( val result = Provider.provideRetrofit().auth(
email, password Credentials.basic(login, password)
).execute() ).execute()
if (result.isSuccessful) {
val body = result.body() return LoginResult(result.isSuccessful, result.message())
if (body != null) {
return body
}
}
return LoginData(false, result.message())
} }
} }

View File

@ -1,11 +1,11 @@
package com.nto.data.utils package com.nto.data.utils
import com.nto.data.models.LoginData import okhttp3.ResponseBody
import retrofit2.Call import retrofit2.Call
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Query import retrofit2.http.Header
interface RetrofitApi { interface RetrofitApi {
@GET("login") @GET("auth")
fun login(@Query("email") email: String, @Query("password") password: String): Call<LoginData> fun auth(@Header("Authorization") token: String): Call<ResponseBody>
} }

View File

@ -1,7 +1,7 @@
package com.nto.domain.repository package com.nto.domain.repository
import com.nto.data.models.LoginData import com.nto.data.models.LoginResult
interface DomainRepository { interface DomainRepository {
suspend fun login(email: String, password: String): LoginData suspend fun auth(email: String, password: String): LoginResult
} }

View File

@ -1,22 +1,20 @@
package com.nto.domain.repository package com.nto.domain.repository
import com.nto.data.models.LoginData import com.nto.data.models.LoginResult
import com.nto.data.repository.DataRepositoryImpl import com.nto.data.repository.DataRepositoryImpl
import java.io.IOException import java.io.IOException
import java.security.MessageDigest
import javax.inject.Inject import javax.inject.Inject
class DomainRepositoryImpl @Inject constructor(private val dataRepositoryImpl: DataRepositoryImpl) : class DomainRepositoryImpl @Inject constructor(private val dataRepositoryImpl: DataRepositoryImpl) :
DomainRepository { DomainRepository {
override suspend fun login(email: String, password: String): LoginData { override suspend fun auth(email: String, password: String): LoginResult {
return try { return try {
dataRepositoryImpl.login( dataRepositoryImpl.auth(
email = email, login = email,
password = MessageDigest.getInstance("SHA-256").digest(password.toByteArray()) password = password
.toString()
) )
} catch (e: IOException) { } catch (e: IOException) {
LoginData(false, "IO exception was thrown: ${e.message}") LoginResult(false, "IO exception was thrown: ${e.message}")
} }
} }
} }

View File

@ -1,16 +1,15 @@
package com.nto.domain.usecase package com.nto.domain.usecase
import com.nto.data.models.LoginData import com.nto.data.models.LoginResult
import com.nto.domain.repository.DomainRepositoryImpl import com.nto.domain.repository.DomainRepositoryImpl
import javax.inject.Inject import javax.inject.Inject
class LoginUseCase @Inject constructor(private val domainRepositoryImpl: DomainRepositoryImpl) { class LoginUseCase @Inject constructor(private val domainRepositoryImpl: DomainRepositoryImpl) {
fun checkCredentials(email: String, password: String): Boolean { fun checkCredentials(email: String, password: String): Boolean {
val emailRegex = Regex("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\$") return password.isNotBlank() && email.isNotBlank()
return password.isNotBlank() && emailRegex.matches(email)
} }
suspend fun login(email: String, password: String): LoginData { suspend fun auth(email: String, password: String): LoginResult {
return domainRepositoryImpl.login(email, password) return domainRepositoryImpl.auth(email, password)
} }
} }

View File

@ -1,18 +1,24 @@
package com.nto.presentation.screens.loginScreen package com.nto.presentation.screens.loginScreen
import android.content.Context
import android.widget.Toast
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import com.nto.data.utils.Destinations
import com.nto.domain.usecase.LoginUseCase
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.invoke
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class LoginViewModel @Inject constructor(): ViewModel(){ class LoginViewModel @Inject constructor(private val useCase: LoginUseCase, @ApplicationContext private val context: Context) : ViewModel() {
private val _state = MutableStateFlow(LoginScreenState()) private val _state = MutableStateFlow(LoginScreenState())
val state: StateFlow<LoginScreenState> val state: StateFlow<LoginScreenState>
@ -29,12 +35,25 @@ class LoginViewModel @Inject constructor(): ViewModel(){
} }
private fun checkInput() { private fun checkInput() {
//TODO: domain level val state = _state.value
val result = useCase.checkCredentials(state.email, state.password)
_state.tryEmit(_state.value.copy(disabled = !result))
} }
fun login(navController: NavHostController) { fun login(navController: NavHostController) {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
//TODO: domain level val state = _state.value
val result = useCase.auth(state.email, state.password)
if (result.message != null) {
Dispatchers.Main {
Toast.makeText(context, result.message, Toast.LENGTH_LONG).show()
}
}
if (result.successful) {
Dispatchers.Main {
navController.navigate(Destinations.Profile.toString())
}
}
} }
} }
} }

View File

@ -5,7 +5,7 @@
<string name="text_password">Пароль</string> <string name="text_password">Пароль</string>
<string name="greeting_login_description">Войдите в свой аккаунт чтобы продолжить</string> <string name="greeting_login_description">Войдите в свой аккаунт чтобы продолжить</string>
<string name="greeting_login">Вход</string> <string name="greeting_login">Вход</string>
<string name="placholder_login" translatable="false">pivanov</string> <string name="placholder_login" translatable="false">\@pivanov</string>
<string name="placeholder_password" translatable="false">**********</string> <string name="placeholder_password" translatable="false">**********</string>
<string name="title_profile">Профиль</string> <string name="title_profile">Профиль</string>
<string name="label_qr_login">Вход по коду</string> <string name="label_qr_login">Вход по коду</string>