feat: LoginUseCase done

This commit is contained in:
a1pha 2025-02-19 18:52:20 +03:00
parent 3298dd98b4
commit 16199d485e
8 changed files with 148 additions and 52 deletions

@ -1,6 +1,5 @@
package ru.myitschool.work.data
import android.util.Log
import ru.myitschool.work.data.dto.UserDto
import ru.myitschool.work.data.local.CredentialsLocalDataSource
import ru.myitschool.work.data.local.UserLocalDataSource
@ -19,9 +18,15 @@ class UserRepositoryImpl(
return runCatching {
networkDataSource.login(credentialsLocalDataSource.updateToken(login, password))
.onSuccess { dto ->
map(dto).onSuccess { userLocalDataSource.cacheData(it) }
}
.fold(
onSuccess = { dto ->
map(dto).fold(
onSuccess = { userLocalDataSource.cacheData(it) },
onFailure = { error(it) }
)
},
onFailure = { error(it) }
)
}
}
@ -45,15 +50,26 @@ class UserRepositoryImpl(
return userLocalDataSource.getUser()!!
}
private fun map(userDto: UserDto): Result<UserEntity> {
private suspend fun map(userDto: UserDto): Result<UserEntity> {
return runCatching {
UserEntity(
id = userDto.id ?: error("Null user id"),
name = userDto.name ?: error("Null user name"),
lastVisit = userDto.lastVisit ?: error("Null user lastVisit"),
photoUrl = userDto.photoUrl ?: error("Null user photoUrl"),
position = userDto.position ?: error("Null user position")
position = userDto.position ?: error("Null user position"),
isAdmin = userDto.roleId?.let { it ->
networkDataSource.isRoleHasAdminPermissions(
it,
credentialsLocalDataSource.getToken()
).fold(onSuccess = { it }, onFailure = { error(it) })
} ?: error("Null user roleId")
)
}
}
override suspend fun getUserByLogin(login: String): Result<UserEntity> {
return networkDataSource.getUserByLogin(login, credentialsLocalDataSource.getToken()).fold(
onSuccess = { map(it) }, onFailure = { error(it) }
)
}
}

@ -1,31 +1,22 @@
package ru.myitschool.work.data.dto;
package ru.myitschool.work.data.dto
import androidx.annotation.Nullable;
import com.google.gson.annotations.SerializedName;
import kotlinx.serialization.Serializable;
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
public class UserDto {
@Nullable
@SerializedName("id")
public String id;
@Nullable
@SerializedName("name")
public String name;
@Nullable
@SerializedName("lastVisit")
public String lastVisit;
@Nullable
@SerializedName("photo")
public String photoUrl;
@Nullable
@SerializedName("position")
public String position;
@Nullable
@SerializedName("login")
public String login;
}
data class UserDto(
@SerialName("roleId")
val roleId: Int?,
@SerialName("name")
val name: String?,
@SerialName("lastVisit")
val lastVisit: String?,
@SerialName("photo")
val photoUrl: String?,
@SerialName("position")
val position: String?,
@SerialName("login")
val login: String?,
@SerialName("isCardBlocked")
val isCardBlocked: Boolean?
)

@ -14,7 +14,7 @@ object UserNetworkDataSource {
suspend fun isUserExist(login: String): Result<Boolean> = withContext(Dispatchers.IO) {
runCatching {
val result = KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/users/username/$login")
val result = KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/employees/$login")
result.status == HttpStatusCode.OK
}
}
@ -22,16 +22,45 @@ object UserNetworkDataSource {
suspend fun login(token: String): Result<UserDto> =
withContext(Dispatchers.IO) {
runCatching {
val result = KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/users/login") {
headers {
append(HttpHeaders.Authorization, token)
val result =
KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/employees/login") {
headers {
append(HttpHeaders.Authorization, token)
}
}
}
if (result.status != HttpStatusCode.OK)
error("Status ${result.status}")
result.body()
}
}
suspend fun getUserByLogin() {}
suspend fun isRoleHasAdminPermissions(roleId: Int, token: String): Result<Boolean> =
withContext(Dispatchers.IO) {
runCatching {
val response =
KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/roles/info?$roleId") {
headers {
append(HttpHeaders.Authorization, token)
}
}
response.status == HttpStatusCode.OK
}
}
suspend fun getUserByLogin(login: String, token: String): Result<UserDto> =
withContext(Dispatchers.IO) {
runCatching {
val response =
KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/employees/find?${login}") {
headers {
append(HttpHeaders.Authorization, token)
}
}
if (response.status == HttpStatusCode.OK)
error("Status ${response.status}")
response.body()
}
}
}

@ -1,9 +1,10 @@
package ru.myitschool.work.domain.entities
data class UserEntity(
val id: String,
val isAdmin: Boolean,
val name: String,
val lastVisit: String,
val photoUrl: String,
val position: String,
)

@ -0,0 +1,10 @@
package ru.myitschool.work.domain.user
import ru.myitschool.work.domain.entities.UserEntity
class GetUserByLoginUseCase(
private val repository: UserRepository
) {
suspend operator fun invoke(login: String): Result<UserEntity> = repository.getUserByLogin(login)
}

@ -5,4 +5,5 @@ import ru.myitschool.work.domain.entities.UserEntity
interface UserRepository {
suspend fun getCurrentUser(): UserEntity
suspend fun getUserByLogin(login: String) : Result<UserEntity>
}

@ -1,8 +1,9 @@
package ru.myitschool.work.ui.login
import android.graphics.Color
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.core.content.ContextCompat
import androidx.core.widget.doAfterTextChanged
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
@ -32,11 +33,18 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
binding.error.visibleOrGone(state is LoginViewModel.State.Error)
when (state) {
is LoginViewModel.State.Error -> binding.error.text = state.errorMessage
is LoginViewModel.State.Loading -> Unit
is LoginViewModel.State.Error -> {
binding.error.text = state.errorMessage
setButtonActive()
}
is LoginViewModel.State.Loading -> setButtonInactive()
is LoginViewModel.State.Waiting -> Unit
is LoginViewModel.State.LoginCheckCompleted -> binding.login.isEnabled =
state.isCompleted
is LoginViewModel.State.LoginCheckCompleted -> {
state.isCompleted.let {
if (it) setButtonActive() else setButtonInactive()
binding.login.isEnabled = it
}
}
}
}
@ -57,6 +65,18 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
}
}
private fun setButtonInactive() {
binding.login.setTextColor(Color.BLACK)
binding.login.background =
ContextCompat.getDrawable(requireContext(), R.drawable.inactive_button)
}
private fun setButtonActive() {
binding.login.setTextColor(Color.WHITE)
binding.login.background =
ContextCompat.getDrawable(requireContext(), R.drawable.main_button)
}
override fun onDestroy() {
_binding = null
super.onDestroy()

@ -2,10 +2,11 @@ package ru.myitschool.work.ui.profile
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.paging.LoadState
import com.squareup.picasso.Picasso
import ru.myitschool.work.R
import ru.myitschool.work.databinding.FragmentUserBinding
@ -22,14 +23,17 @@ class UserFragment : Fragment(R.layout.fragment_user) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
_binding = FragmentUserBinding.bind(view)
val adapter = PassesListAdapter()
binding.passes.adapter = adapter
viewModel.state.collectWithLifecycle(this) { state ->
(binding.refresh as SwipeRefreshLayout).isRefreshing =
state is UserViewModel.State.Loading
binding.refresh.isRefreshing = state is UserViewModel.State.Loading
binding.content?.visibleOrGone(state is UserViewModel.State.Show)
when (state) {
is UserViewModel.State.Loading -> Unit
is UserViewModel.State.Show -> {
val user = state.userEntity
binding.findUser.visibleOrGone(user.isAdmin)
binding.fullname.text = user.name
binding.position.text = user.position
binding.lastEntry.text = user.lastVisit
@ -37,14 +41,38 @@ class UserFragment : Fragment(R.layout.fragment_user) {
}
}
(binding.refresh as SwipeRefreshLayout).setOnRefreshListener {
viewModel.listState.collectWithLifecycle(this) { listState ->
adapter.submitData(listState)
}
adapter.loadStateFlow.collectWithLifecycle(this) { data ->
val dataState = data.refresh
binding.refresh.isRefreshing = dataState is LoadState.Loading
binding.error.visibleOrGone(dataState is LoadState.Error)
if (dataState is LoadState.Error) {
binding.error.text = dataState.error.toString()
}
}
binding.refresh.setOnRefreshListener {
viewModel.onRefresh()
adapter.refresh()
}
binding.logout.setOnClickListener {
viewModel.onLogout()
AlertDialog.Builder(requireContext())
.setTitle("Выход")
.setMessage("Вы уверены, что хотите выйти из аккаунта?")
.setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(android.R.string.ok) { _, _ -> viewModel.onLogout() }
.show()
findNavController().navigate(R.id.action_userFragment_to_loginFragment)
}
binding.findUser.setOnClickListener {
findNavController().navigate(R.id.find_user)
}
}
}